diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index e57cbfa..6cc10fe 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1133,4 +1133,186 @@
         <item>4</item> <!-- AutofillManager.FLAG_ADD_CLIENT_VERBOSE -->
     </string-array>
 
+    <string-array name="enabled_networks_choices" translatable="false">
+        <item>@string/network_lte</item>
+        <item>@string/network_3G</item>
+        <item>@string/network_2G</item>
+    </string-array>
+    <string-array name="enabled_networks_4g_choices" translatable="false">
+        <item>@string/network_4G</item>
+        <item>@string/network_3G</item>
+        <item>@string/network_2G</item>
+    </string-array>
+    <string-array name="enabled_networks_values" translatable="false">
+        <item>"9"</item>
+        <item>"0"</item>
+        <item>"1"</item>
+    </string-array>
+
+    <string-array name="cdma_system_select_choices">
+        <!-- System select dialog screen, setting option name -->
+        <item>Home only</item>
+        <!-- Remove the following option "Affiliated Networks" from the option list -->
+        <!-- <item>Affiliated Networks</item> -->
+        <!-- System select dialog screen, setting option name -->
+        <item>Automatic</item>
+    </string-array>
+    <string-array name="cdma_system_select_values" translatable="false">
+        <!-- Do not translate. -->
+        <item>"0"</item>
+        <!-- Remove the following value "1" which corresponds to "Affiliated Networks" above -->
+        <!-- <item>"1"</item>  -->
+        <!-- Do not translate. -->
+        <item>"2"</item>
+    </string-array>
+
+    <!-- The preferred network modes in Mobile network settings -->
+    <string-array name="preferred_network_mode_choices">
+        <item>GSM/WCDMA preferred</item>
+        <item>GSM only</item>
+        <item>WCDMA only</item>
+        <item>GSM/WCDMA auto</item>
+        <item>CDMA/EvDo auto</item>
+        <item>CDMA w/o EvDo</item>
+        <item>EvDo only</item>
+        <item>CDMA/EvDo/GSM/WCDMA</item>
+        <item>CDMA + LTE/EvDo</item>
+        <item>GSM/WCDMA/LTE</item>
+        <item>Global</item>
+        <item>LTE</item>
+        <item>LTE / WCDMA</item>
+        <item>TDSCDMA only</item>
+        <item>TDSCDMA/WCDMA</item>
+        <item>LTE/TDSCDMA</item>
+        <item>TDSCDMA/GSM</item>
+        <item>LTE/TDSCDMA/GSM</item>
+        <item>TDSCDMA/GSM/WCDMA</item>
+        <item>LTE/TDSCDMA/WCDMA</item>
+        <item>LTE/TDSCDMA/GSM/WCDMA</item>
+        <item>TDSCDMA/CDMA/EVDO/GSM/WCDMA </item>
+        <item>LTE/TDSCDMA/CDMA/EVDO/GSM/WCDMA</item>
+    </string-array>
+    <!-- The preferred network modes RIL constants, in order of the modes above,
+         e.g. the choice "GSM/WCDMA preferred" has the corresponding value "0" -->
+    <string-array name="preferred_network_mode_values"  translatable="false">
+        <item>"0"</item>
+        <item>"1"</item>
+        <item>"2"</item>
+        <item>"3"</item>
+        <item>"4"</item>
+        <item>"5"</item>
+        <item>"6"</item>
+        <item>"7"</item>
+        <item>"8"</item>
+        <item>"9"</item>
+        <item>"10"</item>
+        <item>"11"</item>
+        <item>"12"</item>
+        <item>"13"</item>
+        <item>"14"</item>
+        <item>"15"</item>
+        <item>"16"</item>
+        <item>"17"</item>
+        <item>"18"</item>
+        <item>"19"</item>
+        <item>"20"</item>
+        <item>"21"</item>
+        <item>"22"</item>
+    </string-array>
+
+    <!-- Choices for CDMA subscription-->
+    <string-array name="cdma_subscription_choices">
+        <item>RUIM/SIM</item>
+        <item>NV</item>
+    </string-array>
+    <!-- Values for CDMA subscription-->
+    <string-array name="cdma_subscription_values">
+        <item>"0"</item>
+        <item>"1"</item>
+    </string-array>
+
+    <string-array name="enabled_networks_except_gsm_choices" translatable="false">
+        <item>@string/network_lte</item>
+        <item>@string/network_3G</item>
+    </string-array>
+    <string-array name="enabled_networks_except_gsm_4g_choices" translatable="false">
+        <item>@string/network_4G</item>
+        <item>@string/network_3G</item>
+    </string-array>
+    <string-array name="enabled_networks_except_gsm_values" translatable="false">
+        <item>"9"</item>
+        <item>"0"</item>
+    </string-array>
+
+    <string-array name="enabled_networks_except_lte_choices" translatable="false">
+        <item>@string/network_3G</item>
+        <item>@string/network_2G</item>
+    </string-array>
+    <string-array name="enabled_networks_except_lte_values" translatable="false">
+        <item>"0"</item>
+        <item>"1"</item>
+    </string-array>
+
+    <string-array name="enabled_networks_except_gsm_lte_choices" translatable="false">
+        <item>@string/network_3G</item>
+    </string-array>
+    <string-array name="enabled_networks_except_gsm_lte_values" translatable="false">
+        <item>"0"</item>
+    </string-array>
+
+    <string-array name="enabled_networks_cdma_choices" translatable="false">
+        <item>@string/network_lte</item>
+        <item>@string/network_3G</item>
+        <item>@string/network_1x</item>
+        <item>@string/network_global</item>
+    </string-array>
+    <string-array name="enabled_networks_cdma_values" translatable="false">
+        <item>"8"</item>
+        <item>"4"</item>
+        <item>"5"</item>
+        <item>"10"</item>
+    </string-array>
+
+    <string-array name="enabled_networks_cdma_no_lte_choices" translatable="false">
+        <item>@string/network_3G</item>
+        <item>@string/network_1x</item>
+    </string-array>
+    <string-array name="enabled_networks_cdma_no_lte_values" translatable="false">
+        <item>"4"</item>
+        <item>"5"</item>
+    </string-array>
+
+    <string-array name="enabled_networks_cdma_only_lte_choices" translatable="false">
+        <item>@string/network_lte</item>
+        <item>@string/network_global</item>
+    </string-array>
+    <string-array name="enabled_networks_cdma_only_lte_values" translatable="false">
+        <item>"8"</item>
+        <item>"10"</item>
+    </string-array>
+
+    <string-array name="enabled_networks_tdscdma_choices" translatable="false">
+        <item>@string/network_lte</item>
+        <item>@string/network_3G</item>
+        <item>@string/network_2G</item>
+    </string-array>
+    <string-array name="enabled_networks_tdscdma_values" translatable="false">
+        <item>"22"</item>
+        <item>"18"</item>
+        <item>"1"</item>
+    </string-array>
+
+    <!--String arrays for World preferred netwrok modes -->
+    <string-array name="preferred_network_mode_choices_world_mode">
+        <item>Global</item>
+        <item>LTE / CDMA</item>
+        <item>LTE / GSM / UMTS</item>
+    </string-array>
+
+    <string-array name="preferred_network_mode_values_world_mode">
+        <item>"10"</item>
+        <item>"8"</item>
+        <item>"9"</item>
+    </string-array>
+
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index b9a69f1..0129768 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -136,4 +136,8 @@
 
     <!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
     <bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
+
+    <!-- TODO(b/114749736): migrate override for config value -->
+    <!-- Show enabled lte option for lte device -->
+    <bool name="config_enabled_lte" translatable="false">false</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d78b7b0..0060202 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10112,4 +10112,151 @@
 
     <!-- Message informs the user that has no SIM card in personalized Settings [CHAR LIMIT=30] -->
     <string name="no_sim_card">No SIM card</string>
