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 0e8b158..f9465f4 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -23,16 +23,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;
@@ -142,7 +145,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 =
@@ -172,6 +174,7 @@
         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;
@@ -212,6 +215,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);
@@ -476,6 +526,8 @@
             mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
             mSubscriptionManager = SubscriptionManager.from(getActivity());
 
+            bindNetworkQueryService();
+
             if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
                 mUnavailable = true;
                 getActivity().setContentView(R.layout.telephony_disallowed_preference_screen);
@@ -542,6 +594,7 @@
 
         @Override
         public void onDestroy() {
+            unbindNetworkQueryService();
             super.onDestroy();
             getActivity().unregisterReceiver(mPhoneChangeReceiver);
         }
@@ -675,7 +728,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);
                 }
@@ -691,7 +745,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();
@@ -777,7 +832,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);
                 }
@@ -887,7 +943,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);
             }
@@ -1568,22 +1624,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..c01db91
--- /dev/null
+++ b/src/com/android/phone/NetworkOperators.java
@@ -0,0 +1,240 @@
+/*
+ * 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.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..a0d81fc
--- /dev/null
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -0,0 +1,415 @@
+/*
+ * 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.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 31bca92..bf611a6 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -603,10 +603,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/PhoneSearchIndexablesProvider.java b/src/com/android/phone/PhoneSearchIndexablesProvider.java
index 171f74f..fe9d214 100644
--- a/src/com/android/phone/PhoneSearchIndexablesProvider.java
+++ b/src/com/android/phone/PhoneSearchIndexablesProvider.java
@@ -16,6 +16,18 @@
 
 package com.android.phone;
 
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID;
+import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS;
+import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS;
+import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS;
+
 import android.content.Context;
 import android.database.Cursor;
 import android.database.MatrixCursor;
@@ -23,19 +35,6 @@
 import android.provider.SearchIndexableResource;
 import android.provider.SearchIndexablesProvider;
 
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK;
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID;
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME;
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID;
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION;
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE;
-import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS;
-
-import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS;
-import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS;
-import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS;
-
 public class PhoneSearchIndexablesProvider extends SearchIndexablesProvider {
     private static final String TAG = "PhoneSearchIndexablesProvider";
 
@@ -82,7 +81,7 @@
         if (!userManager.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", "carrier_settings_euicc_key"};
             for (String nik : values) {
                 final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length];
