Scaffolding for SipTransport Impl & Implement SipTransport#isSupported
Creates a new SipTransportController class, which hooks into
TelephonyRcsService and will implement the SipDelegate
management.
SipDelegateManager#isSupported is implemented, which
ensures all of the following are true before returning
supported:
- ImsService#CAPABILITY_SIP_DELEGATE_CREATION is set on ImsService
- ImsService returns non-null implementation of SipTransportImplBase
- CarrierConfigManager.Ims.KEY_RCS_SINGLE_REGISTRATION_REQUIRED_BOOL is true
Bug: 154763999
Test: atest TeleServiceTests
Merged-In: I01677351c53b8c8480736f1a6539ece0bedf685f
Change-Id: I01677351c53b8c8480736f1a6539ece0bedf685f
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index 13bfe3b..9d712d3 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -17,7 +17,7 @@
package com.android;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doAnswer;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -32,9 +32,11 @@
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsManager;
import android.test.mock.MockContext;
+import android.util.SparseArray;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
import java.util.concurrent.Executor;
@@ -46,11 +48,19 @@
@Mock SubscriptionManager mMockSubscriptionManager;
@Mock ImsManager mMockImsManager;
- private PersistableBundle mCarrierConfig = new PersistableBundle();
+ private SparseArray<PersistableBundle> mCarrierConfigs = new SparseArray<>();
public TestContext() {
MockitoAnnotations.initMocks(this);
- doReturn(mCarrierConfig).when(mMockCarrierConfigManager).getConfigForSubId(anyInt());
+ doAnswer((Answer<PersistableBundle>) invocation -> {
+ int subId = (int) invocation.getArguments()[0];
+ if (subId < 0) {
+ return new PersistableBundle();
+ }
+ PersistableBundle b = mCarrierConfigs.get(subId);
+
+ return (b != null ? b : new PersistableBundle());
+ }).when(mMockCarrierConfigManager).getConfigForSubId(anyInt());
}
@Override
@@ -140,7 +150,15 @@
return null;
}
- public PersistableBundle getCarrierConfig() {
- return mCarrierConfig;
+ /**
+ * @return CarrierConfig PersistableBundle for the subscription specified.
+ */
+ public PersistableBundle getCarrierConfig(int subId) {
+ PersistableBundle b = mCarrierConfigs.get(subId);
+ if (b == null) {
+ b = new PersistableBundle();
+ mCarrierConfigs.put(subId, b);
+ }
+ return b;
}
}
diff --git a/tests/src/com/android/TestExecutorService.java b/tests/src/com/android/TestExecutorService.java
new file mode 100644
index 0000000..fec502a
--- /dev/null
+++ b/tests/src/com/android/TestExecutorService.java
@@ -0,0 +1,193 @@
+/*
+ * 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 com.android;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * An implementation of ExecutorService that just runs the requested task on the thread that it
+ * was called on for testing purposes.
+ */
+public class TestExecutorService implements ScheduledExecutorService {
+
+ private static class CompletedFuture<T> implements Future<T>, ScheduledFuture<T> {
+
+ private final Callable<T> mTask;
+ private final long mDelayMs;
+
+ CompletedFuture(Callable<T> task) {
+ mTask = task;
+ mDelayMs = 0;
+ }
+
+ CompletedFuture(Callable<T> task, long delayMs) {
+ mTask = task;
+ mDelayMs = delayMs;
+ }
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return false;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return false;
+ }
+
+ @Override
+ public boolean isDone() {
+ return true;
+ }
+
+ @Override
+ public T get() throws InterruptedException, ExecutionException {
+ try {
+ return mTask.call();
+ } catch (Exception e) {
+ throw new ExecutionException(e);
+ }
+ }
+
+ @Override
+ public T get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ try {
+ return mTask.call();
+ } catch (Exception e) {
+ throw new ExecutionException(e);
+ }
+ }
+
+ @Override
+ public long getDelay(TimeUnit unit) {
+ if (unit == TimeUnit.MILLISECONDS) {
+ return mDelayMs;
+ } else {
+ // not implemented
+ return 0;
+ }
+ }
+
+ @Override
+ public int compareTo(Delayed o) {
+ if (o == null) return 1;
+ if (o.getDelay(TimeUnit.MILLISECONDS) > mDelayMs) return -1;
+ if (o.getDelay(TimeUnit.MILLISECONDS) < mDelayMs) return 1;
+ return 0;
+ }
+ }
+
+ @Override
+ public void shutdown() {
+ }
+
+ @Override
+ public List<Runnable> shutdownNow() {
+ return null;
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return false;
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return false;
+ }
+
+ @Override
+ public boolean awaitTermination(long timeout, TimeUnit unit) {
+ return false;
+ }
+
+ @Override
+ public <T> Future<T> submit(Callable<T> task) {
+ return new CompletedFuture<>(task);
+ }
+
+ @Override
+ public <T> Future<T> submit(Runnable task, T result) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public Future<?> submit(Runnable task) {
+ task.run();
+ return new CompletedFuture<>(() -> null);
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout,
+ TimeUnit unit) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
+ // No need to worry about delays yet
+ command.run();
+ return new CompletedFuture<>(() -> null, delay);
+ }
+
+ @Override
+ public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
+ return new CompletedFuture<>(callable, delay);
+ }
+
+ @Override
+ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period,
+ TimeUnit unit) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,
+ long delay, TimeUnit unit) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ command.run();
+ }
+}
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 2060e6f..07fe6a8 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -936,14 +936,14 @@
// Setup test to not support SUPL on the non-DDS subscription
doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
- getTestContext().getCarrierConfig().putStringArray(
+ getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
null);
testPhone.getServiceState().setRoaming(false);
- getTestContext().getCarrierConfig().putInt(
+ getTestContext().getCarrierConfig(0 /*subId*/).putInt(
CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
- getTestContext().getCarrierConfig().putString(
+ getTestContext().getCarrierConfig(0 /*subId*/).putString(
CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "150");
delayDialRunnable.run();
@@ -1021,14 +1021,14 @@
// Setup test to not support SUPL on the non-DDS subscription
doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
- getTestContext().getCarrierConfig().putStringArray(
+ getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
null);
testPhone.getServiceState().setRoaming(false);
- getTestContext().getCarrierConfig().putInt(
+ getTestContext().getCarrierConfig(0 /*subId*/).putInt(
CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
- getTestContext().getCarrierConfig().putString(
+ getTestContext().getCarrierConfig(0 /*subId*/).putString(
CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
delayDialRunnable.run();
@@ -1047,14 +1047,14 @@
// If the non-DDS supports SUPL, dont switch data
doReturn(false).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
- getTestContext().getCarrierConfig().putStringArray(
+ getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
null);
testPhone.getServiceState().setRoaming(false);
- getTestContext().getCarrierConfig().putInt(
+ getTestContext().getCarrierConfig(0 /*subId*/).putInt(
CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
- getTestContext().getCarrierConfig().putString(
+ getTestContext().getCarrierConfig(0 /*subId*/).putString(
CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
delayDialRunnable.run();
@@ -1073,14 +1073,14 @@
// Setup test to not support SUPL on the non-DDS subscription
doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
- getTestContext().getCarrierConfig().putStringArray(
+ getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
null);
testPhone.getServiceState().setRoaming(true);
- getTestContext().getCarrierConfig().putInt(
+ getTestContext().getCarrierConfig(0 /*subId*/).putInt(
CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
- getTestContext().getCarrierConfig().putString(
+ getTestContext().getCarrierConfig(0 /*subId*/).putString(
CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
delayDialRunnable.run();
@@ -1107,13 +1107,13 @@
doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
String[] roamingPlmns = new String[1];
roamingPlmns[0] = testRoamingOperator;
- getTestContext().getCarrierConfig().putStringArray(
+ getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
roamingPlmns);
- getTestContext().getCarrierConfig().putInt(
+ getTestContext().getCarrierConfig(0 /*subId*/).putInt(
CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
- getTestContext().getCarrierConfig().putString(
+ getTestContext().getCarrierConfig(0 /*subId*/).putString(
CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
delayDialRunnable.run();
@@ -1140,13 +1140,13 @@
doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
String[] roamingPlmns = new String[1];
roamingPlmns[0] = testRoamingOperator;
- getTestContext().getCarrierConfig().putStringArray(
+ getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
roamingPlmns);
- getTestContext().getCarrierConfig().putInt(
+ getTestContext().getCarrierConfig(0 /*subId*/).putInt(
CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
- getTestContext().getCarrierConfig().putString(
+ getTestContext().getCarrierConfig(0 /*subId*/).putString(
CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
delayDialRunnable.run();
diff --git a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
new file mode 100644
index 0000000..65a95cd
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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 com.android.services.telephony.rcs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+
+import android.telephony.ims.ImsException;
+import android.telephony.ims.aidl.ISipTransport;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+import com.android.TestExecutorService;
+import com.android.ims.RcsFeatureManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+@RunWith(AndroidJUnit4.class)
+public class SipTransportControllerTest extends TelephonyTestBase {
+
+ @Mock private RcsFeatureManager mRcsManager;
+ @Mock private ISipTransport mSipTransport;
+
+ private final TestExecutorService mExecutorService = new TestExecutorService();
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @SmallTest
+ @Test
+ public void isSupportedRcsNotConnected() {
+ SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+ try {
+ controller.isSupported(0 /*subId*/);
+ fail();
+ } catch (ImsException e) {
+ assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+ }
+ }
+
+ @SmallTest
+ @Test
+ public void isSupportedInvalidSubId() {
+ SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+ try {
+ controller.isSupported(1 /*subId*/);
+ fail();
+ } catch (ImsException e) {
+ assertEquals(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION, e.getCode());
+ }
+ }
+
+ @SmallTest
+ @Test
+ public void isSupportedSubIdChanged() {
+ SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+ controller.onAssociatedSubscriptionUpdated(1 /*subId*/);
+ try {
+ controller.isSupported(0 /*subId*/);
+ fail();
+ } catch (ImsException e) {
+ assertEquals(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION, e.getCode());
+ }
+ }
+
+ @SmallTest
+ @Test
+ public void isSupportedSipTransportAvailableRcsConnected() throws Exception {
+ SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+ doReturn(mSipTransport).when(mRcsManager).getSipTransport();
+ controller.onRcsConnected(mRcsManager);
+ try {
+ assertTrue(controller.isSupported(0 /*subId*/));
+ } catch (ImsException e) {
+ fail();
+ }
+ }
+
+ @SmallTest
+ @Test
+ public void isSupportedSipTransportNotAvailableRcsDisconnected() throws Exception {
+ SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+ doReturn(mSipTransport).when(mRcsManager).getSipTransport();
+ controller.onRcsConnected(mRcsManager);
+ controller.onRcsDisconnected();
+ try {
+ controller.isSupported(0 /*subId*/);
+ fail();
+ } catch (ImsException e) {
+ assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+ }
+ }
+
+ @SmallTest
+ @Test
+ public void isSupportedSipTransportNotAvailableRcsConnected() throws Exception {
+ SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+ doReturn(null).when(mRcsManager).getSipTransport();
+ controller.onRcsConnected(mRcsManager);
+ try {
+ assertFalse(controller.isSupported(0 /*subId*/));
+ } catch (ImsException e) {
+ fail();
+ }
+ }
+
+ @SmallTest
+ @Test
+ public void isSupportedImsServiceNotAvailableRcsConnected() throws Exception {
+ SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+ doThrow(new ImsException("", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE))
+ .when(mRcsManager).getSipTransport();
+ controller.onRcsConnected(mRcsManager);
+ try {
+ controller.isSupported(0 /*subId*/);
+ fail();
+ } catch (ImsException e) {
+ assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+ }
+ }
+
+ private SipTransportController createController(int slotId, int subId) {
+ return new SipTransportController(mContext, slotId, subId, mExecutorService);
+ }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
index cfb68b7..ffbb71d 100644
--- a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
+++ b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
@@ -52,6 +52,8 @@
@Mock TelephonyRcsService.FeatureFactory mFeatureFactory;
@Mock UserCapabilityExchangeImpl mMockUceSlot0;
@Mock UserCapabilityExchangeImpl mMockUceSlot1;
+ @Mock SipTransportController mMockSipTransportSlot0;
+ @Mock SipTransportController mMockSipTransportSlot1;
@Mock RcsFeatureController.RegistrationHelperFactory mRegistrationFactory;
@Mock RcsFeatureController.FeatureConnectorFactory<RcsFeatureManager> mFeatureConnectorFactory;
@Mock FeatureConnector<RcsFeatureManager> mFeatureConnector;
@@ -72,6 +74,10 @@
anyInt());
doReturn(mMockUceSlot1).when(mFeatureFactory).createUserCapabilityExchange(any(), eq(1),
anyInt());
+ doReturn(mMockSipTransportSlot0).when(mFeatureFactory).createSipTransportController(any(),
+ eq(0), anyInt());
+ doReturn(mMockSipTransportSlot1).when(mFeatureFactory).createSipTransportController(any(),
+ eq(1), anyInt());
//set up default slot-> sub ID mappings.
setSlotToSubIdMapping(0 /*slotId*/, 1/*subId*/);
setSlotToSubIdMapping(1 /*slotId*/, 2/*subId*/);
@@ -84,7 +90,8 @@
@Test
public void testUserCapabilityExchangePresenceConnected() {
- setCarrierConfig(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true /*isEnabled*/);
+ setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ true /*isEnabled*/);
createRcsService(1 /*numSlots*/);
verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
verify(mFeatureControllerSlot0).connect();
@@ -92,7 +99,8 @@
@Test
public void testUserCapabilityExchangeOptionsConnected() {
- setCarrierConfig(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true /*isEnabled*/);
+ setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL,
+ true /*isEnabled*/);
createRcsService(1 /*numSlots*/);
verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
verify(mFeatureControllerSlot0).connect();
@@ -108,6 +116,55 @@
}
@Test
+ public void testSipTransportConnected() {
+ createRcsService(1 /*numSlots*/);
+ verify(mFeatureControllerSlot0, never()).addFeature(mMockSipTransportSlot0,
+ SipTransportController.class);
+ verify(mFeatureControllerSlot0, never()).connect();
+
+
+ // Send carrier config update for each slot.
+ setCarrierConfig(1 /*subId*/,
+ CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
+ true /*isEnabled*/);
+ sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
+ verify(mFeatureControllerSlot0).addFeature(mMockSipTransportSlot0,
+ SipTransportController.class);
+ verify(mFeatureControllerSlot0).connect();
+ verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
+ }
+
+ @Test
+ public void testSipTransportConnectedOneSlot() {
+ createRcsService(2 /*numSlots*/);
+ verify(mFeatureControllerSlot0, never()).addFeature(mMockSipTransportSlot0,
+ SipTransportController.class);
+ verify(mFeatureControllerSlot0, never()).connect();
+ verify(mFeatureControllerSlot0, never()).addFeature(mMockSipTransportSlot1,
+ SipTransportController.class);
+ verify(mFeatureControllerSlot1, never()).connect();
+
+
+ // Send carrier config update for slot 0 only
+ setCarrierConfig(1 /*subId*/,
+ CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
+ true /*isEnabled*/);
+ setCarrierConfig(2 /*subId*/,
+ CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
+ false /*isEnabled*/);
+ sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
+ sendCarrierConfigChanged(1 /*slotId*/, 2 /*subId*/);
+ verify(mFeatureControllerSlot0).addFeature(mMockSipTransportSlot0,
+ SipTransportController.class);
+ verify(mFeatureControllerSlot1, never()).addFeature(mMockSipTransportSlot0,
+ SipTransportController.class);
+ verify(mFeatureControllerSlot0).connect();
+ verify(mFeatureControllerSlot1, never()).connect();
+ verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
+ verify(mFeatureControllerSlot1, never()).updateAssociatedSubscription(1);
+ }
+
+ @Test
public void testNoFeaturesEnabledCarrierConfigChanged() {
createRcsService(1 /*numSlots*/);
// No carrier config set for UCE.
@@ -122,7 +179,10 @@
@Test
public void testSlotUpdates() {
- setCarrierConfig(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true /*isEnabled*/);
+ setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ true /*isEnabled*/);
+ setCarrierConfig(2 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ true /*isEnabled*/);
TelephonyRcsService service = createRcsService(1 /*numSlots*/);
verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
verify(mFeatureControllerSlot0).connect();
@@ -163,7 +223,10 @@
@Test
public void testCarrierConfigUpdate() {
- setCarrierConfig(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true /*isEnabled*/);
+ setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ true /*isEnabled*/);
+ setCarrierConfig(2 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ true /*isEnabled*/);
createRcsService(2 /*numSlots*/);
verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UserCapabilityExchangeImpl.class);
@@ -182,20 +245,42 @@
@Test
public void testCarrierConfigUpdateUceToNoUce() {
- setCarrierConfig(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true /*isEnabled*/);
+ setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ true /*isEnabled*/);
createRcsService(1 /*numSlots*/);
verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
verify(mFeatureControllerSlot0).connect();
// Send carrier config update for each slot.
- setCarrierConfig(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, false /*isEnabled*/);
+ setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ false /*isEnabled*/);
sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
verify(mFeatureControllerSlot0).removeFeature(UserCapabilityExchangeImpl.class);
verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
}
@Test
+ public void testCarrierConfigUpdateTransportToNoTransport() {
+ setCarrierConfig(1 /*subId*/,
+ CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
+ true /*isEnabled*/);
+ createRcsService(1 /*numSlots*/);
+ verify(mFeatureControllerSlot0).addFeature(mMockSipTransportSlot0,
+ SipTransportController.class);
+ verify(mFeatureControllerSlot0).connect();
+
+
+ // Send carrier config update for each slot.
+ setCarrierConfig(1 /*subId*/,
+ CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
+ false /*isEnabled*/);
+ sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
+ verify(mFeatureControllerSlot0).removeFeature(SipTransportController.class);
+ verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
+ }
+
+ @Test
public void testCarrierConfigUpdateNoUceToUce() {
createRcsService(1 /*numSlots*/);
verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
@@ -204,7 +289,8 @@
// Send carrier config update for each slot.
- setCarrierConfig(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true /*isEnabled*/);
+ setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
+ true /*isEnabled*/);
sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
verify(mFeatureControllerSlot0).connect();
@@ -218,8 +304,8 @@
mReceiverCaptor.getValue().onReceive(mContext, intent);
}
- private void setCarrierConfig(String key, boolean value) {
- PersistableBundle bundle = mContext.getCarrierConfig();
+ private void setCarrierConfig(int subId, String key, boolean value) {
+ PersistableBundle bundle = mContext.getCarrierConfig(subId);
bundle.putBoolean(key, value);
}