Update ImsStateCallbackController

Support dynamic multi-sim configuration change.

PhoneConfigurationManager#registerForMultiSimConfigChange is used
to listen for the change and update the number of slots.

Bug: 178016400
Test: atest ImsStateCallbackControllerTest

Change-Id: I2009b184b3122f158c34464e9adcc96c4b9e2fdd
diff --git a/src/com/android/phone/ImsStateCallbackController.java b/src/com/android/phone/ImsStateCallbackController.java
index 109c524..c7f15bf 100644
--- a/src/com/android/phone/ImsStateCallbackController.java
+++ b/src/com/android/phone/ImsStateCallbackController.java
@@ -36,6 +36,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.AsyncResult;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -55,6 +56,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IImsStateCallback;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConfigurationManager;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.telephony.util.HandlerExecutor;
@@ -118,6 +120,7 @@
     private static final int EVENT_UNREGISTER_CALLBACK = 3;
     private static final int EVENT_CARRIER_CONFIG_CHANGED = 4;
     private static final int EVENT_EXTERNAL_RCS_STATE_CHANGED = 5;
+    private static final int EVENT_MSIM_CONFIGURATION_CHANGE = 6;
 
     private static ImsStateCallbackController sInstance;
 
@@ -217,6 +220,16 @@
                     onExternalRcsStateChanged((ExternalRcsFeatureState) msg.obj);
                     break;
 
+                case EVENT_MSIM_CONFIGURATION_CHANGE:
+                    AsyncResult result = (AsyncResult) msg.obj;
+                    Integer numSlots = (Integer) result.result;
+                    if (numSlots == null) {
+                        Log.w(TAG, "msim config change with null num slots");
+                        break;
+                    }
+                    updateFeatureControllerSize(numSlots);
+                    break;
+
                 default:
                     loge("Unhandled event " + msg.what);
             }
@@ -651,6 +664,9 @@
         mTelephonyRegistryManager.addOnSubscriptionsChangedListener(
                 mSubChangedListener, mSubChangedListener.getHandlerExecutor());
 
+        PhoneConfigurationManager.registerForMultiSimConfigChange(mHandler,
+                EVENT_MSIM_CONFIGURATION_CHANGE, null);
+
         mApp.registerReceiver(mReceiver, new IntentFilter(
                 CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
 
diff --git a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
index 431b7e6..75690bb 100644
--- a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
+++ b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
@@ -789,6 +789,39 @@
         assertFalse(mImsStateCallbackController.isRegistered(mCallback3));
     }
 
+    @Test
+    @SmallTest
+    public void testSlotUpdates() throws Exception {
+        createController(1);
+
+        verify(mMmTelFeatureConnectorSlot0, times(1)).connect();
+        verify(mRcsFeatureConnectorSlot0, times(1)).connect();
+        verify(mMmTelFeatureConnectorSlot0, times(0)).disconnect();
+        verify(mRcsFeatureConnectorSlot0, times(0)).disconnect();
+
+        // Add a new slot.
+        mImsStateCallbackController.updateFeatureControllerSize(2);
+
+        // connect in slot 1
+        verify(mMmTelFeatureConnectorSlot1, times(1)).connect();
+        verify(mRcsFeatureConnectorSlot1, times(1)).connect();
+
+        // no change in slot 0
+        verify(mMmTelFeatureConnectorSlot0, times(1)).connect();
+        verify(mRcsFeatureConnectorSlot0, times(1)).connect();
+
+        // Remove a slot.
+        mImsStateCallbackController.updateFeatureControllerSize(1);
+
+        // destroy in slot 1
+        verify(mMmTelFeatureConnectorSlot1, times(1)).disconnect();
+        verify(mRcsFeatureConnectorSlot1, times(1)).disconnect();
+
+        // no change in slot 0
+        verify(mMmTelFeatureConnectorSlot0, times(0)).disconnect();
+        verify(mRcsFeatureConnectorSlot0, times(0)).disconnect();
+    }
+
     private void createController(int slotCount) throws Exception {
         if (Looper.myLooper() == null) {
             Looper.prepare();