From 60c693aa8dfd6b8f038c0fa7b8ef4735365d3fbb Mon Sep 17 00:00:00 2001 From: George Chang Date: Thu, 8 Apr 2021 22:05:11 +0800 Subject: [PATCH] Add NfcManagerTests Bug: 184837312 Test: atest NfcManagerTests Change-Id: I1838a8232a34d9b2f35941408c499f59c68aa5e7 --- core/java/android/nfc/TEST_MAPPING | 7 + core/tests/nfctests/Android.bp | 38 ++++ core/tests/nfctests/AndroidManifest.xml | 31 ++++ core/tests/nfctests/AndroidTest.xml | 32 ++++ core/tests/nfctests/OWNERS | 1 + .../NfcControllerAlwaysOnListenerTest.java | 166 ++++++++++++++++++ 6 files changed, 275 insertions(+) create mode 100644 core/java/android/nfc/TEST_MAPPING create mode 100644 core/tests/nfctests/Android.bp create mode 100644 core/tests/nfctests/AndroidManifest.xml create mode 100644 core/tests/nfctests/AndroidTest.xml create mode 100644 core/tests/nfctests/OWNERS create mode 100644 core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java diff --git a/core/java/android/nfc/TEST_MAPPING b/core/java/android/nfc/TEST_MAPPING new file mode 100644 index 0000000000000..71ad687b78890 --- /dev/null +++ b/core/java/android/nfc/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "NfcManagerTests" + } + ] +} diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp new file mode 100644 index 0000000000000..335cea140df65 --- /dev/null +++ b/core/tests/nfctests/Android.bp @@ -0,0 +1,38 @@ +// Copyright 2021 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "NfcManagerTests", + static_libs: [ + "androidx.test.ext.junit", + "androidx.test.rules", + "mockito-target-minus-junit4", + ], + libs: [ + "android.test.runner", + ], + srcs: ["src/**/*.java"], + platform_apis: true, + certificate: "platform", + test_suites: ["device-tests"], +} diff --git a/core/tests/nfctests/AndroidManifest.xml b/core/tests/nfctests/AndroidManifest.xml new file mode 100644 index 0000000000000..99e2c34c656ba --- /dev/null +++ b/core/tests/nfctests/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + diff --git a/core/tests/nfctests/AndroidTest.xml b/core/tests/nfctests/AndroidTest.xml new file mode 100644 index 0000000000000..490d6f5df1977 --- /dev/null +++ b/core/tests/nfctests/AndroidTest.xml @@ -0,0 +1,32 @@ + + + + diff --git a/core/tests/nfctests/OWNERS b/core/tests/nfctests/OWNERS new file mode 100644 index 0000000000000..34b095c7fda06 --- /dev/null +++ b/core/tests/nfctests/OWNERS @@ -0,0 +1 @@ +include /core/java/android/nfc/OWNERS diff --git a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java new file mode 100644 index 0000000000000..43f9b6feea452 --- /dev/null +++ b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java @@ -0,0 +1,166 @@ +/* + * Copyright 2021 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.nfc; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.nfc.NfcAdapter.ControllerAlwaysOnListener; +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.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; + +/** + * Test of {@link NfcControllerAlwaysOnListener}. + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class NfcControllerAlwaysOnListenerTest { + + private INfcAdapter mNfcAdapter = mock(INfcAdapter.class); + + private Throwable mThrowRemoteException = new RemoteException("RemoteException"); + + private static Executor getExecutor() { + return new Executor() { + @Override + public void execute(Runnable command) { + command.run(); + } + }; + } + + private static void verifyListenerInvoked(ControllerAlwaysOnListener listener) { + verify(listener, times(1)).onControllerAlwaysOnChanged(anyBoolean()); + } + + @Test + public void testRegister_RegisterUnregister() throws RemoteException { + NfcControllerAlwaysOnListener mListener = + new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class); + ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class); + + // Verify that the state listener registered with the NFC Adapter + mListener.register(getExecutor(), mockListener1); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // Register a second client and no new call to NFC Adapter + mListener.register(getExecutor(), mockListener2); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // Unregister first listener + mListener.unregister(mockListener1); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any()); + + // Unregister second listener and the state listener registered with the NFC Adapter + mListener.unregister(mockListener2); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + verify(mNfcAdapter, times(1)).unregisterControllerAlwaysOnListener(any()); + } + + @Test + public void testRegister_FirstRegisterFails() throws RemoteException { + NfcControllerAlwaysOnListener mListener = + new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class); + ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class); + + // Throw a remote exception whenever first registering + doThrow(mThrowRemoteException).when(mNfcAdapter).registerControllerAlwaysOnListener( + any()); + + mListener.register(getExecutor(), mockListener1); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // No longer throw an exception, instead succeed + doNothing().when(mNfcAdapter).registerControllerAlwaysOnListener(any()); + + // Register a different listener + mListener.register(getExecutor(), mockListener2); + verify(mNfcAdapter, times(2)).registerControllerAlwaysOnListener(any()); + + // Ensure first and second listener were invoked + mListener.onControllerAlwaysOnChanged(true); + verifyListenerInvoked(mockListener1); + verifyListenerInvoked(mockListener2); + } + + @Test + public void testRegister_RegisterSameListenerTwice() throws RemoteException { + NfcControllerAlwaysOnListener mListener = + new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class); + + // Register the same listener Twice + mListener.register(getExecutor(), mockListener); + mListener.register(getExecutor(), mockListener); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // Invoke a state change and ensure the listener is only called once + mListener.onControllerAlwaysOnChanged(true); + verifyListenerInvoked(mockListener); + } + + @Test + public void testNotify_AllListenersNotified() throws RemoteException { + + NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter); + List mockListeners = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class); + listener.register(getExecutor(), mockListener); + mockListeners.add(mockListener); + } + + // Invoke a state change and ensure all listeners are invoked + listener.onControllerAlwaysOnChanged(true); + for (ControllerAlwaysOnListener mListener : mockListeners) { + verifyListenerInvoked(mListener); + } + } + + @Test + public void testStateChange_CorrectValue() { + runStateChangeValue(true, true); + runStateChangeValue(false, false); + + } + + private void runStateChangeValue(boolean isEnabledIn, boolean isEnabledOut) { + NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class); + listener.register(getExecutor(), mockListener); + listener.onControllerAlwaysOnChanged(isEnabledIn); + verify(mockListener, times(1)).onControllerAlwaysOnChanged(isEnabledOut); + verify(mockListener, times(0)).onControllerAlwaysOnChanged(!isEnabledOut); + } +}