Snap for 4653471 from d24b685891366f5e7e3f2f9b8bbfd32647af10c0 to pi-release

Change-Id: I8c0622c7302169969ce0d4e742a2b4813fd831a0
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index 521b46a..2a35fd3 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -339,10 +339,19 @@
         private void notifyReady() throws ImsException {
             ImsManager manager;
             synchronized (mLock) {
-                mRetryCount = 0;
                 manager = mImsManager;
             }
-            mListener.connectionReady(manager);
+            try {
+                mListener.connectionReady(manager);
+            }
+            catch (ImsException e) {
+                Log.w(TAG, "Connector: notifyReady exception: " + e.getMessage());
+                throw e;
+            }
+            // Only reset retry count if connectionReady does not generate an ImsException/
+            synchronized (mLock) {
+                mRetryCount = 0;
+            }
         }
 
         private void notifyNotReady() {
@@ -1421,10 +1430,18 @@
     }
 
     /*
-     * Returns a flag indicating whether the IMS service is available. If it is not available,
-     * it will try to connect before reporting failure.
+     * Returns a flag indicating whether the IMS service is available. If it is not available or
+     * busy, it will try to connect before reporting failure.
      */
     public boolean isServiceAvailable() {
+        // If we are busy resolving dynamic IMS bindings, we are not available yet.
+        TelephonyManager tm = (TelephonyManager)
+                mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        if (tm.isResolvingImsBinding()) {
+            Log.d(TAG, "isServiceAvailable: resolving IMS binding, returning false");
+            return false;
+        }
+
         connectIfServiceIsAvailable();
         // mImsServiceProxy will always create an ImsServiceProxy.
         return mMmTelFeatureConnection.isBinderAlive();
@@ -1556,7 +1573,6 @@
             throw new NullPointerException("registration callback can't be null");
         }
 
-        checkAndThrowExceptionIfServiceUnavailable();
         try {
             mMmTelFeatureConnection.addRegistrationCallback(callback);
             log("Registration Callback registered.");
@@ -1568,6 +1584,27 @@
     }
 
     /**
+     * Removes a previously added registration callback that was added via
+     * {@link #addRegistrationCallback(ImsRegistrationImplBase.Callback)} .
+     * @param callback A {@link ImsRegistrationImplBase.Callback} that was previously added.
+     * @throws ImsException when the ImsService connection is not available.
+     */
+    public void removeRegistrationListener(ImsRegistrationImplBase.Callback callback)
+        throws ImsException {
+        if (callback == null) {
+            throw new NullPointerException("registration callback can't be null");
+        }
+
+        try {
+            mMmTelFeatureConnection.removeRegistrationCallback(callback);
+            log("Registration callback removed.");
+        } catch (RemoteException e) {
+            throw new ImsException("removeRegistrationCallback(IRIB)", e,
+                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+        }
+    }
+
+    /**
      * Adds a callback that gets called when MMTel capability status has changed, for example when
      * Voice over IMS or VT over IMS is not available currently.
      * @param callback A {@link ImsFeature.CapabilityCallback} that will notify the caller when
diff --git a/src/java/com/android/ims/MmTelFeatureConnection.java b/src/java/com/android/ims/MmTelFeatureConnection.java
index 2d11ae6..6028f6f 100644
--- a/src/java/com/android/ims/MmTelFeatureConnection.java
+++ b/src/java/com/android/ims/MmTelFeatureConnection.java
@@ -196,7 +196,7 @@
             IImsRegistration imsRegistration = getRegistration();
             if (imsRegistration != null) {
                 try {
-                    getRegistration().addRegistrationCallback(mRegistrationCallbackAdapter);
+                    getRegistration().removeRegistrationCallback(mRegistrationCallbackAdapter);
                 } catch (RemoteException e) {
                     Log.w(TAG, "removeConnection: couldn't remove registration callback");
                 }