Merge "Modify the contact picker for call forwarding to directly show contact list"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 58a65d7..a5df742 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -339,6 +339,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.settings.NETWORK_OPERATOR_SETTINGS" />
                 <action android:name="android.settings.DATA_ROAMING_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
@@ -351,17 +352,6 @@
         <!-- service to handle network query requests sent to RIL -->
         <service android:name="NetworkQueryService" />
 
-        <activity android:name="NetworkSetting"
-                android:label="@string/networks"
-                android:configChanges="orientation|screenSize|keyboardHidden"
-                android:theme="@style/NetworkOperatorsSettingsTheme">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <action android:name="android.settings.NETWORK_OPERATOR_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
         <activity android:name="GsmUmtsCallOptions"
                 android:label="@string/gsm_umts_options"
                 android:theme="@style/DialerSettingsLight">
diff --git a/res/layout/edit_fdn_contact_screen.xml b/res/layout/edit_fdn_contact_screen.xml
index 24e0c6b..c7ba0d4 100644
--- a/res/layout/edit_fdn_contact_screen.xml
+++ b/res/layout/edit_fdn_contact_screen.xml
@@ -31,7 +31,8 @@
         android:singleLine="true"
         android:scrollHorizontally="true"
         android:autoText="false"
-        android:capitalize="words" />
+        android:capitalize="words"
+        android:textAlignment="viewStart" />
 
     <EditText android:id="@+id/fdn_number"
         android:hint="@string/number"
@@ -42,7 +43,8 @@
         android:singleLine="true"
         android:scrollHorizontally="true"
         android:autoText="false"
-        android:capitalize="none" />
+        android:capitalize="none"
+        android:textAlignment="viewStart" />
 
     <Button android:id="@+id/button"
         android:layout_width="wrap_content"
diff --git a/res/values/config.xml b/res/values/config.xml
index 0d0bd22..615d43f 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -153,10 +153,10 @@
     <!-- Class name for the default main Dialer activity [DO NOT TRANSLATE] -->
     <string name="dialer_default_class" translatable="false">com.android.dialer.DialtactsActivity</string>
 
-    <!-- Package name for the network operator settings [DO NOT TRANSLATE] -->
-    <string name="network_operator_settings_package" translatable="false">com.android.phone</string>
-    <!-- Class name for the network operator settings activity [DO NOT TRANSLATE] -->
-    <string name="network_operator_settings_class" translatable="false">com.android.phone.NetworkSetting</string>
+    <!-- Package name for the mobile network settings [DO NOT TRANSLATE] -->
+    <string name="mobile_network_settings_package" translatable="false">com.android.phone</string>
+    <!-- Class name for the mobile network settings activity [DO NOT TRANSLATE] -->
+    <string name="mobile_network_settings_class" translatable="false">com.android.phone.MobileNetworkSettings</string>
 
     <!-- CDMA activation goes through HFA -->
     <!-- DEPRECATED: Use CarrierConfigManager#KEY_USE_HFA_FOR_PROVISIONING_BOOL -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 14cd952..8366ae3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -178,8 +178,6 @@
     <!-- Voicemail notifications title. The user clicks on this preference navigate to the system settings screen for that channel
     .[CHAR LIMIT=30] -->
     <string name="voicemail_notifications_preference_title">Notifications</string>
-    <!-- Mobile network settings screen, setting option name -->
-    <string name="networks">Network operators</string>
     <!-- Cell Broadcast settings title.  [CHAR LIMIT=50] -->
     <string name="cell_broadcast_settings">Emergency broadcasts</string>
     <!-- Call settings screen title -->
@@ -371,8 +369,6 @@
     <string name="load_networks_progress">Searching\u2026</string>
     <!-- Available networks screen, text when no networks are found -->
     <string name="empty_networks_list">No networks found.</string>
-    <!-- Available networks screen, setting option name -->
-    <string name="search_networks">Search networks</string>
     <!-- Available networks screen, toast when an error is encountered when searching for networks -->
     <string name="network_query_error">Error while searching for networks.</string>
     <!-- Available networks screen, toast when registering on a specific network -->
@@ -383,10 +379,6 @@
     <string name="connect_later">Can\'t connect to this network right now. Try again later.</string>
     <!-- Available networks screen, toast when registered on a specific network -->
     <string name="registration_done">Registered on network.</string>
-    <!-- Mobile network settings screen setting option summary text -->
-    <string name="sum_carrier_select">Choose a network operator</string>
-    <!-- Available networks screen, setting summary text -->
-    <string name="sum_search_networks">Search for all available networks</string>
     <!-- Available networks screen, name of switch button for whether to select network automatically -->
     <string name="select_automatically">Automatically select network</string>
     <!-- Available networks screen, name of button when user wants to select network manually  -->
diff --git a/res/xml/carrier_select.xml b/res/xml/carrier_select.xml
deleted file mode 100644
index 1e04285..0000000
--- a/res/xml/carrier_select.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        android:key="list_networks_key" 
-        android:title="@string/label_available">
-    <Preference 
-        android:key="button_srch_netwrks_key" 
-        android:title="@string/search_networks"
-        android:summary="@string/sum_search_networks"
-        android:persistent="false"/>
-    <Preference 
-        android:key="button_auto_select_key" 
-        android:title="@string/select_automatically"
-        android:persistent="false"/>
-</PreferenceScreen>
diff --git a/res/xml/gsm_umts_options.xml b/res/xml/gsm_umts_options.xml
index 86fe41d..4c74d73 100644
--- a/res/xml/gsm_umts_options.xml
+++ b/res/xml/gsm_umts_options.xml
@@ -17,6 +17,22 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:settings="http://schemas.android.com/apk/res/com.android.phone">
 
+    <com.android.phone.NetworkOperators
+        android:key="network_operators_category_key"
+        android:title="@string/network_operator_category"
+        android:persistent="false">
+
+        <SwitchPreference
+            android:key="button_auto_select_key"
+            android:title="@string/select_automatically"
+            android:persistent="false"/>
+
+        <com.android.phone.NetworkSelectListPreference
+            android:key="button_network_select_key"
+            android:title="@string/network_select_title"
+            android:persistent="false"/>
+    </com.android.phone.NetworkOperators>
+
     <PreferenceScreen
         android:key="button_apn_key"
         android:title="@string/apn_settings"
@@ -27,13 +43,6 @@
     </PreferenceScreen>
 
     <PreferenceScreen
-        android:key="button_carrier_sel_key"
-        android:title="@string/networks"
-        android:summary="@string/sum_carrier_select"
-        android:persistent="false">
-    </PreferenceScreen>
-
-    <PreferenceScreen
         android:key="carrier_settings_key"
         android:title="@string/carrier_settings_title">
         <intent android:action="android.intent.action.MAIN"
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 1d264fb..e5527bc 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -42,6 +42,7 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
+import android.telephony.ims.feature.ImsFeature;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -50,6 +51,7 @@
 import android.widget.Toast;
 
 import com.android.ims.ImsConfig;
+import com.android.ims.ImsException;
 import com.android.ims.ImsManager;
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.Phone;
@@ -105,6 +107,7 @@
     private static final String ENABLE_VIDEO_CALLING_KEY = "button_enable_video_calling";
 
     private Phone mPhone;
+    private ImsManager mImsMgr;
     private SubscriptionInfoHelper mSubscriptionInfoHelper;
     private TelecomManager mTelecomManager;
 