+
+    <!-- Carrier variant of Enhaced 4G LTE Mode title.  [CHAR LIMIT=50] -->
+    <string name="enhanced_4g_lte_mode_title_variant">Advanced Calling</string>
+    <!-- The following strings are summaries for preferred network modes in Mobile network settings,
+     and have a character limit of 100 -->
+    <!-- WCDMA preferred [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_wcdma_perf_summary">Preferred network mode: WCDMA preferred</string>
+    <!-- GSM only [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_gsm_only_summary">Preferred network mode: GSM only</string>
+    <!-- WCDMA only [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_wcdma_only_summary">Preferred network mode: WCDMA only</string>
+    <!-- GSM / WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_gsm_wcdma_summary">Preferred network mode: GSM / WCDMA</string>
+    <!-- CDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_cdma_summary">Preferred network mode: CDMA</string>
+    <!-- CDMA / EvDo [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_cdma_evdo_summary">Preferred network mode: CDMA / EvDo</string>
+    <!-- CDMA only [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_cdma_only_summary">Preferred network mode: CDMA only</string>
+    <!-- EvDo only [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_evdo_only_summary">Preferred network mode: EvDo only</string>
+    <!-- CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_cdma_evdo_gsm_wcdma_summary">Preferred network mode: CDMA/EvDo/GSM/WCDMA</string>
+    <!-- LTE [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_summary">Preferred network mode: LTE </string>
+    <!-- GSM/WCDMA/LTE [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_gsm_wcdma_summary">Preferred network mode: GSM/WCDMA/LTE</string>
+    <!-- CDMA+LTE/EVDO [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_cdma_evdo_summary">Preferred network mode: CDMA+LTE/EVDO</string>
+    <!-- Global [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_global_summary">Preferred network mode: Global</string>
+    <!-- LTE / WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_wcdma_summary">Preferred network mode: LTE / WCDMA</string>
+    <!-- LTE / GSM / UMTS [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_gsm_umts_summary">Preferred network mode: LTE / GSM / UMTS</string>
+    <!-- LTE / CDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_cdma_summary">Preferred network mode: LTE / CDMA</string>
+    <!-- TDSCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_tdscdma_summary">Preferred network mode: TDSCDMA</string>
+    <!-- TDSCDMA / WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_tdscdma_wcdma_summary">Preferred network mode: TDSCDMA / WCDMA</string>
+    <!-- LTE / TDSCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_tdscdma_summary">Preferred network mode: LTE / TDSCDMA</string>
+    <!-- TDSCDMA / GSM [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_tdscdma_gsm_summary">Preferred network mode: TDSCDMA / GSM</string>
+    <!-- LTE/GSM/TDSCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_tdscdma_gsm_summary">Preferred network mode: LTE/GSM/TDSCDMA</string>
+    <!-- TDSCDMA/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_tdscdma_gsm_wcdma_summary">Preferred network mode: TDSCDMA/GSM/WCDMA</string>
+    <!-- LTE/TDSCDMA/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_tdscdma_wcdma_summary">Preferred network mode: LTE/TDSCDMA/WCDMA</string>
+    <!-- LTE/TDSCDMA/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_tdscdma_gsm_wcdma_summary">Preferred network mode: LTE/TDSCDMA/GSM/WCDMA</string>
+    <!-- TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
+    <!-- LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
+
+    <!-- Text for Network lte [CHAR LIMIT=NONE] -->
+    <string name="network_lte">LTE (recommended)</string>
+    <!-- Text for Network 4g [CHAR LIMIT=NONE] -->
+    <string name="network_4G">4G (recommended)</string>
+    <!-- Text for Network 3g [CHAR LIMIT=NONE] -->
+    <string name="network_3G" translatable="false">3G</string>
+    <!-- Text for Network 2g [CHAR LIMIT=NONE] -->
+    <string name="network_2G" translatable="false">2G</string>
+    <!-- Text for Network 1x [CHAR LIMIT=NONE] -->
+    <string name="network_1x" translatable="false">1x</string>
+    <!-- Text for Network global [CHAR LIMIT=NONE] -->
+    <string name="network_global">Global</string>
+
+    <!-- Configuration setting for world mode Format is <true;GID if any to be checked> [CHAR LIMIT=NONE] -->
+    <string translatable="false" name="config_world_mode"/>
+
+    <!-- Available networks screen, text when no networks connected [CHAR LIMIT=NONE] -->
+    <string name="network_disconnected">Disconnected</string>
+    <!-- Available networks screen, text when network connected [CHAR LIMIT=NONE] -->
+    <string name="network_connected">Connected</string>
+    <!-- Available networks screen, text when a network is connecting [CHAR LIMIT=NONE] -->
+    <string name="network_connecting">Connecting\u2026</string>
+    <!-- Available networks screen, text when a network cannot be connected [CHAR LIMIT=NONE] -->
+    <string name="network_could_not_connect">Couldn’t connect</string>
+
+    <!-- Available networks screen title/heading [CHAR LIMIT=NONE] -->
+    <string name="label_available">Available networks</string>
+    <!-- Mobile network settings screen, toast when searching for available networks [CHAR LIMIT=NONE] -->
+    <string name="load_networks_progress">Searching\u2026</string>
+    <!-- Available networks screen, text when no networks are found [CHAR LIMIT=NONE] -->
+    <string name="empty_networks_list">No networks found.</string>
+    <!-- Available networks screen, toast when an error is encountered when searching for networks [CHAR LIMIT=NONE] -->
+    <string name="network_query_error">Couldn\u2019t find networks. Try again.</string>
+    <!-- Available networks screen, toast when registering on a specific network [CHAR LIMIT=NONE] -->
+    <string name="register_on_network">Registering on <xliff:g id="network" example="Verizon">%s</xliff:g>\u2026</string>
+    <!-- Available networks screen, toast when SIM card isn't allowed on a network [CHAR LIMIT=NONE] -->
+    <string name="not_allowed">Your SIM card doesn\u2019t allow a connection to this network.</string>
+    <!-- Available networks screen, toast when unable to connect to a network temporarily [CHAR LIMIT=NONE] -->
+    <string name="connect_later">Can\u2019t connect to this network right now. Try again later.</string>
+    <!-- Available networks screen, toast when registered on a specific network [CHAR LIMIT=NONE] -->
+    <string name="registration_done">Registered on network.</string>
+
+    <!-- Available networks screen, name of switch button for whether to select network automatically [CHAR LIMIT=NONE] -->
+    <string name="select_automatically">Automatically select network</string>
+
+    <!-- Available networks screen, name of button when user wants to select network manually [CHAR LIMIT=NONE] -->
+    <string name="choose_network_title">Choose network</string>
+    <!-- A menu item in "Mobile network settings" that allows the user to update the phone
+     with mobile operator specific settings. [CHAR LIMIT=25] -->
+    <string name="carrier_settings_title">Carrier settings</string>
+    <!-- Preference title for launching an account manager page for prepaid LTE [CHAR LIMIT=30] -->
+    <string name="cdma_lte_data_service">Set up data service</string>
+    <!-- Mobile network settings screen, title of Mobile Data switch preference [CHAR LIMIT=NONE] -->
+    <string name="mobile_data_settings_title">Mobile data</string>
+    <!-- Mobile network settings screen, title of Mobile data switch preference [CHAR LIMIT=NONE] -->
+    <string name="mobile_data_settings_summary">Access data using mobile network</string>
+
+    <!-- Title for preferred network type [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_title">Preferred network type</string>
+    <!-- Summary for preferred network type [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_summary">Change the network operating mode</string>
+    <!-- Dialog title for preferred network type [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_dialogtitle">Preferred network type</string>
+    <!-- Mobile network settings screen, name of the option to manage carrier profiles on devices which support embedded carrier profiles [CHAR LIMIT=NONE] -->
+    <string name="carrier_settings_euicc">Carrier</string>
+
+    <!-- Mobile network settings screen, name for call settings category [CHAR LIMIT=NONE] -->
+    <string name="call_category">Calling</string>
+    <!-- Mobile network settings screen, title of Video calling setting [CHAR LIMIT=NONE] -->
+    <string name="video_calling_settings_title">Carrier video calling</string>
+
+    <!-- Mobile network settings screen, setting option name [CHAR LIMIT=NONE] -->
+    <string name="cdma_system_select_title">System select</string>
+    <!-- Mobile network settings screen, setting summary text [CHAR LIMIT=NONE] -->
+    <string name="cdma_system_select_summary">Change the CDMA roaming mode</string>
+    <!-- System select settings screen title [CHAR LIMIT=NONE] -->
+    <string name="cdma_system_select_dialogtitle">System select</string>
+
+    <!-- Mobile network settings screen, name for network operator category [CHAR LIMIT=NONE] -->
+    <string name="network_operator_category">Network</string>
+    <!-- Available networks screen, name of button when user wants to select network manually [CHAR LIMIT=NONE] -->
+    <string name="network_select_title">Network</string>
+
+    <!-- Title for CDMA subscription [CHAR LIMIT=50] -->
+    <string name="cdma_subscription_title">CDMA subscription</string>
+    <!-- Summary for CDMA subscription [CHAR LIMIT=NONE] -->
+    <string name="cdma_subscription_summary">Change between RUIM/SIM and NV</string>
+    <!-- Dialog title for CDMA subscription [CHAR LIMIT=30] -->
+    <string name="cdma_subscription_dialogtitle">subscription</string>
 </resources>
diff --git a/res/xml/cdma_options.xml b/res/xml/cdma_options.xml
new file mode 100644
index 0000000..f6ef97a
--- /dev/null
+++ b/res/xml/cdma_options.xml
@@ -0,0 +1,54 @@
+<?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">
+
+    <com.android.phone.CdmaSystemSelectListPreference
+        android:key="cdma_system_select_key"
+        android:title="@string/cdma_system_select_title"
+        android:summary="@string/cdma_system_select_summary"
+        android:entries="@array/cdma_system_select_choices"
+        android:entryValues="@array/cdma_system_select_values"
+        android:dialogTitle="@string/cdma_system_select_dialogtitle" />
+
+    <com.android.phone.CdmaSubscriptionListPreference
+        android:key="cdma_subscription_key"
+        android:title="@string/cdma_subscription_title"
+        android:summary="@string/cdma_subscription_summary"
+        android:entries="@array/cdma_subscription_choices"
+        android:entryValues="@array/cdma_subscription_values"
+        android:dialogTitle="@string/cdma_subscription_dialogtitle" />
+
+    <!--We want separate APN setting from reset of settings because-->
+    <!--we want user to change it with caution.-->
+    <PreferenceCategory
+        android:key="category_cdma_apn_key">
+        <!-- The launching Intent will be defined thru code as we need to pass some Extra -->
+        <com.android.phone.RestrictedPreference
+            android:key="button_cdma_apn_key"
+            android:title="@string/apn_settings"
+            android:persistent="false"/>
+    </PreferenceCategory>
+
+    <Preference
+        android:key="carrier_settings_key"
+        android:title="@string/carrier_settings_title">
+        <intent android:action="android.intent.action.MAIN"
+                android:targetPackage="@string/carrier_settings"
+                android:targetClass="@string/carrier_settings_menu" />
+    </Preference>
+
+</PreferenceScreen>
diff --git a/res/xml/gsm_umts_options.xml b/res/xml/gsm_umts_options.xml
new file mode 100644
index 0000000..81b2deb
--- /dev/null
+++ b/res/xml/gsm_umts_options.xml
@@ -0,0 +1,60 @@
+<?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">
+
+    <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"/>
+
+        <Preference
+            android:key="button_choose_network_key"
+            android:title="@string/choose_network_title"
+            android:fragment="com.android.phone.NetworkSelectSetting" />
+    </com.android.phone.NetworkOperators>
+
+    <!--We want separate APN setting from reset of settings because-->
+    <!--we want user to change it with caution.-->
+    <PreferenceCategory
+        android:key="category_gsm_apn_key"
+        android:layout="@layout/preference_category_no_label">
+
+        <com.android.phone.RestrictedPreference
+            android:key="button_gsm_apn_key"
+            android:title="@string/apn_settings"
+            android:persistent="false" />
+    </PreferenceCategory>
+
+    <PreferenceScreen
+        android:key="carrier_settings_key"
+        android:title="@string/carrier_settings_title">
+        <intent android:action="android.intent.action.MAIN"
+                android:targetPackage="@string/carrier_settings"
+                android:targetClass="@string/carrier_settings_menu" />
+    </PreferenceScreen>
+
+</PreferenceScreen>
diff --git a/res/xml/network_setting_fragment.xml b/res/xml/network_setting_fragment.xml
new file mode 100644
index 0000000..d334861
--- /dev/null
+++ b/res/xml/network_setting_fragment.xml
@@ -0,0 +1,91 @@
+<?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">
+
+    <PreferenceScreen
+        android:key="cdma_lte_data_service_key"
+        android:title="@string/cdma_lte_data_service">
+    </PreferenceScreen>
+
+    <com.android.phone.MobileDataPreference
+        android:key="mobile_data_enable"
+        android:title="@string/mobile_data_settings_title"
+        android:summary="@string/mobile_data_settings_summary"/>
+
+    <com.android.phone.RestrictedSwitchPreference
+        android:key="button_roaming_key"
+        android:title="@string/roaming"
+        android:persistent="false"
+        android:summaryOn="@string/roaming_enable"
+        android:summaryOff="@string/roaming_disable"/>
+
+    <com.android.phone.DataUsagePreference
+        android:key="data_usage_summary"
+        android:title="@string/data_usage_title" />
+
+    <com.android.phone.AdvancedOptionsPreference
+        android:key="advanced_options"/>
+
+    <SwitchPreference
+        android:key="enhanced_4g_lte"
+        android:title="@string/enhanced_4g_lte_mode_title"
+        android:persistent="false"
+        android:summary="@string/enhanced_4g_lte_mode_summary"/>
+
+    <ListPreference
+        android:key="preferred_network_mode_key"
+        android:title="@string/preferred_network_mode_title"
+        android:summary="@string/preferred_network_mode_summary"
+        android:entries="@array/preferred_network_mode_choices"
+        android:entryValues="@array/preferred_network_mode_values"
+        android:dialogTitle="@string/preferred_network_mode_dialogtitle" />
+
+    <ListPreference
+        android:key="enabled_networks_key"
+        android:title="@string/preferred_network_mode_title"
+        android:summary="@string/preferred_network_mode_summary"
+        android:entries="@array/enabled_networks_choices"
+        android:entryValues="@array/enabled_networks_values"
+        android:dialogTitle="@string/preferred_network_mode_dialogtitle" />
+
+    <Preference
+        android:key="carrier_settings_euicc_key"
+        android:title="@string/carrier_settings_euicc" />
+
+    <PreferenceCategory
+        android:key="calling"
+        android:title="@string/call_category">
+
+        <PreferenceScreen
+            android:key="wifi_calling_key"
+            android:title="@string/wifi_calling_settings_title">
+
+            <intent android:action="android.intent.action.MAIN"
+                    android:targetPackage="com.android.settings"
+                    android:targetClass="com.android.settings.Settings$WifiCallingSettingsActivity">
+                        <extra android:name="show_drawer_menu" android:value="true" />
+            </intent>
+
+        </PreferenceScreen>
+
+        <SwitchPreference
+            android:key="video_calling_key"
+            android:title="@string/video_calling_settings_title"
+            android:persistent="true"/>
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/mobilenetwork/AdvancedOptionsPreference.java b/src/com/android/settings/mobilenetwork/AdvancedOptionsPreference.java
new file mode 100644
index 0000000..23e3cd4
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/AdvancedOptionsPreference.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Customized preference class representing the "Advanced" button that expands to fields that
+ * are hidden by default.
+ */
+public class AdvancedOptionsPreference extends Preference {
+    public AdvancedOptionsPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        setIcon(R.drawable.ic_expand_more);
+        setTitle(R.string.advanced_options_title);
+        TextView summary = view.findViewById(android.R.id.summary);
+        summary.setMaxLines(1);
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/CdmaOptions.java b/src/com/android/settings/mobilenetwork/CdmaOptions.java
new file mode 100644
index 0000000..38c6ca3
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/CdmaOptions.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.content.Intent;
+import android.os.PersistableBundle;
+import android.os.SystemProperties;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.phone.MobileNetworkSettings;
+import com.android.phone.RestrictedPreference;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+
+/**
+ * List of Phone-specific settings screens.
+ */
+public class CdmaOptions {
+    private static final String LOG_TAG = "CdmaOptions";
+
+    private CarrierConfigManager mCarrierConfigManager;
+    private CdmaSystemSelectListPreference mButtonCdmaSystemSelect;
+    private CdmaSubscriptionListPreference mButtonCdmaSubscription;
+    private RestrictedPreference mButtonAPNExpand;
+    private Preference mCategoryAPNExpand;
+    private Preference mButtonCarrierSettings;
+
+    private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
+    private static final String BUTTON_CDMA_SUBSCRIPTION_KEY = "cdma_subscription_key";
+    private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
+    private static final String BUTTON_APN_EXPAND_KEY = "button_cdma_apn_key";
+    private static final String CATEGORY_APN_EXPAND_KEY = "category_cdma_apn_key";
+
+    private PreferenceFragment mPrefFragment;
+    private PreferenceScreen mPrefScreen;
+    private int mSubId;
+
+    public CdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen, int subId) {
+        mPrefFragment = prefFragment;
+        mPrefScreen = prefScreen;
+        mPrefFragment.addPreferencesFromResource(R.xml.cdma_options);
+        mCarrierConfigManager = new CarrierConfigManager(prefFragment.getContext());
+
+        // Initialize preferences.
+        mButtonCdmaSystemSelect = (CdmaSystemSelectListPreference) mPrefScreen
+                .findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY);
+        mButtonCdmaSubscription = (CdmaSubscriptionListPreference) mPrefScreen
+                .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY);
+        mButtonCarrierSettings = mPrefScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
+        mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
+        mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
+
+        updateSubscriptionId(subId);
+    }
+
+    protected void updateSubscriptionId(int subId) {
+        mSubId = subId;
+        int phoneType = TelephonyManager.from(mPrefFragment.getContext())
+                .createForSubscriptionId(mSubId).getPhoneType();
+
+        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+        // Some CDMA carriers want the APN settings.
+        boolean addAPNExpand = shouldAddApnExpandPreference(phoneType, carrierConfig);
+        boolean addCdmaSubscription =
+                deviceSupportsNvAndRuim();
+        // Read platform settings for carrier settings
+        boolean addCarrierSettings =
+                carrierConfig.getBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL);
+
+        mPrefScreen.addPreference(mButtonCdmaSystemSelect);
+        mButtonCdmaSystemSelect.setEnabled(true);
+
+        // Making no assumptions of whether they are added or removed at this point.
+        // Calling add or remove explicitly to make sure they are updated.
+
+        if (addAPNExpand) {
+            log("update: addAPNExpand");
+            mButtonAPNExpand.setDisabledByAdmin(
+                    MobileNetworkSettings.isDpcApnEnforced(mButtonAPNExpand.getContext())
+                            ? RestrictedLockUtilsInternal.getDeviceOwner(
+                                    mButtonAPNExpand.getContext())
+                            : null);
+            mButtonAPNExpand.setOnPreferenceClickListener(
+                    new Preference.OnPreferenceClickListener() {
+                        @Override
+                        public boolean onPreferenceClick(Preference preference) {
+                            MetricsLogger.action(mButtonAPNExpand.getContext(),
+                                    MetricsEvent.ACTION_MOBILE_NETWORK_APN_SETTINGS);
+                            // We need to build the Intent by hand as the Preference Framework
+                            // does not allow to add an Intent with some extras into a Preference
+                            // XML file
+                            final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
+                            // This will setup the Home and Search affordance
+                            intent.putExtra(":settings:show_fragment_as_subsetting", true);
+                            intent.putExtra("sub_id", mSubId);
+                            mPrefFragment.startActivity(intent);
+                            return true;
+                        }
+                    });
+            mPrefScreen.addPreference(mCategoryAPNExpand);
+        } else {
+            mPrefScreen.removePreference(mCategoryAPNExpand);
+        }
+
+        if (addCdmaSubscription) {
+            log("Both NV and Ruim supported, ENABLE subscription type selection");
+            mPrefScreen.addPreference(mButtonCdmaSubscription);
+            mButtonCdmaSubscription.setEnabled(true);
+        } else {
+            log("Both NV and Ruim NOT supported, REMOVE subscription type selection");
+            mPrefScreen.removePreference(mButtonCdmaSubscription);
+        }
+
+        if (addCarrierSettings) {
+            mPrefScreen.addPreference(mButtonCarrierSettings);
+        } else {
+            mPrefScreen.removePreference(mButtonCarrierSettings);
+        }
+    }
+
+    /**
+     * Return whether we should add the APN expandable preference based on the phone type and
+     * carrier config
+     */
+    @VisibleForTesting
+    public static boolean shouldAddApnExpandPreference(int phoneType, PersistableBundle config) {
+        return phoneType == PhoneConstants.PHONE_TYPE_CDMA
+                && config.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL);
+    }
+
+    private boolean deviceSupportsNvAndRuim() {
+        // retrieve the list of subscription types supported by device.
+        String subscriptionsSupported = SystemProperties.get("ril.subscription.types");
+        boolean nvSupported = false;
+        boolean ruimSupported = false;
+
+        log("deviceSupportsnvAnRum: prop=" + subscriptionsSupported);
+        if (!TextUtils.isEmpty(subscriptionsSupported)) {
+            // Searches through the comma-separated list for a match for "NV"
+            // and "RUIM" to update nvSupported and ruimSupported.
+            for (String subscriptionType : subscriptionsSupported.split(",")) {
+                subscriptionType = subscriptionType.trim();
+                if (subscriptionType.equalsIgnoreCase("NV")) {
+                    nvSupported = true;
+                }
+                if (subscriptionType.equalsIgnoreCase("RUIM")) {
+                    ruimSupported = true;
+                }
+            }
+        }
+
+        log("deviceSupportsnvAnRum: nvSupported=" + nvSupported +
+                " ruimSupported=" + ruimSupported);
+        return (nvSupported && ruimSupported);
+    }
+
+    public boolean preferenceTreeClick(Preference preference) {
+        if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
+            log("preferenceTreeClick: return BUTTON_CDMA_ROAMING_KEY true");
+            return true;
+        }
+        if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
+            log("preferenceTreeClick: return CDMA_SUBSCRIPTION_KEY true");
+            return true;
+        }
+        return false;
+    }
+
+    public void showDialog(Preference preference) {
+        if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
+            mButtonCdmaSystemSelect.showDialog(null);
+        } else if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
+            mButtonCdmaSubscription.showDialog(null);
+        }
+    }
+
+    protected void log(String s) {
+        android.util.Log.d(LOG_TAG, s);
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/CdmaSubscriptionListPreference.java b/src/com/android/settings/mobilenetwork/CdmaSubscriptionListPreference.java
new file mode 100644
index 0000000..9752e99
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/CdmaSubscriptionListPreference.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.settingslib.utils.ThreadUtils;
+
+public class CdmaSubscriptionListPreference extends ListPreference {
+
+    private static final String LOG_TAG = "CdmaSubscriptionListPreference";
+
+    // Used for CDMA subscription mode
+    private static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0;
+    private static final int CDMA_SUBSCRIPTION_NV = 1;
+
+    //preferredSubscriptionMode  0 - RUIM/SIM, preferred
+    //                           1 - NV
+    static final int preferredSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION;
+
+    private TelephonyManager mTelephonyManager;
+
+    public CdmaSubscriptionListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mTelephonyManager = TelephonyManager.from(context);
+        setCurrentCdmaSubscriptionModeValue();
+    }
+
+    private void setCurrentCdmaSubscriptionModeValue() {
+        int cdmaSubscriptionMode = Settings.Global.getInt(getContext().getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE, preferredSubscriptionMode);
+        setValue(Integer.toString(cdmaSubscriptionMode));
+    }
+
+    public CdmaSubscriptionListPreference(Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Sets the subscription id associated with this preference.
+     *
+     * @param subId the subscription id.
+     */
+    public void setSubscriptionId(int subId) {
+        mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(subId);
+    }
+
+    @Override
+    protected void showDialog(Bundle state) {
+        setCurrentCdmaSubscriptionModeValue();
+
+        super.showDialog(state);
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (!positiveResult) {
+            //The button was dismissed - no need to set new value
+            return;
+        }
+
+        int buttonCdmaSubscriptionMode = Integer.parseInt(getValue());
+        Log.d(LOG_TAG, "Setting new value " + buttonCdmaSubscriptionMode);
+        int statusCdmaSubscriptionMode;
+        switch(buttonCdmaSubscriptionMode) {
+            case CDMA_SUBSCRIPTION_NV:
+                statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_NV;
+                break;
+            case CDMA_SUBSCRIPTION_RUIM_SIM:
+                statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_RUIM_SIM;
+                break;
+            default:
+                statusCdmaSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION;
+        }
+
+        // Set the CDMA subscription mode, when mode has been successfully changed, update the
+        // mode to the global setting.
+        ThreadUtils.postOnBackgroundThread(() -> {
+            // The subscription mode selected by user.
+            int cdmaSubscriptionMode = Integer.parseInt(getValue());
+
+            boolean isSuccessed = mTelephonyManager.setCdmaSubscriptionMode(
+                    statusCdmaSubscriptionMode);
+
+            // Update the global settings if successed.
+            if (isSuccessed) {
+                Settings.Global.putInt(getContext().getContentResolver(),
+                        Settings.Global.CDMA_SUBSCRIPTION_MODE,
+                        cdmaSubscriptionMode);
+            } else {
+                Log.e(LOG_TAG, "Setting Cdma subscription source failed");
+            }
+        });
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/CdmaSystemSelectListPreference.java b/src/com/android/settings/mobilenetwork/CdmaSystemSelectListPreference.java
new file mode 100644
index 0000000..ab62f88
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/CdmaSystemSelectListPreference.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.ListPreference;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.settingslib.utils.ThreadUtils;
+
+public class CdmaSystemSelectListPreference extends ListPreference {
+
+    private static final String LOG_TAG = "CdmaRoamingListPreference";
+    private static final boolean DBG = false;
+
+    private TelephonyManager mTelephonyManager;
+    private MyHandler mHandler = new MyHandler();
+
+    public CdmaSystemSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mHandler = new MyHandler();
+        mTelephonyManager = TelephonyManager.from(context);
+    }
+
+    public CdmaSystemSelectListPreference(Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Sets the subscription id associated with this preference.
+     *
+     * @param subId the subscription id.
+     */
+    public void setSubscriptionId(int subId) {
+        mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(subId);
+        queryCdmaRoamingMode();
+    }
+
+    @Override
+    protected void showDialog(Bundle state) {
+        if (!mTelephonyManager.getEmergencyCallbackMode()) {
+            super.showDialog(state);
+        }
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (positiveResult && (getValue() != null)) {
+            int buttonCdmaRoamingMode = Integer.parseInt(getValue());
+            int settingsCdmaRoamingMode = Settings.Global.getInt(
+                    getContext().getContentResolver(),
+                    Settings.Global.CDMA_ROAMING_MODE,
+                    TelephonyManager.CDMA_ROAMING_MODE_HOME);
+            if (buttonCdmaRoamingMode != settingsCdmaRoamingMode) {
+                int cdmaRoamingMode = TelephonyManager.CDMA_ROAMING_MODE_ANY;
+                if (buttonCdmaRoamingMode != TelephonyManager.CDMA_ROAMING_MODE_ANY) {
+                    cdmaRoamingMode = TelephonyManager.CDMA_ROAMING_MODE_HOME;
+                }
+                //Set the Settings.Secure network mode
+                Settings.Global.putInt(
+                        getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
+                        buttonCdmaRoamingMode);
+                //Set the roaming preference mode
+                setCdmaRoamingMode(cdmaRoamingMode);
+            }
+        } else {
+            Log.d(LOG_TAG, String.format("onDialogClosed: positiveResult=%b value=%s -- do nothing",
+                    positiveResult, getValue()));
+        }
+    }
+
+    private class MyHandler extends Handler {
+
+        static final int MESSAGE_GET_ROAMING_PREFERENCE = 0;
+        static final int MESSAGE_SET_ROAMING_PREFERENCE = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_ROAMING_PREFERENCE:
+                    handleQueryCdmaRoamingPreference(msg);
+                    break;
+
+                case MESSAGE_SET_ROAMING_PREFERENCE:
+                    handleSetCdmaRoamingPreference(msg);
+                    break;
+            }
+        }
+
+        private void handleQueryCdmaRoamingPreference(Message msg) {
+            int cdmaRoamingMode = msg.arg1;
+
+            if (cdmaRoamingMode != TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT) {
+                int settingsRoamingMode = Settings.Global.getInt(
+                        getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
+                        TelephonyManager.CDMA_ROAMING_MODE_HOME);
+
+                //check that statusCdmaRoamingMode is from an accepted value
+                if (cdmaRoamingMode == TelephonyManager.CDMA_ROAMING_MODE_HOME
+                        || cdmaRoamingMode == TelephonyManager.CDMA_ROAMING_MODE_ANY) {
+                    //check changes in statusCdmaRoamingMode and updates settingsRoamingMode
+                    if (cdmaRoamingMode != settingsRoamingMode) {
+                        settingsRoamingMode = cdmaRoamingMode;
+                        //changes the Settings.Secure accordingly to statusCdmaRoamingMode
+                        Settings.Global.putInt(
+                                getContext().getContentResolver(),
+                                Settings.Global.CDMA_ROAMING_MODE,
+                                settingsRoamingMode);
+                    }
+                    //changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
+                    setValue(Integer.toString(cdmaRoamingMode));
+                }
+                else {
+                    if(DBG) Log.i(LOG_TAG, "reset cdma roaming mode to default" );
+                    resetCdmaRoamingModeToDefault();
+                }
+            }
+        }
+
+        private void handleSetCdmaRoamingPreference(Message msg) {
+            boolean isSuccessed = (boolean) msg.obj;
+
+            if (isSuccessed && (getValue() != null)) {
+                int cdmaRoamingMode = Integer.parseInt(getValue());
+                Settings.Global.putInt(
+                        getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
+                        cdmaRoamingMode );
+            } else {
+                queryCdmaRoamingMode();
+            }
+        }
+
+        private void resetCdmaRoamingModeToDefault() {
+            //set the mButtonCdmaRoam
+            setValue(Integer.toString(TelephonyManager.CDMA_ROAMING_MODE_ANY));
+            //set the Settings.System
+            Settings.Global.putInt(
+                    getContext().getContentResolver(),
+                    Settings.Global.CDMA_ROAMING_MODE,
+                    TelephonyManager.CDMA_ROAMING_MODE_ANY);
+            //Set the Status
+            setCdmaRoamingMode(TelephonyManager.CDMA_ROAMING_MODE_ANY);
+        }
+    }
+
+    private void queryCdmaRoamingMode() {
+        ThreadUtils.postOnBackgroundThread(() -> {
+            Message msg = mHandler.obtainMessage(MyHandler.MESSAGE_GET_ROAMING_PREFERENCE);
+            msg.arg1 = mTelephonyManager.getCdmaRoamingMode();
+            msg.sendToTarget();
+        });
+    }
+
+    private void setCdmaRoamingMode(int mode) {
+        ThreadUtils.postOnBackgroundThread(() -> {
+            Message msg = mHandler.obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE);
+            msg.obj = mTelephonyManager.setCdmaRoamingMode(mode);
+            msg.sendToTarget();
+        });
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/DataUsagePreference.java b/src/com/android/settings/mobilenetwork/DataUsagePreference.java
new file mode 100644
index 0000000..594f83b
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/DataUsagePreference.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.NetworkTemplate;
+import android.preference.Preference;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.text.format.Formatter;
+import android.util.AttributeSet;
+
+import com.android.settingslib.net.DataUsageController;
+
+/**
+ * The preference that shows mobile data usage summary and
+ * leads to mobile data usage list page.
+ */
+public class DataUsagePreference extends Preference {
+
+    private NetworkTemplate mTemplate;
+    private int mSubId;
+
+    public DataUsagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * After creating this preference, this functions needs to be called to
+     * initialize which subID it connects to.
+     */
+    public void initialize(int subId) {
+        Activity activity = (Activity) getContext();
+
+        mSubId = subId;
+        mTemplate = getNetworkTemplate(activity, subId);
+
+        DataUsageController controller = new DataUsageController(activity);
+
+        DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate);
+        setSummary(activity.getString(R.string.data_usage_template,
+                Formatter.formatFileSize(activity, usageInfo.usageLevel), usageInfo.period));
+        setIntent(getIntent());
+    }
+
+    @Override
+    public Intent getIntent() {
+        Intent intent = new Intent(Settings.ACTION_MOBILE_DATA_USAGE);
+
+        intent.putExtra(Settings.EXTRA_NETWORK_TEMPLATE, mTemplate);
+        intent.putExtra(Settings.EXTRA_SUB_ID, mSubId);
+
+        return intent;
+    }
+
+    private NetworkTemplate getNetworkTemplate(Activity activity, int subId) {
+        TelephonyManager tm = (TelephonyManager) activity
+                .getSystemService(Context.TELEPHONY_SERVICE);
+        NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
+                tm.getSubscriberId(subId));
+        return NetworkTemplate.normalize(mobileAll,
+                tm.getMergedSubscriberIds());
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/GsmUmtsOptions.java b/src/com/android/settings/mobilenetwork/GsmUmtsOptions.java
new file mode 100644
index 0000000..8400ec3
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/GsmUmtsOptions.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.PersistableBundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.phone.INetworkQueryService;
+import com.android.phone.MobileNetworkSettings;
+import com.android.phone.PhoneGlobals;
+import com.android.phone.RestrictedPreference;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+
+/**
+ * List of Network-specific settings screens.
+ */
+public class GsmUmtsOptions {
+    private static final String LOG_TAG = "GsmUmtsOptions";
+
+    private CarrierConfigManager mCarrierConfigManager;
+    private RestrictedPreference mButtonAPNExpand;
+    private Preference mCategoryAPNExpand;
+    Preference mCarrierSettingPref;
+
+    private NetworkOperators mNetworkOperator;
+
+    private static final String BUTTON_APN_EXPAND_KEY = "button_gsm_apn_key";
+    private static final String CATEGORY_APN_EXPAND_KEY = "category_gsm_apn_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;
+
+    public GsmUmtsOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
+            final int subId, INetworkQueryService queryService) {
+        final Context context = prefFragment.getContext();
+        mPrefFragment = prefFragment;
+        mPrefScreen = prefScreen;
+        mCarrierConfigManager = new CarrierConfigManager(context);
+        mPrefFragment.addPreferencesFromResource(R.xml.gsm_umts_options);
+        mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
+        mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
+        mNetworkOperator = (NetworkOperators) mPrefScreen
+                .findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
+        mCarrierSettingPref = mPrefScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
+
+        mNetworkOperator.initialize();
+
+        update(subId, queryService);
+    }
+
+    // Unlike mPrefFragment or mPrefScreen, subId or queryService may change during lifecycle of
+    // GsmUmtsOptions. When that happens, we update GsmUmtsOptions with new parameters.
+    protected void update(final int subId, INetworkQueryService queryService) {
+        boolean addAPNExpand = true;
+        boolean addNetworkOperatorsCategory = true;
+        boolean addCarrierSettings = true;
+        final TelephonyManager telephonyManager = TelephonyManager.from(mPrefFragment.getContext())
+                .createForSubscriptionId(subId);
+        Phone phone = PhoneGlobals.getPhone(subId);
+        if (phone == null) return;
+        if (telephonyManager.getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
+            log("Not a GSM phone");
+            addAPNExpand = false;
+            mNetworkOperator.setEnabled(false);
+        } else {
+            log("Not a CDMA phone");
+            PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
+
+            // Determine which options to display. For GSM these are defaulted to true in
+            // CarrierConfigManager, but they maybe overriden by DefaultCarrierConfigService or a
+            // carrier app.
+            // Note: these settings used to be controlled with overlays in
+            // Telephony/res/values/config.xml
+            if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL)
+                    && mCategoryAPNExpand != null) {
+                addAPNExpand = false;
+            }
+            if (!carrierConfig.getBoolean(
+                    CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL)) {
+                addNetworkOperatorsCategory = false;
+            }
+
+            if (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)) {
+                if (phone.isCspPlmnEnabled()) {
+                    log("[CSP] Enabling Operator Selection menu.");
+                    mNetworkOperator.setEnabled(true);
+                } else {
+                    log("[CSP] Disabling Operator Selection menu.");
+                    addNetworkOperatorsCategory = false;
+                }
+            }
+
+            // Read platform settings for carrier settings
+            addCarrierSettings = carrierConfig.getBoolean(
+                    CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL);
+        }
+
+        // Making no assumptions of whether they are added or removed at this point.
+        // Calling add or remove explicitly to make sure they are updated.
+
+        if (addAPNExpand) {
+            log("update: addAPNExpand");
+            mButtonAPNExpand.setDisabledByAdmin(
+                    MobileNetworkSettings.isDpcApnEnforced(mButtonAPNExpand.getContext())
+                            ? RestrictedLockUtilsInternal.getDeviceOwner(
+                                    mButtonAPNExpand.getContext())
+                            : null);
+            mButtonAPNExpand.setOnPreferenceClickListener(
+                    new Preference.OnPreferenceClickListener() {
+                        @Override
+                        public boolean onPreferenceClick(Preference preference) {
+                            MetricsLogger.action(mButtonAPNExpand.getContext(),
+                                    MetricsEvent.ACTION_MOBILE_NETWORK_APN_SETTINGS);
+                            // We need to build the Intent by hand as the Preference Framework
+                            // does not allow to add an Intent with some extras into a Preference
+                            // XML file
+                            final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
+                            // This will setup the Home and Search affordance
+                            intent.putExtra(":settings:show_fragment_as_subsetting", true);
+                            intent.putExtra(EXTRA_SUB_ID, subId);
+                            mPrefFragment.startActivity(intent);
+                            return true;
+                        }
+                    });
+            mPrefScreen.addPreference(mCategoryAPNExpand);
+        } else {
+            mPrefScreen.removePreference(mCategoryAPNExpand);
+        }
+
+        if (addNetworkOperatorsCategory) {
+            mPrefScreen.addPreference(mNetworkOperator);
+            mNetworkOperator.update(subId, queryService);
+        } else {
+            mPrefScreen.removePreference(mNetworkOperator);
+        }
+
+        if (addCarrierSettings) {
+            mPrefScreen.addPreference(mCarrierSettingPref);
+        } else {
+            mPrefScreen.removePreference(mCarrierSettingPref);
+        }
+
+    }
+
+    protected boolean preferenceTreeClick(Preference preference) {
+        return mNetworkOperator.preferenceTreeClick(preference);
+    }
+
+    protected void log(String s) {
+        android.util.Log.d(LOG_TAG, s);
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/MobileDataPreference.java b/src/com/android/settings/mobilenetwork/MobileDataPreference.java
new file mode 100644
index 0000000..39f4d2c
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/MobileDataPreference.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.DialogPreference;
+import android.preference.PreferenceScreen;
+import android.provider.Settings.Global;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.Checkable;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import java.util.List;
+
+/**
+ * Customized Preference to enable / disable mobile data.
+ * Basically copy of with com.android.settings.CellDataPreference.
+ */
+public class MobileDataPreference extends DialogPreference {
+
+    private static final boolean DBG = false;
+    private static final String TAG = "MobileDataPreference";
+
+    public int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    public boolean mChecked;
+    // Whether to show the dialog to ask switching default data subscription.
+    // Should be true only when a multi-sim phone only supports data connection on a single phone,
+    // and user is enabling data on the non-default phone.
+    public boolean mMultiSimDialog;
+    private TelephonyManager mTelephonyManager;
+    private SubscriptionManager mSubscriptionManager;
+
+    public MobileDataPreference(Context context, AttributeSet attrs) {
+        super(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
+    }
+
+    // Must be called to avoid binder leakage.
+    void dispose() {
+        mListener.setListener(false, mSubId, getContext());
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable s) {
+        CellDataState state = (CellDataState) s;
+        super.onRestoreInstanceState(state.getSuperState());
+        mTelephonyManager = TelephonyManager.from(getContext());
+        mChecked = state.mChecked;
+        mMultiSimDialog = state.mMultiSimDialog;
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            mSubId = state.mSubId;
+            setKey(getKey() + mSubId);
+        }
+        notifyChanged();
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        CellDataState state = new CellDataState(super.onSaveInstanceState());
+        state.mChecked = mChecked;
+        state.mMultiSimDialog = mMultiSimDialog;
+        state.mSubId = mSubId;
+        return state;
+    }
+
+    @Override
+    protected void onAttachedToActivity() {
+        super.onAttachedToActivity();
+        mListener.setListener(true, mSubId, getContext());
+    }
+
+    @Override
+    protected void onPrepareForRemoval() {
+        mListener.setListener(false, mSubId, getContext());
+        super.onPrepareForRemoval();
+    }
+
+    /**
+     * Initialize this preference with subId.
+     */
+    public void initialize(int subId) {
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            throw new IllegalArgumentException("MobileDataPreference needs a SubscriptionInfo");
+        }
+        mSubscriptionManager = SubscriptionManager.from(getContext());
+        mTelephonyManager = TelephonyManager.from(getContext());
+        if (mSubId != subId) {
+            mSubId = subId;
+            setKey(getKey() + subId);
+        }
+        updateChecked();
+    }
+
+    private void updateChecked() {
+        setChecked(mTelephonyManager.getDataEnabled(mSubId));
+    }
+
+    @Override
+    public void performClick(PreferenceScreen preferenceScreen) {
+        if (!isEnabled() || !SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            return;
+        }
+        final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(
+                mSubId);
+        final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
+        final boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
+        final boolean isMultipleDataOnCapable =
+                (mTelephonyManager.getNumberOfModemsWithSimultaneousDataConnections() > 1);
+        final boolean isDefaultDataSubscription = (nextSir != null && currentSir != null
+                && currentSir.getSubscriptionId() == nextSir.getSubscriptionId());
+        if (mChecked) {
+            if (!isMultiSim) {
+                // disabling data; show confirmation dialog which eventually
+                // calls setMobileDataEnabled() once user confirms.
+                mMultiSimDialog = false;
+                super.performClick(preferenceScreen);
+            } else {
+                // Don't show any dialog.
+                setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
+            }
+        } else {
+            if (isMultiSim && !isMultipleDataOnCapable && !isDefaultDataSubscription) {
+                // enabling data and setting to default; show confirmation dialog which eventually
+                // calls setMobileDataEnabled() once user confirms.
+                mMultiSimDialog = true;
+                super.performClick(preferenceScreen);
+            } else {
+                // Don't show any dialog.
+                setMobileDataEnabled(true /* enabled */, false /* disableOtherSubscriptions */);
+            }
+        }
+    }
+
+    private void setMobileDataEnabled(boolean enabled, boolean disableOtherSubscriptions) {
+        if (DBG) Log.d(TAG, "setMobileDataEnabled(" + enabled + "," + mSubId + ")");
+
+        MetricsLogger.action(getContext(), MetricsEvent.ACTION_MOBILE_NETWORK_MOBILE_DATA_TOGGLE,
+                enabled);
+
+        mTelephonyManager.setDataEnabled(mSubId, enabled);
+
+        if (disableOtherSubscriptions) {
+            disableDataForOtherSubscriptions(mSubId);
+        }
+
+        setChecked(enabled);
+    }
+
+    private void setChecked(boolean checked) {
+        if (mChecked == checked) return;
+        mChecked = checked;
+        notifyChanged();
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        View checkableView = view.findViewById(com.android.internal.R.id.switch_widget);
+        checkableView.setClickable(false);
+        ((Checkable) checkableView).setChecked(mChecked);
+    }
+
+    @Override
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+        if (mMultiSimDialog) {
+            showMultiSimDialog(builder);
+        } else {
+            showDisableDialog(builder);
+        }
+    }
+
+    private void showDisableDialog(AlertDialog.Builder builder) {
+        builder.setTitle(null)
+                .setMessage(R.string.data_usage_disable_mobile)
+                .setPositiveButton(android.R.string.ok, this)
+                .setNegativeButton(android.R.string.cancel, null);
+    }
+
+    private void showMultiSimDialog(AlertDialog.Builder builder) {
+        final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
+        final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
+
+        final String previousName = (nextSir == null)
+                ? getContext().getResources().getString(R.string.sim_selection_required_pref)
+                : nextSir.getDisplayName().toString();
+
+        builder.setTitle(R.string.sim_change_data_title);
+        builder.setMessage(getContext().getString(R.string.sim_change_data_message,
+                String.valueOf(currentSir != null ? currentSir.getDisplayName() : null),
+                previousName));
+
+        builder.setPositiveButton(R.string.ok, this);
+        builder.setNegativeButton(R.string.cancel, null);
+    }
+
+    private void disableDataForOtherSubscriptions(int subId) {
+        List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+        if (subInfoList != null) {
+            for (SubscriptionInfo subInfo : subInfoList) {
+                if (subInfo.getSubscriptionId() != subId) {
+                    mTelephonyManager.setDataEnabled(subInfo.getSubscriptionId(), false);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (which != DialogInterface.BUTTON_POSITIVE) {
+            return;
+        }
+        if (mMultiSimDialog) {
+            mSubscriptionManager.setDefaultDataSubId(mSubId);
+            setMobileDataEnabled(true /* enabled */, true /* disableOtherSubscriptions */);
+        } else {
+            // TODO: extend to modify policy enabled flag.
+            setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
+        }
+    }
+
+    private final DataStateListener mListener = new DataStateListener() {
+        @Override
+        public void onChange(boolean selfChange) {
+            updateChecked();
+        }
+    };
+
+    /**
+     * Listener that listens mobile data state change.
+     */
+    public abstract static class DataStateListener extends ContentObserver {
+        public DataStateListener() {
+            super(new Handler(Looper.getMainLooper()));
+        }
+
+        /**
+         * Set / Unset data state listening, specifying subId.
+         */
+        public void setListener(boolean listening, int subId, Context context) {
+            if (listening) {
+                Uri uri = Global.getUriFor(Global.MOBILE_DATA);
+                if (TelephonyManager.getDefault().getSimCount() != 1) {
+                    uri = Global.getUriFor(Global.MOBILE_DATA + subId);
+                }
+                context.getContentResolver().registerContentObserver(uri, false, this);
+            } else {
+                context.getContentResolver().unregisterContentObserver(this);
+            }
+        }
+    }
+
+    /**
+     * Class that represents state of mobile data state.
+     * Used by onSaveInstanceState and onRestoreInstanceState.
+     */
+    public static class CellDataState extends BaseSavedState {
+        public int mSubId;
+        public boolean mChecked;
+        public boolean mMultiSimDialog;
+
+        public CellDataState(Parcelable base) {
+            super(base);
+        }
+
+        public CellDataState(Parcel source) {
+            super(source);
+            mChecked = source.readByte() != 0;
+            mMultiSimDialog = source.readByte() != 0;
+            mSubId = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeByte((byte) (mChecked ? 1 : 0));
+            dest.writeByte((byte) (mMultiSimDialog ? 1 : 0));
+            dest.writeInt(mSubId);
+        }
+
+        public static final Creator<CellDataState> CREATOR = new Creator<CellDataState>() {
+            @Override
+            public CellDataState createFromParcel(Parcel source) {
+                return new CellDataState(source);
+            }
+
+            @Override
+            public CellDataState[] newArray(int size) {
+                return new CellDataState[size];
+            }
+        };
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/MobileNetworkFragment.java b/src/com/android/settings/mobilenetwork/MobileNetworkFragment.java
new file mode 100644
index 0000000..03e7d79
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/MobileNetworkFragment.java
@@ -0,0 +1,2003 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.DialogFragment;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
+import android.provider.Settings;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TabHost;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsManager;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.phone.AdvancedOptionsPreference;
+import com.android.phone.CdmaOptions;
+import com.android.phone.CdmaSystemSelectListPreference;
+import com.android.phone.DataUsagePreference;
+import com.android.phone.EmergencyCallbackModeExitDialog;
+import com.android.phone.GsmUmtsOptions;
+import com.android.phone.MobileDataPreference;
+import com.android.phone.MobileNetworkSettings;
+import com.android.phone.NetworkOperators;
+import com.android.phone.NetworkSelectListPreference;
+import com.android.phone.RestrictedSwitchPreference;
+import com.android.phone.RoamingDialogFragment;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public static class MobileNetworkFragment extends PreferenceFragment implements
+        Preference.OnPreferenceChangeListener, com.android.phone.RoamingDialogFragment.RoamingDialogListener {
+
+    // debug data
+    private static final String LOG_TAG = "NetworkSettings";
+    private static final boolean DBG = true;
+    public static final int REQUEST_CODE_EXIT_ECM = 17;
+
+    // Number of active Subscriptions to show tabs
+    private static final int TAB_THRESHOLD = 2;
+
+    // Number of last phone number digits shown in Euicc Setting tab
+    private static final int NUM_LAST_PHONE_DIGITS = 4;
+
+    // fragment tag for roaming data dialog
+    private static final String ROAMING_TAG = "RoamingDialogFragment";
+
+    //String keys for preference lookup
+    private static final String BUTTON_PREFERED_NETWORK_MODE = "preferred_network_mode_key";
+    private static final String BUTTON_ROAMING_KEY = "button_roaming_key";
+    private static final String BUTTON_CDMA_LTE_DATA_SERVICE_KEY = "cdma_lte_data_service_key";
+    private static final String BUTTON_ENABLED_NETWORKS_KEY = "enabled_networks_key";
+    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_CARRIER_SETTINGS_KEY = "carrier_settings_key";
+    private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
+    private static final String BUTTON_CDMA_SUBSCRIPTION_KEY = "cdma_subscription_key";
+    private static final String BUTTON_CARRIER_SETTINGS_EUICC_KEY =
+            "carrier_settings_euicc_key";
+    private static final String BUTTON_WIFI_CALLING_KEY = "wifi_calling_key";
+    private static final String BUTTON_VIDEO_CALLING_KEY = "video_calling_key";
+    private static final String BUTTON_MOBILE_DATA_ENABLE_KEY = "mobile_data_enable";
+    private static final String BUTTON_DATA_USAGE_KEY = "data_usage_summary";
+    private static final String BUTTON_ADVANCED_OPTIONS_KEY = "advanced_options";
+    private static final String CATEGORY_CALLING_KEY = "calling";
+    private static final String CATEGORY_GSM_APN_EXPAND_KEY = "category_gsm_apn_key";
+    private static final String CATEGORY_CDMA_APN_EXPAND_KEY = "category_cdma_apn_key";
+    private static final String BUTTON_GSM_APN_EXPAND_KEY = "button_gsm_apn_key";
+    private static final String BUTTON_CDMA_APN_EXPAND_KEY = "button_cdma_apn_key";
+
+    private final BroadcastReceiver
+            mPhoneChangeReceiver = new MobileNetworkSettings.MobileNetworkFragment.PhoneChangeReceiver();
+    private final ContentObserver
+            mDpcEnforcedContentObserver = new MobileNetworkSettings.MobileNetworkFragment.DpcApnEnforcedObserver();
+
+    static final int preferredNetworkMode = Phone.PREFERRED_NT_MODE;
+
+    //Information about logical "up" Activity
+    private static final String UP_ACTIVITY_PACKAGE = "com.android.settings";
+    private static final String UP_ACTIVITY_CLASS =
+            "com.android.settings.Settings$WirelessSettingsActivity";
+
+    //Information that needs to save into Bundle.
+    private static final String EXPAND_ADVANCED_FIELDS = "expand_advanced_fields";
+    //Intent extra to indicate expand all fields.
+    private static final String EXPAND_EXTRA = "expandable";
+
+    private SubscriptionManager mSubscriptionManager;
+    private TelephonyManager mTelephonyManager;
+    private CarrierConfigManager mCarrierConfigManager;
+    private int mSubId;
+
+    //UI objects
+    private com.android.phone.AdvancedOptionsPreference mAdvancedOptions;
+    private ListPreference mButtonPreferredNetworkMode;
+    private ListPreference mButtonEnabledNetworks;
+    private RestrictedSwitchPreference mButtonDataRoam;
+    private SwitchPreference mButton4glte;
+    private Preference mLteDataServicePref;
+    private Preference mEuiccSettingsPref;
+    private PreferenceCategory mCallingCategory;
+    private Preference mWiFiCallingPref;
+    private SwitchPreference mVideoCallingPref;
+    private NetworkSelectListPreference mButtonNetworkSelect;
+    private com.android.phone.MobileDataPreference mMobileDataPref;
+    private com.android.phone.DataUsagePreference mDataUsagePref;
+
+    private static final String iface = "rmnet0"; //TODO: this will go away
+    private List<SubscriptionInfo> mActiveSubInfos;
+
+    private UserManager mUm;
+    private ImsManager mImsMgr;
+    private MobileNetworkSettings.MobileNetworkFragment.MyHandler mHandler;
+    private boolean mOkClicked;
+    private boolean mExpandAdvancedFields;
+
+    // We assume the the value returned by mTabHost.getCurrentTab() == slotId
+    private TabHost mTabHost;
+
+    //GsmUmts options and Cdma options
+    com.android.phone.GsmUmtsOptions mGsmUmtsOptions;
+    com.android.phone.CdmaOptions mCdmaOptions;
+
+    private Preference mClickedPreference;
+    private boolean mShow4GForLTE;
+    private boolean mIsGlobalCdma;
+    private boolean mOnlyAutoSelectInHomeNW;
+    private boolean mUnavailable;
+
+    private class PhoneCallStateListener extends PhoneStateListener {
+        /*
+         * Enable/disable the 'Enhanced 4G LTE Mode' when in/out of a call
+         * and depending on TTY mode and TTY support over VoLTE.
+         * @see android.telephony.PhoneStateListener#onCallStateChanged(int,
+         * java.lang.String)
+         */
+        @Override
+        public void onCallStateChanged(int state, String incomingNumber) {
+            if (DBG) log("PhoneStateListener.onCallStateChanged: state=" + state);
+
+            updateEnhanced4gLteState();
+            updateWiFiCallState();
+            updateVideoCallState();
+            updatePreferredNetworkType();
+        }
+
+        /**
+         * Listen to different subId if it's changed.
+         */
+        protected void updateSubscriptionId(Integer subId) {
+            if (subId.equals(MobileNetworkSettings.MobileNetworkFragment.PhoneCallStateListener.this.mSubId)) {
+                return;
+            }
+
+            MobileNetworkSettings.MobileNetworkFragment.PhoneCallStateListener.this.mSubId = subId;
+
+            mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
+
+            // Now, listen to new subId if it's valid.
+            if (SubscriptionManager.isValidSubscriptionId(subId)) {
+                mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
+            }
+        }
+    }
+
+    private final MobileNetworkSettings.MobileNetworkFragment.PhoneCallStateListener
+            mPhoneStateListener = new MobileNetworkSettings.MobileNetworkFragment.PhoneCallStateListener();
+
+    @Override
+    public void onPositiveButtonClick(DialogFragment dialog) {
+        mTelephonyManager.setDataRoamingEnabled(true);
+        mButtonDataRoam.setChecked(true);
+        MetricsLogger.action(getContext(),
+                getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
+                true);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        if (getListView() != null) {
+            getListView().setDivider(null);
+        }
+    }
+
+    public void onIntentUpdate(Intent intent) {
+        if (!mUnavailable) {
+            updateCurrentTab(intent);
+        }
+    }
+
+    /**
+     * Invoked on each preference click in this hierarchy, overrides
+     * PreferenceActivity's implementation.  Used to make sure we track the
+     * preference click events.
+     */
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+            Preference preference) {
+        sendMetricsEventPreferenceClicked(preferenceScreen, preference);
+
+        /** TODO: Refactor and get rid of the if's using subclasses */
+        if (preference.getKey().equals(BUTTON_4G_LTE_KEY)) {
+            return true;
+        } else if (mGsmUmtsOptions != null &&
+                mGsmUmtsOptions.preferenceTreeClick(preference) == true) {
+            return true;
+        } else if (mCdmaOptions != null &&
+                mCdmaOptions.preferenceTreeClick(preference) == true) {
+            if (mTelephonyManager.getEmergencyCallbackMode()) {
+
+                mClickedPreference = preference;
+
+                // In ECM mode launch ECM app dialog
+                startActivityForResult(
+                        new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null),
+                        REQUEST_CODE_EXIT_ECM);
+            }
+            return true;
+        } else if (preference == mButtonPreferredNetworkMode) {
+            //displays the value taken from the Settings.System
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                    getContext().getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
+                    preferredNetworkMode);
+            mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
+            return true;
+        } else if (preference == mLteDataServicePref) {
+            String tmpl = android.provider.Settings.Global.getString(
+                    getActivity().getContentResolver(),
+                    android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL);
+            if (!TextUtils.isEmpty(tmpl)) {
+                String imsi = mTelephonyManager.getSubscriberId();
+                if (imsi == null) {
+                    imsi = "";
+                }
+                final String url = TextUtils.isEmpty(tmpl) ? null
+                        : TextUtils.expandTemplate(tmpl, imsi).toString();
+                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+                startActivity(intent);
+            } else {
+                android.util.Log.e(LOG_TAG, "Missing SETUP_PREPAID_DATA_SERVICE_URL");
+            }
+            return true;
+        }  else if (preference == mButtonEnabledNetworks) {
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                    getContext().getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
+                    preferredNetworkMode);
+            mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
+            return true;
+        } else if (preference == mButtonDataRoam) {
+            // Do not disable the preference screen if the user clicks Data roaming.
+            return true;
+        } else if (preference == mEuiccSettingsPref) {
+            Intent intent = new Intent(EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS);
+            startActivity(intent);
+            return true;
+        } else if (preference == mWiFiCallingPref || preference == mVideoCallingPref
+                || preference == mMobileDataPref || preference == mDataUsagePref) {
+            return false;
+        } else if (preference == mAdvancedOptions) {
+            mExpandAdvancedFields = true;
+            updateBody();
+            return true;
+        } else {
+            // if the button is anything but the simple toggle preference,
+            // we'll need to disable all preferences to reject all click
+            // events until the sub-activity's UI comes up.
+            preferenceScreen.setEnabled(false);
+            // Let the intents be launched by the Preference manager
+            return false;
+        }
+    }
+
+    private final SubscriptionManager.OnSubscriptionsChangedListener
+            mOnSubscriptionsChangeListener
+            = new SubscriptionManager.OnSubscriptionsChangedListener() {
+        @Override
+        public void onSubscriptionsChanged() {
+            if (DBG) log("onSubscriptionsChanged:");
+            initializeSubscriptions();
+        }
+    };
+
+    private int getSlotIdFromIntent(Intent intent) {
+        Bundle data = intent.getExtras();
+        int subId = -1;
+        if (data != null) {
+            subId = data.getInt(Settings.EXTRA_SUB_ID, -1);
+        }
+        return SubscriptionManager.getSlotIndex(subId);
+    }
+
+    private void initializeSubscriptions() {
+        final Activity activity = getActivity();
+        if (activity == null || activity.isDestroyed()) {
+            // Process preferences in activity only if its not destroyed
+            return;
+        }
+        int currentTab = 0;
+        if (DBG) log("initializeSubscriptions:+");
+
+        // Before updating the the active subscription list check
+        // if tab updating is needed as the list is changing.
+        List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
+        MobileNetworkSettings.TabState state = isUpdateTabsNeeded(sil);
+
+        // Update to the active subscription list
+        mActiveSubInfos.clear();
+        if (sil != null) {
+            mActiveSubInfos.addAll(sil);
+            // If there is only 1 sim then currenTab should represent slot no. of the sim.
+            if (sil.size() == 1) {
+                currentTab = sil.get(0).getSimSlotIndex();
+            }
+        }
+
+        switch (state) {
+            case UPDATE: {
+                if (DBG) log("initializeSubscriptions: UPDATE");
+                currentTab = mTabHost != null ? mTabHost.getCurrentTab() : 0;
+
+                mTabHost = (TabHost) getActivity().findViewById(android.R.id.tabhost);
+                mTabHost.setup();
+
+                // Update the tabName. Since the mActiveSubInfos are in slot order
+                // we can iterate though the tabs and subscription info in one loop. But
+                // we need to handle the case where a slot may be empty.
+
+                Iterator<SubscriptionInfo> siIterator = mActiveSubInfos.listIterator();
+                SubscriptionInfo si = siIterator.hasNext() ? siIterator.next() : null;
+                for (int simSlotIndex = 0; simSlotIndex  < mActiveSubInfos.size();
+                        simSlotIndex++) {
+                    String tabName;
+                    if (si != null && si.getSimSlotIndex() == simSlotIndex) {
+                        // Slot is not empty and we match
+                        tabName = String.valueOf(si.getDisplayName());
+                        si = siIterator.hasNext() ? siIterator.next() : null;
+                    } else {
+                        // Slot is empty, set name to unknown
+                        tabName = getResources().getString(R.string.unknown);
+                    }
+                    if (DBG) {
+                        log("initializeSubscriptions:tab=" + simSlotIndex + " name=" + tabName);
+                    }
+
+                    mTabHost.addTab(buildTabSpec(String.valueOf(simSlotIndex), tabName));
+                }
+
+                mTabHost.setOnTabChangedListener(mTabListener);
+                mTabHost.setCurrentTab(currentTab);
+                break;
+            }
+            case NO_TABS: {
+                if (DBG) log("initializeSubscriptions: NO_TABS");
+
+                if (mTabHost != null) {
+                    mTabHost.clearAllTabs();
+                    mTabHost = null;
+                }
+                break;
+            }
+            case DO_NOTHING: {
+                if (DBG) log("initializeSubscriptions: DO_NOTHING");
+                if (mTabHost != null) {
+                    currentTab = mTabHost.getCurrentTab();
+                }
+                break;
+            }
+        }
+        updatePhone(currentTab);
+        updateBody();
+        if (DBG) log("initializeSubscriptions:-");
+    }
+
+    private MobileNetworkSettings.TabState isUpdateTabsNeeded(List<SubscriptionInfo> newSil) {
+        MobileNetworkSettings.TabState state = MobileNetworkSettings.TabState.DO_NOTHING;
+        if (newSil == null) {
+            if (mActiveSubInfos.size() >= TAB_THRESHOLD) {
+                if (DBG) log("isUpdateTabsNeeded: NO_TABS, size unknown and was tabbed");
+                state = MobileNetworkSettings.TabState.NO_TABS;
+            }
+        } else if (newSil.size() < TAB_THRESHOLD && mActiveSubInfos.size() >= TAB_THRESHOLD) {
+            if (DBG) log("isUpdateTabsNeeded: NO_TABS, size went to small");
+            state = MobileNetworkSettings.TabState.NO_TABS;
+        } else if (newSil.size() >= TAB_THRESHOLD && mActiveSubInfos.size() < TAB_THRESHOLD) {
+            if (DBG) log("isUpdateTabsNeeded: UPDATE, size changed");
+            state = MobileNetworkSettings.TabState.UPDATE;
+        } else if (newSil.size() >= TAB_THRESHOLD) {
+            Iterator<SubscriptionInfo> siIterator = mActiveSubInfos.iterator();
+            for(SubscriptionInfo newSi : newSil) {
+                SubscriptionInfo curSi = siIterator.next();
+                if (!newSi.getDisplayName().equals(curSi.getDisplayName())) {
+                    if (DBG) log("isUpdateTabsNeeded: UPDATE, new name="
+                            + newSi.getDisplayName());
+                    state = MobileNetworkSettings.TabState.UPDATE;
+                    break;
+                }
+            }
+        }
+        if (DBG) {
+            Log.i(LOG_TAG, "isUpdateTabsNeeded:- " + state
+                    + " newSil.size()=" + ((newSil != null) ? newSil.size() : 0)
+                    + " mActiveSubInfos.size()=" + mActiveSubInfos.size());
+        }
+        return state;
+    }
+
+    private TabHost.OnTabChangeListener mTabListener = new TabHost.OnTabChangeListener() {
+        @Override
+        public void onTabChanged(String tabId) {
+            if (DBG) log("onTabChanged:");
+            // The User has changed tab; update the body.
+            updatePhone(Integer.parseInt(tabId));
+            updateBody();
+        }
+    };
+
+    private void updatePhone(int slotId) {
+        final SubscriptionInfo sir = mSubscriptionManager
+                .getActiveSubscriptionInfoForSimSlotIndex(slotId);
+
+        if (sir != null) {
+            mSubId = sir.getSubscriptionId();
+
+            Log.i(LOG_TAG, "updatePhone:- slotId=" + slotId + " sir=" + sir);
+
+            mImsMgr = ImsManager.getInstance(getContext(),
+                    SubscriptionManager.getPhoneId(mSubId));
+            mTelephonyManager = new TelephonyManager(getContext(), mSubId);
+            if (mImsMgr == null) {
+                log("updatePhone :: Could not get ImsManager instance!");
+            } else if (DBG) {
+                log("updatePhone :: mImsMgr=" + mImsMgr);
+            }
+        } else {
+            // There is no active subscription in the given slot.
+            mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        }
+
+        mPhoneStateListener.updateSubscriptionId(mSubId);
+    }
+
+    private TabHost.TabContentFactory mEmptyTabContent = new TabHost.TabContentFactory() {
+        @Override
+        public View createTabContent(String tag) {
+            return new View(mTabHost.getContext());
+        }
+    };
+
+    private TabHost.TabSpec buildTabSpec(String tag, String title) {
+        return mTabHost.newTabSpec(tag).setIndicator(title).setContent(
+                mEmptyTabContent);
+    }
+
+    private void updateCurrentTab(Intent intent) {
+        int slotId = getSlotIdFromIntent(intent);
+        if (slotId >= 0 && mTabHost != null && mTabHost.getCurrentTab() != slotId) {
+            mTabHost.setCurrentTab(slotId);
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        // If advanced fields are already expanded, we save it and expand it
+        // when it's re-created.
+        outState.putBoolean(EXPAND_ADVANCED_FIELDS, mExpandAdvancedFields);
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        Log.i(LOG_TAG, "onCreate:+");
+        super.onCreate(icicle);
+
+        final Activity activity = getActivity();
+        if (activity == null || activity.isDestroyed()) {
+            Log.e(LOG_TAG, "onCreate:- with no valid activity.");
+            return;
+        }
+
+        mHandler = new MobileNetworkSettings.MobileNetworkFragment.MyHandler();
+        mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
+        mSubscriptionManager = SubscriptionManager.from(activity);
+        mTelephonyManager = (TelephonyManager) activity.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        mCarrierConfigManager = new CarrierConfigManager(getContext());
+
+        if (icicle != null) {
+            mExpandAdvancedFields = icicle.getBoolean(EXPAND_ADVANCED_FIELDS, false);
+        } else if (getActivity().getIntent().getBooleanExtra(EXPAND_EXTRA, false)) {
+            mExpandAdvancedFields = true;
+        }
+
+        addPreferencesFromResource(R.xml.network_setting_fragment);
+
+        mButton4glte = (SwitchPreference)findPreference(BUTTON_4G_LTE_KEY);
+        mButton4glte.setOnPreferenceChangeListener(this);
+
+        mCallingCategory = (PreferenceCategory) findPreference(CATEGORY_CALLING_KEY);
+        mWiFiCallingPref = findPreference(BUTTON_WIFI_CALLING_KEY);
+        mVideoCallingPref = (SwitchPreference) findPreference(BUTTON_VIDEO_CALLING_KEY);
+        mMobileDataPref = (MobileDataPreference) findPreference(BUTTON_MOBILE_DATA_ENABLE_KEY);
+        mDataUsagePref = (DataUsagePreference) findPreference(BUTTON_DATA_USAGE_KEY);
+
+        try {
+            Context con = activity.createPackageContext("com.android.systemui", 0);
+            int id = con.getResources().getIdentifier("config_show4GForLTE",
+                    "bool", "com.android.systemui");
+            mShow4GForLTE = con.getResources().getBoolean(id);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(LOG_TAG, "NameNotFoundException for show4GFotLTE");
+            mShow4GForLTE = false;
+        }
+
+        //get UI object references
+        PreferenceScreen prefSet = getPreferenceScreen();
+
+        mButtonDataRoam = (RestrictedSwitchPreference) prefSet.findPreference(
+                BUTTON_ROAMING_KEY);
+        mButtonPreferredNetworkMode = (ListPreference) prefSet.findPreference(
+                BUTTON_PREFERED_NETWORK_MODE);
+        mButtonEnabledNetworks = (ListPreference) prefSet.findPreference(
+                BUTTON_ENABLED_NETWORKS_KEY);
+        mAdvancedOptions = (AdvancedOptionsPreference) prefSet.findPreference(
+                BUTTON_ADVANCED_OPTIONS_KEY);
+        mButtonDataRoam.setOnPreferenceChangeListener(this);
+
+        mLteDataServicePref = prefSet.findPreference(BUTTON_CDMA_LTE_DATA_SERVICE_KEY);
+
+        mEuiccSettingsPref = prefSet.findPreference(BUTTON_CARRIER_SETTINGS_EUICC_KEY);
+        mEuiccSettingsPref.setOnPreferenceChangeListener(this);
+
+        // Initialize mActiveSubInfo
+        int max = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
+        mActiveSubInfos = new ArrayList<SubscriptionInfo>(max);
+
+        int currentTab = mTabHost != null ? mTabHost.getCurrentTab() : 0;
+        updatePhone(currentTab);
+        if (hasActiveSubscriptions()) {
+            updateEnabledNetworksEntries();
+        }
+        Log.i(LOG_TAG, "onCreate:-");
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(com.android.internal.R.layout.common_tab_settings,
+                container, false);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)
+                || !mUm.isSystemUser()) {
+            mUnavailable = true;
+            getActivity().setContentView(R.layout.telephony_disallowed_preference_screen);
+        } else {
+            initializeSubscriptions();
+            updateCurrentTab(getActivity().getIntent());
+        }
+    }
+
+    private class PhoneChangeReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.i(LOG_TAG, "onReceive:");
+            if (getActivity() == null || getContext() == null) {
+                // Received broadcast and activity is in the process of being torn down.
+                return;
+            }
+            // When the radio changes (ex: CDMA->GSM), refresh all options.
+            updateBody();
+        }
+    }
+
+    private class DpcApnEnforcedObserver extends ContentObserver {
+        DpcApnEnforcedObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            Log.i(LOG_TAG, "DPC enforced onChange:");
+            if (getActivity() == null || getContext() == null) {
+                // Received content change and activity is in the process of being torn down.
+                return;
+            }
+            updateBody();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mMobileDataPref != null) {
+            mMobileDataPref.dispose();
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        Log.i(LOG_TAG, "onResume:+");
+
+        if (mUnavailable) {
+            Log.i(LOG_TAG, "onResume:- ignore mUnavailable == false");
+            return;
+        }
+
+        // upon resumption from the sub-activity, make sure we re-enable the
+        // preferences.
+        getPreferenceScreen().setEnabled(true);
+
+        // Set UI state in onResume because a user could go home, launch some
+        // app to change this setting's backend, and re-launch this settings app
+        // and the UI state would be inconsistent with actual state
+        mButtonDataRoam.setChecked(mTelephonyManager.isDataRoamingEnabled());
+
+        if (getPreferenceScreen().findPreference(BUTTON_PREFERED_NETWORK_MODE) != null
+                || getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null)  {
+            updatePreferredNetworkUIFromDb();
+        }
+
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+        // NOTE: Buttons will be enabled/disabled in mPhoneStateListener
+        updateEnhanced4gLteState();
+
+        // Video calling and WiFi calling state might have changed.
+        updateCallingCategory();
+
+        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
+
+        final Context context = getActivity();
+        IntentFilter intentFilter = new IntentFilter(
+                TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+        context.registerReceiver(mPhoneChangeReceiver, intentFilter);
+        context.getContentResolver().registerContentObserver(ENFORCE_MANAGED_URI, false,
+                mDpcEnforcedContentObserver);
+
+        Log.i(LOG_TAG, "onResume:-");
+
+    }
+
+    private boolean hasActiveSubscriptions() {
+        return mActiveSubInfos.size() > 0;
+    }
+
+    private void updateBodyBasicFields(Activity activity, PreferenceScreen prefSet,
+            int phoneSubId, boolean hasActiveSubscriptions) {
+        Context context = activity.getApplicationContext();
+
+        ActionBar actionBar = activity.getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+
+        prefSet.addPreference(mMobileDataPref);
+        prefSet.addPreference(mButtonDataRoam);
+        prefSet.addPreference(mDataUsagePref);
+
+        mMobileDataPref.setEnabled(hasActiveSubscriptions);
+        mButtonDataRoam.setEnabled(hasActiveSubscriptions);
+        mDataUsagePref.setEnabled(hasActiveSubscriptions);
+
+        if (hasActiveSubscriptions) {
+            // Customized preferences needs to be initialized with subId.
+            mMobileDataPref.initialize(phoneSubId);
+            mDataUsagePref.initialize(phoneSubId);
+
+            // Initialize states of mButtonDataRoam.
+            mButtonDataRoam.setChecked(mTelephonyManager.isDataRoamingEnabled());
+            mButtonDataRoam.setDisabledByAdmin(false);
+            if (mButtonDataRoam.isEnabled()) {
+                if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
+                        UserManager.DISALLOW_DATA_ROAMING, UserHandle.myUserId())) {
+                    mButtonDataRoam.setEnabled(false);
+                } else {
+                    mButtonDataRoam.checkRestrictionAndSetDisabled(
+                            UserManager.DISALLOW_DATA_ROAMING);
+                }
+            }
+        }
+    }
+
+    private void updateBody() {
+        final Activity activity = getActivity();
+        final PreferenceScreen prefSet = getPreferenceScreen();
+        final boolean hasActiveSubscriptions = hasActiveSubscriptions();
+
+        if (activity == null || activity.isDestroyed()) {
+            Log.e(LOG_TAG, "updateBody with no valid activity.");
+            return;
+        }
+
+        if (prefSet == null) {
+            Log.e(LOG_TAG, "updateBody with no null prefSet.");
+            return;
+        }
+
+        prefSet.removeAll();
+
+        updateBodyBasicFields(activity, prefSet, mSubId, hasActiveSubscriptions);
+
+        if (hasActiveSubscriptions) {
+            if (mExpandAdvancedFields) {
+                updateBodyAdvancedFields(activity, prefSet, mSubId, hasActiveSubscriptions);
+            } else {
+                prefSet.addPreference(mAdvancedOptions);
+            }
+        } else {
+            // Shows the "Carrier" preference that allows user to add a e-sim profile.
+            if (showEuiccSettings(getContext())) {
+                mEuiccSettingsPref.setSummary(null /* summary */);
+                prefSet.addPreference(mEuiccSettingsPref);
+            }
+        }
+    }
+
+    private void updateBodyAdvancedFields(Activity activity, PreferenceScreen prefSet,
+            int phoneSubId, boolean hasActiveSubscriptions) {
+        boolean isLteOnCdma = mTelephonyManager.getLteOnCdmaMode()
+                == PhoneConstants.LTE_ON_CDMA_TRUE;
+
+        if (DBG) {
+            log("updateBody: isLteOnCdma=" + isLteOnCdma + " phoneSubId=" + phoneSubId);
+        }
+
+        prefSet.addPreference(mButtonPreferredNetworkMode);
+        prefSet.addPreference(mButtonEnabledNetworks);
+        prefSet.addPreference(mButton4glte);
+
+        if (showEuiccSettings(getActivity())) {
+            prefSet.addPreference(mEuiccSettingsPref);
+            String spn = mTelephonyManager.getSimOperatorName();
+            if (TextUtils.isEmpty(spn)) {
+                mEuiccSettingsPref.setSummary(null);
+            } else {
+                mEuiccSettingsPref.setSummary(spn);
+            }
+        }
+
+        int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                getContext().getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                preferredNetworkMode);
+
+        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+        mIsGlobalCdma = isLteOnCdma
+                && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
+        if (carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)) {
+            prefSet.removePreference(mButtonPreferredNetworkMode);
+            prefSet.removePreference(mButtonEnabledNetworks);
+            prefSet.removePreference(mLteDataServicePref);
+        } else if (carrierConfig.getBoolean(CarrierConfigManager
+                .KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)
+                && !mTelephonyManager.getServiceState().getRoaming()
+                && mTelephonyManager.getServiceState().getDataRegState()
+                == ServiceState.STATE_IN_SERVICE) {
+            prefSet.removePreference(mButtonPreferredNetworkMode);
+            prefSet.removePreference(mButtonEnabledNetworks);
+
+            final int phoneType = mTelephonyManager.getPhoneType();
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                updateCdmaOptions(this, prefSet, mSubId);
+            } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                updateGsmUmtsOptions(this, prefSet, phoneSubId);
+            } else {
+                throw new IllegalStateException("Unexpected phone type: " + phoneType);
+            }
+            // Since pref is being hidden from user, set network mode to default
+            // in case it is currently something else. That is possible if user
+            // changed the setting while roaming and is now back to home network.
+            settingsNetworkMode = preferredNetworkMode;
+        } else if (carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_WORLD_PHONE_BOOL) == true) {
+            prefSet.removePreference(mButtonEnabledNetworks);
+            // set the listener for the mButtonPreferredNetworkMode list preference so we can issue
+            // change Preferred Network Mode.
+            mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
+
+            updateCdmaOptions(this, prefSet, mSubId);
+            updateGsmUmtsOptions(this, prefSet, phoneSubId);
+        } else {
+            prefSet.removePreference(mButtonPreferredNetworkMode);
+            updateEnabledNetworksEntries();
+            mButtonEnabledNetworks.setOnPreferenceChangeListener(this);
+            if (DBG) log("settingsNetworkMode: " + settingsNetworkMode);
+        }
+
+        final boolean missingDataServiceUrl = TextUtils.isEmpty(
+                android.provider.Settings.Global.getString(activity.getContentResolver(),
+                        android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL));
+        if (!isLteOnCdma || missingDataServiceUrl) {
+            prefSet.removePreference(mLteDataServicePref);
+        } else {
+            android.util.Log.d(LOG_TAG, "keep ltePref");
+        }
+
+        updateEnhanced4gLteState();
+        updatePreferredNetworkType();
+        updateCallingCategory();
+
+        // Enable link to CMAS app settings depending on the value in config.xml.
+        final boolean isCellBroadcastAppLinkEnabled = activity.getResources().getBoolean(
+                com.android.internal.R.bool.config_cellBroadcastAppLinks);
+        if (!mUm.isAdminUser() || !isCellBroadcastAppLinkEnabled
+                || mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS)) {
+            PreferenceScreen root = getPreferenceScreen();
+            Preference ps = findPreference(BUTTON_CELL_BROADCAST_SETTINGS);
+            if (ps != null) {
+                root.removePreference(ps);
+            }
+        }
+
+        /**
+         * Listen to extra preference changes that need as Metrics events logging.
+         */
+        if (prefSet.findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY) != null) {
+            prefSet.findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY)
+                    .setOnPreferenceChangeListener(this);
+        }
+
+        if (prefSet.findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY) != null) {
+            prefSet.findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY)
+                    .setOnPreferenceChangeListener(this);
+        }
+
+        // Get the networkMode from Settings.System and displays it
+        mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
+        mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
+        UpdatePreferredNetworkModeSummary(settingsNetworkMode);
+        UpdateEnabledNetworksValueAndSummary(settingsNetworkMode);
+        // Display preferred network type based on what modem returns b/18676277
+        new MobileNetworkSettings.SetPreferredNetworkAsyncTask(
+                mTelephonyManager,
+                mSubId,
+                settingsNetworkMode,
+                mHandler.obtainMessage(MobileNetworkSettings.MobileNetworkFragment.MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+                .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+
+        /**
+         * Enable/disable depending upon if there are any active subscriptions.
+         *
+         * I've decided to put this enable/disable code at the bottom as the
+         * code above works even when there are no active subscriptions, thus
+         * putting it afterwards is a smaller change. This can be refined later,
+         * but you do need to remember that this all needs to work when subscriptions
+         * change dynamically such as when hot swapping sims.
+         */
+        boolean useVariant4glteTitle = carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL);
+        int enhanced4glteModeTitleId = useVariant4glteTitle ?
+                R.string.enhanced_4g_lte_mode_title_variant :
+                R.string.enhanced_4g_lte_mode_title;
+
+        mOnlyAutoSelectInHomeNW = carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL);
+        mButton4glte.setTitle(enhanced4glteModeTitleId);
+        mLteDataServicePref.setEnabled(hasActiveSubscriptions);
+        Preference ps;
+        ps = findPreference(BUTTON_CELL_BROADCAST_SETTINGS);
+        if (ps != null) {
+            ps.setEnabled(hasActiveSubscriptions);
+        }
+        ps = findPreference(CATEGORY_GSM_APN_EXPAND_KEY);
+        if (ps != null) {
+            ps.setEnabled(hasActiveSubscriptions);
+        }
+        ps = findPreference(CATEGORY_CDMA_APN_EXPAND_KEY);
+        if (ps != null) {
+            ps.setEnabled(hasActiveSubscriptions);
+        }
+        ps = findPreference(com.android.phone.NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
+        if (ps != null) {
+            ps.setEnabled(hasActiveSubscriptions);
+        }
+        ps = findPreference(BUTTON_CARRIER_SETTINGS_KEY);
+        if (ps != null) {
+            ps.setEnabled(hasActiveSubscriptions);
+        }
+        ps = findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY);
+        if (ps != null) {
+            ps.setEnabled(hasActiveSubscriptions);
+        }
+        ps = findPreference(CATEGORY_CALLING_KEY);
+        if (ps != null) {
+            ps.setEnabled(hasActiveSubscriptions);
+        }
+        ps = findPreference(com.android.phone.NetworkOperators.BUTTON_AUTO_SELECT_KEY);
+        if (ps != null) {
+            ps.setSummary(null);
+            if (mTelephonyManager.getServiceState().getRoaming()) {
+                ps.setEnabled(true);
+            } else {
+                ps.setEnabled(!mOnlyAutoSelectInHomeNW);
+                if (mOnlyAutoSelectInHomeNW) {
+                    ps.setSummary(getResources().getString(
+                            R.string.manual_mode_disallowed_summary,
+                            mTelephonyManager.getSimOperatorName()));
+                }
+            }
+        }
+    }
+
+    // Requires that mSubId is up to date
+    void updateEnabledNetworksEntries() {
+        final int phoneType = mTelephonyManager.getPhoneType();
+        final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            final int lteForced = android.provider.Settings.Global.getInt(
+                    getContext().getContentResolver(),
+                    android.provider.Settings.Global.LTE_SERVICE_FORCED + mSubId,
+                    0);
+            final boolean isLteOnCdma = mTelephonyManager.getLteOnCdmaMode()
+                    == PhoneConstants.LTE_ON_CDMA_TRUE;
+            final int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                    getContext().getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
+                    preferredNetworkMode);
+            if (isLteOnCdma) {
+                if (lteForced == 0) {
+                    mButtonEnabledNetworks.setEntries(
+                            R.array.enabled_networks_cdma_choices);
+                    mButtonEnabledNetworks.setEntryValues(
+                            R.array.enabled_networks_cdma_values);
+                } else {
+                    switch (settingsNetworkMode) {
+                        case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                        case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                        case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
+                            mButtonEnabledNetworks.setEntries(
+                                    R.array.enabled_networks_cdma_no_lte_choices);
+                            mButtonEnabledNetworks.setEntryValues(
+                                    R.array.enabled_networks_cdma_no_lte_values);
+                            break;
+                        case TelephonyManager.NETWORK_MODE_GLOBAL:
+                        case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                        case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_ONLY:
+                            mButtonEnabledNetworks.setEntries(
+                                    R.array.enabled_networks_cdma_only_lte_choices);
+                            mButtonEnabledNetworks.setEntryValues(
+                                    R.array.enabled_networks_cdma_only_lte_values);
+                            break;
+                        default:
+                            mButtonEnabledNetworks.setEntries(
+                                    R.array.enabled_networks_cdma_choices);
+                            mButtonEnabledNetworks.setEntryValues(
+                                    R.array.enabled_networks_cdma_values);
+                            break;
+                    }
+                }
+            }
+            updateCdmaOptions(this, getPreferenceScreen(), mSubId);
+
+        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+            if (isSupportTdscdma()) {
+                mButtonEnabledNetworks.setEntries(
+                        R.array.enabled_networks_tdscdma_choices);
+                mButtonEnabledNetworks.setEntryValues(
+                        R.array.enabled_networks_tdscdma_values);
+            } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
+                    && !getResources().getBoolean(R.bool.config_enabled_lte)) {
+                mButtonEnabledNetworks.setEntries(
+                        R.array.enabled_networks_except_gsm_lte_choices);
+                mButtonEnabledNetworks.setEntryValues(
+                        R.array.enabled_networks_except_gsm_lte_values);
+            } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
+                int select = mShow4GForLTE
+                        ? R.array.enabled_networks_except_gsm_4g_choices
+                        : R.array.enabled_networks_except_gsm_choices;
+                mButtonEnabledNetworks.setEntries(select);
+                mButtonEnabledNetworks.setEntryValues(
+                        R.array.enabled_networks_except_gsm_values);
+            } else if (!getResources().getBoolean(R.bool.config_enabled_lte)) {
+                mButtonEnabledNetworks.setEntries(
+                        R.array.enabled_networks_except_lte_choices);
+                mButtonEnabledNetworks.setEntryValues(
+                        R.array.enabled_networks_except_lte_values);
+            } else if (mIsGlobalCdma) {
+                mButtonEnabledNetworks.setEntries(
+                        R.array.enabled_networks_cdma_choices);
+                mButtonEnabledNetworks.setEntryValues(
+                        R.array.enabled_networks_cdma_values);
+            } else {
+                int select = mShow4GForLTE ? R.array.enabled_networks_4g_choices
+                        : R.array.enabled_networks_choices;
+                mButtonEnabledNetworks.setEntries(select);
+                mButtonEnabledNetworks.setEntryValues(
+                        R.array.enabled_networks_values);
+            }
+            updateGsmUmtsOptions(this, getPreferenceScreen(), mSubId);
+        } else {
+            throw new IllegalStateException("Unexpected phone type: " + phoneType);
+        }
+        if (isWorldMode()) {
+            mButtonEnabledNetworks.setEntries(
+                    R.array.preferred_network_mode_choices_world_mode);
+            mButtonEnabledNetworks.setEntryValues(
+                    R.array.preferred_network_mode_values_world_mode);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        if (DBG) log("onPause:+");
+
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+
+        mSubscriptionManager
+                .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
+
+        final Context context = getActivity();
+        context.unregisterReceiver(mPhoneChangeReceiver);
+        context.getContentResolver().unregisterContentObserver(mDpcEnforcedContentObserver);
+        if (DBG) log("onPause:-");
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference
+     * changes specifically on CLIR.
+     *
+     * @param preference is the preference to be changed, should be mButtonCLIR.
+     * @param objValue should be the value of the selection, NOT its localized
+     * display value.
+     */
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        sendMetricsEventPreferenceChanged(getPreferenceScreen(), preference, objValue);
+
+        final int phoneSubId = mSubId;
+        if (preference == mButtonPreferredNetworkMode) {
+            //NOTE onPreferenceChange seems to be called even if there is no change
+            //Check if the button value is changed from the System.Setting
+            mButtonPreferredNetworkMode.setValue((String) objValue);
+            int buttonNetworkMode;
+            buttonNetworkMode = Integer.parseInt((String) objValue);
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                    getContext().getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                    preferredNetworkMode);
+            if (buttonNetworkMode != settingsNetworkMode) {
+                int modemNetworkMode;
+                // if new mode is invalid ignore it
+                switch (buttonNetworkMode) {
+                    case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
+                    case TelephonyManager.NETWORK_MODE_GSM_ONLY:
+                    case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
+                    case TelephonyManager.NETWORK_MODE_GSM_UMTS:
+                    case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                    case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                    case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
+                    case TelephonyManager.NETWORK_MODE_GLOBAL:
+                    case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                    case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_ONLY:
+                    case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                        // This is one of the modes we recognize
+                        modemNetworkMode = buttonNetworkMode;
+                        break;
+                    default:
+                        loge("Invalid Network Mode (" +buttonNetworkMode+ ") chosen. Ignore.");
+                        return true;
+                }
+
+                android.provider.Settings.Global.putInt(
+                        getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                        buttonNetworkMode );
+                //Set the modem network mode
+                new MobileNetworkSettings.SetPreferredNetworkAsyncTask(
+                        mTelephonyManager,
+                        mSubId,
+                        modemNetworkMode,
+                        mHandler.obtainMessage(MobileNetworkSettings.MobileNetworkFragment.MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+                        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+            }
+        } else if (preference == mButtonEnabledNetworks) {
+            mButtonEnabledNetworks.setValue((String) objValue);
+            int buttonNetworkMode;
+            buttonNetworkMode = Integer.parseInt((String) objValue);
+            if (DBG) log("buttonNetworkMode: " + buttonNetworkMode);
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                    getContext().getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                    preferredNetworkMode);
+            if (buttonNetworkMode != settingsNetworkMode) {
+                int modemNetworkMode;
+                // if new mode is invalid ignore it
+                switch (buttonNetworkMode) {
+                    case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
+                    case TelephonyManager.NETWORK_MODE_GSM_ONLY:
+                    case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                    case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                    case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                    case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                        // This is one of the modes we recognize
+                        modemNetworkMode = buttonNetworkMode;
+                        break;
+                    default:
+                        loge("Invalid Network Mode (" +buttonNetworkMode+ ") chosen. Ignore.");
+                        return true;
+                }
+
+                UpdateEnabledNetworksValueAndSummary(buttonNetworkMode);
+
+                android.provider.Settings.Global.putInt(
+                        getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                        buttonNetworkMode );
+                //Set the modem network mode
+                new MobileNetworkSettings.SetPreferredNetworkAsyncTask(
+                        mTelephonyManager,
+                        mSubId,
+                        modemNetworkMode,
+                        mHandler.obtainMessage(MobileNetworkSettings.MobileNetworkFragment.MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE))
+                        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+            }
+        } else if (preference == mButton4glte) {
+            boolean enhanced4gMode = !mButton4glte.isChecked();
+            mButton4glte.setChecked(enhanced4gMode);
+            mImsMgr.setEnhanced4gLteModeSetting(mButton4glte.isChecked());
+        } else if (preference == mButtonDataRoam) {
+            if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam.");
+
+            //normally called on the toggle click
+            if (!mButtonDataRoam.isChecked()) {
+                PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(
+                        mSubId);
+                if (carrierConfig != null && carrierConfig.getBoolean(
+                        CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL)) {
+                    mTelephonyManager.setDataRoamingEnabled(true);
+                    MetricsLogger.action(getContext(),
+                            getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
+                            true);
+                } else {
+                    // MetricsEvent with no value update.
+                    MetricsLogger.action(getContext(),
+                            getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam));
+                    // First confirm with a warning dialog about charges
+                    mOkClicked = false;
+                    com.android.phone.RoamingDialogFragment
+                            fragment = new com.android.phone.RoamingDialogFragment();
+                    Bundle b = new Bundle();
+                    b.putInt(RoamingDialogFragment.SUB_ID_KEY, mSubId);
+                    fragment.setArguments(b);
+                    fragment.show(getFragmentManager(), ROAMING_TAG);
+                    // Don't update the toggle unless the confirm button is actually pressed.
+                    return false;
+                }
+            } else {
+                mTelephonyManager.setDataRoamingEnabled(false);
+                MetricsLogger.action(getContext(),
+                        getMetricsEventCategory(getPreferenceScreen(), mButtonDataRoam),
+                        false);
+                return true;
+            }
+        } else if (preference == mVideoCallingPref) {
+            // If mButton4glte is not checked, mVideoCallingPref should be disabled.
+            // So it only makes sense to call phoneMgr.enableVideoCalling if it's checked.
+            if (mButton4glte.isChecked()) {
+                mImsMgr.setVtSetting((boolean) objValue);
+                return true;
+            } else {
+                loge("mVideoCallingPref should be disabled if mButton4glte is not checked.");
+                mVideoCallingPref.setEnabled(false);
+                return false;
+            }
+        } else if (preference == getPreferenceScreen()
+                .findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY)
+                || preference == getPreferenceScreen()
+                .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
+            return true;
+        }
+
+        updateBody();
+        // always let the preference setting proceed.
+        return true;
+    }
+
+    private boolean is4gLtePrefEnabled(PersistableBundle carrierConfig) {
+        return (mTelephonyManager.getCallState(mSubId)
+                == TelephonyManager.CALL_STATE_IDLE)
+                && mImsMgr != null
+                && mImsMgr.isNonTtyOrTtyOnVolteEnabled()
+                && carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL);
+    }
+
+    private class MyHandler extends Handler {
+
+        static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 0;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
+                    handleSetPreferredNetworkTypeResponse(msg);
+                    break;
+            }
+        }
+
+        private void handleSetPreferredNetworkTypeResponse(Message msg) {
+            final Activity activity = getActivity();
+            if (activity == null || activity.isDestroyed()) {
+                // Access preferences of activity only if it is not destroyed
+                // or if fragment is not attached to an activity.
+                return;
+            }
+
+            boolean success = (boolean) msg.obj;
+
+            if (success) {
+                int networkMode;
+                if (getPreferenceScreen().findPreference(
+                        BUTTON_PREFERED_NETWORK_MODE) != null)  {
+                    networkMode =  Integer.parseInt(mButtonPreferredNetworkMode.getValue());
+                    android.provider.Settings.Global.putInt(
+                            getContext().getContentResolver(),
+                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE
+                                    + mSubId,
+                            networkMode );
+                }
+                if (getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null) {
+                    networkMode = Integer.parseInt(mButtonEnabledNetworks.getValue());
+                    android.provider.Settings.Global.putInt(
+                            getContext().getContentResolver(),
+                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE
+                                    + mSubId,
+                            networkMode );
+                }
+            } else {
+                Log.i(LOG_TAG, "handleSetPreferredNetworkTypeResponse:" +
+                        "exception in setting network mode.");
+                updatePreferredNetworkUIFromDb();
+            }
+        }
+    }
+
+    private void updatePreferredNetworkUIFromDb() {
+        int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                getContext().getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mSubId,
+                preferredNetworkMode);
+
+        if (DBG) {
+            log("updatePreferredNetworkUIFromDb: settingsNetworkMode = " +
+                    settingsNetworkMode);
+        }
+
+        UpdatePreferredNetworkModeSummary(settingsNetworkMode);
+        UpdateEnabledNetworksValueAndSummary(settingsNetworkMode);
+        // changes the mButtonPreferredNetworkMode accordingly to settingsNetworkMode
+        mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
+    }
+
+    private void UpdatePreferredNetworkModeSummary(int NetworkMode) {
+        switch(NetworkMode) {
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_tdscdma_gsm_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_tdscdma_gsm_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_wcdma_perf_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_GSM_ONLY:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_gsm_only_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_tdscdma_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_wcdma_only_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_GSM_UMTS:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_gsm_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                switch (mTelephonyManager.getLteOnCdmaMode()) {
+                    case PhoneConstants.LTE_ON_CDMA_TRUE:
+                        mButtonPreferredNetworkMode.setSummary(
+                                R.string.preferred_network_mode_cdma_summary);
+                        break;
+                    case PhoneConstants.LTE_ON_CDMA_FALSE:
+                    default:
+                        mButtonPreferredNetworkMode.setSummary(
+                                R.string.preferred_network_mode_cdma_evdo_summary);
+                        break;
+                }
+                break;
+            case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_cdma_only_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_evdo_only_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_tdscdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_ONLY:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_tdscdma_gsm_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_tdscdma_gsm_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_gsm_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_cdma_evdo_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_tdscdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+                        || mIsGlobalCdma
+                        || isWorldMode()) {
+                    mButtonPreferredNetworkMode.setSummary(
+                            R.string.preferred_network_mode_global_summary);
+                } else {
+                    mButtonPreferredNetworkMode.setSummary(
+                            R.string.preferred_network_mode_lte_summary);
+                }
+                break;
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_tdscdma_cdma_evdo_gsm_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_GLOBAL:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_cdma_evdo_gsm_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_tdscdma_wcdma_summary);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_wcdma_summary);
+                break;
+            default:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_global_summary);
+        }
+    }
+
+    private void UpdateEnabledNetworksValueAndSummary(int NetworkMode) {
+        switch (NetworkMode) {
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
+                mButtonEnabledNetworks.setValue(
+                        Integer.toString(TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA));
+                mButtonEnabledNetworks.setSummary(R.string.network_3G);
+                break;
+            case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
+            case TelephonyManager.NETWORK_MODE_GSM_UMTS:
+            case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
+                if (!mIsGlobalCdma) {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager.NETWORK_MODE_WCDMA_PREF));
+                    mButtonEnabledNetworks.setSummary(R.string.network_3G);
+                } else {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager
+                                    .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                    mButtonEnabledNetworks.setSummary(R.string.network_global);
+                }
+                break;
+            case TelephonyManager.NETWORK_MODE_GSM_ONLY:
+                if (!mIsGlobalCdma) {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager.NETWORK_MODE_GSM_ONLY));
+                    mButtonEnabledNetworks.setSummary(R.string.network_2G);
+                } else {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager
+                                    .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                    mButtonEnabledNetworks.setSummary(R.string.network_global);
+                }
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
+                if (isWorldMode()) {
+                    mButtonEnabledNetworks.setSummary(
+                            R.string.preferred_network_mode_lte_gsm_umts_summary);
+                    controlCdmaOptions(false);
+                    controlGsmOptions(true);
+                    break;
+                }
+            case TelephonyManager.NETWORK_MODE_LTE_ONLY:
+            case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
+                if (!mIsGlobalCdma) {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA));
+                    mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
+                            ? R.string.network_4G : R.string.network_lte);
+                } else {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager
+                                    .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                    mButtonEnabledNetworks.setSummary(R.string.network_global);
+                }
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                if (isWorldMode()) {
+                    mButtonEnabledNetworks.setSummary(
+                            R.string.preferred_network_mode_lte_cdma_summary);
+                    controlCdmaOptions(true);
+                    controlGsmOptions(false);
+                } else {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO));
+                    mButtonEnabledNetworks.setSummary(R.string.network_lte);
+                }
+                break;
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                mButtonEnabledNetworks.setValue(
+                        Integer.toString(TelephonyManager
+                                .NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
+                mButtonEnabledNetworks.setSummary(R.string.network_3G);
+                break;
+            case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+            case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
+            case TelephonyManager.NETWORK_MODE_GLOBAL:
+                mButtonEnabledNetworks.setValue(
+                        Integer.toString(TelephonyManager.NETWORK_MODE_CDMA_EVDO));
+                mButtonEnabledNetworks.setSummary(R.string.network_3G);
+                break;
+            case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                mButtonEnabledNetworks.setValue(
+                        Integer.toString(TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO));
+                mButtonEnabledNetworks.setSummary(R.string.network_1x);
+                break;
+            case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
+                mButtonEnabledNetworks.setValue(
+                        Integer.toString(TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY));
+                mButtonEnabledNetworks.setSummary(R.string.network_3G);
+                break;
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+            case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+            case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                if (isSupportTdscdma()) {
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager
+                                    .NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
+                    mButtonEnabledNetworks.setSummary(R.string.network_lte);
+                } else {
+                    if (isWorldMode()) {
+                        controlCdmaOptions(true);
+                        controlGsmOptions(false);
+                    }
+                    mButtonEnabledNetworks.setValue(
+                            Integer.toString(TelephonyManager
+                                    .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                    if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+                            || mIsGlobalCdma
+                            || isWorldMode()) {
+                        mButtonEnabledNetworks.setSummary(R.string.network_global);
+                    } else {
+                        mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
+                                ? R.string.network_4G : R.string.network_lte);
+                    }
+                }
+                break;
+            default:
+                String errMsg = "Invalid Network Mode (" + NetworkMode + "). Ignore.";
+                loge(errMsg);
+                mButtonEnabledNetworks.setSummary(errMsg);
+        }
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch(requestCode) {
+            case REQUEST_CODE_EXIT_ECM:
+                Boolean isChoiceYes = data.getBooleanExtra(
+                        EmergencyCallbackModeExitDialog.EXTRA_EXIT_ECM_RESULT, false);
+                if (isChoiceYes) {
+                    // If the phone exits from ECM mode, show the CDMA Options
+                    mCdmaOptions.showDialog(mClickedPreference);
+                } else {
+                    // do nothing
+                }
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    private void updateWiFiCallState() {
+        if (mWiFiCallingPref == null || mCallingCategory == null) {
+            return;
+        }
+
+        // Removes the preference if the wifi calling is disabled.
+        if (!isWifiCallingEnabled(getContext(), SubscriptionManager.getPhoneId(mSubId))) {
+            mCallingCategory.removePreference(mWiFiCallingPref);
+            return;
+        }
+
+        final PhoneAccountHandle simCallManager =
+                TelecomManager.from(getContext()).getSimCallManager();
+
+        if (simCallManager != null) {
+            Intent intent = MobileNetworkSettings.buildPhoneAccountConfigureIntent(
+                    getContext(), simCallManager);
+            PackageManager pm = getContext().getPackageManager();
+            List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
+            mWiFiCallingPref.setTitle(resolutions.get(0).loadLabel(pm));
+            mWiFiCallingPref.setSummary(null);
+            mWiFiCallingPref.setIntent(intent);
+        } else {
+            int resId = com.android.internal.R.string.wifi_calling_off_summary;
+            if (mImsMgr.isWfcEnabledByUser()) {
+                boolean isRoaming = mTelephonyManager.isNetworkRoaming();
+                int wfcMode = mImsMgr.getWfcMode(isRoaming);
+
+                switch (wfcMode) {
+                    case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
+                        resId = com.android.internal.R.string.wfc_mode_wifi_only_summary;
+                        break;
+                    case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED:
+                        resId = com.android.internal.R.string
+                                .wfc_mode_cellular_preferred_summary;
+                        break;
+                    case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED:
+                        resId = com.android.internal.R.string.wfc_mode_wifi_preferred_summary;
+                        break;
+                    default:
+                        if (DBG) log("Unexpected WFC mode value: " + wfcMode);
+                }
+            }
+            mWiFiCallingPref.setSummary(resId);
+        }
+
+        mCallingCategory.addPreference(mWiFiCallingPref);
+        mWiFiCallingPref.setEnabled(mTelephonyManager.getCallState(mSubId)
+                == TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
+    }
+
+    private void updateEnhanced4gLteState() {
+        if (mButton4glte == null) {
+            return;
+        }
+
+        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+
+        if ((mImsMgr == null
+                || !mImsMgr.isVolteEnabledByPlatform()
+                || !mImsMgr.isVolteProvisionedOnDevice()
+                || !isImsServiceStateReady(mImsMgr)
+                || carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL))) {
+            getPreferenceScreen().removePreference(mButton4glte);
+        } else {
+            mButton4glte.setEnabled(is4gLtePrefEnabled(carrierConfig)
+                    && hasActiveSubscriptions());
+            boolean enh4glteMode = mImsMgr.isEnhanced4gLteModeSettingEnabledByUser()
+                    && mImsMgr.isNonTtyOrTtyOnVolteEnabled();
+            mButton4glte.setChecked(enh4glteMode);
+        }
+    }
+
+    private void updateVideoCallState() {
+        if (mVideoCallingPref == null || mCallingCategory == null) {
+            return;
+        }
+
+        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+
+        if (mImsMgr != null
+                && mImsMgr.isVtEnabledByPlatform()
+                && mImsMgr.isVtProvisionedOnDevice()
+                && isImsServiceStateReady(mImsMgr)
+                && (carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
+                || mTelephonyManager.isDataEnabled())) {
+            mCallingCategory.addPreference(mVideoCallingPref);
+            if (!mButton4glte.isChecked()) {
+                mVideoCallingPref.setEnabled(false);
+                mVideoCallingPref.setChecked(false);
+            } else {
+                mVideoCallingPref.setEnabled(mTelephonyManager.getCallState(mSubId)
+                        == TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
+                mVideoCallingPref.setChecked(mImsMgr.isVtEnabledByUser());
+                mVideoCallingPref.setOnPreferenceChangeListener(this);
+            }
+        } else {
+            mCallingCategory.removePreference(mVideoCallingPref);
+        }
+    }
+
+    private void updatePreferredNetworkType() {
+        boolean enabled = mTelephonyManager.getCallState(
+                mSubId) == TelephonyManager.CALL_STATE_IDLE
+                && hasActiveSubscriptions();
+        Log.i(LOG_TAG, "updatePreferredNetworkType: " + enabled);
+        // TODO: Disentangle enabled networks vs preferred network mode, it looks like
+        // both buttons are shown to the user as "Preferred network type" and the options change
+        // based on what looks like World mode.
+        if (mButtonEnabledNetworks != null) {
+            mButtonEnabledNetworks.setEnabled(enabled);
+        }
+        if (mButtonPreferredNetworkMode != null) {
+            mButtonPreferredNetworkMode.setEnabled(enabled);
+        }
+    }
+
+    private void updateCallingCategory() {
+        if (mCallingCategory == null) {
+            return;
+        }
+
+        updateWiFiCallState();
+        updateVideoCallState();
+
+        // If all items in calling category is removed, we remove it from
+        // the screen. Otherwise we'll see title of the category but nothing
+        // is in there.
+        if (mCallingCategory.getPreferenceCount() == 0) {
+            getPreferenceScreen().removePreference(mCallingCategory);
+        } else {
+            getPreferenceScreen().addPreference(mCallingCategory);
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+
+    private static void loge(String msg) {
+        Log.e(LOG_TAG, msg);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
+            // Commenting out "logical up" capability. This is a workaround for issue 5278083.
+            //
+            // Settings app may not launch this activity via UP_ACTIVITY_CLASS but the other
+            // Activity that looks exactly same as UP_ACTIVITY_CLASS ("SubSettings" Activity).
+            // At that moment, this Activity launches UP_ACTIVITY_CLASS on top of the Activity.
+            // which confuses users.
+            // TODO: introduce better mechanism for "up" capability here.
+            /*Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.setClassName(UP_ACTIVITY_PACKAGE, UP_ACTIVITY_CLASS);
+            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            startActivity(intent);*/
+            getActivity().finish();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private boolean isWorldMode() {
+        boolean worldModeOn = false;
+        final String configString = getResources().getString(R.string.config_world_mode);
+
+        if (!TextUtils.isEmpty(configString)) {
+            String[] configArray = configString.split(";");
+            // Check if we have World mode configuration set to True only or config is set to True
+            // and SIM GID value is also set and matches to the current SIM GID.
+            if (configArray != null &&
+                    ((configArray.length == 1 && configArray[0].equalsIgnoreCase("true"))
+                            || (configArray.length == 2 && !TextUtils.isEmpty(configArray[1])
+                            && mTelephonyManager != null
+                            && configArray[1].equalsIgnoreCase(
+                            mTelephonyManager.getGroupIdLevel1())))) {
+                worldModeOn = true;
+            }
+        }
+
+        Log.d(LOG_TAG, "isWorldMode=" + worldModeOn);
+
+        return worldModeOn;
+    }
+
+    private void controlGsmOptions(boolean enable) {
+        PreferenceScreen prefSet = getPreferenceScreen();
+        if (prefSet == null) {
+            return;
+        }
+
+        updateGsmUmtsOptions(this, prefSet, mSubId);
+
+        PreferenceCategory networkOperatorCategory =
+                (PreferenceCategory) prefSet.findPreference(
+                        com.android.phone.NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
+        Preference carrierSettings = prefSet.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
+        if (networkOperatorCategory != null) {
+            if (enable) {
+                networkOperatorCategory.setEnabled(true);
+            } else {
+                prefSet.removePreference(networkOperatorCategory);
+            }
+        }
+        if (carrierSettings != null) {
+            prefSet.removePreference(carrierSettings);
+        }
+    }
+
+    private void controlCdmaOptions(boolean enable) {
+        PreferenceScreen prefSet = getPreferenceScreen();
+        if (prefSet == null) {
+            return;
+        }
+        updateCdmaOptions(this, prefSet, mSubId);
+        com.android.phone.CdmaSystemSelectListPreference systemSelect =
+                (CdmaSystemSelectListPreference)prefSet.findPreference
+                        (BUTTON_CDMA_SYSTEM_SELECT_KEY);
+        systemSelect.setSubscriptionId(mSubId);
+        if (systemSelect != null) {
+            systemSelect.setEnabled(enable);
+        }
+    }
+
+    private boolean isSupportTdscdma() {
+        if (getResources().getBoolean(R.bool.config_support_tdscdma)) {
+            return true;
+        }
+
+        String operatorNumeric = mTelephonyManager.getServiceState().getOperatorNumeric();
+        String[] numericArray = getResources().getStringArray(
+                R.array.config_support_tdscdma_roaming_on_networks);
+        if (numericArray.length == 0 || operatorNumeric == null) {
+            return false;
+        }
+        for (String numeric : numericArray) {
+            if (operatorNumeric.equals(numeric)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Metrics events related methods. it takes care of all preferences possible in this
+     * fragment(except a few that log on their own). It doesn't only include preferences in
+     * network_setting_fragment.xml, but also those defined in GsmUmtsOptions and CdmaOptions.
+     */
+    private void sendMetricsEventPreferenceClicked(
+            PreferenceScreen preferenceScreen, Preference preference) {
+        final int category = getMetricsEventCategory(preferenceScreen, preference);
+        if (category == MetricsProto.MetricsEvent.VIEW_UNKNOWN) {
+            return;
+        }
+
+        // Send MetricsEvent on click. It includes preferences other than SwitchPreferences,
+        // which send MetricsEvent in onPreferenceChange.
+        // For ListPreferences, we log it here without a value, only indicating it's clicked to
+        // open the list dialog. When a value is chosen, another MetricsEvent is logged with
+        // new value in onPreferenceChange.
+        if (preference == mLteDataServicePref || preference == mDataUsagePref
+                || preference == mEuiccSettingsPref || preference == mAdvancedOptions
+                || preference == mWiFiCallingPref || preference == mButtonPreferredNetworkMode
+                || preference == mButtonEnabledNetworks
+                || preference == preferenceScreen.findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY)
+                || preference == preferenceScreen.findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY)
+                || preference == preferenceScreen.findPreference(BUTTON_GSM_APN_EXPAND_KEY)
+                || preference == preferenceScreen.findPreference(BUTTON_CDMA_APN_EXPAND_KEY)
+                || preference == preferenceScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY)) {
+            MetricsLogger.action(getContext(), category);
+        }
+    }
+
+    private void sendMetricsEventPreferenceChanged(
+            PreferenceScreen preferenceScreen, Preference preference, Object newValue) {
+        final int category = getMetricsEventCategory(preferenceScreen, preference);
+        if (category == MetricsProto.MetricsEvent.VIEW_UNKNOWN) {
+            return;
+        }
+
+        // MetricsEvent logging with new value, for SwitchPreferences and ListPreferences.
+        if (preference == mButton4glte || preference == mVideoCallingPref) {
+            MetricsLogger.action(getContext(), category, (Boolean) newValue);
+        } else if (preference == mButtonPreferredNetworkMode
+                || preference == mButtonEnabledNetworks
+                || preference == preferenceScreen
+                .findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY)
+                || preference == preferenceScreen
+                .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
+            // Network select preference sends metrics event in its own listener.
+            MetricsLogger.action(getContext(), category, Integer.valueOf((String) newValue));
+        }
+    }
+
+    private int getMetricsEventCategory(
+            PreferenceScreen preferenceScreen, Preference preference) {
+
+        if (preference == null) {
+            return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
+        } else if (preference == mMobileDataPref) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_MOBILE_DATA_TOGGLE;
+        } else if (preference == mButtonDataRoam) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_DATA_ROAMING_TOGGLE;
+        } else if (preference == mDataUsagePref) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_DATA_USAGE;
+        } else if (preference == mLteDataServicePref) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_SET_UP_DATA_SERVICE;
+        } else if (preference == mAdvancedOptions) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_EXPAND_ADVANCED_FIELDS;
+        } else if (preference == mButton4glte) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_ENHANCED_4G_LTE_MODE_TOGGLE;
+        } else if (preference == mButtonPreferredNetworkMode) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_SELECT_PREFERRED_NETWORK;
+        } else if (preference == mButtonEnabledNetworks) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_SELECT_ENABLED_NETWORK;
+        } else if (preference == mEuiccSettingsPref) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_EUICC_SETTING;
+        } else if (preference == mWiFiCallingPref) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_WIFI_CALLING;
+        } else if (preference == mVideoCallingPref) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_VIDEO_CALLING_TOGGLE;
+        } else if (preference == preferenceScreen
+                .findPreference(com.android.phone.NetworkOperators.BUTTON_AUTO_SELECT_KEY)) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE;
+        } else if (preference == preferenceScreen
+                .findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY)) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK;
+        } else if (preference == preferenceScreen
+                .findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_CDMA_SYSTEM_SELECT;
+        } else if (preference == preferenceScreen
+                .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_CDMA_SUBSCRIPTION_SELECT;
+        } else if (preference == preferenceScreen.findPreference(BUTTON_GSM_APN_EXPAND_KEY)
+                || preference == preferenceScreen.findPreference(BUTTON_CDMA_APN_EXPAND_KEY)) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_APN_SETTINGS;
+        } else if (preference == preferenceScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY)) {
+            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_CARRIER_SETTINGS;
+        } else {
+            return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
+        }
+    }
+
+    private void updateGsmUmtsOptions(PreferenceFragment prefFragment,
+            PreferenceScreen prefScreen, final int subId) {
+        // We don't want to re-create GsmUmtsOptions if already exists. Otherwise, the
+        // preferences inside it will also be re-created which causes unexpected behavior.
+        // For example, the open dialog gets dismissed or detached after pause / resume.
+        if (mGsmUmtsOptions == null) {
+            mGsmUmtsOptions = new GsmUmtsOptions(prefFragment, prefScreen, subId);
+        } else {
+            mGsmUmtsOptions.update(subId);
+        }
+    }
+
+    private void updateCdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
+            int subId) {
+        // We don't want to re-create CdmaOptions if already exists. Otherwise, the preferences
+        // inside it will also be re-created which causes unexpected behavior. For example,
+        // the open dialog gets dismissed or detached after pause / resume.
+        if (mCdmaOptions == null) {
+            mCdmaOptions = new CdmaOptions(prefFragment, prefScreen, subId);
+        } else {
+            mCdmaOptions.updateSubscriptionId(subId);
+        }
+    }
+}
+
+private static final class SetPreferredNetworkAsyncTask extends AsyncTask<Void, Void, Boolean> {
+
+    private final TelephonyManager mTelephonyManager;
+    private final int mSubId;
+    private final int mNetworkType;
+    private final Message mCallback;
+
+    SetPreferredNetworkAsyncTask(
+            TelephonyManager tm, int subId, int networkType, Message callback) {
+        mTelephonyManager = tm;
+        mSubId = subId;
+        mNetworkType = networkType;
+        mCallback = callback;
+    }
+
+    @Override
+    protected Boolean doInBackground(Void... voids) {
+        return mTelephonyManager.setPreferredNetworkType(mSubId, mNetworkType);
+    }
+
+    @Override
+    protected void onPostExecute(Boolean isSuccessed) {
+        mCallback.obj = isSuccessed;
+        mCallback.sendToTarget();
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/mobilenetwork/NetworkOperators.java b/src/com/android/settings/mobilenetwork/NetworkOperators.java
new file mode 100644
index 0000000..b07a170
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/NetworkOperators.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+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 android.widget.Toast;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.phone.NetworkSelectSettingActivity;
+import com.android.settingslib.utils.ThreadUtils;
+
+/**
+ * "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 BUTTON_CHOOSE_NETWORK_KEY = "button_choose_network_key";
+    public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
+
+    //preference objects
+    private NetworkSelectListPreference mNetworkSelect;
+    private TwoStatePreference mAutoSelect;
+    private Preference mChooseNetwork;
+    private ProgressDialog mProgressDialog;
+
+    private int mSubId;
+    private TelephonyManager mTelephonyManager;
+
+    // There's two sets of Auto-Select UI in this class.
+    // If {@code com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI} set as true
+    // {@link mChooseNetwork} will be used, otherwise {@link mNetworkSelect} will be used.
+    boolean mEnableNewManualSelectNetworkUI;
+
+    public NetworkOperators(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NetworkOperators(Context context) {
+        super(context);
+    }
+
+    /**
+     * Initialize NetworkOperators instance.
+     */
+    public void initialize() {
+        mEnableNewManualSelectNetworkUI = getContext().getResources().getBoolean(
+                com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
+        mAutoSelect = (TwoStatePreference) findPreference(BUTTON_AUTO_SELECT_KEY);
+        mChooseNetwork = findPreference(BUTTON_CHOOSE_NETWORK_KEY);
+        mNetworkSelect = (NetworkSelectListPreference) findPreference(BUTTON_NETWORK_SELECT_KEY);
+        if (mEnableNewManualSelectNetworkUI) {
+            removePreference(mNetworkSelect);
+        } else {
+            removePreference(mChooseNetwork);
+        }
+        mProgressDialog = new ProgressDialog(getContext());
+        mTelephonyManager = TelephonyManager.from(getContext());
+    }
+
+    /**
+     * Update NetworkOperators instance if like subId is updated.
+     *
+     * @param subId Corresponding subscription ID of this network.
+     */
+    protected void update(final int subId) {
+        mSubId = subId;
+        mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+
+        if (mAutoSelect != null) {
+            mAutoSelect.setOnPreferenceChangeListener(this);
+        }
+
+        if (mEnableNewManualSelectNetworkUI) {
+            if (mChooseNetwork != null) {
+                ServiceState ss = mTelephonyManager.getServiceState();
+                if (ss != null && ss.getState() == ServiceState.STATE_IN_SERVICE) {
+                    mChooseNetwork.setSummary(mTelephonyManager.getNetworkOperatorName());
+                } else {
+                    mChooseNetwork.setSummary(R.string.network_disconnected);
+                }
+            }
+        } else {
+            if (mNetworkSelect != null) {
+                mNetworkSelect.initialize(mSubId, this, mProgressDialog);
+            }
+        }
+        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;
+            if (DBG) logd("onPreferenceChange autoSelect: " + String.valueOf(autoSelect));
+            selectNetworkAutomatic(autoSelect);
+            MetricsLogger.action(getContext(),
+                    MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE, autoSelect);
+            return true;
+        }
+        return false;
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_AUTO_SELECT_DONE:
+                    mAutoSelect.setEnabled(true);
+                    dismissProgressBar();
+
+                    boolean isSuccessed = (boolean) msg.obj;
+
+                    if (isSuccessed) {
+                        if (DBG) logd("automatic network selection: succeeded!");
+                        displayNetworkSelectionSucceeded();
+                    } else {
+                        if (DBG) logd("automatic network selection: failed!");
+                        displayNetworkSelectionFailed();
+                    }
+
+                    break;
+                case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
+                    int networkSelectionMode = msg.arg1;
+                    if (networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN) {
+                        if (DBG) logd("get network selection mode: failed!");
+                    } else {
+                        boolean autoSelect = networkSelectionMode
+                                == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
+                        if (DBG) {
+                            logd("get network selection mode: "
+                                    + (autoSelect ? "auto" : "manual") + " selection");
+                        }
+                        if (mAutoSelect != null) {
+                            mAutoSelect.setChecked(autoSelect);
+                        }
+                        if (mEnableNewManualSelectNetworkUI) {
+                            if (mChooseNetwork != null) {
+                                mChooseNetwork.setEnabled(!autoSelect);
+                            }
+                        } else {
+                            if (mNetworkSelect != null) {
+                                mNetworkSelect.setEnabled(!autoSelect);
+                            }
+                        }
+                    }
+            }
+            return;
+        }
+    };
+
+    // Used by both mAutoSelect and mNetworkSelect buttons.
+    protected void displayNetworkSelectionFailed() {
+        Toast.makeText(getContext(), R.string.connect_later, Toast.LENGTH_LONG).show();
+    }
+
+    // Used by both mAutoSelect and mNetworkSelect buttons.
+    protected void displayNetworkSelectionSucceeded() {
+        Toast.makeText(getContext(), R.string.registration_done, Toast.LENGTH_LONG).show();
+    }
+
+    private void selectNetworkAutomatic(boolean autoSelect) {
+        if (DBG) logd("selectNetworkAutomatic: " + String.valueOf(autoSelect));
+
+        if (autoSelect) {
+            if (mEnableNewManualSelectNetworkUI) {
+                if (mChooseNetwork != null) {
+                    mChooseNetwork.setEnabled(!autoSelect);
+                }
+            } else {
+                if (mNetworkSelect != null) {
+                    mNetworkSelect.setEnabled(!autoSelect);
+                }
+            }
+            if (DBG) logd("select network automatically...");
+            showAutoSelectProgressBar();
+            mAutoSelect.setEnabled(false);
+            if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+                ThreadUtils.postOnBackgroundThread(() -> {
+                    mTelephonyManager.setNetworkSelectionModeAutomatic();
+                    // Because TelephonyManager#setNetworkSelectionModeAutomatic doesn't have a
+                    // return value, we query the current network selection mode to tell if the
+                    // TelephonyManager#setNetworkSelectionModeAutomatic is successed.
+                    int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
+                    Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
+                    msg.obj = networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
+                    msg.sendToTarget();
+                });
+            }
+        } else {
+            if (mEnableNewManualSelectNetworkUI) {
+                if (mChooseNetwork != null) {
+                    // Open the choose Network page automatically when user turn off the auto-select
+                    openChooseNetworkPage();
+                }
+            } else {
+                if (mNetworkSelect != null) {
+                    mNetworkSelect.onClick();
+                }
+            }
+        }
+    }
+
+    protected void getNetworkSelectionMode() {
+        if (DBG) logd("getting network selection mode...");
+        ThreadUtils.postOnBackgroundThread(() -> {
+            int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
+            Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
+            msg.arg1 = networkSelectionMode;
+            msg.sendToTarget();
+        });
+    }
+
+    private void dismissProgressBar() {
+        if (mProgressDialog != null && mProgressDialog.isShowing()) {
+            mProgressDialog.dismiss();
+        }
+    }
+
+    private void showAutoSelectProgressBar() {
+        mProgressDialog.setMessage(
+                getContext().getResources().getString(R.string.register_automatically));
+        mProgressDialog.setCanceledOnTouchOutside(false);
+        mProgressDialog.setCancelable(false);
+        mProgressDialog.setIndeterminate(true);
+        mProgressDialog.show();
+    }
+
+    /**
+     * Open the Choose network page via {@alink NetworkSelectSettingActivity}
+     */
+    public void openChooseNetworkPage() {
+        Intent intent = NetworkSelectSettingActivity.getIntent(getContext(), mSubId);
+        getContext().startActivity(intent);
+    }
+
+    protected boolean preferenceTreeClick(Preference preference) {
+        if (mEnableNewManualSelectNetworkUI) {
+            if (DBG) logd("enable New AutoSelectNetwork UI");
+            if (preference == mChooseNetwork) {
+                openChooseNetworkPage();
+            }
+            return (preference == mAutoSelect || preference == mChooseNetwork);
+        } else {
+            return (preference == mAutoSelect || preference == mNetworkSelect);
+        }
+    }
+
+    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/settings/mobilenetwork/NetworkScanHelper.java b/src/com/android/settings/mobilenetwork/NetworkScanHelper.java
new file mode 100644
index 0000000..59908bc
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/NetworkScanHelper.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.annotation.IntDef;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.CellInfo;
+import android.telephony.NetworkScan;
+import android.telephony.NetworkScanRequest;
+import android.telephony.RadioAccessSpecifier;
+import android.telephony.TelephonyManager;
+import android.telephony.TelephonyScanManager;
+import android.util.Log;
+
+import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.phone.CellInfoUtil;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
+
+/**
+ * A helper class that builds the common interface and performs the network scan for two different
+ * network scan APIs.
+ */
+public class NetworkScanHelper {
+    public static final String TAG = "NetworkScanHelper";
+    private static final boolean DBG = true;
+
+    /**
+     * Callbacks interface to inform the network scan results.
+     */
+    public interface NetworkScanCallback {
+        /**
+         * Called when the results is returned from {@link TelephonyManager}. This method will be
+         * called at least one time if there is no error occurred during the network scan.
+         *
+         * <p> This method can be called multiple times in one network scan, until
+         * {@link #onComplete()} or {@link #onError(int)} is called.
+         *
+         * @param results
+         */
+        void onResults(List<CellInfo> results);
+
+        /**
+         * Called when the current network scan process is finished. No more
+         * {@link #onResults(List)} will be called for the current network scan after this method is
+         * called.
+         */
+        void onComplete();
+
+        /**
+         * Called when an error occurred during the network scan process.
+         *
+         * <p> There is no more result returned from {@link TelephonyManager} if an error occurred.
+         *
+         * <p> {@link #onComplete()} will not be called if an error occurred.
+         *
+         * @see {@link NetworkScan.ScanErrorCode}
+         */
+        void onError(int errorCode);
+    }
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS, NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS})
+    public @interface NetworkQueryType {}
+
+    /**
+     * Performs the network scan using {@link TelephonyManager#getAvailableNetworks()}. The network
+     * scan results won't be returned to the caller until the network scan is completed.
+     *
+     * <p> This is typically used when the modem doesn't support the new network scan api
+     * {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
+     */
+    public static final int NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS = 1;
+
+    /**
+     * Performs the network scan using {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan
+     * results will be returned to the caller periodically in a small time window until the network
+     * scan is completed. The complete results should be returned in the last called of
+     * {@link NetworkScanCallback#onResults(List)}.
+     *
+     * <p> This is recommended to be used if modem supports the new network scan api
+     * {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}
+     */
+    public static final int NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS = 2;
+
+    /** The constants below are used in the async network scan. */
+    private static final boolean INCREMENTAL_RESULTS = true;
+    private static final int SEARCH_PERIODICITY_SEC = 5;
+    private static final int MAX_SEARCH_TIME_SEC = 300;
+    private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
+
+    private static final NetworkScanRequest NETWORK_SCAN_REQUEST =
+            new NetworkScanRequest(
+                    NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
+                    new RadioAccessSpecifier[]{
+                            // GSM
+                            new RadioAccessSpecifier(
+                                    AccessNetworkType.GERAN,
+                                    null /* bands */,
+                                    null /* channels */),
+                            // LTE
+                            new RadioAccessSpecifier(
+                                    AccessNetworkType.EUTRAN,
+                                    null /* bands */,
+                                    null /* channels */),
+                            // WCDMA
+                            new RadioAccessSpecifier(
+                                    AccessNetworkType.UTRAN,
+                                    null /* bands */,
+                                    null /* channels */)
+                    },
+                    SEARCH_PERIODICITY_SEC,
+                    MAX_SEARCH_TIME_SEC,
+                    INCREMENTAL_RESULTS,
+                    INCREMENTAL_RESULTS_PERIODICITY_SEC,
+                    null /* List of PLMN ids (MCC-MNC) */);
+
+    private final NetworkScanCallback mNetworkScanCallback;
+    private final TelephonyManager mTelephonyManager;
+    private final TelephonyScanManager.NetworkScanCallback mInternalNetworkScanCallback;
+    private final Executor mExecutor;
+
+    private NetworkScan mNetworkScanRequester;
+
+    /** Callbacks for sync network scan */
+    private ListenableFuture<List<CellInfo>> mNetworkScanFuture;
+
+    public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) {
+        mTelephonyManager = tm;
+        mNetworkScanCallback = callback;
+        mInternalNetworkScanCallback = new NetworkScanCallbackImpl();
+        mExecutor = executor;
+    }
+
+    /**
+     * Performs a network scan for the given type {@code type}.
+     * {@link #NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS} is recommended if modem supports
+     * {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
+     *
+     * @param type used to tell which network scan API should be used.
+     */
+    public void startNetworkScan(@NetworkQueryType int type) {
+        if (type == NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS) {
+            mNetworkScanFuture = SettableFuture.create();
+            Futures.addCallback(mNetworkScanFuture, new FutureCallback<List<CellInfo>>() {
+                @Override
+                public void onSuccess(List<CellInfo> result) {
+                    onResults(result);
+                    onComplete();
+                }
+
+                @Override
+                public void onFailure(Throwable t) {
+                    int errCode = Integer.parseInt(t.getMessage());
+                    onError(errCode);
+                }
+            });
+            mExecutor.execute(new NetworkScanSyncTask(
+                    mTelephonyManager, (SettableFuture) mNetworkScanFuture));
+        } else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) {
+            if (DBG) Log.d(TAG, "start network scan async");
+            mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
+                    NETWORK_SCAN_REQUEST,
+                    mExecutor,
+                    mInternalNetworkScanCallback);
+        }
+    }
+
+    /**
+     * The network scan of type {@link #NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS} can't be stopped,
+     * however, the result of the current network scan won't be returned to the callback after
+     * calling this method.
+     */
+    public void stopNetworkQuery() {
+        if (mNetworkScanRequester != null) {
+            mNetworkScanRequester.stopScan();
+            mNetworkScanFuture = null;
+        }
+
+        if (mNetworkScanFuture != null) {
+            mNetworkScanFuture.cancel(true /* mayInterruptIfRunning */);
+            mNetworkScanFuture = null;
+        }
+    }
+
+    private void onResults(List<CellInfo> cellInfos) {
+        mNetworkScanCallback.onResults(cellInfos);
+    }
+
+    private void onComplete() {
+        mNetworkScanCallback.onComplete();
+    }
+
+    private void onError(int errCode) {
+        mNetworkScanCallback.onError(errCode);
+    }
+
+    /**
+     * Converts the status code of {@link CellNetworkScanResult} to one of the
+     * {@link NetworkScan.ScanErrorCode}.
+     * @param errCode status code from {@link CellNetworkScanResult}.
+     *
+     * @return one of the scan error code from {@link NetworkScan.ScanErrorCode}.
+     */
+    private static int convertToScanErrorCode(int errCode) {
+        switch (errCode) {
+            case CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE:
+                return NetworkScan.ERROR_RADIO_INTERFACE_ERROR;
+            case CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE:
+            default:
+                return NetworkScan.ERROR_MODEM_ERROR;
+        }
+    }
+
+    private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
+        public void onResults(List<CellInfo> results) {
+            if (DBG) Log.d(TAG, "async scan onResults() results = " + results);
+            NetworkScanHelper.this.onResults(results);
+        }
+
+        public void onComplete() {
+            if (DBG) Log.d(TAG, "async scan onComplete()");
+            NetworkScanHelper.this.onComplete();
+        }
+
+        public void onError(@NetworkScan.ScanErrorCode int errCode) {
+            if (DBG) Log.d(TAG, "async scan onError() errorCode = " + errCode);
+            NetworkScanHelper.this.onError(errCode);
+        }
+    }
+
+    private static final class NetworkScanSyncTask implements Runnable {
+        private final SettableFuture<List<CellInfo>> mCallback;
+        private final TelephonyManager mTelephonyManager;
+
+        NetworkScanSyncTask(
+                TelephonyManager telephonyManager, SettableFuture<List<CellInfo>> callback) {
+            mTelephonyManager = telephonyManager;
+            mCallback = callback;
+        }
+
+        @Override
+        public void run() {
+            if (DBG) Log.d(TAG, "sync scan start");
+            CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
+            if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) {
+                List<CellInfo> cellInfos = result.getOperators()
+                        .stream()
+                        .map(operatorInfo
+                                -> CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo))
+                        .collect(Collectors.toList());
+                if (DBG) Log.d(TAG, "sync scan complete");
+                mCallback.set(cellInfos);
+            } else {
+                mCallback.setException(new Throwable(
+                        Integer.toString(convertToScanErrorCode(result.getStatus()))));
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/mobilenetwork/NetworkSelectListPreference.java b/src/com/android/settings/mobilenetwork/NetworkSelectListPreference.java
new file mode 100644
index 0000000..95283dc
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/NetworkSelectListPreference.java
@@ -0,0 +1,505 @@
+/*
+ * 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.AsyncTask;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+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 android.widget.Toast;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.telephony.OperatorInfo;
+import com.android.phone.NetworkScanHelper.NetworkScanCallback;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
+/**
+ * "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_MANUALLY_NETWORK_SELECTION_DONE = 1;
+    private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
+    private static final int EVENT_NETWORK_SCAN_COMPLETED = 3;
+    private static final int EVENT_NETWORK_SCAN_ERROR = 4;
+
+    //dialog ids
+    private static final int DIALOG_NETWORK_SELECTION = 100;
+    private static final int DIALOG_NETWORK_LIST_LOAD = 200;
+
+    private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
+
+    private List<CellInfo> mCellInfoList;
+    private CellInfo mCellInfo;
+
+    private int mSubId;
+    private TelephonyManager mTelephonyManager;
+    private NetworkScanHelper mNetworkScanHelper;
+    private NetworkOperators mNetworkOperators;
+    private List<String> mForbiddenPlmns;
+
+    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() {
+        showProgressDialog(DIALOG_NETWORK_LIST_LOAD);
+        TelephonyManager telephonyManager = (TelephonyManager)
+                getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        new AsyncTask<Void, Void, List<String>>() {
+            @Override
+            protected List<String> doInBackground(Void... voids) {
+                String[] forbiddenPlmns = telephonyManager.getForbiddenPlmns();
+                return forbiddenPlmns != null ? Arrays.asList(forbiddenPlmns) : null;
+            }
+
+            @Override
+            protected void onPostExecute(List<String> result) {
+                mForbiddenPlmns = result;
+                loadNetworksList();
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_MANUALLY_NETWORK_SELECTION_DONE:
+                    if (DBG) logd("hideProgressPanel");
+                    dismissProgressDialog();
+
+                    boolean isSuccessed = (boolean) msg.obj;
+                    if (isSuccessed) {
+                        if (DBG) {
+                            logd("manual network selection: succeeded! "
+                                    + getNetworkTitle(mCellInfo));
+                        }
+                        mNetworkOperators.displayNetworkSelectionSucceeded();
+                    } else {
+                        if (DBG) logd("manual network selection: failed!");
+                        mNetworkOperators.displayNetworkSelectionFailed();
+                    }
+                    mNetworkOperators.getNetworkSelectionMode();
+                    break;
+
+                case EVENT_NETWORK_SCAN_RESULTS:
+                    List<CellInfo> results = (List<CellInfo>) msg.obj;
+                    results.removeIf(cellInfo -> cellInfo == null);
+                    mCellInfoList = new ArrayList<>(results);
+                    if (DBG) logd("CALLBACK_SCAN_RESULTS" + mCellInfoList.toString());
+                    break;
+
+                case EVENT_NETWORK_SCAN_COMPLETED:
+                    if (DBG) logd("scan complete, load the cellInfosList");
+                    dismissProgressDialog();
+                    networksListLoaded();
+                    break;
+                case EVENT_NETWORK_SCAN_ERROR:
+                    dismissProgressDialog();
+                    displayNetworkQueryFailed();
+                    mNetworkOperators.getNetworkSelectionMode();
+                    break;
+            }
+            return;
+        }
+    };
+
+    private final NetworkScanHelper.NetworkScanCallback mCallback = new NetworkScanCallback() {
+        public void onResults(List<CellInfo> results) {
+            if (DBG) logd("get scan results: " + results.toString());
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
+            msg.sendToTarget();
+        }
+
+        public void onComplete() {
+            if (DBG) logd("network scan completed.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
+            msg.sendToTarget();
+        }
+
+        public void onError(int error) {
+            if (DBG) logd("network scan error.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR);
+            msg.sendToTarget();
+        }
+    };
+
+    @Override
+    //implemented for DialogInterface.OnCancelListener
+    public void onCancel(DialogInterface dialog) {
+        if (DBG) logd("user manually close the dialog");
+        mNetworkScanHelper.stopNetworkQuery();
+
+        // If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
+        mNetworkOperators.getNetworkSelectionMode();
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+        // If dismissed, we query NetworkSelectMode and update states of AutoSelect button.
+        if (!positiveResult) {
+            mNetworkOperators.getNetworkSelectionMode();
+        }
+    }
+
+    // This initialize method needs to be called for this preference to work properly.
+    protected void initialize(int subId, NetworkOperators networkOperators,
+            ProgressDialog progressDialog) {
+        mSubId = subId;
+        mNetworkOperators = networkOperators;
+        // This preference should share the same progressDialog with networkOperators category.
+        mProgressDialog = progressDialog;
+
+        mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+        mNetworkScanHelper = new NetworkScanHelper(
+                mTelephonyManager, mCallback, mNetworkScanExecutor);
+
+        setSummary(mTelephonyManager.getNetworkOperatorName());
+
+        setOnPreferenceChangeListener(this);
+    }
+
+    @Override
+    protected void onPrepareForRemoval() {
+        destroy();
+        super.onPrepareForRemoval();
+    }
+
+    private void destroy() {
+        dismissProgressDialog();
+
+        if (mNetworkScanHelper != null) {
+            mNetworkScanHelper.stopNetworkQuery();
+        }
+
+        mNetworkScanExecutor.shutdown();
+    }
+
+    private void displayEmptyNetworkList() {
+        Toast.makeText(getContext(), R.string.empty_networks_list, Toast.LENGTH_LONG).show();
+    }
+
+    private void displayNetworkQueryFailed() {
+        Toast.makeText(getContext(), R.string.network_query_error, Toast.LENGTH_LONG).show();
+    }
+
+    private void loadNetworksList() {
+        if (DBG) logd("load networks list...");
+        mNetworkScanHelper.startNetworkScan(
+                NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
+    }
+
+    private void networksListLoaded() {
+        if (DBG) logd("networks list loaded");
+
+        mNetworkOperators.getNetworkSelectionMode();
+        if (mCellInfoList != null) {
+            // create a preference for each item in the list.
+            // just use the operator name instead of the mildly
+            // confusing mcc/mnc.
+            List<CharSequence> networkEntriesList = new ArrayList<>();
+            List<CharSequence> networkEntryValuesList = new ArrayList<>();
+            for (CellInfo cellInfo: mCellInfoList) {
+                // Display each operator name only once.
+                String networkTitle = getNetworkTitle(cellInfo);
+                if (CellInfoUtil.isForbidden(cellInfo, mForbiddenPlmns)) {
+                    networkTitle += " "
+                            + getContext().getResources().getString(R.string.forbidden_network);
+                }
+                networkEntriesList.add(networkTitle);
+                networkEntryValuesList.add(getOperatorNumeric(cellInfo));
+            }
+            setEntries(networkEntriesList.toArray(new CharSequence[networkEntriesList.size()]));
+            setEntryValues(networkEntryValuesList.toArray(
+                    new CharSequence[networkEntryValuesList.size()]));
+
+            super.onClick();
+        } else {
+            displayEmptyNetworkList();
+        }
+    }
+
+    private void dismissProgressDialog() {
+        if (mProgressDialog != null && mProgressDialog.isShowing()) {
+            try {
+                mProgressDialog.dismiss();
+            } catch (IllegalArgumentException ex) {
+                loge("Can't close the progress dialog " + ex);
+            }
+        }
+    }
+
+    private void showProgressDialog(int id) {
+        if (mProgressDialog == null) {
+            mProgressDialog = new ProgressDialog(getContext());
+        } else {
+            // Dismiss progress bar if it's showing now.
+            dismissProgressDialog();
+        }
+
+        switch (id) {
+            case DIALOG_NETWORK_SELECTION:
+                final String networkSelectMsg = getContext().getResources()
+                        .getString(R.string.register_on_network,
+                                getNetworkTitle(mCellInfo));
+                mProgressDialog.setMessage(networkSelectMsg);
+                mProgressDialog.setCanceledOnTouchOutside(false);
+                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.setCancelable(true);
+                mProgressDialog.setIndeterminate(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.
+     */
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        int operatorIndex = findIndexOfValue((String) newValue);
+        mCellInfo = mCellInfoList.get(operatorIndex);
+        if (DBG) logd("selected network: " + mCellInfo.toString());
+
+        MetricsLogger.action(getContext(),
+                MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK);
+
+        if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            ThreadUtils.postOnBackgroundThread(() -> {
+                final OperatorInfo operatorInfo = getOperatorInfoFromCellInfo(mCellInfo);
+                if (DBG) logd("manually selected network: " + operatorInfo.toString());
+                boolean isSuccessed = mTelephonyManager.setNetworkSelectionModeManual(
+                        operatorInfo, true /* persistSelection */);
+                Message msg = mHandler.obtainMessage(EVENT_MANUALLY_NETWORK_SELECTION_DONE);
+                msg.obj = isSuccessed;
+                msg.sendToTarget();
+            });
+        } else {
+            loge("Error selecting network, subscription Id is invalid " + mSubId);
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the title of the network obtained in the manual search.
+     *
+     * @param cellInfo 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(CellInfo cellInfo) {
+        OperatorInfo ni = getOperatorInfoFromCellInfo(cellInfo);
+
+        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);
+        }
+    }
+
+    /**
+     * Returns the operator numeric (MCCMNC) obtained in the manual search.
+     *
+     * @param cellInfo contains the information of the network.
+     * @return MCCMNC string.
+     */
+    private String getOperatorNumeric(CellInfo cellInfo) {
+        return getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
+    }
+
+    /**
+     * Wrap a cell info into an operator info.
+     */
+    private OperatorInfo getOperatorInfoFromCellInfo(CellInfo cellInfo) {
+        OperatorInfo oi;
+        if (cellInfo instanceof CellInfoLte) {
+            CellInfoLte lte = (CellInfoLte) cellInfo;
+            oi = new OperatorInfo(
+                    (String) lte.getCellIdentity().getOperatorAlphaLong(),
+                    (String) lte.getCellIdentity().getOperatorAlphaShort(),
+                    lte.getCellIdentity().getMobileNetworkOperator());
+        } else if (cellInfo instanceof CellInfoWcdma) {
+            CellInfoWcdma wcdma = (CellInfoWcdma) cellInfo;
+            oi = new OperatorInfo(
+                    (String) wcdma.getCellIdentity().getOperatorAlphaLong(),
+                    (String) wcdma.getCellIdentity().getOperatorAlphaShort(),
+                    wcdma.getCellIdentity().getMobileNetworkOperator());
+        } else if (cellInfo instanceof CellInfoGsm) {
+            CellInfoGsm gsm = (CellInfoGsm) cellInfo;
+            oi = new OperatorInfo(
+                    (String) gsm.getCellIdentity().getOperatorAlphaLong(),
+                    (String) gsm.getCellIdentity().getOperatorAlphaShort(),
+                    gsm.getCellIdentity().getMobileNetworkOperator());
+        } else if (cellInfo instanceof CellInfoCdma) {
+            CellInfoCdma cdma = (CellInfoCdma) cellInfo;
+            oi = new OperatorInfo(
+                    (String) cdma.getCellIdentity().getOperatorAlphaLong(),
+                    (String) cdma.getCellIdentity().getOperatorAlphaShort(),
+                    "" /* operator numeric */);
+        } else {
+            oi = new OperatorInfo("", "", "");
+        }
+        return oi;
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        final Parcelable superState = super.onSaveInstanceState();
+        if (isPersistent()) {
+            // No need to save instance state since it's persistent
+            return superState;
+        }
+
+        final SavedState myState = new SavedState(superState);
+        myState.mDialogListEntries = getEntries();
+        myState.mDialogListEntryValues = getEntryValues();
+        myState.mCellInfoList = mCellInfoList;
+        return myState;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (state == null || !state.getClass().equals(SavedState.class)) {
+            // Didn't save state for us in onSaveInstanceState
+            super.onRestoreInstanceState(state);
+            return;
+        }
+
+        SavedState myState = (SavedState) state;
+
+        if (getEntries() == null && myState.mDialogListEntries != null) {
+            setEntries(myState.mDialogListEntries);
+        }
+        if (getEntryValues() == null && myState.mDialogListEntryValues != null) {
+            setEntryValues(myState.mDialogListEntryValues);
+        }
+        if (mCellInfoList == null && myState.mCellInfoList != null) {
+            mCellInfoList = myState.mCellInfoList;
+        }
+
+        super.onRestoreInstanceState(myState.getSuperState());
+    }
+
+    /**
+     *  We save entries, entryValues and operatorInfoList into bundle.
+     *  At onCreate of fragment, dialog will be restored if it was open. In this case,
+     *  we need to restore entries, entryValues and operatorInfoList. Without those information,
+     *  onPreferenceChange will fail if user select network from the dialog.
+     */
+    private static class SavedState extends BaseSavedState {
+        CharSequence[] mDialogListEntries;
+        CharSequence[] mDialogListEntryValues;
+        List<CellInfo> mCellInfoList;
+
+        SavedState(Parcel source) {
+            super(source);
+            final ClassLoader boot = Object.class.getClassLoader();
+            mDialogListEntries = source.readCharSequenceArray();
+            mDialogListEntryValues = source.readCharSequenceArray();
+            mCellInfoList = source.readParcelableList(mCellInfoList, boot);
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeCharSequenceArray(mDialogListEntries);
+            dest.writeCharSequenceArray(mDialogListEntryValues);
+            dest.writeParcelableList(mCellInfoList, flags);
+        }
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+    }
+
+    private void logd(String msg) {
+        Log.d(LOG_TAG, "[NetworksList] " + msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(LOG_TAG, "[NetworksList] " + msg);
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/mobilenetwork/RoamingDialogFragment.java b/src/com/android/settings/mobilenetwork/RoamingDialogFragment.java
new file mode 100644
index 0000000..1b1091b
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/RoamingDialogFragment.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 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.settings.mobilenetwork;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+
+/**
+ * A dialog fragment that asks the user if they are sure they want to turn on data roaming
+ * to avoid accidental charges.
+ */
+public class RoamingDialogFragment extends DialogFragment implements OnClickListener {
+
+    public static final String SUB_ID_KEY = "sub_id_key";
+
+    private CarrierConfigManager mCarrierConfigManager;
+    private int mSubId;
+
+    /**
+     * The interface we expect a host activity to implement.
+     */
+    public interface RoamingDialogListener {
+        void onPositiveButtonClick(DialogFragment dialog);
+    }
+
+    // the host activity which implements the listening interface
+    private RoamingDialogListener mListener;
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        Bundle args = getArguments();
+        mSubId = args.getInt(SUB_ID_KEY);
+        mCarrierConfigManager = new CarrierConfigManager(context);
+
+        // Verify host activity implemented callback interface
+        FragmentManager fragmentManager = getFragmentManager();
+        Fragment fragment = fragmentManager.findFragmentById(R.id.network_setting_content);
+        try {
+            mListener = (RoamingDialogListener) fragment;
+        } catch (ClassCastException e) {
+            throw new ClassCastException(fragment.toString() +
+                    "must implement RoamingDialogListener");
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        int title = R.string.roaming_alert_title;
+        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+        if (carrierConfig != null && carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
+            title = R.string.roaming_check_price_warning;
+        }
+        builder.setMessage(getResources().getString(R.string.roaming_warning))
+                .setTitle(title)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setPositiveButton(android.R.string.yes, this)
+                .setNegativeButton(android.R.string.no, this);
+        return builder.create();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        // let the host know that the positive button has been clicked
+        if (which == dialog.BUTTON_POSITIVE) {
+            mListener.onPositiveButtonClick(this);
+        }
+    }
+}
