Migrate Mobile Network Setting

Bug: 111453847
Test: existing telephony test
Change-Id: Ia6ce09e00b18c0138c26fd1353339fe2f8c2639d
diff --git a/src/com/android/phone/CdmaOptions.java b/src/com/android/phone/CdmaOptions.java
index 93c9879..47c0eb4 100644
--- a/src/com/android/phone/CdmaOptions.java
+++ b/src/com/android/phone/CdmaOptions.java
@@ -24,12 +24,12 @@
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 
@@ -53,15 +53,9 @@
 
     private PreferenceFragment mPrefFragment;
     private PreferenceScreen mPrefScreen;
-    private Phone mPhone;
+    private int mSubId;
 
-    // Constructor for CdmaOptionsTest, since PreferenceScreen is final and cannot be mocked
-    @VisibleForTesting
-    public CdmaOptions(Phone phone) {
-        mPhone = phone;
-    }
-
-    public CdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen, Phone phone) {
+    public CdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen, int subId) {
         mPrefFragment = prefFragment;
         mPrefScreen = prefScreen;
         mPrefFragment.addPreferencesFromResource(R.xml.cdma_options);
@@ -75,19 +69,18 @@
         mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
         mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
 
-        update(phone);
+        updateSubscriptionId(subId);
     }
 
-    // Unlike mPrefFragment or mPrefScreen, mPhone may change during lifecycle of CdmaOptions.
-    // For example, a new sim card is inserted. When that happens, we update CdmaOptions with new
-    // phone.
-    protected void update(Phone phone) {
-        mPhone = phone;
+    protected void updateSubscriptionId(int subId) {
+        mSubId = subId;
+        int phoneType = TelephonyManager.from(mPrefFragment.getContext())
+                .createForSubscriptionId(mSubId).getPhoneType();
 
         PersistableBundle carrierConfig =
-                PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+                PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
         // Some CDMA carriers want the APN settings.
-        boolean addAPNExpand = shouldAddApnExpandPreference(carrierConfig);
+        boolean addAPNExpand = shouldAddApnExpandPreference(phoneType, carrierConfig);
         boolean addCdmaSubscription =
                 deviceSupportsNvAndRuim();
         // Read platform settings for carrier settings
@@ -119,7 +112,7 @@
                             final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
                             // This will setup the Home and Search affordance
                             intent.putExtra(":settings:show_fragment_as_subsetting", true);
-                            intent.putExtra("sub_id", mPhone.getSubId());
+                            intent.putExtra("sub_id", mSubId);
                             mPrefFragment.startActivity(intent);
                             return true;
                         }
@@ -150,12 +143,9 @@
      * carrier config
      */
     @VisibleForTesting
-    public boolean shouldAddApnExpandPreference(PersistableBundle config) {
-        if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
-                && config.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL)) {
-            return true;
-        }
-        return false;
+    public static boolean shouldAddApnExpandPreference(int phoneType, PersistableBundle config) {
+        return phoneType == PhoneConstants.PHONE_TYPE_CDMA
+                && config.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL);
     }
 
     private boolean deviceSupportsNvAndRuim() {
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 0c6c5da..2f443b8 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -35,7 +35,7 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.AsyncResult;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -76,7 +76,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.phone.settings.PhoneAccountSettingsFragment;
 import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -348,6 +347,7 @@
 
         private SubscriptionManager mSubscriptionManager;
         private TelephonyManager mTelephonyManager;
+        private int mSubId;
 
         //UI objects
         private AdvancedOptionsPreference mAdvancedOptions;
@@ -368,7 +368,6 @@
         private List<SubscriptionInfo> mActiveSubInfos;
 
         private UserManager mUm;
-        private Phone mPhone;
         private ImsManager mImsMgr;
         private MyHandler mHandler;
         private boolean mOkClicked;
@@ -402,20 +401,20 @@
                 updateVideoCallState();
             }
 
-            /*
-             * Listen to different subId if mPhone is updated.
+            /**
+             * Listen to different subId if it's changed.
              */