@@ -188,6 +191,17 @@
         mTelecomManager = TelecomManager.from(this);
     }
 
+    private void updateImsManager(Phone phone) {
+        log("updateImsManager :: phone.getContext()=" + phone.getContext()
+                + " phone.getPhoneId()=" + phone.getPhoneId());
+        mImsMgr = ImsManager.getInstance(phone.getContext(), phone.getPhoneId());
+        if (mImsMgr == null) {
+            log("updateImsManager :: Could not get ImsManager instance!");
+        } else {
+            log("updateImsManager :: mImsMgr=" + mImsMgr);
+        }
+    }
+
     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
@@ -210,6 +224,7 @@
     protected void onResume() {
         super.onResume();
 
+        updateImsManager(mPhone);
         PreferenceScreen preferenceScreen = getPreferenceScreen();
         if (preferenceScreen != null) {
             preferenceScreen.removeAll();
@@ -347,6 +362,19 @@
             }
             wifiCallingSettings.setSummary(resId);
         }
+
+        try {
+            if (mImsMgr.getImsServiceStatus() != ImsFeature.STATE_READY) {
+                log("Feature state not ready so remove vt and wfc settings for "
+                        + " phone =" + mPhone.getPhoneId());
+                prefSet.removePreference(wifiCallingSettings);
+                prefSet.removePreference(mEnableVideoCalling);
+            }
+        } catch (ImsException ex) {
+            log("Exception when trying to get ImsServiceStatus: " + ex);
+            prefSet.removePreference(wifiCallingSettings);
+            prefSet.removePreference(mEnableVideoCalling);
+        }
     }
 
     /**
diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
index 70ba4af..697fca8 100644
--- a/src/com/android/phone/GsmUmtsOptions.java
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -22,9 +22,9 @@
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
+import android.preference.TwoStatePreference;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
-import android.content.ComponentName;
 
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
@@ -36,34 +36,43 @@
     private static final String LOG_TAG = "GsmUmtsOptions";
 
     private PreferenceScreen mButtonAPNExpand;
-    private PreferenceScreen mButtonOperatorSelectionExpand;
+    private TwoStatePreference mButtonAutoSelect;
+    private NetworkSelectListPreference mButtonOperatorSelection;
+
+    private NetworkOperators mNetworkOperator;
 
     private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key";
-    private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key";
     private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
+
     public static final String EXTRA_SUB_ID = "sub_id";
     private PreferenceFragment mPrefFragment;
     private PreferenceScreen mPrefScreen;
+    INetworkQueryService mNetworkQueryService;
     private int mSubId;
 
     public GsmUmtsOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
-            final int subId) {
+            final int subId, INetworkQueryService queryService) {
         mPrefFragment = prefFragment;
         mPrefScreen = prefScreen;
         mSubId = subId;
+        mNetworkQueryService = queryService;
         create();
     }
 
     protected void create() {
         mPrefFragment.addPreferencesFromResource(R.xml.gsm_umts_options);
         mButtonAPNExpand = (PreferenceScreen) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
+
+        mNetworkOperator = (NetworkOperators) mPrefScreen
+                .findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
+        mNetworkOperator.initialize(mPrefScreen, mSubId, mNetworkQueryService);
+
         boolean removedAPNExpand = false;
-        mButtonOperatorSelectionExpand =
-                (PreferenceScreen) mPrefScreen.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+        boolean removedNetworkOperatorsCategory = false;
         if (PhoneFactory.getDefaultPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
             log("Not a GSM phone");
             mButtonAPNExpand.setEnabled(false);
-            mButtonOperatorSelectionExpand.setEnabled(false);
+            mNetworkOperator.setEnabled(false);
         } else {
             log("Not a CDMA phone");
             Resources res = mPrefFragment.getResources();
@@ -83,17 +92,19 @@
             if (!carrierConfig.getBoolean(
                     CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL)) {
                 mPrefScreen.removePreference(mPrefScreen
-                        .findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY));
+                        .findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY));
+                removedNetworkOperatorsCategory = true;
             }
 
             if (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)) {
                 if (PhoneFactory.getDefaultPhone().isCspPlmnEnabled()) {
                     log("[CSP] Enabling Operator Selection menu.");
-                    mButtonOperatorSelectionExpand.setEnabled(true);
+                    mNetworkOperator.setEnabled(true);
                 } else {
                     log("[CSP] Disabling Operator Selection menu.");
                     mPrefScreen.removePreference(mPrefScreen
-                          .findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY));
+                            .findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY));
+                    removedNetworkOperatorsCategory = true;
                 }
             }
 
@@ -124,25 +135,22 @@
                         }
             });
         }
-        if (mPrefScreen.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY) != null) {
-            mButtonOperatorSelectionExpand.setOnPreferenceClickListener(
-                    new Preference.OnPreferenceClickListener() {
-                        @Override
-                        public boolean onPreferenceClick(Preference preference) {
-                            final Intent intent = new Intent(Intent.ACTION_MAIN);
-                            intent.setComponent(new ComponentName("com.android.phone",
-                                    "com.android.phone.NetworkSetting"));
-                            intent.putExtra(EXTRA_SUB_ID, mSubId);
-                            mPrefFragment.startActivity(intent);
-                            return true;
-                        }
-            });
+
+        if (!removedNetworkOperatorsCategory) {
+            mButtonAutoSelect = (TwoStatePreference) mPrefScreen
+                    .findPreference(NetworkOperators.BUTTON_AUTO_SELECT_KEY);
+            mButtonOperatorSelection = (NetworkSelectListPreference) mPrefScreen
+                    .findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY);
         }
     }
 
     public boolean preferenceTreeClick(Preference preference) {
-        log("preferenceTreeClick: return false");
-        return false;
+        if (preference == mButtonAutoSelect || preference == mButtonOperatorSelection) {
+            return true;
+        } else {
+            log("preferenceTreeClick: return false");
+            return false;
+        }
     }
 
     protected void log(String s) {
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 03865fe..cca6703 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -22,16 +22,19 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.UserHandle;
@@ -46,6 +49,7 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
+import android.telephony.ims.feature.ImsFeature;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -61,6 +65,7 @@
 import android.widget.TabHost;
 
 import com.android.ims.ImsConfig;
+import com.android.ims.ImsException;
 import com.android.ims.ImsManager;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
@@ -177,7 +182,6 @@
         private static final String BUTTON_4G_LTE_KEY = "enhanced_4g_lte";
         private static final String BUTTON_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
         private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key";
-        private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key";
         private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
         private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
         private static final String BUTTON_CARRIER_SETTINGS_EUICC_KEY =
@@ -208,12 +212,14 @@
         private PreferenceCategory mCallingCategory;
         private Preference mWiFiCallingPref;
         private SwitchPreference mVideoCallingPref;
+        private NetworkSelectListPreference mButtonNetworkSelect;
 
         private static final String iface = "rmnet0"; //TODO: this will go away
         private List<SubscriptionInfo> mActiveSubInfos;
 
         private UserManager mUm;
         private Phone mPhone;
+        private ImsManager mImsMgr;
         private MyHandler mHandler;
         private boolean mOkClicked;
 
@@ -248,6 +254,53 @@
             }
         };
 
+        /**
+         * Service connection code for the NetworkQueryService.
+         * Handles the work of binding to a local object so that we can make
+         * the appropriate service calls.
+         */
+
+        /** Local service interface */
+        private INetworkQueryService mNetworkQueryService = null;
+
+        private void setNetworkQueryService() {
+            mButtonNetworkSelect = (NetworkSelectListPreference) getPreferenceScreen()
+                    .findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY);
+            if (mButtonNetworkSelect != null) {
+                mButtonNetworkSelect.setNetworkQueryService(mNetworkQueryService);
+            }
+
+        }
+        /** Service connection */
+        private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
+
+            /** Handle the task of binding the local object to the service */
+            public void onServiceConnected(ComponentName className, IBinder service) {
+                if (DBG) log("connection created, binding local service.");
+                mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
+                setNetworkQueryService();
+            }
+
+            /** Handle the task of cleaning up the local binding */
+            public void onServiceDisconnected(ComponentName className) {
+                if (DBG) log("connection disconnected, cleaning local binding.");
+                mNetworkQueryService = null;
+                setNetworkQueryService();
+            }
+        };
+
+        private void bindNetworkQueryService() {
+            getContext().startService(new Intent(getContext(), NetworkQueryService.class));
+            getContext().bindService(new Intent(getContext(), NetworkQueryService.class).setAction(
+                        NetworkQueryService.ACTION_LOCAL_BINDER),
+                        mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
+        }
+
+        private void unbindNetworkQueryService() {
+            // unbind the service.
+            getContext().unbindService(mNetworkQueryServiceConnection);
+        }
+
         @Override
         public void onPositiveButtonClick(DialogFragment dialog) {
             mPhone.setDataRoamingEnabled(true);
@@ -486,6 +539,13 @@
                 mPhone = PhoneGlobals.getPhone();
             }
             Log.i(LOG_TAG, "updatePhone:- slotId=" + slotId + " sir=" + sir);
+
+            mImsMgr = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
+            if (mImsMgr == null) {
+                log("updatePhone :: Could not get ImsManager instance!");
+            } else if (DBG) {
+                log("updatePhone :: mImsMgr=" + mImsMgr);
+            }
         }
 
         private TabHost.TabContentFactory mEmptyTabContent = new TabHost.TabContentFactory() {
@@ -517,6 +577,8 @@
             mTelephonyManager = (TelephonyManager) activity.getSystemService(
                             Context.TELEPHONY_SERVICE);
 
+            bindNetworkQueryService();
+
             if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
                 mUnavailable = true;
                 activity.setContentView(R.layout.telephony_disallowed_preference_screen);
@@ -595,6 +657,7 @@
 
         @Override
         public void onDestroy() {
+            unbindNetworkQueryService();
             super.onDestroy();
             if (getActivity() != null && !getActivity().isDestroyed()) {
                 getActivity().unregisterReceiver(mPhoneChangeReceiver);
@@ -715,7 +778,8 @@
                         mGsmUmtsOptions = null;
                     }
                 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
+                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId,
+                            mNetworkQueryService);
                 } else {
                     throw new IllegalStateException("Unexpected phone type: " + phoneType);
                 }
