Merge "Adds Tests for new IMS APIs"
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/ImsFeatureTest.java b/tests/telephonytests/src/android/telephony/ims/internal/ImsFeatureTest.java
new file mode 100644
index 0000000..888ab13
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/ImsFeatureTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.internal.feature.CapabilityChangeRequest;
+import android.telephony.ims.internal.feature.ImsFeature;
+import android.telephony.ims.internal.feature.MmTelFeature;
+import android.telephony.ims.internal.stub.ImsRegistrationImplBase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.ims.internal.IImsFeatureStatusCallback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class ImsFeatureTest {
+
+ private TestImsFeature mTestImsFeature;
+ private ImsFeature.CapabilityCallback mCapabilityCallback;
+
+ @Mock
+ private IImsFeatureStatusCallback mTestStatusCallback;
+ @Mock
+ private IImsFeatureStatusCallback mTestStatusCallback2;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mTestImsFeature = new TestImsFeature();
+ mCapabilityCallback = Mockito.spy(new ImsFeature.CapabilityCallback());
+ mTestImsFeature.addCapabilityCallback(mCapabilityCallback);
+ }
+
+ @After
+ public void tearDown() {
+ mTestImsFeature = null;
+ mCapabilityCallback = null;
+ }
+
+ @Test
+ @SmallTest
+ public void testSetCallbackAndNotify() throws Exception {
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback);
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback2);
+
+ verify(mTestStatusCallback).notifyImsFeatureStatus(eq(ImsFeature.STATE_UNAVAILABLE));
+ verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_UNAVAILABLE));
+ }
+
+ @Test
+ @SmallTest
+ public void testSetFeatureAndCheckCallback() throws Exception {
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback);
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback2);
+
+ mTestImsFeature.testSetFeatureState(ImsFeature.STATE_READY);
+
+ verify(mTestStatusCallback).notifyImsFeatureStatus(eq(ImsFeature.STATE_READY));
+ verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_READY));
+ assertEquals(ImsFeature.STATE_READY, mTestImsFeature.getFeatureState());
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigAdd() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+
+ assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_1));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigAddMultiple() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_2));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigHasMultiple() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ assertTrue(c.isCapable(
+ TestImsFeature.CAPABILITY_TEST_1 | TestImsFeature.CAPABILITY_TEST_2));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigRemove() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+ c.removeCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+
+ assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_2));
+ }
+
+ @SmallTest
+ @Test
+ public void testSetCapabilityConfig() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+
+ mTestImsFeature.requestChangeEnabledCapabilities(request, null);
+
+ assertEquals(request, mTestImsFeature.lastRequest);
+ }
+
+
+ @SmallTest
+ @Test
+ public void testSetCapabilityConfigError() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+
+ mTestImsFeature.setCapabilitiesResult = ImsFeature.CAPABILITY_ERROR_GENERIC;
+ mTestImsFeature.requestChangeEnabledCapabilities(request, mCapabilityCallback);
+
+ verify(mCapabilityCallback).onChangeCapabilityConfigurationError(
+ eq(TestImsFeature.CAPABILITY_TEST_1),
+ eq(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN),
+ eq(ImsFeature.CAPABILITY_ERROR_GENERIC));
+ assertEquals(request, mTestImsFeature.lastRequest);
+ }
+
+ @SmallTest
+ @Test
+ public void testNotifyCapabilityStatusChanged() throws Exception {
+ ImsFeature.Capabilities status =
+ new ImsFeature.Capabilities();
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ mTestImsFeature.capabilitiesStatusChanged(status);
+
+ assertEquals(status.getMask(), mTestImsFeature.queryCapabilityStatus().getMask());
+ }
+
+ @SmallTest
+ @Test
+ public void testNotifyCapabilityStatusChangedCallback() throws Exception {
+ ImsFeature.Capabilities status =
+ new ImsFeature.Capabilities();
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ mTestImsFeature.capabilitiesStatusChanged(status);
+
+ assertEquals(status.getMask(), mTestImsFeature.queryCapabilityStatus().getMask());
+ verify(mCapabilityCallback).onCapabilitiesStatusChanged(eq(status));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityChangeContainsFullSets() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1
+ | TestImsFeature.CAPABILITY_TEST_2,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_2,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ request.addCapabilitiesToDisableForTech(TestImsFeature.CAPABILITY_TEST_1,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+
+ mTestImsFeature.changeEnabledCapabilities(request, /*Callback*/null);
+
+ assertTrue(request.getCapabilitiesToDisable().containsAll(
+ mTestImsFeature.lastRequest.getCapabilitiesToDisable()));
+ assertTrue(request.getCapabilitiesToEnable().containsAll(
+ mTestImsFeature.lastRequest.getCapabilitiesToEnable()));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityChangeRequestParcel() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ // add some capabilities
+ request.addCapabilitiesToEnableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+ request.addCapabilitiesToEnableForTech(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO
+ | MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ request.addCapabilitiesToDisableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ request.addCapabilitiesToDisableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+
+ Parcel p = Parcel.obtain();
+ request.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ CapabilityChangeRequest result =
+ CapabilityChangeRequest.CREATOR.createFromParcel(p);
+ p.recycle();
+
+ assertEquals(request, result);
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/ImsRegistrationTests.java b/tests/telephonytests/src/android/telephony/ims/internal/ImsRegistrationTests.java
new file mode 100644
index 0000000..4ae9205
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/ImsRegistrationTests.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ServiceState;
+import android.telephony.ims.internal.aidl.IImsRegistration;
+import android.telephony.ims.internal.feature.ImsFeature;
+import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
+import android.telephony.ims.internal.stub.ImsRegistrationImplBase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.ims.ImsReasonInfo;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+@RunWith(AndroidJUnit4.class)
+public class ImsRegistrationTests {
+
+ @Spy private ImsRegistrationImplBase.Callback mCallback;
+ private TestImsRegistration mRegistration;
+ private IImsRegistration mRegBinder;
+
+ @Before
+ public void setup() throws RemoteException {
+ MockitoAnnotations.initMocks(this);
+ mRegistration = new TestImsRegistration();
+ mRegBinder = mRegistration.getBinder();
+ mRegBinder.addRegistrationCallback(mCallback);
+ }
+
+ @After
+ public void tearDown() {
+ mRegistration = null;
+ mRegBinder = null;
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationConfigParcel() {
+ ImsFeatureConfiguration testConfig = new ImsFeatureConfiguration.Builder()
+ .addFeature(ImsFeature.FEATURE_MMTEL)
+ .addFeature(ImsFeature.FEATURE_RCS)
+ .build();
+ Parcel p = Parcel.obtain();
+ testConfig.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ ImsFeatureConfiguration result =
+ ImsFeatureConfiguration.CREATOR.createFromParcel(p);
+ p.recycle();
+
+ assertEquals(testConfig, result);
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationConfigPermutationEqual() {
+ ImsFeatureConfiguration testConfig = new ImsFeatureConfiguration.Builder()
+ .addFeature(ImsFeature.FEATURE_MMTEL)
+ .addFeature(ImsFeature.FEATURE_RCS)
+ .build();
+
+ // Permute field insertion ordering to ensure order doesn't matter.
+ ImsFeatureConfiguration testConfig2 = new ImsFeatureConfiguration.Builder()
+ .addFeature(ImsFeature.FEATURE_RCS)
+ .addFeature(ImsFeature.FEATURE_MMTEL)
+ .build();
+
+ assertEquals(testConfig, testConfig2);
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationConfigConstructorsEqual() {
+ ImsFeatureConfiguration testConfig = new ImsFeatureConfiguration(
+ new int[] {ImsFeature.FEATURE_MMTEL, ImsFeature.FEATURE_RCS});
+
+ // Permute field insertion ordering to ensure order doesn't matter.
+ ImsFeatureConfiguration testConfig2 = new ImsFeatureConfiguration.Builder()
+ .addFeature(ImsFeature.FEATURE_RCS)
+ .addFeature(ImsFeature.FEATURE_MMTEL)
+ .build();
+
+ assertEquals(testConfig, testConfig2);
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackOnRegistered() throws RemoteException {
+ mRegistration.onRegistered(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+
+ verify(mCallback).onRegistered(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackOnRegistering() throws RemoteException {
+ mRegistration.onRegistering(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+
+ verify(mCallback).onRegistering(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackOnDeregistered() throws RemoteException {
+ ImsReasonInfo info = new ImsReasonInfo();
+ mRegistration.onDeregistered(info);
+
+ verify(mCallback).onDeregistered(eq(info));
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackOnTechChangeFailed() throws RemoteException {
+ ImsReasonInfo info = new ImsReasonInfo();
+ mRegistration.onTechnologyChangeFailed(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+ info);
+
+ verify(mCallback).onTechnologyChangeFailed(
+ eq(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN), eq(info));
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackAfterUnregistered() throws RemoteException {
+ mRegBinder.removeRegistrationCallback(mCallback);
+
+ mRegistration.onRegistered(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+
+ verify(mCallback, never()).onRegistered(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackSendCurrentState() throws RemoteException {
+ ImsRegistrationImplBase.Callback mCallback2 = spy(new ImsRegistrationImplBase.Callback());
+ mRegistration.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+
+ mRegBinder.addRegistrationCallback(mCallback2);
+
+ verify(mCallback2).onRegistered(eq(ImsRegistrationImplBase.REGISTRATION_TECH_LTE));
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackGetRegistrationTech() throws RemoteException {
+ mRegistration.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+
+ assertEquals(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+ mRegBinder.getRegistrationTechnology());
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackSendCurrentStateDisconnected() throws RemoteException {
+ ImsRegistrationImplBase.Callback mCallback2 = spy(new ImsRegistrationImplBase.Callback());
+ ImsReasonInfo info = new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NETWORK_NO_LTE_COVERAGE, 0);
+ mRegistration.onDeregistered(info);
+
+ mRegBinder.addRegistrationCallback(mCallback2);
+
+ // The original callback that has been registered should get LTE tech in disconnected
+ // message
+ verify(mCallback).onDeregistered(eq(info));
+ // A callback that has just been registered should get NONE for tech in disconnected
+ // message
+ verify(mCallback2).onDeregistered(eq(info));
+ }
+
+ @SmallTest
+ @Test
+ public void testRegistrationCallbackGetRegistrationTechDisconnected() throws RemoteException {
+ ImsReasonInfo info = new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NETWORK_NO_LTE_COVERAGE, 0);
+
+ mRegistration.onDeregistered(info);
+
+ verify(mCallback).onDeregistered(eq(info));
+ assertEquals(ImsRegistrationImplBase.REGISTRATION_TECH_NONE,
+ mRegBinder.getRegistrationTechnology());
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/ImsServiceTest.java b/tests/telephonytests/src/android/telephony/ims/internal/ImsServiceTest.java
new file mode 100644
index 0000000..f4c1149
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/ImsServiceTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import static com.android.internal.telephony.ims.ImsResolver.SERVICE_INTERFACE;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.internal.aidl.IImsMmTelFeature;
+import android.telephony.ims.internal.aidl.IImsServiceController;
+import android.telephony.ims.internal.feature.ImsFeature;
+import android.telephony.ims.internal.feature.MmTelFeature;
+import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.SparseArray;
+
+import com.android.ims.ImsManager;
+import com.android.ims.internal.IImsFeatureStatusCallback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+/**
+ * Unit tests for ImsService
+ */
+@RunWith(AndroidJUnit4.class)
+public class ImsServiceTest {
+
+ private static final int TEST_SLOT_0 = 0;
+ private static final int TEST_SLOT_1 = 1;
+
+ private TestImsService mTestImsService;
+ private IImsServiceController mTestImsServiceBinder;
+
+ private Context mMockContext;
+ private IImsFeatureStatusCallback mTestCallback;
+
+ @Before
+ public void setUp() throws Exception {
+ mMockContext = mock(Context.class);
+ mTestCallback = mock(IImsFeatureStatusCallback.class);
+ mTestImsService = new TestImsService(mMockContext);
+ mTestImsServiceBinder = (IImsServiceController) mTestImsService.onBind(
+ new Intent(SERVICE_INTERFACE));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mMockContext = null;
+ mTestCallback = null;
+ mTestImsService = null;
+ mTestImsServiceBinder = null;
+ }
+
+ @Test
+ @SmallTest
+ public void testCreateMMTelFeature() throws RemoteException {
+ IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
+ mTestImsService.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
+
+ SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
+ ImsFeature featureToVerify = features.get(ImsFeature.FEATURE_MMTEL);
+ MmTelFeature testMMTelFeature = null;
+ if (featureToVerify instanceof MmTelFeature) {
+ testMMTelFeature = (MmTelFeature) featureToVerify;
+ } else {
+ fail();
+ }
+ assertEquals(mTestImsService.mSpyMmTelFeature, testMMTelFeature);
+ // Verify that upon creating a feature, we assign the callback and get the set feature state
+ // when querying it.
+ verify(mTestImsService.mSpyMmTelFeature).addImsFeatureStatusCallback(eq(mTestCallback));
+ assertEquals(ImsFeature.STATE_READY, f.getFeatureState());
+ }
+
+ @Test
+ @SmallTest
+ public void testRemoveMMTelFeature() throws RemoteException {
+ mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
+
+ mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
+ mTestCallback);
+
+ verify(mTestImsService.mSpyMmTelFeature).onFeatureRemoved();
+ verify(mTestImsService.mSpyMmTelFeature).removeImsFeatureStatusCallback(mTestCallback);
+ SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
+ assertNull(features.get(ImsFeature.FEATURE_MMTEL));
+ }
+
+ @Test
+ @SmallTest
+ public void testCallMethodOnCreatedFeature() throws RemoteException {
+ IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
+
+ f.getUtInterface();
+
+ assertTrue(mTestImsService.mTestMmTelFeature.isUtInterfaceCalled);
+ }
+
+ /**
+ * Tests that the new ImsService still sends the IMS_SERVICE_UP broadcast when the feature is
+ * set to ready.
+ */
+ @Test
+ @SmallTest
+ public void testImsServiceUpSentCompat() throws RemoteException {
+ mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
+
+ mTestImsService.mSpyMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mMockContext).sendBroadcast(intentCaptor.capture());
+ try {
+ // Verify IMS_SERVICE_UP is sent
+ assertNotNull(intentCaptor.getValue());
+ verifyServiceUpSent(intentCaptor.getValue());
+ } catch (IndexOutOfBoundsException e) {
+ fail("Did not receive all intents");
+ }
+ }
+
+ /**
+ * Tests that the new ImsService still sends the IMS_SERVICE_DOWN broadcast when the feature is
+ * set to initializing.
+ */
+ @Test
+ @SmallTest
+ public void testImsServiceDownSentCompatInitializing() throws RemoteException {
+ mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
+
+ mTestImsService.mSpyMmTelFeature.sendSetFeatureState(ImsFeature.STATE_INITIALIZING);
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mMockContext).sendBroadcast(intentCaptor.capture());
+ try {
+ // IMS_SERVICE_DOWN is sent when the service is STATE_INITIALIZING.
+ assertNotNull(intentCaptor.getValue());
+ verifyServiceDownSent(intentCaptor.getValue());
+ } catch (IndexOutOfBoundsException e) {
+ fail("Did not receive all intents");
+ }
+ }
+
+ /**
+ * Tests that the ImsService will return the correct ImsFeatureConfiguration when queried.
+ */
+ @Test
+ @SmallTest
+ public void testQuerySupportedImsFeatures() throws RemoteException {
+ ImsFeatureConfiguration config = new ImsFeatureConfiguration.Builder()
+ .addFeature(ImsFeature.FEATURE_MMTEL)
+ .addFeature(ImsFeature.FEATURE_RCS)
+ .build();
+ mTestImsService.testFeatureConfig = config;
+
+ ImsFeatureConfiguration result = mTestImsServiceBinder.querySupportedImsFeatures();
+
+ assertEquals(config, result);
+ }
+
+ private void verifyServiceDownSent(Intent testIntent) {
+ assertEquals(ImsManager.ACTION_IMS_SERVICE_DOWN, testIntent.getAction());
+ assertEquals(TEST_SLOT_0, testIntent.getIntExtra(ImsManager.EXTRA_PHONE_ID, -1));
+ }
+
+ private void verifyServiceUpSent(Intent testIntent) {
+ assertEquals(ImsManager.ACTION_IMS_SERVICE_UP, testIntent.getAction());
+ assertEquals(TEST_SLOT_0, testIntent.getIntExtra(ImsManager.EXTRA_PHONE_ID, -1));
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/MmTelFeatureTests.java b/tests/telephonytests/src/android/telephony/ims/internal/MmTelFeatureTests.java
new file mode 100644
index 0000000..c2cdd75
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/MmTelFeatureTests.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.os.RemoteException;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.internal.aidl.IImsMmTelFeature;
+import android.telephony.ims.internal.feature.ImsFeature;
+import android.telephony.ims.internal.feature.MmTelFeature;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.ims.internal.IImsCallSession;
+import com.android.ims.internal.ImsCallSession;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+@RunWith(AndroidJUnit4.class)
+public class MmTelFeatureTests {
+
+ private static final int TEST_CAPABILITY = 1;
+ private static final int TEST_RADIO_TECH = 0;
+
+ private TestMmTelFeature mFeature;
+ private IImsMmTelFeature mFeatureBinder;
+ private ImsFeature.CapabilityCallback mCapabilityCallback;
+ private MmTelFeature.Listener mListener;
+
+ @Before
+ public void setup() throws RemoteException {
+ mFeature = new TestMmTelFeature();
+ mFeatureBinder = mFeature.getBinder();
+ mCapabilityCallback = spy(new ImsFeature.CapabilityCallback());
+ mListener = spy(new MmTelFeature.Listener());
+ mFeatureBinder.setListener(mListener);
+ }
+
+ @After
+ public void tearDown() {
+ mFeature = null;
+ mFeatureBinder = null;
+ }
+
+ @SmallTest
+ @Test
+ public void testQueryCapabilityConfiguration() throws Exception {
+ mFeature.queryConfigurationResult = true;
+
+ mFeatureBinder.queryCapabilityConfiguration(TEST_CAPABILITY, TEST_RADIO_TECH,
+ mCapabilityCallback);
+
+ verify(mCapabilityCallback).onQueryCapabilityConfiguration(eq(TEST_CAPABILITY),
+ eq(TEST_RADIO_TECH), eq(true));
+ }
+
+ @SmallTest
+ @Test
+ public void testNewIncomingCall() throws Exception {
+ IImsCallSession sessionBinder = Mockito.mock(IImsCallSession.class);
+ ImsCallSession session = new ImsCallSession(sessionBinder);
+
+ mFeature.incomingCall(session);
+ ArgumentCaptor<ImsCallSession> captor = ArgumentCaptor.forClass(ImsCallSession.class);
+ verify(mListener).onIncomingCall(captor.capture());
+
+ assertEquals(sessionBinder, captor.getValue().getSession());
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/TestImsFeature.java b/tests/telephonytests/src/android/telephony/ims/internal/TestImsFeature.java
new file mode 100644
index 0000000..efbf95e
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/TestImsFeature.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import android.os.IInterface;
+import android.telephony.ims.internal.feature.CapabilityChangeRequest;
+import android.telephony.ims.internal.feature.ImsFeature;
+
+public class TestImsFeature extends ImsFeature {
+
+
+ public static final int CAPABILITY_TEST_1 = 1 << 0;
+ public static final int CAPABILITY_TEST_2 = 1 << 1;
+
+ public int setCapabilitiesResult = ImsFeature.CAPABILITY_SUCCESS;
+ public CapabilityChangeRequest lastRequest;
+ public int onFeatureRemovedCount = 0;
+ public int onFeatureReadyCount = 0;
+
+ public void testSetFeatureState(int featureState) {
+ setFeatureState(featureState);
+ }
+
+ public void capabilitiesStatusChanged(Capabilities c) {
+ notifyCapabilitiesStatusChanged(c);
+ }
+
+ @Override
+ public void changeEnabledCapabilities(CapabilityChangeRequest request,
+ CapabilityCallbackProxy c) {
+ lastRequest = request;
+ if (setCapabilitiesResult != ImsFeature.CAPABILITY_SUCCESS) {
+ // Take the first value to enable and return it as an error.
+ CapabilityChangeRequest.CapabilityPair capPair = request.getCapabilitiesToEnable()
+ .get(0);
+ c.onChangeCapabilityConfigurationError(capPair.getCapability(), capPair.getRadioTech(),
+ ImsFeature.CAPABILITY_ERROR_GENERIC);
+ }
+ }
+
+ @Override
+ public void onFeatureRemoved() {
+ onFeatureRemovedCount++;
+ }
+
+ @Override
+ public void onFeatureReady() {
+ onFeatureReadyCount++;
+ }
+
+ @Override
+ public IInterface getBinder() {
+ return null;
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/TestImsRegistration.java b/tests/telephonytests/src/android/telephony/ims/internal/TestImsRegistration.java
new file mode 100644
index 0000000..6b94efb
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/TestImsRegistration.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
+import android.telephony.ims.internal.stub.ImsRegistrationImplBase;
+
+public class TestImsRegistration extends ImsRegistrationImplBase {
+
+ private ImsFeatureConfiguration mTestConfig;
+ private ImsRegistrationImplBase.Callback mCallback = new ImsRegistrationImplBase.Callback() {
+
+ };
+
+ public void setConfig(ImsFeatureConfiguration c) {
+ mTestConfig = c;
+ }
+
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/TestImsService.java b/tests/telephonytests/src/android/telephony/ims/internal/TestImsService.java
new file mode 100644
index 0000000..97dfff7
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/TestImsService.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.telephony.ims.internal.feature.MmTelFeature;
+import android.telephony.ims.internal.feature.RcsFeature;
+import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
+
+/**
+ * Test ImsService used by mockito to verify functionality.
+ */
+
+public class TestImsService extends ImsService {
+
+ public TestMmTelFeature mSpyMmTelFeature;
+ public TestMmTelFeature mTestMmTelFeature;
+
+ public ImsFeatureConfiguration testFeatureConfig;
+
+ public TestImsService(Context context) {
+ attachBaseContext(context);
+ // Must create real MMTelFeature to initialize ImsFeature objects.
+ mTestMmTelFeature = new TestMmTelFeature();
+ mSpyMmTelFeature = spy(mTestMmTelFeature);
+ }
+
+ @Override
+ public ImsFeatureConfiguration querySupportedImsFeatures() {
+ return testFeatureConfig;
+ }
+
+ @Override
+ public MmTelFeature createMmTelFeature(int slotId) {
+ return mSpyMmTelFeature;
+ }
+
+ @Override
+ public RcsFeature createRcsFeature(int slotId) {
+ return null;
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/TestMmTelFeature.java b/tests/telephonytests/src/android/telephony/ims/internal/TestMmTelFeature.java
new file mode 100644
index 0000000..1f5b23e
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/internal/TestMmTelFeature.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 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.telephony.ims.internal;
+
+import android.os.RemoteException;
+import android.telephony.ims.internal.feature.CapabilityChangeRequest;
+import android.telephony.ims.internal.feature.ImsFeature;
+import android.telephony.ims.internal.feature.MmTelFeature;
+import android.telephony.ims.internal.stub.ImsRegistrationImplBase;
+import android.telephony.ims.stub.ImsEcbmImplBase;
+import android.telephony.ims.stub.ImsMultiEndpointImplBase;
+import android.telephony.ims.stub.ImsUtImplBase;
+
+import com.android.ims.ImsCallProfile;
+import com.android.ims.internal.ImsCallSession;
+
+public class TestMmTelFeature extends MmTelFeature {
+
+ public boolean queryConfigurationResult = false;
+ public int setCapabilitiesResult = ImsFeature.CAPABILITY_SUCCESS;
+ public CapabilityChangeRequest lastRequest;
+ public boolean isUtInterfaceCalled = false;
+
+ public void incomingCall(ImsCallSession c) throws RemoteException {
+ notifyIncomingCall(c);
+ }
+
+ @Override
+ public ImsCallProfile createCallProfile(int callSessionType, int callType) {
+ return super.createCallProfile(callSessionType, callType);
+ }
+
+ @Override
+ public ImsCallSession createCallSession(ImsCallProfile profile,
+ ImsCallSessionListener listener) {
+ return super.createCallSession(profile, listener);
+ }
+
+ @Override
+ public ImsUtImplBase getUt() {
+ isUtInterfaceCalled = true;
+ return super.getUt();
+ }
+
+ @Override
+ public ImsEcbmImplBase getEcbm() {
+ return super.getEcbm();
+ }
+
+ @Override
+ public ImsMultiEndpointImplBase getMultiEndpoint() {
+ return super.getMultiEndpoint();
+ }
+
+ @Override
+ public boolean queryCapabilityConfiguration(@MmTelCapabilities.MmTelCapability int capability,
+ @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
+ // Base implementation - Override to provide functionality
+ return queryConfigurationResult;
+ }
+
+ @Override
+ public void changeEnabledCapabilities(CapabilityChangeRequest request,
+ CapabilityCallbackProxy c) {
+ lastRequest = request;
+ if (setCapabilitiesResult != ImsFeature.CAPABILITY_SUCCESS) {
+ // Take the first value to enable and return it as an error.
+ CapabilityChangeRequest.CapabilityPair capPair = request.getCapabilitiesToEnable()
+ .get(0);
+ c.onChangeCapabilityConfigurationError(capPair.getCapability(), capPair.getRadioTech(),
+ ImsFeature.CAPABILITY_ERROR_GENERIC);
+ }
+ }
+
+ public void sendSetFeatureState(int state) {
+ setFeatureState(state);
+ }
+
+ @Override
+ public void onFeatureRemoved() {
+ }
+
+ @Override
+ public void onFeatureReady() {
+ }
+}