-            protected void updatePhone() {
-                int newSubId = (mPhone != null
-                        && SubscriptionManager.isValidSubscriptionId(mPhone.getSubId()))
-                        ? mPhone.getSubId()
-                        : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            protected void updateSubscriptionId(Integer subId) {
+                if (subId.equals(PhoneCallStateListener.this.mSubId)) {
+                    return;
+                }
 
-                // Now, listen to new subId if it's valid.
+                PhoneCallStateListener.this.mSubId = subId;
+
                 mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
 
-                mSubId = newSubId;
-                if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+                // Now, listen to new subId if it's valid.
+                if (SubscriptionManager.isValidSubscriptionId(subId)) {
                     mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
                 }
             }
@@ -472,7 +471,7 @@
 
         @Override
         public void onPositiveButtonClick(DialogFragment dialog) {
-            mPhone.setDataRoamingEnabled(true);
+            mTelephonyManager.setDataRoamingEnabled(true);
             mButtonDataRoam.setChecked(true);
             MetricsLogger.action(getContext(),
                     getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
@@ -503,7 +502,6 @@
             sendMetricsEventPreferenceClicked(preferenceScreen, preference);
 
             /** TODO: Refactor and get rid of the if's using subclasses */
-            final int phoneSubId = mPhone.getSubId();
             if (preference.getKey().equals(BUTTON_4G_LTE_KEY)) {
                 return true;
             } else if (mGsmUmtsOptions != null &&
@@ -511,7 +509,7 @@
                 return true;
             } else if (mCdmaOptions != null &&
                     mCdmaOptions.preferenceTreeClick(preference) == true) {
-                if (mPhone.isInEcm()) {
+                if (mTelephonyManager.getEmergencyCallbackMode()) {
 
                     mClickedPreference = preference;
 
@@ -524,8 +522,8 @@
             } else if (preference == mButtonPreferredNetworkMode) {
                 //displays the value taken from the Settings.System
                 int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                        mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                        getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
                         preferredNetworkMode);
                 mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
                 return true;
@@ -548,8 +546,8 @@
                 return true;
             }  else if (preference == mButtonEnabledNetworks) {
                 int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                        mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                        getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
                         preferredNetworkMode);
                 mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
                 return true;
@@ -724,27 +722,26 @@
         private void updatePhone(int slotId) {
             final SubscriptionInfo sir = mSubscriptionManager
                     .getActiveSubscriptionInfoForSimSlotIndex(slotId);
+
             if (sir != null) {
-                int phoneId = SubscriptionManager.getPhoneId(sir.getSubscriptionId());
-                if (SubscriptionManager.isValidPhoneId(phoneId)) {
-                    mPhone = PhoneFactory.getPhone(phoneId);
+                mSubId = sir.getSubscriptionId();
+
+                Log.i(LOG_TAG, "updatePhone:- slotId=" + slotId + " sir=" + sir);
+
+                mImsMgr = ImsManager.getInstance(getContext(),
+                        SubscriptionManager.getPhoneId(mSubId));
+                mTelephonyManager = new TelephonyManager(getContext(), mSubId);
+                if (mImsMgr == null) {
+                    log("updatePhone :: Could not get ImsManager instance!");
+                } else if (DBG) {
+                    log("updatePhone :: mImsMgr=" + mImsMgr);
                 }
-            }
-            if (mPhone == null) {
-                // Do the best we can
-                mPhone = PhoneGlobals.getPhone();
-            }
-            Log.i(LOG_TAG, "updatePhone:- slotId=" + slotId + " sir=" + sir);
-
-            mImsMgr = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
-            mTelephonyManager = new TelephonyManager(mPhone.getContext(), mPhone.getSubId());
-            if (mImsMgr == null) {
-                log("updatePhone :: Could not get ImsManager instance!");
-            } else if (DBG) {
-                log("updatePhone :: mImsMgr=" + mImsMgr);
+            } else {
+                // There is no active subscription in the given slot.
+                mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
             }
 
-            mPhoneStateListener.updatePhone();
+            mPhoneStateListener.updateSubscriptionId(mSubId);
         }
 
         private TabHost.TabContentFactory mEmptyTabContent = new TabHost.TabContentFactory() {
@@ -845,7 +842,9 @@
 
             int currentTab = mTabHost != null ? mTabHost.getCurrentTab() : 0;
             updatePhone(currentTab);
-            updateEnabledNetworksEntries();
+            if (hasActiveSubscriptions()) {
+                updateEnabledNetworksEntries();
+            }
             Log.i(LOG_TAG, "onCreate:-");
         }
 
@@ -924,7 +923,7 @@
             // Set UI state in onResume because a user could go home, launch some
             // app to change this setting's backend, and re-launch this settings app
             // and the UI state would be inconsistent with actual state
-            mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
+            mButtonDataRoam.setChecked(mTelephonyManager.isDataRoamingEnabled());
 
             if (getPreferenceScreen().findPreference(BUTTON_PREFERED_NETWORK_MODE) != null
                     || getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null)  {
@@ -970,24 +969,26 @@
             prefSet.addPreference(mButtonDataRoam);
             prefSet.addPreference(mDataUsagePref);
 
-            // Customized preferences needs to be initialized with subId.
-            mMobileDataPref.initialize(phoneSubId);
-            mDataUsagePref.initialize(phoneSubId);
-
             mMobileDataPref.setEnabled(hasActiveSubscriptions);
             mButtonDataRoam.setEnabled(hasActiveSubscriptions);
             mDataUsagePref.setEnabled(hasActiveSubscriptions);
 
-            // Initialize states of mButtonDataRoam.
-            mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
-            mButtonDataRoam.setDisabledByAdmin(false);
-            if (mButtonDataRoam.isEnabled()) {
-                if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
-                        UserManager.DISALLOW_DATA_ROAMING, UserHandle.myUserId())) {
-                    mButtonDataRoam.setEnabled(false);
-                } else {
-                    mButtonDataRoam.checkRestrictionAndSetDisabled(
-                            UserManager.DISALLOW_DATA_ROAMING);
+            if (hasActiveSubscriptions) {
+                // Customized preferences needs to be initialized with subId.
+                mMobileDataPref.initialize(phoneSubId);
+                mDataUsagePref.initialize(phoneSubId);
+
+                // Initialize states of mButtonDataRoam.
+                mButtonDataRoam.setChecked(mTelephonyManager.isDataRoamingEnabled());
+                mButtonDataRoam.setDisabledByAdmin(false);
+                if (mButtonDataRoam.isEnabled()) {
+                    if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
+                            UserManager.DISALLOW_DATA_ROAMING, UserHandle.myUserId())) {
+                        mButtonDataRoam.setEnabled(false);
+                    } else {
+                        mButtonDataRoam.checkRestrictionAndSetDisabled(
+                                UserManager.DISALLOW_DATA_ROAMING);
+                    }
                 }
             }
         }
@@ -995,7 +996,6 @@
         private void updateBody() {
             final Activity activity = getActivity();
             final PreferenceScreen prefSet = getPreferenceScreen();
-            final int phoneSubId = mPhone.getSubId();
             final boolean hasActiveSubscriptions = hasActiveSubscriptions();
 
             if (activity == null || activity.isDestroyed()) {
@@ -1010,18 +1010,27 @@
 
             prefSet.removeAll();
 
-            updateBodyBasicFields(activity, prefSet, phoneSubId, hasActiveSubscriptions);
+            updateBodyBasicFields(activity, prefSet, mSubId, hasActiveSubscriptions);
 
-            if (mExpandAdvancedFields) {
-                updateBodyAdvancedFields(activity, prefSet, phoneSubId, hasActiveSubscriptions);
+            if (hasActiveSubscriptions) {
+                if (mExpandAdvancedFields) {
+                    updateBodyAdvancedFields(activity, prefSet, mSubId, hasActiveSubscriptions);
+                } else {
+                    prefSet.addPreference(mAdvancedOptions);
+                }
             } else {
-                prefSet.addPreference(mAdvancedOptions);
+                // Shows the "Carrier" preference that allows user to add a e-sim profile.
+                if (showEuiccSettings(getContext())) {
+                    mEuiccSettingsPref.setSummary(null /* summary */);
+                    prefSet.addPreference(mEuiccSettingsPref);
+                }
             }
         }
 
         private void updateBodyAdvancedFields(Activity activity, PreferenceScreen prefSet,
                 int phoneSubId, boolean hasActiveSubscriptions) {
-            boolean isLteOnCdma = mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
+            boolean isLteOnCdma = mTelephonyManager.getLteOnCdmaMode()
+                    == PhoneConstants.LTE_ON_CDMA_TRUE;
 
             if (DBG) {
                 log("updateBody: isLteOnCdma=" + isLteOnCdma + " phoneSubId=" + phoneSubId);
@@ -1042,12 +1051,12 @@
             }
 
             int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                    mPhone.getContext().getContentResolver(),
+                    getContext().getContentResolver(),
                     android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                     preferredNetworkMode);
 
             PersistableBundle carrierConfig =
-                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
             mIsGlobalCdma = isLteOnCdma
                     && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
             if (carrierConfig.getBoolean(
@@ -1057,15 +1066,15 @@
                 prefSet.removePreference(mLteDataServicePref);
             } else if (carrierConfig.getBoolean(CarrierConfigManager
                     .KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)
-                    && !mPhone.getServiceState().getRoaming()
-                    && mPhone.getServiceState().getDataRegState()
+                    && !mTelephonyManager.getServiceState().getRoaming()
+                    && mTelephonyManager.getServiceState().getDataRegState()
                     == ServiceState.STATE_IN_SERVICE) {
                 prefSet.removePreference(mButtonPreferredNetworkMode);
                 prefSet.removePreference(mButtonEnabledNetworks);
 
-                final int phoneType = mPhone.getPhoneType();
+                final int phoneType = mTelephonyManager.getPhoneType();
                 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                    updateCdmaOptions(this, prefSet, mPhone);
+                    updateCdmaOptions(this, prefSet, mSubId);
                 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
                     updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
                 } else {
@@ -1082,7 +1091,7 @@
                 // change Preferred Network Mode.
                 mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
 
-                updateCdmaOptions(this, prefSet, mPhone);
+                updateCdmaOptions(this, prefSet, mSubId);
                 updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
             } else {
                 prefSet.removePreference(mButtonPreferredNetworkMode);
@@ -1134,8 +1143,12 @@
             UpdatePreferredNetworkModeSummary(settingsNetworkMode);
             UpdateEnabledNetworksValueAndSummary(settingsNetworkMode);
             // Display preferred network type based on what modem returns b/18676277
-            mPhone.setPreferredNetworkType(settingsNetworkMode, mHandler
-                    .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+            new SetPreferredNetworkAsyncTask(
+                    mTelephonyManager,
+                    mSubId,
+                    settingsNetworkMode,
+                    mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+                    .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
 
             /**
              * Enable/disable depending upon if there are any active subscriptions.
@@ -1189,19 +1202,19 @@
 
         // Requires that mPhone is up to date
         void updateEnabledNetworksEntries() {
-            final int phoneType = mPhone.getPhoneType();
+            final int phoneType = mTelephonyManager.getPhoneType();
             final PersistableBundle carrierConfig =
-                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
             if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                 final int lteForced = android.provider.Settings.Global.getInt(
-                        mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.LTE_SERVICE_FORCED + mPhone.getSubId(),
+                        getContext().getContentResolver(),
+                        android.provider.Settings.Global.LTE_SERVICE_FORCED + mSubId,
                         0);
-                final boolean isLteOnCdma = mPhone.getLteOnCdmaMode()
+                final boolean isLteOnCdma = mTelephonyManager.getLteOnCdmaMode()
                         == PhoneConstants.LTE_ON_CDMA_TRUE;
                 final int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                        mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mPhone.getSubId(),
+                        getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
                         preferredNetworkMode);
                 if (isLteOnCdma) {
                     if (lteForced == 0) {
@@ -1237,7 +1250,7 @@
                         }
                     }
                 }
-                updateCdmaOptions(this, getPreferenceScreen(), mPhone);
+                updateCdmaOptions(this, getPreferenceScreen(), mSubId);
 
             } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
                 if (isSupportTdscdma()) {
@@ -1275,7 +1288,7 @@
                     mButtonEnabledNetworks.setEntryValues(
                             R.array.enabled_networks_values);
                 }
-                updateGsmUmtsOptions(this, getPreferenceScreen(), mPhone.getSubId(),
+                updateGsmUmtsOptions(this, getPreferenceScreen(), mSubId,
                         mNetworkQueryService);
             } else {
                 throw new IllegalStateException("Unexpected phone type: " + phoneType);
@@ -1315,7 +1328,7 @@
         public boolean onPreferenceChange(Preference preference, Object objValue) {
             sendMetricsEventPreferenceChanged(getPreferenceScreen(), preference, objValue);
 
-            final int phoneSubId = mPhone.getSubId();
+            final int phoneSubId = mSubId;
             if (preference == mButtonPreferredNetworkMode) {
                 //NOTE onPreferenceChange seems to be called even if there is no change
                 //Check if the button value is changed from the System.Setting
@@ -1323,7 +1336,7 @@
                 int buttonNetworkMode;
                 buttonNetworkMode = Integer.parseInt((String) objValue);
                 int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                        mPhone.getContext().getContentResolver(),
+                        getContext().getContentResolver(),
                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         preferredNetworkMode);
                 if (buttonNetworkMode != settingsNetworkMode) {
@@ -1362,12 +1375,16 @@
                     }
 
                     android.provider.Settings.Global.putInt(
-                            mPhone.getContext().getContentResolver(),
+                            getContext().getContentResolver(),
                             android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                             buttonNetworkMode );
                     //Set the modem network mode
-                    mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
-                            .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+                    new SetPreferredNetworkAsyncTask(
+                            mTelephonyManager,
+                            mSubId,
+                            modemNetworkMode,
+                            mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+                            .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                 }
             } else if (preference == mButtonEnabledNetworks) {
                 mButtonEnabledNetworks.setValue((String) objValue);
@@ -1375,7 +1392,7 @@
                 buttonNetworkMode = Integer.parseInt((String) objValue);
                 if (DBG) log("buttonNetworkMode: " + buttonNetworkMode);
                 int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                        mPhone.getContext().getContentResolver(),
+                        getContext().getContentResolver(),
                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         preferredNetworkMode);
                 if (buttonNetworkMode != settingsNetworkMode) {
@@ -1410,12 +1427,16 @@
                     UpdateEnabledNetworksValueAndSummary(buttonNetworkMode);
 
                     android.provider.Settings.Global.putInt(
-                            mPhone.getContext().getContentResolver(),
+                            getContext().getContentResolver(),
                             android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                             buttonNetworkMode );
                     //Set the modem network mode
-                    mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
-                            .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+                    new SetPreferredNetworkAsyncTask(
+                            mTelephonyManager,
+                            mSubId,
+                            modemNetworkMode,
+                            mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+                            .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                 }
             } else if (preference == mButton4glte) {
                 boolean enhanced4gMode = !mButton4glte.isChecked();
@@ -1427,10 +1448,10 @@
                 //normally called on the toggle click
                 if (!mButtonDataRoam.isChecked()) {
                     PersistableBundle carrierConfig =
-                            PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+                            PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
                     if (carrierConfig != null && carrierConfig.getBoolean(
                             CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL)) {
-                        mPhone.setDataRoamingEnabled(true);
+                        mTelephonyManager.setDataRoamingEnabled(true);
                         MetricsLogger.action(getContext(),
                                 getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
                                 true);
@@ -1441,13 +1462,15 @@
                         // First confirm with a warning dialog about charges
                         mOkClicked = false;
                         RoamingDialogFragment fragment = new RoamingDialogFragment();
-                        fragment.setPhone(mPhone);
+                        Bundle b = new Bundle();
+                        b.putInt(RoamingDialogFragment.SUB_ID_KEY, mSubId);
+                        fragment.setArguments(b);
                         fragment.show(getFragmentManager(), ROAMING_TAG);
                         // Don't update the toggle unless the confirm button is actually pressed.
                         return false;
                     }
                 } else {
-                    mPhone.setDataRoamingEnabled(false);
+                    mTelephonyManager.setDataRoamingEnabled(false);
                     MetricsLogger.action(getContext(),
                             getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
                             false);
@@ -1477,7 +1500,7 @@
         }
 
         private boolean is4gLtePrefEnabled(PersistableBundle carrierConfig) {
-            return (mTelephonyManager.getCallState(mPhone.getSubId())
+            return (mTelephonyManager.getCallState(mSubId)
                     == TelephonyManager.CALL_STATE_IDLE)
                     && mImsMgr != null
                     && mImsMgr.isNonTtyOrTtyOnVolteEnabled()
@@ -1506,26 +1529,25 @@
                     return;
                 }
 
-                AsyncResult ar = (AsyncResult) msg.obj;
-                final int phoneSubId = mPhone.getSubId();
+                boolean success = (boolean) msg.obj;
 
-                if (ar.exception == null) {
+                if (success) {
                     int networkMode;
                     if (getPreferenceScreen().findPreference(
                             BUTTON_PREFERED_NETWORK_MODE) != null)  {
                         networkMode =  Integer.parseInt(mButtonPreferredNetworkMode.getValue());
                         android.provider.Settings.Global.putInt(
-                                mPhone.getContext().getContentResolver(),
+                                getContext().getContentResolver(),
                                 android.provider.Settings.Global.PREFERRED_NETWORK_MODE
-                                        + phoneSubId,
+                                        + mSubId,
                                 networkMode );
                     }
                     if (getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null) {
                         networkMode = Integer.parseInt(mButtonEnabledNetworks.getValue());
                         android.provider.Settings.Global.putInt(
-                                mPhone.getContext().getContentResolver(),
+                                getContext().getContentResolver(),
                                 android.provider.Settings.Global.PREFERRED_NETWORK_MODE
-                                        + phoneSubId,
+                                        + mSubId,
                                 networkMode );
                     }
                 } else {
@@ -1537,11 +1559,9 @@
         }
 
         private void updatePreferredNetworkUIFromDb() {
-            final int phoneSubId = mPhone.getSubId();
-
             int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                    mPhone.getContext().getContentResolver(),
-                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                    getContext().getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
                     preferredNetworkMode);
 
             if (DBG) {
@@ -1586,7 +1606,7 @@
                             R.string.preferred_network_mode_gsm_wcdma_summary);
                     break;
                 case Phone.NT_MODE_CDMA:
-                    switch (mPhone.getLteOnCdmaMode()) {
+                    switch (mTelephonyManager.getLteOnCdmaMode()) {
                         case PhoneConstants.LTE_ON_CDMA_TRUE:
                             mButtonPreferredNetworkMode.setSummary(
                                     R.string.preferred_network_mode_cdma_summary);
@@ -1639,9 +1659,9 @@
                             R.string.preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary);
                     break;
                 case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
-                    if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ||
-                            mIsGlobalCdma ||
-                            isWorldMode()) {
+                    if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+                            || mIsGlobalCdma
+                            || isWorldMode()) {
                         mButtonPreferredNetworkMode.setSummary(
                                 R.string.preferred_network_mode_global_summary);
                     } else {
@@ -1776,9 +1796,9 @@
                         }
                         mButtonEnabledNetworks.setValue(
                                 Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
-                        if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ||
-                                mIsGlobalCdma ||
-                                isWorldMode()) {
+                        if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+                                || mIsGlobalCdma
+                                || isWorldMode()) {
                             mButtonEnabledNetworks.setSummary(R.string.network_global);
                         } else {
                             mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
@@ -1818,7 +1838,7 @@
             }
 
             // Removes the preference if the wifi calling is disabled.
-            if (!isWifiCallingEnabled(getContext(), mPhone.getPhoneId())) {
+            if (!isWifiCallingEnabled(getContext(), SubscriptionManager.getPhoneId(mSubId))) {
                 mCallingCategory.removePreference(mWiFiCallingPref);
                 return;
             }
@@ -1829,7 +1849,7 @@
             if (simCallManager != null) {
                 Intent intent = PhoneAccountSettingsFragment.buildPhoneAccountConfigureIntent(
                         getContext(), simCallManager);
-                PackageManager pm = mPhone.getContext().getPackageManager();
+                PackageManager pm = getContext().getPackageManager();
                 List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
                 mWiFiCallingPref.setTitle(resolutions.get(0).loadLabel(pm));
                 mWiFiCallingPref.setSummary(null);
@@ -1859,7 +1879,7 @@
             }
 
             mCallingCategory.addPreference(mWiFiCallingPref);
-            mWiFiCallingPref.setEnabled(mTelephonyManager.getCallState(mPhone.getSubId())
+            mWiFiCallingPref.setEnabled(mTelephonyManager.getCallState(mSubId)
                     == TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
         }
 
@@ -1869,7 +1889,7 @@
             }
 
             PersistableBundle carrierConfig = PhoneGlobals.getInstance()
-                    .getCarrierConfigForSubId(mPhone.getSubId());
+                    .getCarrierConfigForSubId(mSubId);
 
             if ((mImsMgr == null
                     || !mImsMgr.isVolteEnabledByPlatform()
@@ -1893,7 +1913,7 @@
             }
 
             PersistableBundle carrierConfig = PhoneGlobals.getInstance()
-                    .getCarrierConfigForSubId(mPhone.getSubId());
+                    .getCarrierConfigForSubId(mSubId);
 
             if (mImsMgr != null
                     && mImsMgr.isVtEnabledByPlatform()
@@ -1901,13 +1921,13 @@
                     && isImsServiceStateReady(mImsMgr)
                     && (carrierConfig.getBoolean(
                         CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
-                        || mPhone.mDcTracker.isDataEnabled())) {
+                        || mTelephonyManager.isDataEnabled())) {
                 mCallingCategory.addPreference(mVideoCallingPref);
                 if (!mButton4glte.isChecked()) {
                     mVideoCallingPref.setEnabled(false);
                     mVideoCallingPref.setChecked(false);
                 } else {
-                    mVideoCallingPref.setEnabled(mTelephonyManager.getCallState(mPhone.getSubId())
+                    mVideoCallingPref.setEnabled(mTelephonyManager.getCallState(mSubId)
                             == TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
                     mVideoCallingPref.setChecked(mImsMgr.isVtEnabledByUser());
                     mVideoCallingPref.setOnPreferenceChangeListener(this);
@@ -1993,7 +2013,7 @@
                 return;
             }
 
-            updateGsmUmtsOptions(this, prefSet, mPhone.getSubId(), mNetworkQueryService);
+            updateGsmUmtsOptions(this, prefSet, mSubId, mNetworkQueryService);
 
             PreferenceCategory networkOperatorCategory =
                     (PreferenceCategory) prefSet.findPreference(
@@ -2016,7 +2036,7 @@
             if (prefSet == null) {
                 return;
             }
-            updateCdmaOptions(this, prefSet, mPhone);
+            updateCdmaOptions(this, prefSet, mSubId);
             CdmaSystemSelectListPreference systemSelect =
                     (CdmaSystemSelectListPreference)prefSet.findPreference
                             (BUTTON_CDMA_SYSTEM_SELECT_KEY);
@@ -2030,7 +2050,7 @@
                 return true;
             }
 
-            String operatorNumeric = mPhone.getServiceState().getOperatorNumeric();
+            String operatorNumeric = mTelephonyManager.getServiceState().getOperatorNumeric();
             String[] numericArray = getResources().getStringArray(
                     R.array.config_support_tdscdma_roaming_on_networks);
             if (numericArray.length == 0 || operatorNumeric == null) {
@@ -2157,16 +2177,42 @@
         }
 
         private void updateCdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
-                Phone phone) {
+                int subId) {
             // We don't want to re-create CdmaOptions if already exists. Otherwise, the preferences
             // inside it will also be re-created which causes unexpected behavior. For example,
             // the open dialog gets dismissed or detached after pause / resume.
             if (mCdmaOptions == null) {
-                mCdmaOptions = new CdmaOptions(prefFragment, prefScreen, phone);
+                mCdmaOptions = new CdmaOptions(prefFragment, prefScreen, subId);
             } else {
-                mCdmaOptions.update(phone);
+                mCdmaOptions.updateSubscriptionId(subId);
             }
         }
     }
-}
 
+    private static final class SetPreferredNetworkAsyncTask extends AsyncTask<Void, Void, Boolean> {
+
+        private final TelephonyManager mTelephonyManager;
+        private final int mSubId;
+        private final int mNetworkType;
+        private final Message mCallback;
+
+        SetPreferredNetworkAsyncTask(
+                TelephonyManager tm, int subId, int networkType, Message callback) {
+            mTelephonyManager = tm;
+            mSubId = subId;
+            mNetworkType = networkType;
+            mCallback = callback;
+        }
+
+        @Override
+        protected Boolean doInBackground(Void... voids) {
+            return mTelephonyManager.setPreferredNetworkType(mSubId, mNetworkType);
+        }
+
+        @Override
+        protected void onPostExecute(Boolean isSuccessed) {
+            mCallback.obj = isSuccessed;
+            mCallback.sendToTarget();
+        }
+    }
+}
diff --git a/src/com/android/phone/RoamingDialogFragment.java b/src/com/android/phone/RoamingDialogFragment.java
index 4d3bd47..d24967b 100644
--- a/src/com/android/phone/RoamingDialogFragment.java
+++ b/src/com/android/phone/RoamingDialogFragment.java
@@ -27,14 +27,16 @@
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 
-import com.android.internal.telephony.Phone;
-
 /**
  * A dialog fragment that asks the user if they are sure they want to turn on data roaming
  * to avoid accidental charges.
  */
 public class RoamingDialogFragment extends DialogFragment implements OnClickListener {
 
+    public static final String SUB_ID_KEY = "sub_id_key";
+
+    private int mSubId;
+
     /**
      * The interface we expect a host activity to implement.
      */
@@ -45,15 +47,12 @@
     // the host activity which implements the listening interface
     private RoamingDialogListener mListener;
 
-    private Phone mPhone;
-
-    public void setPhone(Phone phone) {
-        mPhone = phone;
-    }
-
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
+        Bundle args = getArguments();
+        mSubId = args.getInt(SUB_ID_KEY);
+
         // Verify host activity implemented callback interface
         FragmentManager fragmentManager = getFragmentManager();
         Fragment fragment = fragmentManager.findFragmentById(R.id.network_setting_content);
@@ -69,13 +68,11 @@
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
         int title = R.string.roaming_alert_title;
-        if (mPhone != null) {
-            PersistableBundle carrierConfig =
-                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
-            if (carrierConfig != null && carrierConfig.getBoolean(
-                    CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
-                title = R.string.roaming_check_price_warning;
-            }
+        PersistableBundle carrierConfig =
+                PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+        if (carrierConfig != null && carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
+            title = R.string.roaming_check_price_warning;
         }
         builder.setMessage(getResources().getString(R.string.roaming_warning))
                 .setTitle(title)