Merge "Network Operator" into "Mobile network" main activity.

Re-write "Network Operator" setting section. Now auto and manual
network select buttons are SwitchPreference and ListPreference
respectively. They are moret tightly coupled and merged into
"Mobile network" main fragment.
Network select button is now a customized ListPreference, which
start network query when clicked, and show query result as list
of networks to choose from.

Test: manual
Bug: 62200802
Change-Id: I8dd796462e14eb6272371bfcc580ad94d199bb67
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4045ff2..87798ac 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -337,6 +337,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>
@@ -349,17 +350,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/values/config.xml b/res/values/config.xml
index 4f36e0b..e42b63a 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 d091a67..f6d0bd0 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/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];