• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.uwb;
18 
19 import static org.junit.Assert.assertThrows;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.anyInt;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.doThrow;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.never;
26 import static org.mockito.Mockito.times;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.AttributionSource;
31 import android.os.PersistableBundle;
32 import android.os.Process;
33 import android.os.RemoteException;
34 
35 import androidx.test.ext.junit.runners.AndroidJUnit4;
36 import androidx.test.filters.SmallTest;
37 
38 import com.android.modules.utils.build.SdkLevel;
39 
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.mockito.ArgumentCaptor;
43 import org.mockito.Mockito;
44 
45 import java.util.List;
46 import java.util.concurrent.Executor;
47 
48 /**
49  * Test of {@link RangingManager}.
50  */
51 @SmallTest
52 @RunWith(AndroidJUnit4.class)
53 public class RangingManagerTest {
54 
55     private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
56     private static final PersistableBundle PARAMS = new PersistableBundle();
57     private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
58     private static final UwbAddress ADDRESS = UwbAddress.fromBytes(new byte[] {0x0, 0x1});
59     private static final byte[] DATA = new byte[] {0x0, 0x1};
60     private static final int UID = Process.myUid();
61     private static final String PACKAGE_NAME = "com.uwb.test";
62     private static final AttributionSource ATTRIBUTION_SOURCE =
63             new AttributionSource.Builder(UID).setPackageName(PACKAGE_NAME).build();
64     private static final String VALID_CHIP_ID = "validChipId";
65     private static final int HANDLE_ID = 12;
66     private static final int PID = Process.myPid();
67 
68     @Test
testOpenSession_OpenRangingInvoked()69     public void testOpenSession_OpenRangingInvoked() throws RemoteException {
70         IUwbAdapter adapter = mock(IUwbAdapter.class);
71         RangingManager rangingManager = new RangingManager(adapter);
72         RangingSession.Callback callback = mock(RangingSession.Callback.class);
73         rangingManager.openSession(
74                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, /* chipIds= */ null);
75         verify(adapter, times(1))
76                 .openRanging(eq(ATTRIBUTION_SOURCE), any(), any(), any(), eq(/* chipId= */ null));
77     }
78 
79     @Test
testOpenSession_validChipId_OpenRangingInvoked()80     public void testOpenSession_validChipId_OpenRangingInvoked() throws RemoteException {
81         IUwbAdapter adapter = mock(IUwbAdapter.class);
82         when(adapter.getChipIds()).thenReturn(List.of(VALID_CHIP_ID));
83         RangingManager rangingManager = new RangingManager(adapter);
84         RangingSession.Callback callback = mock(RangingSession.Callback.class);
85         rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, VALID_CHIP_ID);
86         verify(adapter, times(1))
87                 .openRanging(eq(ATTRIBUTION_SOURCE), any(), any(), any(), eq(VALID_CHIP_ID));
88     }
89 
90     @Test
testOpenSession_validChipId_RuntimeException()91     public void testOpenSession_validChipId_RuntimeException() throws RemoteException {
92         IUwbAdapter adapter = mock(IUwbAdapter.class);
93         doThrow(new RemoteException())
94                 .when(adapter)
95                 .openRanging(eq(ATTRIBUTION_SOURCE), any(), any(), any(), eq(VALID_CHIP_ID));
96         Mockito.when(adapter.getChipIds()).thenReturn(List.of(VALID_CHIP_ID));
97         RangingManager rangingManager = new RangingManager(adapter);
98         RangingSession.Callback callback = mock(RangingSession.Callback.class);
99         assertThrows(
100                 RuntimeException.class,
101                 () ->
102                         rangingManager.openSession(
103                                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, VALID_CHIP_ID));
104     }
105 
106     @Test
testOpenSession_invalidChipId_IllegalArgumentException()107     public void testOpenSession_invalidChipId_IllegalArgumentException() throws RemoteException {
108         String invalidChipId = "invalidChipId";
109         IUwbAdapter adapter = mock(IUwbAdapter.class);
110         Mockito.when(adapter.getChipIds()).thenReturn(List.of(VALID_CHIP_ID));
111         RangingManager rangingManager = new RangingManager(adapter);
112         RangingSession.Callback callback = mock(RangingSession.Callback.class);
113         assertThrows(
114                 IllegalArgumentException.class,
115                 () ->
116                         rangingManager.openSession(
117                                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, invalidChipId));
118         verify(adapter, times(0))
119                 .openRanging(eq(ATTRIBUTION_SOURCE), any(), any(), any(), eq(invalidChipId));
120     }
121 
122     @Test
testOnRangingOpened_InvalidSessionHandle()123     public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException {
124         IUwbAdapter adapter = mock(IUwbAdapter.class);
125         RangingManager rangingManager = new RangingManager(adapter);
126         RangingSession.Callback callback = mock(RangingSession.Callback.class);
127 
128         rangingManager.onRangingOpened(new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID));
129         verify(callback, times(0)).onOpened(any());
130     }
131 
132     @Test
testOnRangingOpened_MultipleSessionsRegistered()133     public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException {
134         IUwbAdapter adapter = mock(IUwbAdapter.class);
135         RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
136         RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
137         ArgumentCaptor<SessionHandle> sessionHandleCaptor =
138                 ArgumentCaptor.forClass(SessionHandle.class);
139 
140         RangingManager rangingManager = new RangingManager(adapter);
141         rangingManager.openSession(
142                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1, /* chipIds= */ null);
143         verify(adapter, times(1))
144                 .openRanging(
145                         eq(ATTRIBUTION_SOURCE),
146                         sessionHandleCaptor.capture(),
147                         any(),
148                         any(),
149                         eq(/* chipId= */ null));
150         SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
151 
152         rangingManager.openSession(
153                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2, /* chipIds= */ null);
154         verify(adapter, times(2))
155                 .openRanging(
156                         eq(ATTRIBUTION_SOURCE),
157                         sessionHandleCaptor.capture(),
158                         any(),
159                         any(),
160                         eq(/* chipId= */ null));
161         SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
162 
163         rangingManager.onRangingOpened(sessionHandle1);
164         verify(callback1, times(1)).onOpened(any());
165         verify(callback2, times(0)).onOpened(any());
166 
167         rangingManager.onRangingOpened(sessionHandle2);
168         verify(callback1, times(1)).onOpened(any());
169         verify(callback2, times(1)).onOpened(any());
170     }
171 
172     @Test
testCorrectCallbackInvoked()173     public void testCorrectCallbackInvoked() throws RemoteException {
174         IUwbAdapter adapter = mock(IUwbAdapter.class);
175         RangingManager rangingManager = new RangingManager(adapter);
176         RangingSession.Callback callback = mock(RangingSession.Callback.class);
177 
178         ArgumentCaptor<SessionHandle> sessionHandleCaptor =
179                 ArgumentCaptor.forClass(SessionHandle.class);
180 
181         rangingManager.openSession(
182                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, /* chipIds= */ null);
183         verify(adapter, times(1))
184                 .openRanging(
185                         eq(ATTRIBUTION_SOURCE),
186                         sessionHandleCaptor.capture(),
187                         any(),
188                         any(),
189                         eq(/* chipId= */ null));
190         SessionHandle handle = sessionHandleCaptor.getValue();
191 
192         rangingManager.onRangingOpened(handle);
193         verify(callback, times(1)).onOpened(any());
194 
195         rangingManager.onRangingStarted(handle, PARAMS);
196         verify(callback, times(1)).onStarted(eq(PARAMS));
197 
198         rangingManager.onRangingStartFailed(handle, REASON, PARAMS);
199         verify(callback, times(1)).onStartFailed(eq(REASON), eq(PARAMS));
200 
201         RangingReport report = UwbTestUtils.getRangingReports(1);
202         rangingManager.onRangingResult(handle, report);
203         verify(callback, times(1)).onReportReceived(eq(report));
204 
205         rangingManager.onRangingReconfigured(handle, PARAMS);
206         verify(callback, times(1)).onReconfigured(eq(PARAMS));
207 
208         rangingManager.onRangingReconfigureFailed(handle, REASON, PARAMS);
209         verify(callback, times(1)).onReconfigureFailed(eq(REASON), eq(PARAMS));
210 
211         rangingManager.onRangingStopped(handle, REASON, PARAMS);
212         verify(callback, times(1)).onStopped(eq(REASON), eq(PARAMS));
213 
214         rangingManager.onRangingStopFailed(handle, REASON, PARAMS);
215         verify(callback, times(1)).onStopFailed(eq(REASON), eq(PARAMS));
216 
217         rangingManager.onControleeAdded(handle, PARAMS);
218         verify(callback, times(1)).onControleeAdded(eq(PARAMS));
219 
220         rangingManager.onControleeAddFailed(handle, REASON, PARAMS);
221         verify(callback, times(1)).onControleeAddFailed(eq(REASON), eq(PARAMS));
222 
223         rangingManager.onControleeRemoved(handle, PARAMS);
224         verify(callback, times(1)).onControleeRemoved(eq(PARAMS));
225 
226         rangingManager.onControleeRemoveFailed(handle, REASON, PARAMS);
227         verify(callback, times(1)).onControleeRemoveFailed(eq(REASON), eq(PARAMS));
228 
229         rangingManager.onRangingPaused(handle, PARAMS);
230         verify(callback, times(1)).onPaused(eq(PARAMS));
231 
232         rangingManager.onRangingPauseFailed(handle, REASON, PARAMS);
233         verify(callback, times(1)).onPauseFailed(eq(REASON), eq(PARAMS));
234 
235         rangingManager.onRangingResumed(handle, PARAMS);
236         verify(callback, times(1)).onResumed(eq(PARAMS));
237 
238         rangingManager.onRangingResumeFailed(handle, REASON, PARAMS);
239         verify(callback, times(1)).onResumeFailed(eq(REASON), eq(PARAMS));
240 
241         rangingManager.onDataSent(handle, ADDRESS, PARAMS);
242         verify(callback, times(1)).onDataSent(eq(ADDRESS), eq(PARAMS));
243 
244         rangingManager.onDataSendFailed(handle, ADDRESS, REASON, PARAMS);
245         verify(callback, times(1)).onDataSendFailed(eq(ADDRESS), eq(REASON), eq(PARAMS));
246 
247         // Test should only run on V+ devices.
248         if (SdkLevel.isAtLeastV()) {
249             rangingManager.onDataTransferPhaseConfigured(handle, PARAMS);
250             verify(callback, times(1)).onDataTransferPhaseConfigured(eq(PARAMS));
251 
252             rangingManager.onDataTransferPhaseConfigFailed(handle, REASON, PARAMS);
253             verify(callback, times(1)).onDataTransferPhaseConfigFailed(eq(REASON), eq(PARAMS));
254         }
255 
256         rangingManager.onDataReceived(handle, ADDRESS, PARAMS, DATA);
257         verify(callback, times(1)).onDataReceived(eq(ADDRESS), eq(PARAMS), eq(DATA));
258 
259         rangingManager.onDataReceiveFailed(handle, ADDRESS, REASON, PARAMS);
260         verify(callback, times(1)).onDataReceiveFailed(eq(ADDRESS), eq(REASON), eq(PARAMS));
261 
262         rangingManager.onServiceDiscovered(handle, PARAMS);
263         verify(callback, times(1)).onServiceDiscovered(eq(PARAMS));
264 
265         rangingManager.onServiceConnected(handle, PARAMS);
266         verify(callback, times(1)).onServiceConnected(eq(PARAMS));
267 
268         // Test should only run on U+ devices.
269         if (SdkLevel.isAtLeastU()) {
270             rangingManager.onRangingRoundsUpdateDtTagStatus(handle, PARAMS);
271             verify(callback, times(1))
272                     .onRangingRoundsUpdateDtTagStatus(eq(PARAMS));
273         }
274 
275         // Test should only run on V+ devices.
276         if (SdkLevel.isAtLeastV()) {
277             rangingManager.onHybridSessionControllerConfigured(handle, PARAMS);
278             verify(callback, times(1))
279                     .onHybridSessionControllerConfigured(eq(PARAMS));
280 
281             rangingManager.onHybridSessionControllerConfigurationFailed(handle, REASON, PARAMS);
282             verify(callback, times(1))
283                     .onHybridSessionControllerConfigurationFailed(eq(REASON), eq(PARAMS));
284 
285             rangingManager.onHybridSessionControleeConfigured(handle, PARAMS);
286             verify(callback, times(1))
287                     .onHybridSessionControleeConfigured(eq(PARAMS));
288 
289             rangingManager.onHybridSessionControleeConfigurationFailed(handle, REASON, PARAMS);
290             verify(callback, times(1))
291                     .onHybridSessionControleeConfigurationFailed(eq(REASON), eq(PARAMS));
292         }
293 
294         rangingManager.onRangingClosed(handle, REASON, PARAMS);
295         verify(callback, times(1)).onClosed(eq(REASON), eq(PARAMS));
296     }
297 
298     @Test
testNoCallbackInvoked_sessionClosed()299     public void testNoCallbackInvoked_sessionClosed() throws RemoteException {
300         IUwbAdapter adapter = mock(IUwbAdapter.class);
301         RangingManager rangingManager = new RangingManager(adapter);
302         RangingSession.Callback callback = mock(RangingSession.Callback.class);
303 
304         ArgumentCaptor<SessionHandle> sessionHandleCaptor =
305                 ArgumentCaptor.forClass(SessionHandle.class);
306 
307         rangingManager.openSession(
308                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, /* chipIds= */ null);
309         verify(adapter, times(1))
310                 .openRanging(
311                         eq(ATTRIBUTION_SOURCE),
312                         sessionHandleCaptor.capture(),
313                         any(),
314                         any(),
315                         eq(/* chipId= */ null));
316         SessionHandle handle = sessionHandleCaptor.getValue();
317         rangingManager.onRangingClosed(handle, REASON, PARAMS);
318         verify(callback, times(1)).onClosed(eq(REASON), eq(PARAMS));
319 
320         rangingManager.onRangingOpened(handle);
321         verify(callback, never()).onOpened(any());
322 
323         rangingManager.onRangingStarted(handle, PARAMS);
324         verify(callback, never()).onStarted(eq(PARAMS));
325 
326         rangingManager.onRangingStartFailed(handle, REASON, PARAMS);
327         verify(callback, never()).onStartFailed(eq(REASON), eq(PARAMS));
328 
329         RangingReport report = UwbTestUtils.getRangingReports(1);
330         rangingManager.onRangingResult(handle, report);
331         verify(callback, never()).onReportReceived(eq(report));
332 
333         rangingManager.onRangingReconfigured(handle, PARAMS);
334         verify(callback, never()).onReconfigured(eq(PARAMS));
335 
336         rangingManager.onRangingReconfigureFailed(handle, REASON, PARAMS);
337         verify(callback, never()).onReconfigureFailed(eq(REASON), eq(PARAMS));
338 
339         rangingManager.onRangingStopped(handle, REASON, PARAMS);
340         verify(callback, never()).onStopped(eq(REASON), eq(PARAMS));
341 
342         rangingManager.onRangingStopFailed(handle, REASON, PARAMS);
343         verify(callback, never()).onStopFailed(eq(REASON), eq(PARAMS));
344 
345         rangingManager.onControleeAdded(handle, PARAMS);
346         verify(callback, never()).onControleeAdded(eq(PARAMS));
347 
348         rangingManager.onControleeAddFailed(handle, REASON, PARAMS);
349         verify(callback, never()).onControleeAddFailed(eq(REASON), eq(PARAMS));
350 
351         rangingManager.onControleeRemoved(handle, PARAMS);
352         verify(callback, never()).onControleeRemoved(eq(PARAMS));
353 
354         rangingManager.onControleeRemoveFailed(handle, REASON, PARAMS);
355         verify(callback, never()).onControleeRemoveFailed(eq(REASON), eq(PARAMS));
356 
357         rangingManager.onRangingPaused(handle, PARAMS);
358         verify(callback, never()).onPaused(eq(PARAMS));
359 
360         rangingManager.onRangingPauseFailed(handle, REASON, PARAMS);
361         verify(callback, never()).onPauseFailed(eq(REASON), eq(PARAMS));
362 
363         rangingManager.onRangingResumed(handle, PARAMS);
364         verify(callback, never()).onResumed(eq(PARAMS));
365 
366         rangingManager.onRangingResumeFailed(handle, REASON, PARAMS);
367         verify(callback, never()).onResumeFailed(eq(REASON), eq(PARAMS));
368 
369         rangingManager.onDataSent(handle, ADDRESS, PARAMS);
370         verify(callback, never()).onDataSent(eq(ADDRESS), eq(PARAMS));
371 
372         rangingManager.onDataSendFailed(handle, ADDRESS, REASON, PARAMS);
373         verify(callback, never()).onDataSendFailed(eq(ADDRESS), eq(REASON), eq(PARAMS));
374 
375         rangingManager.onDataReceived(handle, ADDRESS, PARAMS, DATA);
376         verify(callback, never()).onDataReceived(eq(ADDRESS), eq(PARAMS), eq(DATA));
377 
378         rangingManager.onDataReceiveFailed(handle, ADDRESS, REASON, PARAMS);
379         verify(callback, never()).onDataReceiveFailed(eq(ADDRESS), eq(REASON), eq(PARAMS));
380 
381         // Test should only run on V+ devices.
382         if (SdkLevel.isAtLeastV()) {
383             rangingManager.onDataTransferPhaseConfigured(handle, PARAMS);
384             verify(callback, never()).onDataTransferPhaseConfigured(eq(PARAMS));
385 
386             rangingManager.onDataTransferPhaseConfigFailed(handle, REASON, PARAMS);
387             verify(callback, never()).onDataTransferPhaseConfigFailed(eq(REASON), eq(PARAMS));
388         }
389 
390         rangingManager.onServiceDiscovered(handle, PARAMS);
391         verify(callback, never()).onServiceDiscovered(eq(PARAMS));
392 
393         rangingManager.onServiceConnected(handle, PARAMS);
394         verify(callback, never()).onServiceConnected(eq(PARAMS));
395 
396         if (SdkLevel.isAtLeastV()) {
397             rangingManager.onHybridSessionControllerConfigured(handle, PARAMS);
398             verify(callback, never()).onHybridSessionControllerConfigured(eq(PARAMS));
399 
400             rangingManager.onHybridSessionControllerConfigurationFailed(handle, REASON, PARAMS);
401             verify(callback, never()).onHybridSessionControllerConfigurationFailed(
402                     eq(REASON), eq(PARAMS));
403 
404             rangingManager.onHybridSessionControleeConfigured(handle, PARAMS);
405             verify(callback, never()).onHybridSessionControleeConfigured(eq(PARAMS));
406 
407             rangingManager.onHybridSessionControleeConfigurationFailed(handle, REASON, PARAMS);
408             verify(callback, never()).onHybridSessionControleeConfigurationFailed(
409                     eq(REASON), eq(PARAMS));
410         }
411 
412         rangingManager.onRangingClosed(handle, REASON, PARAMS);
413         verify(callback, times(1)).onClosed(eq(REASON), eq(PARAMS));
414     }
415 
416     @Test
testOnRangingClosed_MultipleSessionsRegistered()417     public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException {
418         IUwbAdapter adapter = mock(IUwbAdapter.class);
419         // Verify that if multiple sessions are registered, only the session that is
420         // requested to close receives the associated callbacks
421         RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
422         RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
423 
424         RangingManager rangingManager = new RangingManager(adapter);
425         ArgumentCaptor<SessionHandle> sessionHandleCaptor =
426                 ArgumentCaptor.forClass(SessionHandle.class);
427 
428         rangingManager.openSession(
429                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1, /* chipIds= */ null);
430         verify(adapter, times(1))
431                 .openRanging(
432                         eq(ATTRIBUTION_SOURCE),
433                         sessionHandleCaptor.capture(),
434                         any(),
435                         any(),
436                         eq(/* chipId= */ null));
437         SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
438 
439         rangingManager.openSession(
440                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2, /* chipIds= */ null);
441         verify(adapter, times(2))
442                 .openRanging(
443                         eq(ATTRIBUTION_SOURCE),
444                         sessionHandleCaptor.capture(),
445                         any(),
446                         any(),
447                         eq(/* chipId= */ null));
448         SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
449 
450         rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS);
451         verify(callback1, times(1)).onClosed(anyInt(), any());
452         verify(callback2, times(0)).onClosed(anyInt(), any());
453 
454         rangingManager.onRangingClosed(sessionHandle2, REASON, PARAMS);
455         verify(callback1, times(1)).onClosed(anyInt(), any());
456         verify(callback2, times(1)).onClosed(anyInt(), any());
457     }
458 
459     @Test
testOnRangingReport_MultipleSessionsRegistered()460     public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException {
461         IUwbAdapter adapter = mock(IUwbAdapter.class);
462         RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
463         RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
464 
465         ArgumentCaptor<SessionHandle> sessionHandleCaptor =
466                 ArgumentCaptor.forClass(SessionHandle.class);
467 
468         RangingManager rangingManager = new RangingManager(adapter);
469         rangingManager.openSession(
470                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1, /* chipIds= */ null);
471         verify(adapter, times(1))
472                 .openRanging(
473                         eq(ATTRIBUTION_SOURCE),
474                         sessionHandleCaptor.capture(),
475                         any(),
476                         any(),
477                         eq(/* chipId= */ null));
478         SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
479 
480         rangingManager.onRangingStarted(sessionHandle1, PARAMS);
481         rangingManager.openSession(
482                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2, /* chipIds= */ null);
483         verify(adapter, times(2))
484                 .openRanging(
485                         eq(ATTRIBUTION_SOURCE),
486                         sessionHandleCaptor.capture(),
487                         any(),
488                         any(),
489                         eq(/* chipId= */ null));
490         SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
491         rangingManager.onRangingStarted(sessionHandle2, PARAMS);
492 
493         rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1));
494         verify(callback1, times(1)).onReportReceived(any());
495         verify(callback2, times(0)).onReportReceived(any());
496 
497         rangingManager.onRangingResult(sessionHandle2, UwbTestUtils.getRangingReports(1));
498         verify(callback1, times(1)).onReportReceived(any());
499         verify(callback2, times(1)).onReportReceived(any());
500     }
501 
502     @Test
testReasons()503     public void testReasons() throws RemoteException {
504         runReason(RangingChangeReason.LOCAL_API, RangingSession.Callback.REASON_LOCAL_REQUEST);
505 
506         runReason(
507                 RangingChangeReason.MAX_SESSIONS_REACHED,
508                 RangingSession.Callback.REASON_MAX_SESSIONS_REACHED);
509 
510         runReason(
511                 RangingChangeReason.PROTOCOL_SPECIFIC,
512                 RangingSession.Callback.REASON_PROTOCOL_SPECIFIC_ERROR);
513 
514         runReason(
515                 RangingChangeReason.REMOTE_REQUEST, RangingSession.Callback.REASON_REMOTE_REQUEST);
516 
517         runReason(RangingChangeReason.SYSTEM_POLICY, RangingSession.Callback.REASON_SYSTEM_POLICY);
518 
519         runReason(
520                 RangingChangeReason.SYSTEM_REGULATION,
521                 RangingSession.Callback.REASON_SYSTEM_REGULATION);
522 
523         runReason(
524                 RangingChangeReason.BAD_PARAMETERS, RangingSession.Callback.REASON_BAD_PARAMETERS);
525 
526         runReason(RangingChangeReason.UNKNOWN, RangingSession.Callback.REASON_UNKNOWN);
527     }
528 
runReason( @angingChangeReason int reasonIn, @RangingSession.Callback.Reason int reasonOut)529     private void runReason(
530             @RangingChangeReason int reasonIn, @RangingSession.Callback.Reason int reasonOut)
531             throws RemoteException {
532         IUwbAdapter adapter = mock(IUwbAdapter.class);
533         RangingManager rangingManager = new RangingManager(adapter);
534         RangingSession.Callback callback = mock(RangingSession.Callback.class);
535 
536         ArgumentCaptor<SessionHandle> sessionHandleCaptor =
537                 ArgumentCaptor.forClass(SessionHandle.class);
538 
539         rangingManager.openSession(
540                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, /* chipIds= */ null);
541         verify(adapter, times(1))
542                 .openRanging(
543                         eq(ATTRIBUTION_SOURCE),
544                         sessionHandleCaptor.capture(),
545                         any(),
546                         any(),
547                         eq(/* chipId= */ null));
548         SessionHandle handle = sessionHandleCaptor.getValue();
549 
550         rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS);
551         verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
552 
553         // Open a new session
554         rangingManager.openSession(
555                 ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback, /* chipIds= */ null);
556         verify(adapter, times(2))
557                 .openRanging(
558                         eq(ATTRIBUTION_SOURCE),
559                         sessionHandleCaptor.capture(),
560                         any(),
561                         any(),
562                         eq(/* chipId= */ null));
563         handle = sessionHandleCaptor.getValue();
564         rangingManager.onRangingOpened(handle);
565 
566         rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS);
567         verify(callback, times(1)).onStartFailed(eq(reasonOut), eq(PARAMS));
568 
569         rangingManager.onRangingReconfigureFailed(handle, reasonIn, PARAMS);
570         verify(callback, times(1)).onReconfigureFailed(eq(reasonOut), eq(PARAMS));
571 
572         rangingManager.onRangingStopFailed(handle, reasonIn, PARAMS);
573         verify(callback, times(1)).onStopFailed(eq(reasonOut), eq(PARAMS));
574 
575         rangingManager.onRangingClosed(handle, reasonIn, PARAMS);
576         verify(callback, times(1)).onClosed(eq(reasonOut), eq(PARAMS));
577     }
578 }
579