@@ -731,7 +795,8 @@
                 mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
 
                 mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
-                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
+                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId,
+                        mNetworkQueryService);
             } else {
                 prefSet.removePreference(mButtonPreferredNetworkMode);
                 final int phoneType = mPhone.getPhoneType();
@@ -817,7 +882,8 @@
                         mButtonEnabledNetworks.setEntryValues(
                                 R.array.enabled_networks_values);
                     }
-                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
+                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId,
+                            mNetworkQueryService);
                 } else {
                     throw new IllegalStateException("Unexpected phone type: " + phoneType);
                 }
@@ -840,8 +906,16 @@
                 android.util.Log.d(LOG_TAG, "keep ltePref");
             }
 
-            if (hideEnhanced4gLteSettings(getActivity(), carrierConfig)) {
-                Preference pref = prefSet.findPreference(BUTTON_4G_LTE_KEY);
+            Preference pref = prefSet.findPreference(BUTTON_4G_LTE_KEY);
+            try {
+                if ((mImsMgr.getImsServiceStatus() != ImsFeature.STATE_READY)
+                        || hideEnhanced4gLteSettings(getActivity(), carrierConfig)) {
+                    if (pref != null) {
+                        prefSet.removePreference(pref);
+                    }
+                }
+            } catch (ImsException ex) {
+                log("Exception when trying to get ImsServiceStatus: " + ex);
                 if (pref != null) {
                     prefSet.removePreference(pref);
                 }
@@ -924,7 +998,7 @@
             if (ps != null) {
                 ps.setEnabled(hasActiveSubscriptions);
             }
-            ps = findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+            ps = findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
             if (ps != null) {
                 ps.setEnabled(hasActiveSubscriptions);
             }
@@ -1608,22 +1682,24 @@
             }
 
             if (mGsmUmtsOptions == null) {
-                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, mPhone.getSubId());
+                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, mPhone.getSubId(),
+                        mNetworkQueryService);
             }
             PreferenceScreen apnExpand =
                     (PreferenceScreen) prefSet.findPreference(BUTTON_APN_EXPAND_KEY);
