merge in lmp-mr1-wfc-release history after reset to lmp-mr1-wfc-dev
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 59e932b..c9cce3d 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -1889,6 +1889,11 @@
     public Phone getImsPhone();
 
     /**
+     * Start listening for IMS service UP/DOWN events.
+     */
+    public void startMonitoringImsService();
+
+    /**
      * Release the local instance of the ImsPhone and disconnect from
      * the phone.
      * @return the instance of the ImsPhone phone previously owned
diff --git a/src/java/com/android/internal/telephony/PhoneBase.java b/src/java/com/android/internal/telephony/PhoneBase.java
index 0148891..c805110 100644
--- a/src/java/com/android/internal/telephony/PhoneBase.java
+++ b/src/java/com/android/internal/telephony/PhoneBase.java
@@ -86,6 +86,7 @@
 public abstract class PhoneBase extends Handler implements Phone {
     private static final String LOG_TAG = "PhoneBase";
 
+    private boolean mImsIntentReceiverRegistered = false;
     private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -100,12 +101,14 @@
                 }
             }
 
-            if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
-                mImsServiceReady = true;
-                updateImsPhone();
-            } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
-                mImsServiceReady = false;
-                updateImsPhone();
+            synchronized (PhoneProxy.lockForRadioTechnologyChange) {
+                if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
+                    mImsServiceReady = true;
+                    updateImsPhone();
+                } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
+                    mImsServiceReady = false;
+                    updateImsPhone();
+                }
             }
         }
     };
@@ -218,7 +221,6 @@
 
     protected int mPhoneId;
 
-    private final Object mImsLock = new Object();
     private boolean mImsServiceReady = false;
     protected ImsPhone mImsPhone = null;
 
@@ -425,26 +427,36 @@
         mUiccController = UiccController.getInstance();
         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
 
-        // Monitor IMS service - but first poll to see if already up (could miss
-        // intent)
-        ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId());
-        if (imsManager != null && imsManager.isServiceAvailable()) {
-            mImsServiceReady = true;
-            updateImsPhone();
-        }
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
-        filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
-        mContext.registerReceiver(mImsIntentReceiver, filter);
-
         mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
         mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null);
     }
 
     @Override
+    public void startMonitoringImsService() {
+        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
+            filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
+            mContext.registerReceiver(mImsIntentReceiver, filter);
+            mImsIntentReceiverRegistered = true;
+
+            // Monitor IMS service - but first poll to see if already up (could miss
+            // intent)
+            ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId());
+            if (imsManager != null && imsManager.isServiceAvailable()) {
+                mImsServiceReady = true;
+                updateImsPhone();
+            }
+        }
+    }
+
+    @Override
     public void dispose() {
         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            mContext.unregisterReceiver(mImsIntentReceiver);
+            if (mImsIntentReceiverRegistered) {
+                mContext.unregisterReceiver(mImsIntentReceiver);
+                mImsIntentReceiverRegistered = false;
+            }
             mCi.unSetOnCallRing(this);
             // Must cleanup all connectionS and needs to use sendMessage!
             mDcTracker.cleanUpAllConnections(null);
@@ -1904,10 +1916,15 @@
 
     @Override
     public ImsPhone relinquishOwnershipOfImsPhone() {
-        synchronized (mImsLock) {
+        synchronized (PhoneProxy.lockForRadioTechnologyChange) {
             if (mImsPhone == null)
                 return null;
 
+            if (mImsIntentReceiverRegistered) {
+                mContext.unregisterReceiver(mImsIntentReceiver);
+                mImsIntentReceiverRegistered = false;
+            }
+
             ImsPhone imsPhone = mImsPhone;
             mImsPhone = null;
 
@@ -1920,7 +1937,7 @@
 
     @Override
     public void acquireOwnershipOfImsPhone(ImsPhone imsPhone) {
-        synchronized (mImsLock) {
+        synchronized (PhoneProxy.lockForRadioTechnologyChange) {
             if (imsPhone == null)
                 return;
 
@@ -1945,26 +1962,24 @@
     }
 
     protected void updateImsPhone() {
-        synchronized (mImsLock) {
-            Rlog.d(LOG_TAG, "updateImsPhone"
-                    + " mImsServiceReady=" + mImsServiceReady);
+        Rlog.d(LOG_TAG, "updateImsPhone"
+                + " mImsServiceReady=" + mImsServiceReady);
 
-            if (mImsServiceReady && (mImsPhone == null)) {
-                mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
-                CallManager.getInstance().registerPhone(mImsPhone);
-                mImsPhone.registerForSilentRedial(
-                        this, EVENT_INITIATE_SILENT_REDIAL, null);
-            } else if (!mImsServiceReady && (mImsPhone != null)) {
-                CallManager.getInstance().unregisterPhone(mImsPhone);
-                mImsPhone.unregisterForSilentRedial(this);
+        if (mImsServiceReady && (mImsPhone == null)) {
+            mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
+            CallManager.getInstance().registerPhone(mImsPhone);
+            mImsPhone.registerForSilentRedial(
+                    this, EVENT_INITIATE_SILENT_REDIAL, null);
+        } else if (!mImsServiceReady && (mImsPhone != null)) {
+            CallManager.getInstance().unregisterPhone(mImsPhone);
+            mImsPhone.unregisterForSilentRedial(this);
 
-                mImsPhone.dispose();
-                // Potential GC issue if someone keeps a reference to ImsPhone.
-                // However: this change will make sure that such a reference does
-                // not access functions through NULL pointer.
-                //mImsPhone.removeReferences();
-                mImsPhone = null;
-            }
+            mImsPhone.dispose();
+            // Potential GC issue if someone keeps a reference to ImsPhone.
+            // However: this change will make sure that such a reference does
+            // not access functions through NULL pointer.
+            //mImsPhone.removeReferences();
+            mImsPhone = null;
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 9f02433..29ce320 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -151,9 +151,11 @@
                     if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
                         phone = new GSMPhone(context,
                                 sCommandsInterfaces[i], sPhoneNotifier, i);
+                        phone.startMonitoringImsService();
                     } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                         phone = new CDMALTEPhone(context,
                                 sCommandsInterfaces[i], sPhoneNotifier, i);
+                        phone.startMonitoringImsService();
                     }
                     Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " sub = " + i);
 
diff --git a/src/java/com/android/internal/telephony/PhoneProxy.java b/src/java/com/android/internal/telephony/PhoneProxy.java
index 70ee3db..d402565 100644
--- a/src/java/com/android/internal/telephony/PhoneProxy.java
+++ b/src/java/com/android/internal/telephony/PhoneProxy.java
@@ -40,7 +40,6 @@
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.test.SimulatedRadioControl;
 import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.RadioCapability;
 import com.android.internal.telephony.uicc.IccCardProxy;
 import com.android.internal.telephony.uicc.IccFileHandler;
 import com.android.internal.telephony.uicc.IsimRecords;
@@ -50,7 +49,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.List;
-import java.util.Set;
 
 import com.android.internal.telephony.dataconnection.DctController;
 
@@ -301,6 +299,7 @@
             if (imsPhone != null) {
                 mActivePhone.acquireOwnershipOfImsPhone(imsPhone);
             }
+            mActivePhone.startMonitoringImsService();
             mActivePhone.registerForSimRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
         }
 
@@ -1444,6 +1443,9 @@
     public ImsPhone relinquishOwnershipOfImsPhone() { return null; }
 
     @Override
+    public void startMonitoringImsService() {}
+
+    @Override
     public void acquireOwnershipOfImsPhone(ImsPhone imsPhone) { }
 
     @Override