diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2020-12-16 18:52:42 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-12-16 18:52:42 +0000 |
commit | 9b924caa12c07cb724b1492c1a7beaf9a87beb9e (patch) | |
tree | 375f3176b9f3e235fe7b3c7c4488aa9df419e9bb /core/tests | |
parent | 94e3f4ba8fc2cd86fe0bccdbcf56fa83f010b699 (diff) | |
parent | b279293d3bae31e3578e002db1471756f4316cb8 (diff) |
Merge "Implements UWB RangingManager and RangingSession"
Diffstat (limited to 'core/tests')
3 files changed, 464 insertions, 0 deletions
diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java new file mode 100644 index 000000000000..6df1c3ed220f --- /dev/null +++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java @@ -0,0 +1,260 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.uwb; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.os.PersistableBundle; +import android.os.RemoteException; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.Executor; + +/** + * Test of {@link AdapterStateListener}. + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class RangingManagerTest { + + private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class); + private static final Executor EXECUTOR = UwbTestUtils.getExecutor(); + private static final PersistableBundle PARAMS = new PersistableBundle(); + private static final @CloseReason int CLOSE_REASON = CloseReason.UNKNOWN; + + @Test + public void testOpenSession_StartRangingInvoked() throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + rangingManager.openSession(PARAMS, EXECUTOR, callback); + verify(ADAPTER, times(1)).startRanging(eq(rangingManager), eq(PARAMS)); + } + + @Test + public void testOpenSession_ErrorIfSameSessionHandleReturned() throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + SessionHandle handle = new SessionHandle(1); + when(ADAPTER.startRanging(any(), any())).thenReturn(handle); + + rangingManager.openSession(PARAMS, EXECUTOR, callback); + + // Calling openSession will cause the same session handle to be returned. The onClosed + // callback should be invoked + RangingSession.Callback callback2 = mock(RangingSession.Callback.class); + rangingManager.openSession(PARAMS, EXECUTOR, callback2); + verify(callback, times(0)).onClosed(anyInt(), any()); + verify(callback2, times(1)).onClosed(anyInt(), any()); + } + + @Test + public void testOnRangingStarted_ValidSessionHandle() throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + SessionHandle handle = new SessionHandle(1); + when(ADAPTER.startRanging(any(), any())).thenReturn(handle); + + rangingManager.openSession(PARAMS, EXECUTOR, callback); + rangingManager.onRangingStarted(handle, PARAMS); + verify(callback, times(1)).onOpenSuccess(any(), any()); + } + + @Test + public void testOnRangingStarted_InvalidSessionHandle() throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + + rangingManager.onRangingStarted(new SessionHandle(2), PARAMS); + verify(callback, times(0)).onOpenSuccess(any(), any()); + } + + @Test + public void testOnRangingStarted_MultipleSessionsRegistered() throws RemoteException { + SessionHandle sessionHandle1 = new SessionHandle(1); + SessionHandle sessionHandle2 = new SessionHandle(2); + RangingSession.Callback callback1 = mock(RangingSession.Callback.class); + RangingSession.Callback callback2 = mock(RangingSession.Callback.class); + + when(ADAPTER.startRanging(any(), any())) + .thenReturn(sessionHandle1) + .thenReturn(sessionHandle2); + + RangingManager rangingManager = new RangingManager(ADAPTER); + rangingManager.openSession(PARAMS, EXECUTOR, callback1); + rangingManager.openSession(PARAMS, EXECUTOR, callback2); + + rangingManager.onRangingStarted(sessionHandle1, PARAMS); + verify(callback1, times(1)).onOpenSuccess(any(), any()); + verify(callback2, times(0)).onOpenSuccess(any(), any()); + + rangingManager.onRangingStarted(sessionHandle2, PARAMS); + verify(callback1, times(1)).onOpenSuccess(any(), any()); + verify(callback2, times(1)).onOpenSuccess(any(), any()); + } + + @Test + public void testOnRangingClosed_OnRangingClosedCalled() throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + SessionHandle handle = new SessionHandle(1); + when(ADAPTER.startRanging(any(), any())).thenReturn(handle); + rangingManager.openSession(PARAMS, EXECUTOR, callback); + + rangingManager.onRangingClosed(handle, CLOSE_REASON, PARAMS); + verify(callback, times(1)).onClosed(anyInt(), any()); + } + + @Test + public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException { + // Verify that if multiple sessions are registered, only the session that is + // requested to close receives the associated callbacks + SessionHandle sessionHandle1 = new SessionHandle(1); + SessionHandle sessionHandle2 = new SessionHandle(2); + RangingSession.Callback callback1 = mock(RangingSession.Callback.class); + RangingSession.Callback callback2 = mock(RangingSession.Callback.class); + + when(ADAPTER.startRanging(any(), any())) + .thenReturn(sessionHandle1) + .thenReturn(sessionHandle2); + + RangingManager rangingManager = new RangingManager(ADAPTER); + rangingManager.openSession(PARAMS, EXECUTOR, callback1); + rangingManager.openSession(PARAMS, EXECUTOR, callback2); + + rangingManager.onRangingClosed(sessionHandle1, CLOSE_REASON, PARAMS); + verify(callback1, times(1)).onClosed(anyInt(), any()); + verify(callback2, times(0)).onClosed(anyInt(), any()); + + rangingManager.onRangingClosed(sessionHandle2, CLOSE_REASON, PARAMS); + verify(callback1, times(1)).onClosed(anyInt(), any()); + verify(callback2, times(1)).onClosed(anyInt(), any()); + } + + @Test + public void testOnRangingReport_OnReportReceived() throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + SessionHandle handle = new SessionHandle(1); + when(ADAPTER.startRanging(any(), any())).thenReturn(handle); + rangingManager.openSession(PARAMS, EXECUTOR, callback); + rangingManager.onRangingStarted(handle, PARAMS); + + RangingReport report = UwbTestUtils.getRangingReports(1); + rangingManager.onRangingResult(handle, report); + verify(callback, times(1)).onReportReceived(eq(report)); + } + + @Test + public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException { + SessionHandle sessionHandle1 = new SessionHandle(1); + SessionHandle sessionHandle2 = new SessionHandle(2); + RangingSession.Callback callback1 = mock(RangingSession.Callback.class); + RangingSession.Callback callback2 = mock(RangingSession.Callback.class); + + when(ADAPTER.startRanging(any(), any())) + .thenReturn(sessionHandle1) + .thenReturn(sessionHandle2); + + RangingManager rangingManager = new RangingManager(ADAPTER); + rangingManager.openSession(PARAMS, EXECUTOR, callback1); + rangingManager.onRangingStarted(sessionHandle1, PARAMS); + rangingManager.openSession(PARAMS, EXECUTOR, callback2); + rangingManager.onRangingStarted(sessionHandle2, PARAMS); + + rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1)); + verify(callback1, times(1)).onReportReceived(any()); + verify(callback2, times(0)).onReportReceived(any()); + + rangingManager.onRangingResult(sessionHandle2, UwbTestUtils.getRangingReports(1)); + verify(callback1, times(1)).onReportReceived(any()); + verify(callback2, times(1)).onReportReceived(any()); + } + + @Test + public void testOnClose_Reasons() throws RemoteException { + runOnClose_Reason(CloseReason.LOCAL_API, + RangingSession.Callback.CLOSE_REASON_LOCAL_CLOSE_API); + + runOnClose_Reason(CloseReason.MAX_SESSIONS_REACHED, + RangingSession.Callback.CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED); + + runOnClose_Reason(CloseReason.PROTOCOL_SPECIFIC, + RangingSession.Callback.CLOSE_REASON_PROTOCOL_SPECIFIC); + + runOnClose_Reason(CloseReason.REMOTE_REQUEST, + RangingSession.Callback.CLOSE_REASON_REMOTE_REQUEST); + + runOnClose_Reason(CloseReason.SYSTEM_POLICY, + RangingSession.Callback.CLOSE_REASON_LOCAL_SYSTEM_POLICY); + + runOnClose_Reason(CloseReason.UNKNOWN, + RangingSession.Callback.CLOSE_REASON_UNKNOWN); + } + + private void runOnClose_Reason(@CloseReason int reasonIn, + @RangingSession.Callback.CloseReason int reasonOut) throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + SessionHandle handle = new SessionHandle(1); + when(ADAPTER.startRanging(any(), any())).thenReturn(handle); + rangingManager.openSession(PARAMS, EXECUTOR, callback); + + rangingManager.onRangingClosed(handle, reasonIn, PARAMS); + verify(callback, times(1)).onClosed(eq(reasonOut), eq(PARAMS)); + } + + @Test + public void testStartFailureReasons() throws RemoteException { + runOnRangingStartFailed_Reason(StartFailureReason.BAD_PARAMETERS, + RangingSession.Callback.CLOSE_REASON_LOCAL_BAD_PARAMETERS); + + runOnRangingStartFailed_Reason(StartFailureReason.MAX_SESSIONS_REACHED, + RangingSession.Callback.CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED); + + runOnRangingStartFailed_Reason(StartFailureReason.PROTOCOL_SPECIFIC, + RangingSession.Callback.CLOSE_REASON_PROTOCOL_SPECIFIC); + + runOnRangingStartFailed_Reason(StartFailureReason.SYSTEM_POLICY, + RangingSession.Callback.CLOSE_REASON_LOCAL_SYSTEM_POLICY); + + runOnRangingStartFailed_Reason(StartFailureReason.UNKNOWN, + RangingSession.Callback.CLOSE_REASON_UNKNOWN); + } + + private void runOnRangingStartFailed_Reason(@StartFailureReason int reasonIn, + @RangingSession.Callback.CloseReason int reasonOut) throws RemoteException { + RangingManager rangingManager = new RangingManager(ADAPTER); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + SessionHandle handle = new SessionHandle(1); + when(ADAPTER.startRanging(any(), any())).thenReturn(handle); + rangingManager.openSession(PARAMS, EXECUTOR, callback); + + rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS); + verify(callback, times(1)).onClosed(eq(reasonOut), eq(PARAMS)); + } +} diff --git a/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java b/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java new file mode 100644 index 000000000000..702c68ebc9de --- /dev/null +++ b/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.uwb; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.os.PersistableBundle; +import android.os.RemoteException; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.Executor; + +/** + * Test of {@link RangingSession}. + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class RangingSessionTest { + private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class); + private static final Executor EXECUTOR = UwbTestUtils.getExecutor(); + private static final PersistableBundle PARAMS = new PersistableBundle(); + private static final @RangingSession.Callback.CloseReason int CLOSE_REASON = + RangingSession.Callback.CLOSE_REASON_LOCAL_GENERIC_ERROR; + + @Test + public void testOnRangingStarted_OnOpenSuccessCalled() { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + verifyOpenState(session, false); + + session.onRangingStarted(PARAMS); + verifyOpenState(session, true); + + // Verify that the onOpenSuccess callback was invoked + verify(callback, times(1)).onOpenSuccess(eq(session), any()); + verify(callback, times(0)).onClosed(anyInt(), any()); + } + + @Test + public void testOnRangingStarted_CannotOpenClosedSession() { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + + session.onRangingStarted(PARAMS); + verifyOpenState(session, true); + verify(callback, times(1)).onOpenSuccess(eq(session), any()); + verify(callback, times(0)).onClosed(anyInt(), any()); + + session.onRangingClosed(CLOSE_REASON, PARAMS); + verifyOpenState(session, false); + verify(callback, times(1)).onOpenSuccess(eq(session), any()); + verify(callback, times(1)).onClosed(anyInt(), any()); + + // Now invoke the ranging started callback and ensure the session remains closed + session.onRangingStarted(PARAMS); + verifyOpenState(session, false); + verify(callback, times(1)).onOpenSuccess(eq(session), any()); + verify(callback, times(1)).onClosed(anyInt(), any()); + } + + @Test + public void testOnRangingClosed_OnClosedCalledWhenSessionNotOpen() { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + verifyOpenState(session, false); + + session.onRangingClosed(CLOSE_REASON, PARAMS); + verifyOpenState(session, false); + + // Verify that the onOpenSuccess callback was invoked + verify(callback, times(0)).onOpenSuccess(eq(session), any()); + verify(callback, times(1)).onClosed(anyInt(), any()); + } + + @Test public void testOnRangingClosed_OnClosedCalled() { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + session.onRangingStarted(PARAMS); + session.onRangingClosed(CLOSE_REASON, PARAMS); + verify(callback, times(1)).onClosed(anyInt(), any()); + + verifyOpenState(session, false); + session.onRangingClosed(CLOSE_REASON, PARAMS); + verify(callback, times(2)).onClosed(anyInt(), any()); + } + + @Test + public void testOnRangingResult_OnReportReceivedCalled() { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + verifyOpenState(session, false); + + session.onRangingStarted(PARAMS); + verifyOpenState(session, true); + + RangingReport report = UwbTestUtils.getRangingReports(1); + session.onRangingResult(report); + verify(callback, times(1)).onReportReceived(eq(report)); + } + + @Test + public void testClose() throws RemoteException { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + session.onRangingStarted(PARAMS); + + // Calling close multiple times should invoke closeRanging until the session receives + // the onClosed callback. + int totalCallsBeforeOnRangingClosed = 3; + for (int i = 1; i <= totalCallsBeforeOnRangingClosed; i++) { + session.close(); + verifyOpenState(session, true); + verify(ADAPTER, times(i)).closeRanging(handle); + verify(callback, times(0)).onClosed(anyInt(), any()); + } + + // After onClosed is invoked, then the adapter should no longer be called for each call to + // the session's close. + final int totalCallsAfterOnRangingClosed = 2; + for (int i = 1; i <= totalCallsAfterOnRangingClosed; i++) { + session.onRangingClosed(CLOSE_REASON, PARAMS); + verifyOpenState(session, false); + verify(ADAPTER, times(totalCallsBeforeOnRangingClosed)).closeRanging(handle); + verify(callback, times(i)).onClosed(anyInt(), any()); + } + } + + @Test + public void testOnRangingResult_OnReportReceivedCalledWhenOpen() { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + + assertFalse(session.isOpen()); + session.onRangingStarted(PARAMS); + assertTrue(session.isOpen()); + + // Verify that the onReportReceived callback was invoked + RangingReport report = UwbTestUtils.getRangingReports(1); + session.onRangingResult(report); + verify(callback, times(1)).onReportReceived(report); + } + + @Test + public void testOnRangingResult_OnReportReceivedNotCalledWhenNotOpen() { + SessionHandle handle = new SessionHandle(123); + RangingSession.Callback callback = mock(RangingSession.Callback.class); + RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle); + + assertFalse(session.isOpen()); + + // Verify that the onReportReceived callback was invoked + RangingReport report = UwbTestUtils.getRangingReports(1); + session.onRangingResult(report); + verify(callback, times(0)).onReportReceived(report); + } + + private void verifyOpenState(RangingSession session, boolean expected) { + assertEquals(expected, session.isOpen()); + } +} diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java index fb7509248b38..b4b2e303443e 100644 --- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java +++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java @@ -22,6 +22,7 @@ import android.os.SystemClock; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; public class UwbTestUtils { private UwbTestUtils() {} @@ -96,4 +97,13 @@ public class UwbTestUtils { } return UwbAddress.fromBytes(addressBytes); } + + public static Executor getExecutor() { + return new Executor() { + @Override + public void execute(Runnable command) { + command.run(); + } + }; + } } |