-            PreferenceScreen operatorSelectionExpand =
-                    (PreferenceScreen) prefSet.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+            PreferenceCategory networkOperatorCategory =
+                    (PreferenceCategory) prefSet.findPreference(
+                            NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
             PreferenceScreen carrierSettings =
                     (PreferenceScreen) prefSet.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
             if (apnExpand != null) {
                 apnExpand.setEnabled(isWorldMode() || enable);
             }
-            if (operatorSelectionExpand != null) {
+            if (networkOperatorCategory != null) {
                 if (enable) {
-                    operatorSelectionExpand.setEnabled(true);
+                    networkOperatorCategory.setEnabled(true);
                 } else {
-                    prefSet.removePreference(operatorSelectionExpand);
+                    prefSet.removePreference(networkOperatorCategory);
                 }
             }
             if (carrierSettings != null) {
diff --git a/src/com/android/phone/NetworkOperators.java b/src/com/android/phone/NetworkOperators.java
new file mode 100644
index 0000000..b46bec9
--- /dev/null
+++ b/src/com/android/phone/NetworkOperators.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.preference.TwoStatePreference;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+/**
+ * "Networks" settings UI for the Phone app.
+ */
+public class NetworkOperators extends PreferenceCategory
+        implements Preference.OnPreferenceChangeListener {
+
+    private static final String LOG_TAG = "NetworkOperators";
+    private static final boolean DBG = true;
+
+    private static final int EVENT_AUTO_SELECT_DONE = 100;
+    private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 200;
+
+    //String keys for preference lookup
+    public static final String BUTTON_NETWORK_SELECT_KEY = "button_network_select_key";
+    public static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
+    public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
+
+    int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
+
+    //preference objects
+    private NetworkSelectListPreference mNetworkSelect;
+    private TwoStatePreference mAutoSelect;
+
+    private int mSubId;
+
+    public NetworkOperators(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public NetworkOperators(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public NetworkOperators(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NetworkOperators(Context context) {
+        super(context);
+    }
+
+    /**
+     * Initialize NetworkOperators instance with information like subId, queryService.
+     * It is required to have preferences work properly.
+     *
+     * @param prefScreen prefScreen this category is in.
+     * @param subId Corresponding subscription ID of this network.
+     * @param queryService The service to do network queries.
+     */
+    public void initialize(PreferenceScreen prefScreen,
+            final int subId, INetworkQueryService queryService) {
+        mSubId = subId;
+
+        mNetworkSelect =
+                (NetworkSelectListPreference) prefScreen.findPreference(BUTTON_NETWORK_SELECT_KEY);
+        mAutoSelect =
+                (TwoStatePreference) prefScreen.findPreference(BUTTON_AUTO_SELECT_KEY);
+
+        mPhoneId = SubscriptionManager.getPhoneId(mSubId);
+
+        if (mAutoSelect != null) {
+            mAutoSelect.setOnPreferenceChangeListener(this);
+        }
+
+        if (mAutoSelect != null) {
+            mNetworkSelect.initialize(mSubId, queryService, this);
+        }
+
+        getNetworkSelectionMode();
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference
+     * changes specifically on auto select button.
+     *
+     * @param preference is the preference to be changed, should be auto select button.
+     * @param newValue should be the value of whether autoSelect is checked.
+     */
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mAutoSelect) {
+            boolean autoSelect = (Boolean) newValue;
+            selectNetworkAutomatic(autoSelect);
+            return true;
+        }
+        return false;
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_AUTO_SELECT_DONE:
+                    mAutoSelect.setEnabled(true);
+
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) logd("automatic network selection: failed!");
+                        displayNetworkSelectionFailed(ar.exception);
+                    } else {
+                        if (DBG) logd("automatic network selection: succeeded!");
+                        displayNetworkSelectionSucceeded();
+                    }
+
+                    break;
+                case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) logd("get network selection mode: failed!");
+                    } else if (ar.result != null) {
+                        try {
+                            int[] modes = (int[]) ar.result;
+                            boolean autoSelect = (modes[0] == 0);
+                            if (DBG) {
+                                logd("get network selection mode: "
+                                        + (autoSelect ? "auto" : "manual") + " selection");
+                            }
+                            if (mAutoSelect != null) {
+                                mAutoSelect.setChecked(autoSelect);
+                            }
+                            if (mNetworkSelect != null) {
+                                mNetworkSelect.setEnabled(!autoSelect);
+                            }
+                        } catch (Exception e) {
+                            if (DBG) loge("get network selection mode: unable to parse result.");
+                        }
+                    }
+            }
+
+            return;
+        }
+    };
+
+    // Used by both mAutoSelect and mNetworkSelect buttons.
+    protected void displayNetworkSelectionFailed(Throwable ex) {
+        String status;
+
+        if ((ex != null && ex instanceof CommandException)
+                && ((CommandException) ex).getCommandError()
+                        == CommandException.Error.ILLEGAL_SIM_OR_ME) {
+            status = getContext().getResources().getString(R.string.not_allowed);
+        } else {
+            status = getContext().getResources().getString(R.string.connect_later);
+        }
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+
+        TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
+        Phone phone = PhoneFactory.getPhone(mPhoneId);
+        if (phone != null) {
+            ServiceState ss = tm.getServiceStateForSubscriber(phone.getSubId());
+            if (ss != null) {
+                app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId());
+            }
+        }
+    }
+
+    // Used by both mAutoSelect and mNetworkSelect buttons.
+    protected void displayNetworkSelectionSucceeded() {
+        String status = getContext().getResources().getString(R.string.registration_done);
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void selectNetworkAutomatic(boolean autoSelect) {
+        if (mNetworkSelect != null) {
+            mNetworkSelect.setEnabled(!autoSelect);
+        }
+        if (autoSelect) {
+            if (DBG) logd("select network automatically...");
+            mAutoSelect.setEnabled(false);
+            Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
+            Phone phone = PhoneFactory.getPhone(mPhoneId);
+            if (phone != null) {
+                phone.setNetworkSelectionModeAutomatic(msg);
+            }
+        } else if (mNetworkSelect != null) {
+            mNetworkSelect.onClick();
+        }
+    }
+
+    protected void getNetworkSelectionMode() {
+        if (DBG) logd("getting network selection mode...");
+        Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
+        Phone phone = PhoneFactory.getPhone(mPhoneId);
+        if (phone != null) {
+            phone.getNetworkSelectionMode(msg);
+        }
+    }
+
+    private void logd(String msg) {
+        Log.d(LOG_TAG, "[NetworksList] " + msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(LOG_TAG, "[NetworksList] " + msg);
+    }
+}
diff --git a/src/com/android/phone/NetworkSelectListPreference.java b/src/com/android/phone/NetworkSelectListPreference.java
new file mode 100644
index 0000000..28050c9
--- /dev/null
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.OperatorInfo;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+import java.util.List;
+
+
+/**
+ * "Networks" preference in "Mobile network" settings UI for the Phone app.
+ * It's used to manually search and choose mobile network. Enabled only when
+ * autoSelect preference is turned off.
+ */
+public class NetworkSelectListPreference extends ListPreference
+        implements DialogInterface.OnCancelListener,
+        Preference.OnPreferenceChangeListener{
+
+    private static final String LOG_TAG = "networkSelect";
+    private static final boolean DBG = true;
+
+    private static final int EVENT_NETWORK_SCAN_COMPLETED = 100;
+    private static final int EVENT_NETWORK_SELECTION_DONE = 200;
+
+    //dialog ids
+    private static final int DIALOG_NETWORK_SELECTION = 100;
+    private static final int DIALOG_NETWORK_LIST_LOAD = 200;
+
+    private int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
+    private List<OperatorInfo> mOperatorInfoList;
+    private  OperatorInfo mOperatorInfo;
+
+    private int mSubId;
+    private NetworkOperators mNetworkOperators;
+
+    private ProgressDialog mProgressDialog;
+    public NetworkSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NetworkSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onClick() {
+        loadNetworksList();
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_NETWORK_SCAN_COMPLETED:
+                    networksListLoaded((List<OperatorInfo>) msg.obj, msg.arg1);
+                    break;
+
+                case EVENT_NETWORK_SELECTION_DONE:
+                    if (DBG) logd("hideProgressPanel");
+                    try {
+                        dismissProgressBar();
+                    } catch (IllegalArgumentException e) {
+                    }
+                    setEnabled(true);
+
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) logd("manual network selection: failed!");
+                        mNetworkOperators.displayNetworkSelectionFailed(ar.exception);
+                    } else {
+                        if (DBG) {
+                            logd("manual network selection: succeeded!"
+                                    + getNetworkTitle(mOperatorInfo));
+                        }
+                        mNetworkOperators.displayNetworkSelectionSucceeded();
+                    }
+                    mNetworkOperators.getNetworkSelectionMode();
+                    break;
+            }
+
+            return;
+        }
+    };
+
+    INetworkQueryService mNetworkQueryService = null;
+    /**
+     * This implementation of INetworkQueryServiceCallback is used to receive
+     * callback notifications from the network query service.
+     */
+    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
+
+        /** place the message on the looper queue upon query completion. */
+        public void onQueryComplete(List<OperatorInfo> networkInfoArray, int status) {
+            if (DBG) logd("notifying message loop of query completion.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED,
+                    status, 0, networkInfoArray);
+            msg.sendToTarget();
+        }
+    };
+
+    @Override
+    //implemented for DialogInterface.OnCancelListener
+    public void onCancel(DialogInterface dialog) {
+        // request that the service stop the query with this callback object.
+        try {
+            if (mNetworkQueryService != null) {
+                mNetworkQueryService.stopNetworkQuery(mCallback);
+            }
+            // If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
+            mNetworkOperators.getNetworkSelectionMode();
+        } catch (RemoteException e) {
+            loge("onCancel: exception from stopNetworkQuery " + e);
+        }
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        // If dismissed, we query NetworkSelectMode and update states of AutoSelect button.
+        if (!positiveResult) {
+            mNetworkOperators.getNetworkSelectionMode();
+        }
+    }
+
+    /**
+     * Return normalized carrier name given network info.
+     *
+     * @param ni is network information in OperatorInfo type.
+     */
+    public String getNormalizedCarrierName(OperatorInfo ni) {
+        if (ni != null) {
+            return ni.getOperatorAlphaLong() + " (" + ni.getOperatorNumeric() + ")";
+        }
+        return null;
+    }
+
+    // This method is provided besides initialize() because bind to network query service
+    // may be binded after initialize(). In that case this method needs to be called explicitly
+    // to set mNetworkQueryService. Otherwise mNetworkQueryService will remain null.
+    public void setNetworkQueryService(INetworkQueryService queryService) {
+        mNetworkQueryService = queryService;
+    }
+
+    // This initialize method needs to be called for this preference to work properly.
+    protected void initialize(int subId, INetworkQueryService queryService,
+            NetworkOperators networkOperators) {
+        mSubId = subId;
+        mNetworkQueryService = queryService;
+        mNetworkOperators = networkOperators;
+
+        if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            mPhoneId = SubscriptionManager.getPhoneId(mSubId);
+        }
+
+        TelephonyManager telephonyManager = (TelephonyManager)
+                getContext().getSystemService(Context.TELEPHONY_SERVICE);
+
+        setSummary(telephonyManager.getNetworkOperatorName());
+
+        setOnPreferenceChangeListener(this);
+    }
+
+    @Override
+    protected void onPrepareForRemoval() {
+        destroy();
+        super.onPrepareForRemoval();
+    }
+
+    private void destroy() {
+        try {
+            dismissProgressBar();
+        } catch (IllegalArgumentException e) {
+            loge("onDestroy: exception from dismissProgressBar " + e);
+        }
+
+        try {
+            if (mNetworkQueryService != null) {
+                // used to un-register callback
+                mNetworkQueryService.unregisterCallback(mCallback);
+            }
+        } catch (RemoteException e) {
+            loge("onDestroy: exception from unregisterCallback " + e);
+        }
+    }
+
+    private void displayEmptyNetworkList() {
+        String status = getContext().getResources().getString(R.string.empty_networks_list);
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void displayNetworkSeletionInProgress() {
+        showProgressBar(DIALOG_NETWORK_SELECTION);
+    }
+
+    private void displayNetworkQueryFailed(int error) {
+        String status = getContext().getResources().getString(R.string.network_query_error);
+
+        try {
+            dismissProgressBar();
+        } catch (IllegalArgumentException e1) {
+            // do nothing
+        }
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void loadNetworksList() {
+        if (DBG) logd("load networks list...");
+
+        showProgressBar(DIALOG_NETWORK_LIST_LOAD);
+
+        // delegate query request to the service.
+        try {
+            if (mNetworkQueryService != null) {
+                mNetworkQueryService.startNetworkQuery(mCallback, mPhoneId);
+            } else {
+                displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
+            }
+        } catch (RemoteException e) {
+            loge("loadNetworksList: exception from startNetworkQuery " + e);
+            displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
+        }
+    }
+
+    /**
+     * networksListLoaded has been rewritten to take an array of
+     * OperatorInfo objects and a status field, instead of an
+     * AsyncResult.  Otherwise, the functionality which takes the
+     * OperatorInfo array and creates a list of preferences from it,
+     * remains unchanged.
+     */
+    private void networksListLoaded(List<OperatorInfo> result, int status) {
+        if (DBG) logd("networks list loaded");
+
+        // used to un-register callback
+        try {
+            if (mNetworkQueryService != null) {
+                mNetworkQueryService.unregisterCallback(mCallback);
+            }
+        } catch (RemoteException e) {
+            loge("networksListLoaded: exception from unregisterCallback " + e);
+        }
+
+        // update the state of the preferences.
+        if (DBG) logd("hideProgressPanel");
+
+        // Always try to dismiss the dialog because activity may
+        // be moved to background after dialog is shown.
+        try {
+            dismissProgressBar();
+        } catch (IllegalArgumentException e) {
+            // It's not a error in following scenario, we just ignore it.
+            // "Load list" dialog will not show, if NetworkQueryService is
+            // connected after this activity is moved to background.
+            loge("Fail to dismiss network load list dialog " + e);
+        }
+
+        setEnabled(true);
+        clearList();
+
+        if (status != NetworkQueryService.QUERY_OK) {
+            if (DBG) logd("error while querying available networks");
+            displayNetworkQueryFailed(status);
+        } else {
+            if (result != null) {
+                // create a preference for each item in the list.
+                // just use the operator name instead of the mildly
+                // confusing mcc/mnc.
+                mOperatorInfoList = result;
+                CharSequence[] networkEntries = new CharSequence[result.size()];
+                CharSequence[] networkEntryValues = new CharSequence[result.size()];
+                for (int i = 0; i < mOperatorInfoList.size(); i++) {
+                    networkEntries[i] = getNetworkTitle(mOperatorInfoList.get(i));
+                    networkEntryValues[i] = Integer.toString(i + 2);
+                }
+
+                setEntries(networkEntries);
+                setEntryValues(networkEntryValues);
+
+                super.onClick();
+            } else {
+                displayEmptyNetworkList();
+            }
+        }
+    }
+
+    /**
+     * Returns the title of the network obtained in the manual search.
+     *
+     * @param ni contains the information of the network.
+     *
+     * @return Long Name if not null/empty, otherwise Short Name if not null/empty,
+     * else MCCMNC string.
+     */
+    private String getNetworkTitle(OperatorInfo ni) {
+        if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
+            return ni.getOperatorAlphaLong();
+        } else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
+            return ni.getOperatorAlphaShort();
+        } else {
+            BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+            return bidiFormatter.unicodeWrap(ni.getOperatorNumeric(), TextDirectionHeuristics.LTR);
+        }
+    }
+
+    private void clearList() {
+        if (mOperatorInfoList != null) {
+            mOperatorInfoList.clear();
+        }
+    }
+
+    private void dismissProgressBar() {
+        if (mProgressDialog != null && mProgressDialog.isShowing()) {
+            mProgressDialog.dismiss();
+        }
+    }
+
+    private void showProgressBar(int id) {
+        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD)) {
+            mProgressDialog = new ProgressDialog(getContext());
+            switch (id) {
+                case DIALOG_NETWORK_SELECTION:
+                    final String networkSelectMsg = getContext().getResources()
+                            .getString(R.string.register_on_network,
+                                    getNetworkTitle(mOperatorInfo));
+                    mProgressDialog.setMessage(networkSelectMsg);
+                    mProgressDialog.setCancelable(false);
+                    mProgressDialog.setIndeterminate(true);
+                    break;
+                case DIALOG_NETWORK_LIST_LOAD:
+                    mProgressDialog.setMessage(
+                            getContext().getResources().getString(R.string.load_networks_progress));
+                    mProgressDialog.setCanceledOnTouchOutside(false);
+                    mProgressDialog.setOnCancelListener(this);
+                    break;
+                default:
+            }
+            mProgressDialog.show();
+        }
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference
+     * changes specifically on this button.
+     *
+     * @param preference is the preference to be changed, should be network select button.
+     * @param newValue should be the value of the selection as index of operators.
+     */
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        int operatorIndex = findIndexOfValue((String) newValue);
+        mOperatorInfo = mOperatorInfoList.get(operatorIndex);
+
+        if (DBG) logd("selected network: " + getNetworkTitle(mOperatorInfo));
+
+        Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
+        Phone phone = PhoneFactory.getPhone(mPhoneId);
+        if (phone != null) {
+            phone.selectNetworkManually(mOperatorInfo, true, msg);
+            displayNetworkSeletionInProgress();
+        } else {
+            loge("Error selecting network. phone is null.");
+        }
+
+        return true;
+    }
+
+    private void logd(String msg) {
+        Log.d(LOG_TAG, "[NetworksList] " + msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(LOG_TAG, "[NetworksList] " + msg);
+    }
+}
diff --git a/src/com/android/phone/NetworkSetting.java b/src/com/android/phone/NetworkSetting.java
deleted file mode 100644
index 72ad513..0000000
--- a/src/com/android/phone/NetworkSetting.java
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserManager;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
-import android.preference.PreferenceScreen;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.telephony.SubscriptionManager;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.OperatorInfo;
-
-import java.util.HashMap;
-import java.util.List;
-import android.text.BidiFormatter;
-import android.text.TextDirectionHeuristics;
-
-/**
- * "Networks" settings UI for the Phone app.
- */
-public class NetworkSetting extends PreferenceActivity
-        implements DialogInterface.OnCancelListener {
-
-    private static final String LOG_TAG = "phone";
-    private static final boolean DBG = true;
-
-    private static final int EVENT_NETWORK_SCAN_COMPLETED = 100;
-    private static final int EVENT_NETWORK_SELECTION_DONE = 200;
-    private static final int EVENT_AUTO_SELECT_DONE = 300;
-
-    //dialog ids
-    private static final int DIALOG_NETWORK_SELECTION = 100;
-    private static final int DIALOG_NETWORK_LIST_LOAD = 200;
-    private static final int DIALOG_NETWORK_AUTO_SELECT = 300;
-
-    //String keys for preference lookup
-    private static final String LIST_NETWORKS_KEY = "list_networks_key";
-    private static final String BUTTON_SRCH_NETWRKS_KEY = "button_srch_netwrks_key";
-    private static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
-
-    //map of network controls to the network data.
-    private HashMap<Preference, OperatorInfo> mNetworkMap;
-
-    int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
-    protected boolean mIsForeground = false;
-
-    private UserManager mUm;
-    private boolean mUnavailable;
-
-    /** message for network selection */
-    String mNetworkSelectMsg;
-
-    //preference objects
-    private PreferenceGroup mNetworkList;
-    private Preference mSearchButton;
-    private Preference mAutoSelect;
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult ar;
-            switch (msg.what) {
-                case EVENT_NETWORK_SCAN_COMPLETED:
-                    networksListLoaded ((List<OperatorInfo>) msg.obj, msg.arg1);
-                    break;
-
-                case EVENT_NETWORK_SELECTION_DONE:
-                    if (DBG) log("hideProgressPanel");
-                    removeDialog(DIALOG_NETWORK_SELECTION);
-                    getPreferenceScreen().setEnabled(true);
-
-                    ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        if (DBG) log("manual network selection: failed!");
-                        displayNetworkSelectionFailed(ar.exception);
-                    } else {
-                        if (DBG) log("manual network selection: succeeded!");
-                        displayNetworkSelectionSucceeded();
-                    }
-
-                    break;
-                case EVENT_AUTO_SELECT_DONE:
-                    if (DBG) log("hideProgressPanel");
-
-                    // Always try to dismiss the dialog because activity may
-                    // be moved to background after dialog is shown.
-                    try {
-                        dismissDialog(DIALOG_NETWORK_AUTO_SELECT);
-                    } catch (IllegalArgumentException e) {
-                        // "auto select" is always trigged in foreground, so "auto select" dialog
-                        //  should be shown when "auto select" is trigged. Should NOT get
-                        // this exception, and Log it.
-                        Log.w(LOG_TAG, "[NetworksList] Fail to dismiss auto select dialog ", e);
-                    }
-                    getPreferenceScreen().setEnabled(true);
-
-                    ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        if (DBG) log("automatic network selection: failed!");
-                        displayNetworkSelectionFailed(ar.exception);
-                    } else {
-                        if (DBG) log("automatic network selection: succeeded!");
-                        displayNetworkSelectionSucceeded();
-                    }
-
-                    break;
-            }
-
-            return;
-        }
-    };
-
-    /**
-     * Service connection code for the NetworkQueryService.
-     * Handles the work of binding to a local object so that we can make
-     * the appropriate service calls.
-     */
-
-    /** Local service interface */
-    private INetworkQueryService mNetworkQueryService = null;
-
-    /** Service connection */
-    private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
-
-        /** Handle the task of binding the local object to the service */
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            if (DBG) log("connection created, binding local service.");
-            mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
-        }
-
-        /** Handle the task of cleaning up the local binding */
-        public void onServiceDisconnected(ComponentName className) {
-            if (DBG) log("connection disconnected, cleaning local binding.");
-            mNetworkQueryService = null;
-        }
-    };
-
-    /**
-     * This implementation of INetworkQueryServiceCallback is used to receive
-     * callback notifications from the network query service.
-     */
-    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
-
-        /** place the message on the looper queue upon query completion. */
-        public void onQueryComplete(List<OperatorInfo> networkInfoArray, int status) {
-            if (DBG) log("notifying message loop of query completion.");
-            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED,
-                    status, 0, networkInfoArray);
-            msg.sendToTarget();
-        }
-    };
-
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        boolean handled = false;
-
-        if (preference == mSearchButton) {
-            loadNetworksList();
-            handled = true;
-        } else if (preference == mAutoSelect) {
-            selectNetworkAutomatic();
-            handled = true;
-        } else {
-            Preference selectedCarrier = preference;
-
-            String networkStr = selectedCarrier.getTitle().toString();
-            if (DBG) log("selected network: " + networkStr);
-
-            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
-            Phone phone = PhoneFactory.getPhone(mPhoneId);
-            if (phone != null) {
-                phone.selectNetworkManually(mNetworkMap.get(selectedCarrier), true, msg);
-                displayNetworkSeletionInProgress(networkStr);
-                handled = true;
-            } else {
-                log("Error selecting network. phone is null.");
-            }
-
-
-        }
-
-        return handled;
-    }
-
-    //implemented for DialogInterface.OnCancelListener
-    public void onCancel(DialogInterface dialog) {
-        // request that the service stop the query with this callback object.
-        try {
-            mNetworkQueryService.stopNetworkQuery(mCallback);
-        } catch (RemoteException e) {
-            log("onCancel: exception from stopNetworkQuery " + e);
-        }
-        finish();
-    }
-
-    public String getNormalizedCarrierName(OperatorInfo ni) {
-        if (ni != null) {
-            return ni.getOperatorAlphaLong() + " (" + ni.getOperatorNumeric() + ")";
-        }
-        return null;
-    }
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mUm = (UserManager) getSystemService(Context.USER_SERVICE);
-
-        if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
-            setContentView(R.layout.telephony_disallowed_preference_screen);
-            mUnavailable = true;
-            return;
-        }
-
-        addPreferencesFromResource(R.xml.carrier_select);
-
-        int subId;
-        Intent intent = getIntent();
-        if (intent != null && intent.getExtras() != null) {
-            subId = intent.getExtras().getInt(GsmUmtsOptions.EXTRA_SUB_ID);
-            if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                mPhoneId = SubscriptionManager.getPhoneId(subId);
-            }
-        }
-
-        mNetworkList = (PreferenceGroup) getPreferenceScreen().findPreference(LIST_NETWORKS_KEY);
-        mNetworkMap = new HashMap<Preference, OperatorInfo>();
-
-        mSearchButton = getPreferenceScreen().findPreference(BUTTON_SRCH_NETWRKS_KEY);
-        mAutoSelect = getPreferenceScreen().findPreference(BUTTON_AUTO_SELECT_KEY);
-
-        // Start the Network Query service, and bind it.
-        // The OS knows to start he service only once and keep the instance around (so
-        // long as startService is called) until a stopservice request is made.  Since
-        // we want this service to just stay in the background until it is killed, we
-        // don't bother stopping it from our end.
-        startService (new Intent(this, NetworkQueryService.class));
-        bindService (new Intent(this, NetworkQueryService.class).setAction(
-                NetworkQueryService.ACTION_LOCAL_BINDER),
-                mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mIsForeground = true;
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mIsForeground = false;
-    }
-
-    /**
-     * Override onDestroy() to unbind the query service, avoiding service
-     * leak exceptions.
-     */
-    @Override
-    protected void onDestroy() {
-        try {
-            // used to un-register callback
-            mNetworkQueryService.unregisterCallback(mCallback);
-        } catch (RemoteException e) {
-            log("onDestroy: exception from unregisterCallback " + e);
-        }
-
-        if (!mUnavailable) {
-            // unbind the service.
-            unbindService(mNetworkQueryServiceConnection);
-        }
-        super.onDestroy();
-    }
-
-    @Override
-    protected Dialog onCreateDialog(int id) {
-
-        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD) ||
-                (id == DIALOG_NETWORK_AUTO_SELECT)) {
-            ProgressDialog dialog = new ProgressDialog(this);
-            switch (id) {
-                case DIALOG_NETWORK_SELECTION:
-                    // It would be more efficient to reuse this dialog by moving
-                    // this setMessage() into onPreparedDialog() and NOT use
-                    // removeDialog().  However, this is not possible since the
-                    // message is rendered only 2 times in the ProgressDialog -
-                    // after show() and before onCreate.
-                    dialog.setMessage(mNetworkSelectMsg);
-                    dialog.setCancelable(false);
-                    dialog.setIndeterminate(true);
-                    break;
-                case DIALOG_NETWORK_AUTO_SELECT:
-                    dialog.setMessage(getResources().getString(R.string.register_automatically));
-                    dialog.setCancelable(false);
-                    dialog.setIndeterminate(true);
-                    break;
-                case DIALOG_NETWORK_LIST_LOAD:
-                default:
-                    // reinstate the cancelablity of the dialog.
-                    dialog.setMessage(getResources().getString(R.string.load_networks_progress));
-                    dialog.setCanceledOnTouchOutside(false);
-                    dialog.setOnCancelListener(this);
-                    break;
-            }
-            return dialog;
-        }
-        return null;
-    }
-
-    @Override
-    protected void onPrepareDialog(int id, Dialog dialog) {
-        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD) ||
-                (id == DIALOG_NETWORK_AUTO_SELECT)) {
-            // when the dialogs come up, we'll need to indicate that
-            // we're in a busy state to dissallow further input.
-            getPreferenceScreen().setEnabled(false);
-        }
-    }
-
-    private void displayEmptyNetworkList(boolean flag) {
-        mNetworkList.setTitle(flag ? R.string.empty_networks_list : R.string.label_available);
-    }
-
-    private void displayNetworkSeletionInProgress(String networkStr) {
-        // TODO: use notification manager?
-        mNetworkSelectMsg = getResources().getString(R.string.register_on_network, networkStr);
-
-        if (mIsForeground) {
-            showDialog(DIALOG_NETWORK_SELECTION);
-        }
-    }
-
-    private void displayNetworkQueryFailed(int error) {
-        String status = getResources().getString(R.string.network_query_error);
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
-    }
-
-    private void displayNetworkSelectionFailed(Throwable ex) {
-        String status;
-
-        if ((ex != null && ex instanceof CommandException) &&
-                ((CommandException)ex).getCommandError()
-                  == CommandException.Error.ILLEGAL_SIM_OR_ME)
-        {
-            status = getResources().getString(R.string.not_allowed);
-        } else {
-            status = getResources().getString(R.string.connect_later);
-        }
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
-
-        TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
-        Phone phone = PhoneFactory.getPhone(mPhoneId);
-        if (phone != null) {
-            ServiceState ss = tm.getServiceStateForSubscriber(phone.getSubId());
-            if (ss != null) {
-                app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId());
-            }
-        }
-    }
-
-    private void displayNetworkSelectionSucceeded() {
-        String status = getResources().getString(R.string.registration_done);
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
-
-        mHandler.postDelayed(new Runnable() {
-            public void run() {
-                finish();
-            }
-        }, 3000);
-    }
-
-    private void loadNetworksList() {
-        if (DBG) log("load networks list...");
-
-        if (mIsForeground) {
-            showDialog(DIALOG_NETWORK_LIST_LOAD);
-        }
-
-        // delegate query request to the service.
-        try {
-            mNetworkQueryService.startNetworkQuery(mCallback, mPhoneId);
-        } catch (RemoteException e) {
-            log("loadNetworksList: exception from startNetworkQuery " + e);
-            if (mIsForeground) {
-                try {
-                    dismissDialog(DIALOG_NETWORK_LIST_LOAD);
-                } catch (IllegalArgumentException e1) {
-                    // do nothing
-                }
-            }
-        }
-
-        displayEmptyNetworkList(false);
-    }
-
-    /**
-     * networksListLoaded has been rewritten to take an array of
-     * OperatorInfo objects and a status field, instead of an
-     * AsyncResult.  Otherwise, the functionality which takes the
-     * OperatorInfo array and creates a list of preferences from it,
-     * remains unchanged.
-     */
-    private void networksListLoaded(List<OperatorInfo> result, int status) {
-        if (DBG) log("networks list loaded");
-
-        // used to un-register callback
-        try {
-            mNetworkQueryService.unregisterCallback(mCallback);
-        } catch (RemoteException e) {
-            log("networksListLoaded: exception from unregisterCallback " + e);
-        }
-
-        // update the state of the preferences.
-        if (DBG) log("hideProgressPanel");
-
-        // Always try to dismiss the dialog because activity may
-        // be moved to background after dialog is shown.
-        try {
-            dismissDialog(DIALOG_NETWORK_LIST_LOAD);
-        } catch (IllegalArgumentException e) {
-            // It's not a error in following scenario, we just ignore it.
-            // "Load list" dialog will not show, if NetworkQueryService is
-            // connected after this activity is moved to background.
-            if (DBG) log("Fail to dismiss network load list dialog " + e);
-        }
-
-        getPreferenceScreen().setEnabled(true);
-        clearList();
-
-        if (status != NetworkQueryService.QUERY_OK) {
-            if (DBG) log("error while querying available networks");
-            displayNetworkQueryFailed(status);
-            displayEmptyNetworkList(true);
-        } else {
-            if (result != null){
-                displayEmptyNetworkList(false);
-
-                // create a preference for each item in the list.
-                // just use the operator name instead of the mildly
-                // confusing mcc/mnc.
-                for (OperatorInfo ni : result) {
-                    Preference carrier = new Preference(this, null);
-                    carrier.setTitle(getNetworkTitle(ni));
-                    carrier.setPersistent(false);
-                    mNetworkList.addPreference(carrier);
-                    mNetworkMap.put(carrier, ni);
-
-                    if (DBG) log("  " + ni);
-                }
-            } else {
-                displayEmptyNetworkList(true);
-            }
-        }
-    }
-
-    /**
-     * Returns the title of the network obtained in the manual search.
-     *
-     * @param OperatorInfo contains the information of the network.
-     *
-     * @return Long Name if not null/empty, otherwise Short Name if not null/empty,
-     * else MCCMNC string.
-     */
-
-    private String getNetworkTitle(OperatorInfo ni) {
-        if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
-            return ni.getOperatorAlphaLong();
-        } else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
-            return ni.getOperatorAlphaShort();
-        } else {
-            BidiFormatter bidiFormatter = BidiFormatter.getInstance();
-            return bidiFormatter.unicodeWrap(ni.getOperatorNumeric(), TextDirectionHeuristics.LTR);
-        }
-    }
-
-    private void clearList() {
-        for (Preference p : mNetworkMap.keySet()) {
-            mNetworkList.removePreference(p);
-        }
-        mNetworkMap.clear();
-    }
-
-    private void selectNetworkAutomatic() {
-        if (DBG) log("select network automatically...");
-        if (mIsForeground) {
-            showDialog(DIALOG_NETWORK_AUTO_SELECT);
-        }
-
-        Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
-        Phone phone = PhoneFactory.getPhone(mPhoneId);
-        if (phone != null) {
-            phone.setNetworkSelectionModeAutomatic(msg);
-        }
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, "[NetworksList] " + msg);
-    }
-}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 1764d4c..da97582 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -16,6 +16,8 @@
 
 package com.android.phone;
 
