Better handle MSIM DDS changed event
Brad Ebinger [Tue, 18 Apr 2017 18:45:26 +0000 (11:45 -0700)]
On DSDS MSIM devices, when Default Data Subscription event
is received, the ImsService may choose to switch which
Slot ID is active.

This change better handles that switch and removes a
crash that was happening due to
ImsServiceProxy#getFeatureStatus getting called
circularly.

Bug: 37361882
Test: Run Telephony unit tests
Merged-In: I0dece4059e23b75b6774ba814f6460919b14ff94
Merged-In: I1130e81c2e5078513adf7e36dcff947e8d77e4bf
Change-Id: I4aa1e7aa01a9c36bad5ef9c89f45a1a60671ca8b

src/java/com/android/ims/ImsManager.java

index 17bb555..07b9ac0 100644 (file)
@@ -1422,7 +1422,17 @@ public class ImsManager {
         mImsConfigListener = listener;
     }
 
-    public void addNotifyStatusChangedCallback(ImsServiceProxy.INotifyStatusChanged c) {
+
+    /**
+     * Adds a callback for status changed events if the binder is already available. If it is not,
+     * this method will throw an ImsException.
+     */
+    public void addNotifyStatusChangedCallbackIfAvailable(ImsServiceProxy.INotifyStatusChanged c)
+            throws ImsException {
+        if (!mImsServiceProxy.isBinderAlive()) {
+            throw new ImsException("Binder is not active!",
+                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+        }
         if (c != null) {
             mStatusCallbacks.add(c);
         }
@@ -1833,8 +1843,6 @@ public class ImsManager {
     }
 
     public int getImsServiceStatus() throws ImsException {
-        checkAndThrowExceptionIfServiceUnavailable();
-
         return mImsServiceProxy.getFeatureStatus();
     }
 
@@ -1966,7 +1974,8 @@ public class ImsManager {
     }
 
     /**
-     * Binds the IMS service only if the service is not created.
+     * Checks to see if the ImsService Binder is connected. If it is not, we try to create the
+     * connection again.
      */
     private void checkAndThrowExceptionIfServiceUnavailable()
             throws ImsException {
@@ -2016,13 +2025,13 @@ public class ImsManager {
         TelephonyManager tm = (TelephonyManager)
                 mContext.getSystemService(Context.TELEPHONY_SERVICE);
         ImsServiceProxy serviceProxy = new ImsServiceProxy(mPhoneId, ImsFeature.MMTEL);
+        serviceProxy.setStatusCallback(() ->  mStatusCallbacks.forEach(
+                ImsServiceProxy.INotifyStatusChanged::notifyStatusChanged));
         // Returns null if the service is not available.
         IImsServiceController b = tm.getImsServiceControllerAndListen(mPhoneId,
                 ImsFeature.MMTEL, serviceProxy.getListener());
         if (b != null) {
             serviceProxy.setBinder(b.asBinder());
-            serviceProxy.setStatusCallback(() -> mStatusCallbacks.forEach(
-                            ImsServiceProxy.INotifyStatusChanged::notifyStatusChanged));
             // Trigger the cache to be updated for feature status.
             serviceProxy.getFeatureStatus();
         } else {
@@ -2042,9 +2051,13 @@ public class ImsManager {
     private ImsCallSession createCallSession(int serviceId,
             ImsCallProfile profile) throws ImsException {
         try {
+            // Throws an exception if the ImsService Feature is not ready to accept commands.
             return new ImsCallSession(mImsServiceProxy.createCallSession(serviceId, profile, null));
         } catch (RemoteException e) {
-            return null;
+            Rlog.w(TAG, "CreateCallSession: Error, remote exception: " + e.getMessage());
+            throw new ImsException("createCallSession()", e,
+                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+
         }
     }