change control thread from binder to main for PhoneInterfaceManager#registerImsRegistrationCallback

change control thread from binder to main for PhoneInterfaceManager#registerImsRegistrationCallback

Bug: 238143538
Test: atest ImsStateCallbackController
Test: manaul test with AT&T SIM
1. flashing
2. adb kill -9 system_server
3. check registering callback in text log

Change-Id: I83bb37c978ff06553d0c20825c932f79637e47e9
diff --git a/src/com/android/phone/ImsStateCallbackController.java b/src/com/android/phone/ImsStateCallbackController.java
index 57c1787..edad754 100644
--- a/src/com/android/phone/ImsStateCallbackController.java
+++ b/src/com/android/phone/ImsStateCallbackController.java
@@ -68,6 +68,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 
 /**
@@ -143,6 +144,10 @@
     private final SparseArray<MmTelFeatureListener> mMmTelFeatureListeners = new SparseArray<>();
     private final SparseArray<RcsFeatureListener> mRcsFeatureListeners = new SparseArray<>();
 
+    // Container to store ImsManager instance by subId
+    private final ConcurrentHashMap<Integer, ImsManager> mSubIdToImsManagerCache =
+            new ConcurrentHashMap<>();
+
     private final SubscriptionManager mSubscriptionManager;
     private final TelephonyRegistryManager mTelephonyRegistryManager;
     private MmTelFeatureConnectorFactory mMmTelFeatureFactory;
@@ -282,6 +287,13 @@
             if (mSubId == subId) return;
             logd(mLogPrefix + "setSubId changed subId=" + subId);
 
+            // subId changed from valid to invalid
+            if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                if (VDBG) logv(mLogPrefix + "setSubId remove ImsManager " + mSubId);
+                // remove ImsManager reference associated with subId
+                mSubIdToImsManagerCache.remove(mSubId);
+            }
+
             mSubId = subId;
         }
 
@@ -298,6 +310,12 @@
             mSubId = subId;
             if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) return;
 
+            // store ImsManager reference associated with subId
+            if (manager != null) {
+                if (VDBG) logv(mLogPrefix + "connectionReady add ImsManager " + subId);
+                mSubIdToImsManagerCache.put(subId, manager);
+            }
+
             mState = STATE_READY;
             mReason = AVAILABLE;
             mHasConfig = true;
@@ -311,6 +329,10 @@
             reason = convertReasonType(reason);
             if (mReason == reason) return;
 
+            // remove ImsManager reference associated with subId
+            if (VDBG) logv(mLogPrefix + "connectionUnavailable remove ImsManager " + mSubId);
+            mSubIdToImsManagerCache.remove(mSubId);
+
             connectionUnavailableInternal(reason);
         }
 
@@ -319,7 +341,7 @@
             mReason = reason;
 
             /* If having no IMS package for MMTEL,
-             * dicard the reason except REASON_NO_IMS_SERVICE_CONFIGURED. */
+             * discard the reason except REASON_NO_IMS_SERVICE_CONFIGURED. */
             if (!mHasConfig && reason != REASON_NO_IMS_SERVICE_CONFIGURED) return;
 
             onFeatureStateChange(mSubId, FEATURE_MMTEL, mState, mReason);
@@ -973,6 +995,19 @@
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_CALLBACK, cb));
     }
 
+    /**
+     * Get ImsManager reference associated with subId
+     *
+     * @param subId subscribe ID
+     * @return instance of ImsManager associated with subId, but if ImsService is not
+     * available return null
+     */
+    public ImsManager getImsManager(int subId) {
+        if (VDBG) logv("getImsManager subId = " + subId);
+
+        return mSubIdToImsManagerCache.get(subId);
+    }
+
     private void removeInactiveCallbacks(
             ArrayList<IBinder> inactiveCallbacks, String message) {
         if (inactiveCallbacks == null || inactiveCallbacks.size() == 0) return;
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index f1f0a68..4d38320 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -4032,7 +4032,18 @@
         try {
             int slotId = getSlotIndexOrException(subId);
             verifyImsMmTelConfiguredOrThrow(slotId);
-            ImsManager.getInstance(mApp, slotId).addRegistrationCallbackForSubscription(c, subId);
+
+            ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
+            if (controller != null) {
+                ImsManager imsManager = controller.getImsManager(subId);
+                if (imsManager != null) {
+                    imsManager.addRegistrationCallbackForSubscription(c, subId);
+                } else {
+                    throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+                }
+            } else {
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
+            }
         } catch (ImsException e) {
             throw new ServiceSpecificException(e.getCode());
         } finally {
@@ -4053,14 +4064,20 @@
             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
         }
         final long token = Binder.clearCallingIdentity();
+
         try {
-            ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
-                    .removeRegistrationCallbackForSubscription(c, subId);
-        } catch (ImsException e) {
-            Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
-                    + "is inactive, ignoring unregister.");
-            // If the subscription is no longer active, just return, since the callback
-            // will already have been removed internally.
+            ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
+            if (controller != null) {
+                ImsManager imsManager = controller.getImsManager(subId);
+                if (imsManager != null) {
+                    imsManager.removeRegistrationCallbackForSubscription(c, subId);
+                } else {
+                    Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
+                            + "is inactive, ignoring unregister.");
+                    // If the ImsManager is not valid, just return, since the callback
+                    // will already have been removed internally.
+                }
+            }
         } finally {
             Binder.restoreCallingIdentity(token);
         }