+import static android.Manifest.permission.READ_PHONE_STATE;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -60,8 +62,6 @@
 import java.util.List;
 import java.util.Set;
 
-import static android.Manifest.permission.READ_PHONE_STATE;
-
 /**
  * NotificationManager-related utility code for the Phone app.
  *
@@ -597,10 +597,10 @@
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-        // Use NetworkSetting to handle the selection intent
+        // Use MobileNetworkSettings to handle the selection intent
         intent.setComponent(new ComponentName(
-                mContext.getString(R.string.network_operator_settings_package),
-                mContext.getString(R.string.network_operator_settings_class)));
+                mContext.getString(R.string.mobile_network_settings_package),
+                mContext.getString(R.string.mobile_network_settings_class)));
         intent.putExtra(GsmUmtsOptions.EXTRA_SUB_ID, subId);
         PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
 
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 7493858..d3dd93c 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -156,8 +156,6 @@
     private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
     private static final int CMD_SEND_ENVELOPE = 25;
     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
-    private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
-    private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
     private static final int CMD_EXCHANGE_SIM_IO = 31;
@@ -723,21 +721,6 @@
                     handleNullReturnEvent(msg, "setPreferredNetworkType");
                     break;
 
-                case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
-                    request = (MainThreadRequest)msg.obj;
-                    onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
-                    mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted);
-                    break;
-
-                case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    request = (MainThreadRequest)ar.userObj;
-                    request.result = ar;
-                    synchronized (request) {
-                        request.notifyAll();
-                    }
-                    break;
-
                 case CMD_SET_VOICEMAIL_NUMBER:
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
@@ -3152,39 +3135,6 @@
     }
 
     @Override
-    @Deprecated
-    public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
-        enforceModifyPermission();
-
-        int returnValue = 0;
-        try {
-            AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
-            if(result.exception == null) {
-                if (result.result != null) {
-                    byte[] responseData = (byte[])(result.result);
-                    if(responseData.length > oemResp.length) {
-                        Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
-                                responseData.length +  "bytes. Buffer Size is " +
-                                oemResp.length + "bytes.");
-                    }
-                    System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
-                    returnValue = responseData.length;
-                }
-            } else {
-                CommandException ex = (CommandException) result.exception;
-                returnValue = ex.getCommandError().ordinal();
-                if(returnValue > 0) returnValue *= -1;
-            }
-        } catch (RuntimeException e) {
-            Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
-            returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
-            if(returnValue > 0) returnValue *= -1;
-        }
-
-        return returnValue;
-    }
-
-    @Override
     public void setRadioCapability(RadioAccessFamily[] rafs) {
         try {
             ProxyController.getInstance().setRadioCapability(rafs);
diff --git a/src/com/android/phone/PhoneSearchIndexablesProvider.java b/src/com/android/phone/PhoneSearchIndexablesProvider.java
index 1cee227..ed3c7df 100644
--- a/src/com/android/phone/PhoneSearchIndexablesProvider.java
+++ b/src/com/android/phone/PhoneSearchIndexablesProvider.java
@@ -102,7 +102,7 @@
         if (!mUserManager.isAdminUser()) {
             final String[] values = new String[]{"preferred_network_mode_key", "button_roaming_key",
                     "cdma_lte_data_service_key", "enabled_networks_key", "enhanced_4g_lte",
-                    "button_apn_key", "button_carrier_sel_key", "carrier_settings_key",
+                    "button_apn_key", "button_network_select_key", "carrier_settings_key",
                     "cdma_system_select_key", "esim_list_profile"};
             for (String nik : values) {
                 cursor.addRow(createNonIndexableRow(nik));
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index 04e8bf5..4d55421 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PersistableBundle;
 import android.os.UserManager;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
@@ -31,6 +32,7 @@
 import android.preference.SwitchPreference;
 import android.provider.ContactsContract.CommonDataKinds;
 import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyManager;
 import android.text.BidiFormatter;
 import android.text.TextDirectionHeuristics;
@@ -250,6 +252,10 @@
             mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
             mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
             mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
+            if (!getBooleanCarrierConfig(
+                    CarrierConfigManager.KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL)) {
+                mSubMenuVoicemailSettings.setEnabled(false);
+            }
         }
 
         mVoicemailProviders = (VoicemailProviderListPreference) findPreference(
@@ -545,6 +551,23 @@
         }
     }
 
+    /**
+     * Get the boolean config from carrier config manager.
+     *
+     * @param key config key defined in CarrierConfigManager
+     * @return boolean value of corresponding key.
+     */
+    private boolean getBooleanCarrierConfig(String key) {
+        PersistableBundle b = PhoneGlobals.getInstance()
+                .getCarrierConfigForSubId(mPhone.getSubId());
+        if (b != null) {
+            return b.getBoolean(key);
+        } else {
+            // Return static default defined in CarrierConfigManager.
+            return CarrierConfigManager.getDefaultConfig().getBoolean(key);
+        }
+    }
+
 
     //*********************************************************************************************
     // Activity Dialog Methods