Merge changes I7a0845c0,I45ecbc86,I3d0203b7,I7cfc27ff

* changes:
  Refactor DataUsagePreference
  Refactor carrier settings
  Refactor CdmaApnPreference
  Refactor CdmaSubscriptionListPreference
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9ed8417..ac8f305 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10259,6 +10259,9 @@
     <!-- Mobile network settings screen, message asking the user to check their pricing with their Carrier, when enabling Data roaming. [CHAR LIMIT=NONE] -->
     <string name="roaming_check_price_warning">Check with your network provider for pricing.</string>
 
+    <!-- Title for mobile data preference, to display the mobile data usage for each app. [CHAR LIMIT=NONE]-->
+    <string name="mobile_data_usage_title">App data usage</string>
+
     <!-- Available networks screen, summary when button disallowed due to permanent automatic mode [CHAR LIMIT=NONE] -->
     <string name="manual_mode_disallowed_summary">Unavailable when connected to <xliff:g id="carrier" example="verizon">%1$s</xliff:g></string>
 </resources>
diff --git a/res/xml/cdma_options.xml b/res/xml/cdma_options.xml
deleted file mode 100644
index 9226588..0000000
--- a/res/xml/cdma_options.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2008 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <com.android.settings.network.telephony.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.settingslib.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">
-        <!-- b/114749736, create a preference controller to build intent -->
-    </Preference>
-
-</PreferenceScreen>
diff --git a/res/xml/gsm_umts_options.xml b/res/xml/gsm_umts_options.xml
index f5439a4..1d1d4f3 100644
--- a/res/xml/gsm_umts_options.xml
+++ b/res/xml/gsm_umts_options.xml
@@ -27,7 +27,7 @@
             android:title="@string/select_automatically"
             android:persistent="false"/>
 
-        <com.android.settings.mobilenetwork.NetworkSelectListPreference
+        <com.android.settings.network.telephony.NetworkSelectListPreference
             android:key="button_network_select_key"
             android:title="@string/network_select_title"
             android:persistent="false"/>
diff --git a/res/xml/network_setting_fragment.xml b/res/xml/network_setting_fragment.xml
index 255c498..ce1644f 100644
--- a/res/xml/network_setting_fragment.xml
+++ b/res/xml/network_setting_fragment.xml
@@ -38,9 +38,10 @@
         android:summaryOn="@string/roaming_enable"
         android:summaryOff="@string/roaming_disable"/>
 
-    <com.android.settings.network.telephony.DataUsagePreference
+    <Preference
         android:key="data_usage_summary"
-        android:title="@string/data_usage_title" />
+        android:title="@string/mobile_data_usage_title"
+        settings:controller="com.android.settings.network.telephony.DataUsagePreferenceController"/>
 
     <SwitchPreference
         android:key="enhanced_4g_lte"
@@ -100,4 +101,29 @@
         android:dialogTitle="@string/cdma_system_select_dialogtitle"
         settings:controller="com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController"/>
 
+    <ListPreference
+        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"
+        settings:controller="com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController"/>
+
+    <!--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">
+        <com.android.settingslib.RestrictedPreference
+            android:key="button_cdma_apn_key"
+            android:title="@string/apn_settings"
+            android:persistent="false"
+            settings:controller="com.android.settings.network.telephony.cdma.CdmaApnPreferenceController"/>
+    </PreferenceCategory>
+
+    <Preference
+        android:key="carrier_settings_key"
+        android:title="@string/carrier_settings_title"
+        settings:controller="com.android.settings.network.telephony.CarrierPreferenceController">
+    </Preference>
+
 </PreferenceScreen>
diff --git a/src/com/android/settings/network/telephony/CarrierPreferenceController.java b/src/com/android/settings/network/telephony/CarrierPreferenceController.java
new file mode 100644
index 0000000..957eaaa
--- /dev/null
+++ b/src/com/android/settings/network/telephony/CarrierPreferenceController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.network.telephony;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * Preference controller for "Carrier Settings"
+ */
+public class CarrierPreferenceController extends BasePreferenceController {
+
+    @VisibleForTesting
+    CarrierConfigManager mCarrierConfigManager;
+    private int mSubId;
+
+    public CarrierPreferenceController(Context context, String key) {
+        super(context, key);
+        mCarrierConfigManager = new CarrierConfigManager(context);
+    }
+
+    public void init(int subId) {
+        mSubId = subId;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+
+        // Return available if it is in CDMA or GSM mode, and the flag is on
+        return carrierConfig != null
+                && carrierConfig.getBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL)
+                && (MobileNetworkUtils.isCdmaOptions(mContext, mSubId)
+                || MobileNetworkUtils.isGsmOptions(mContext, mSubId))
+                ? AVAILABLE
+                : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (getPreferenceKey().equals(preference.getKey())) {
+            //TODO(b/117651939): start carrier settings activity
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/src/com/android/settings/network/telephony/CdmaOptions.java b/src/com/android/settings/network/telephony/CdmaOptions.java
index b927e25..c573128 100644
--- a/src/com/android/settings/network/telephony/CdmaOptions.java
+++ b/src/com/android/settings/network/telephony/CdmaOptions.java
@@ -16,25 +16,11 @@
 
 package com.android.settings.network.telephony;
 
-import android.content.Intent;
-import android.os.PersistableBundle;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.telephony.CarrierConfigManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
 import androidx.preference.Preference;
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceScreen;
 
-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.settings.R;
-import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.settingslib.RestrictedPreference;
 
 /**
  * List of Phone-specific settings screens.
@@ -42,137 +28,18 @@
 public class CdmaOptions {
     private static final String LOG_TAG = "CdmaOptions";
 
-    private CarrierConfigManager mCarrierConfigManager;
-    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 PreferenceFragmentCompat mPrefFragment;
-    private PreferenceScreen mPrefScreen;
-    private int mSubId;
 
-    public CdmaOptions(PreferenceFragmentCompat prefFragment, PreferenceScreen prefScreen, int subId) {
+    public CdmaOptions(PreferenceFragmentCompat prefFragment, PreferenceScreen prefScreen,
+            int subId) {
         mPrefFragment = prefFragment;
-        mPrefScreen = prefScreen;
-        mPrefFragment.addPreferencesFromResource(R.xml.cdma_options);
-        mCarrierConfigManager = new CarrierConfigManager(prefFragment.getContext());
-
-        // Initialize preferences.
-        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);
-
-        // 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(
-                    MobileNetworkUtils.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) {
+        //TODO(b/114749736): handle it in preferenceController and remove this file
         if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
             log("preferenceTreeClick: return BUTTON_CDMA_ROAMING_KEY true");
             return true;
@@ -184,12 +51,6 @@
         return false;
     }
 
-    public void showDialog(Preference preference) {
-        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/network/telephony/CdmaSubscriptionListPreference.java b/src/com/android/settings/network/telephony/CdmaSubscriptionListPreference.java
deleted file mode 100644
index 559ba2d..0000000
--- a/src/com/android/settings/network/telephony/CdmaSubscriptionListPreference.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.network.telephony;
-
-import android.content.Context;
-import android.os.Bundle;
-import androidx.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 = "CdmaSubListPref";
-
-    // 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);
-    }
-
-    //TODO(b/114749736): move this logic to preference controller
-    protected void showDialog(Bundle state) {
-        setCurrentCdmaSubscriptionModeValue();
-    }
-
-    //TODO(b/114749736): move this logic to preference controller
-    protected void onDialogClosed(boolean 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/network/telephony/DataUsagePreference.java b/src/com/android/settings/network/telephony/DataUsagePreference.java
deleted file mode 100644
index 437ba63..0000000
--- a/src/com/android/settings/network/telephony/DataUsagePreference.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.network.telephony;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.NetworkTemplate;
-import androidx.preference.Preference;
-import android.provider.Settings;
-import android.telephony.TelephonyManager;
-import android.text.format.Formatter;
-import android.util.AttributeSet;
-
-import com.android.settings.R;
-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) {
-        final Context context = getContext();
-        mSubId = subId;
-        mTemplate = getNetworkTemplate(context, subId);
-
-        DataUsageController controller = new DataUsageController(context);
-
-        DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate);
-        setSummary(context.getString(R.string.data_usage_template,
-                Formatter.formatFileSize(context, 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(Context context, int subId) {
-        TelephonyManager tm = (TelephonyManager) context
-                .getSystemService(Context.TELEPHONY_SERVICE);
-        NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
-                tm.getSubscriberId(subId));
-        return NetworkTemplate.normalize(mobileAll,
-                tm.getMergedSubscriberIds());
-    }
-}
diff --git a/src/com/android/settings/network/telephony/DataUsagePreferenceController.java b/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
new file mode 100644
index 0000000..07c58c1
--- /dev/null
+++ b/src/com/android/settings/network/telephony/DataUsagePreferenceController.java
@@ -0,0 +1,100 @@
+/*
+ * 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.network.telephony;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.NetworkTemplate;
+import android.provider.Settings;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.text.format.Formatter;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.net.DataUsageController;
+
+/**
+ * Preference controller for "Data usage"
+ */
+public class DataUsagePreferenceController extends BasePreferenceController {
+
+    private NetworkTemplate mTemplate;
+    private DataUsageController.DataUsageInfo mDataUsageInfo;
+    private Intent mIntent;
+    private int mSubId;
+
+    public DataUsagePreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                ? AVAILABLE
+                : AVAILABLE_UNSEARCHABLE;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            mContext.startActivity(mIntent);
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        final boolean enabled = mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        preference.setEnabled(enabled);
+
+        if (enabled) {
+            preference.setSummary(mContext.getString(R.string.data_usage_template,
+                    Formatter.formatFileSize(mContext, mDataUsageInfo.usageLevel),
+                    mDataUsageInfo.period));
+        }
+    }
+
+    public void init(int subId) {
+        mSubId = subId;
+
+        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            mTemplate = getNetworkTemplate(mContext, subId);
+
+            final DataUsageController controller = new DataUsageController(mContext);
+            mDataUsageInfo = controller.getDataUsageInfo(mTemplate);
+
+            mIntent = new Intent(Settings.ACTION_MOBILE_DATA_USAGE);
+            mIntent.putExtra(Settings.EXTRA_NETWORK_TEMPLATE, mTemplate);
+            mIntent.putExtra(Settings.EXTRA_SUB_ID, mSubId);
+        }
+    }
+
+    private NetworkTemplate getNetworkTemplate(Context context, int subId) {
+        final TelephonyManager tm = TelephonyManager.from(context).createForSubscriptionId(subId);
+        NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(tm.getSubscriberId());
+
+        return NetworkTemplate.normalize(mobileAll, tm.getMergedSubscriberIds());
+    }
+
+}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkFragment.java b/src/com/android/settings/network/telephony/MobileNetworkFragment.java
index 3977cdd..5e6f5d5 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkFragment.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkFragment.java
@@ -66,6 +66,8 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.network.telephony.cdma.CdmaApnPreferenceController;
+import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController;
 import com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
@@ -159,9 +161,9 @@
     private Preference mWiFiCallingPref;
     private SwitchPreference mVideoCallingPref;
     private NetworkSelectListPreference mButtonNetworkSelect;
-    private DataUsagePreference mDataUsagePref;
 
     private CdmaSystemSelectPreferenceController mCdmaSystemSelectPreferenceController;
+    private CdmaSubscriptionPreferenceController mCdmaSubscriptionPreferenceController;
 
     private static final String iface = "rmnet0"; //TODO: this will go away
     private List<SubscriptionInfo> mActiveSubInfos;
@@ -304,8 +306,7 @@
             Intent intent = new Intent(EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS);
             startActivity(intent);
             return true;
-        } else if (preference == mWiFiCallingPref || preference == mVideoCallingPref
-                || preference == mDataUsagePref) {
+        } else if (preference == mWiFiCallingPref || preference == mVideoCallingPref) {
             return false;
         } else {
             // if the button is anything but the simple toggle preference,
@@ -397,9 +398,14 @@
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
         use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
+        use(CdmaApnPreferenceController.class).init(mSubId);
+        use(CarrierPreferenceController.class).init(mSubId);
+        use(DataUsagePreferenceController.class).init(mSubId);
 
         mCdmaSystemSelectPreferenceController = use(CdmaSystemSelectPreferenceController.class);
         mCdmaSystemSelectPreferenceController.init(getPreferenceManager(), mSubId);
+        mCdmaSubscriptionPreferenceController = use(CdmaSubscriptionPreferenceController.class);
+        mCdmaSubscriptionPreferenceController.init(getPreferenceManager(), mSubId);
     }
 
     @Override
@@ -426,7 +432,6 @@
         mCallingCategory = (PreferenceCategory) findPreference(CATEGORY_CALLING_KEY);
         mWiFiCallingPref = findPreference(BUTTON_WIFI_CALLING_KEY);
         mVideoCallingPref = (SwitchPreference) findPreference(BUTTON_VIDEO_CALLING_KEY);
-        mDataUsagePref = (DataUsagePreference) findPreference(BUTTON_DATA_USAGE_KEY);
 
         try {
             Context con = context.createPackageContext("com.android.systemui", 0);
@@ -576,14 +581,10 @@
         }
 
         prefSet.addPreference(mButtonDataRoam);
-        prefSet.addPreference(mDataUsagePref);
 
         mButtonDataRoam.setEnabled(hasActiveSubscriptions);
-        mDataUsagePref.setEnabled(hasActiveSubscriptions);
 
         if (hasActiveSubscriptions) {
-            // Customized preferences needs to be initialized with subId.
-            mDataUsagePref.initialize(phoneSubId);
 
             // Initialize states of mButtonDataRoam.
             mButtonDataRoam.setChecked(mTelephonyManager.isDataRoamingEnabled());
@@ -724,15 +725,6 @@
             }
         }
 
-        /**
-         * Listen to extra preference changes that need as Metrics events logging.
-         */
-
-        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));
@@ -1093,9 +1085,6 @@
                 mVideoCallingPref.setEnabled(false);
                 return false;
             }
-        } else if (preference == getPreferenceScreen()
-                .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
-            return true;
         }
 
         updateBody();
@@ -1431,11 +1420,13 @@
                         EXTRA_EXIT_ECM_RESULT, false);
                 if (isChoiceYes) {
                     // If the phone exits from ECM mode, show the CDMA Options
-                    if (TextUtils.equals(mClickedPreference.getKey(),
+                    final String key = mClickedPreference.getKey();
+                    if (TextUtils.equals(key,
                             mCdmaSystemSelectPreferenceController.getPreferenceKey())) {
                         mCdmaSystemSelectPreferenceController.showDialog();
-                    } else {
-                        mCdmaOptions.showDialog(mClickedPreference);
+                    } else if (TextUtils.equals(key,
+                            mCdmaSubscriptionPreferenceController.getPreferenceKey())) {
+                        mCdmaSubscriptionPreferenceController.showDialog();
                     }
                 } else {
                     // do nothing
@@ -1704,7 +1695,7 @@
         // 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
+        if (preference == mLteDataServicePref
                 || preference == mEuiccSettingsPref
                 || preference == mWiFiCallingPref || preference == mButtonPreferredNetworkMode
                 || preference == mButtonEnabledNetworks
@@ -1745,8 +1736,6 @@
             return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
         } 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 == mButton4glte) {
@@ -1802,8 +1791,6 @@
         // the open dialog gets dismissed or detached after pause / resume.
         if (mCdmaOptions == null) {
             mCdmaOptions = new CdmaOptions(prefFragment, prefScreen, subId);
-        } else {
-            mCdmaOptions.updateSubscriptionId(subId);
         }
     }
 
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index 666db1b..8950178 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -275,6 +275,20 @@
         return false;
     }
 
+    public static boolean isGsmOptions(Context context, int subId) {
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return false;
+        }
+        final TelephonyManager telephonyManager = TelephonyManager.from(context)
+                .createForSubscriptionId(subId);
+
+        if (telephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Return {@code true} if it is world mode, and we may show advanced options in telephony
      * settings
diff --git a/src/com/android/settings/network/telephony/cdma/CdmaApnPreferenceController.java b/src/com/android/settings/network/telephony/cdma/CdmaApnPreferenceController.java
new file mode 100644
index 0000000..eaacdb2
--- /dev/null
+++ b/src/com/android/settings/network/telephony/cdma/CdmaApnPreferenceController.java
@@ -0,0 +1,87 @@
+/*
+ * 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.network.telephony.cdma;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.PersistableBundle;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.network.ApnSettings;
+import com.android.settings.network.telephony.MobileNetworkUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.RestrictedPreference;
+
+/**
+ * Preference controller for "CDMA Apn"
+ */
+public class CdmaApnPreferenceController extends CdmaBasePreferenceController {
+
+    private static final String CATEGORY_KEY = "category_cdma_apn_key";
+    @VisibleForTesting
+    CarrierConfigManager mCarrierConfigManager;
+
+    public CdmaApnPreferenceController(Context context, String key) {
+        super(context, key);
+        mCarrierConfigManager = new CarrierConfigManager(context);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+
+        return carrierConfig != null
+                && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL)
+                && MobileNetworkUtils.isCdmaOptions(mContext, mSubId)
+                ? AVAILABLE
+                : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        if (isAvailable()) {
+            ((RestrictedPreference) mPreference).setDisabledByAdmin(
+                    MobileNetworkUtils.isDpcApnEnforced(mContext)
+                            ? RestrictedLockUtilsInternal.getDeviceOwner(mContext)
+                            : null);
+        } else {
+            screen.findPreference(CATEGORY_KEY).setVisible(false);
+        }
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (getPreferenceKey().equals(preference.getKey())) {
+            // This activity runs in phone process, we must use intent to start
+            final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
+            // This will setup the Home and Search affordance
+            intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true);
+            intent.putExtra(ApnSettings.SUB_ID, mSubId);
+            mContext.startActivity(intent);
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/src/com/android/settings/network/telephony/cdma/CdmaBasePreferenceController.java b/src/com/android/settings/network/telephony/cdma/CdmaBasePreferenceController.java
new file mode 100644
index 0000000..3e9ebc6
--- /dev/null
+++ b/src/com/android/settings/network/telephony/cdma/CdmaBasePreferenceController.java
@@ -0,0 +1,112 @@
+/*
+ * 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.network.telephony.cdma;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.network.telephony.MobileNetworkUtils;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+/**
+ * Preference controller related to CDMA category
+ */
+public abstract class CdmaBasePreferenceController extends BasePreferenceController
+        implements LifecycleObserver, OnStart, OnStop {
+
+    protected Preference mPreference;
+    protected TelephonyManager mTelephonyManager;
+    protected PreferenceManager mPreferenceManager;
+    protected int mSubId;
+    private DataContentObserver mDataContentObserver;
+
+    public CdmaBasePreferenceController(Context context, String key) {
+        super(context, key);
+        mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
+    }
+
+    @Override
+    public void onStart() {
+        mDataContentObserver.register(mContext, mSubId);
+    }
+
+    @Override
+    public void onStop() {
+        mDataContentObserver.unRegister(mContext);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return MobileNetworkUtils.isCdmaOptions(mContext, mSubId)
+                ? AVAILABLE
+                : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    public void init(PreferenceManager preferenceManager, int subId) {
+        mPreferenceManager = preferenceManager;
+        mSubId = subId;
+        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+    }
+
+    public void init(int subId) {
+        init(null, subId);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    /**
+     * Listener that listens to mobile data state change.
+     */
+    public class DataContentObserver extends ContentObserver {
+
+        public DataContentObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            updateState(mPreference);
+        }
+
+        public void register(Context context, int subId) {
+            final Uri uri = Settings.Global.getUriFor(
+                    Settings.Global.PREFERRED_NETWORK_MODE + subId);
+            context.getContentResolver().registerContentObserver(uri, false, this);
+        }
+
+        public void unRegister(Context context) {
+            context.getContentResolver().unregisterContentObserver(this);
+        }
+    }
+}
diff --git a/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceController.java b/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceController.java
new file mode 100644
index 0000000..eb14664
--- /dev/null
+++ b/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceController.java
@@ -0,0 +1,110 @@
+/*
+ * 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.network.telephony.cdma;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+
+import com.android.internal.telephony.Phone;
+import com.android.settings.network.telephony.MobileNetworkUtils;
+
+/**
+ * Preference controller for "CDMA subscription"
+ */
+public class CdmaSubscriptionPreferenceController extends CdmaBasePreferenceController
+        implements ListPreference.OnPreferenceChangeListener {
+    private static final String TYPE_NV = "NV";
+    private static final String TYPE_RUIM = "RUIM";
+
+    @VisibleForTesting
+    ListPreference mPreference;
+
+    public CdmaSubscriptionPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return MobileNetworkUtils.isCdmaOptions(mContext, mSubId) && deviceSupportsNvAndRuim()
+                ? AVAILABLE
+                : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        final ListPreference listPreference = (ListPreference) preference;
+        listPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE, Phone.PREFERRED_CDMA_SUBSCRIPTION);
+        if (mode != Phone.CDMA_SUBSCRIPTION_UNKNOWN) {
+            listPreference.setValue(Integer.toString(mode));
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object object) {
+        final int newMode = Integer.parseInt((String) object);
+        //TODO(b/117611981): only set it in one place
+        if (mTelephonyManager.setCdmaSubscriptionMode(newMode)) {
+            Settings.Global.putInt(mContext.getContentResolver(),
+                    Settings.Global.CDMA_SUBSCRIPTION_MODE, newMode);
+            return true;
+        }
+
+        return false;
+    }
+
+    public void showDialog() {
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE, Phone.PREFERRED_CDMA_SUBSCRIPTION);
+
+        mPreference.setValue(Integer.toString(mode));
+        mPreferenceManager.showDialog(mPreference);
+    }
+
+    @VisibleForTesting
+    boolean deviceSupportsNvAndRuim() {
+        // retrieve the list of subscription types supported by device.
+        final String subscriptionsSupported = SystemProperties.get("ril.subscription.types");
+        boolean nvSupported = false;
+        boolean ruimSupported = false;
+
+        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(TYPE_NV)) {
+                    nvSupported = true;
+                } else if (subscriptionType.equalsIgnoreCase(TYPE_RUIM)) {
+                    ruimSupported = true;
+                }
+            }
+        }
+
+        return (nvSupported && ruimSupported);
+    }
+}
diff --git a/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java b/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java
index 3d47fec..95e5dae 100644
--- a/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java
+++ b/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java
@@ -17,64 +17,20 @@
 package com.android.settings.network.telephony.cdma;
 
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 
-import androidx.annotation.VisibleForTesting;
 import androidx.preference.ListPreference;
 import androidx.preference.Preference;
-import androidx.preference.PreferenceManager;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.core.BasePreferenceController;
-import com.android.settings.network.telephony.MobileNetworkUtils;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
 
 /**
  * Preference controller for "System Select"
  */
-public class CdmaSystemSelectPreferenceController extends BasePreferenceController
-        implements LifecycleObserver, OnStart, OnStop, ListPreference.OnPreferenceChangeListener {
-
-    @VisibleForTesting
-    ListPreference mPreference;
-    private TelephonyManager mTelephonyManager;
-    private PreferenceManager mPreferenceManager;
-    private DataContentObserver mDataContentObserver;
-    private int mSubId;
+public class CdmaSystemSelectPreferenceController extends CdmaBasePreferenceController
+        implements ListPreference.OnPreferenceChangeListener {
 
     public CdmaSystemSelectPreferenceController(Context context, String key) {
         super(context, key);
-        mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
-    }
-
-    @Override
-    public void onStart() {
-        mDataContentObserver.register(mContext, mSubId);
-    }
-
-    @Override
-    public void onStop() {
-        mDataContentObserver.unRegister(mContext);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return MobileNetworkUtils.isCdmaOptions(mContext, mSubId)
-                ? AVAILABLE
-                : CONDITIONALLY_UNAVAILABLE;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = (ListPreference) screen.findPreference(getPreferenceKey());
     }
 
     @Override
@@ -106,12 +62,6 @@
         return false;
     }
 
-    public void init(PreferenceManager preferenceManager, int subId) {
-        mPreferenceManager = preferenceManager;
-        mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
-    }
-
     public void showDialog() {
         if (!mTelephonyManager.getEmergencyCallbackMode()) {
             mPreferenceManager.showDialog(mPreference);
@@ -119,37 +69,13 @@
     }
 
     private void resetCdmaRoamingModeToDefault() {
+        final ListPreference listPreference = (ListPreference) mPreference;
         //set the mButtonCdmaRoam
-        mPreference.setValue(Integer.toString(TelephonyManager.CDMA_ROAMING_MODE_ANY));
+        listPreference.setValue(Integer.toString(TelephonyManager.CDMA_ROAMING_MODE_ANY));
         //set the Settings.System
         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.CDMA_ROAMING_MODE,
                 TelephonyManager.CDMA_ROAMING_MODE_ANY);
         //Set the Status
         mTelephonyManager.setCdmaRoamingMode(TelephonyManager.CDMA_ROAMING_MODE_ANY);
     }
-
-    /**
-     * Listener that listens mobile data state change.
-     */
-    public class DataContentObserver extends ContentObserver {
-
-        public DataContentObserver(Handler handler) {
-            super(handler);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            super.onChange(selfChange);
-            updateState(mPreference);
-        }
-
-        public void register(Context context, int subId) {
-            Uri uri = Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE + subId);
-            context.getContentResolver().registerContentObserver(uri, false, this);
-        }
-
-        public void unRegister(Context context) {
-            context.getContentResolver().unregisterContentObserver(this);
-        }
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/CarrierPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/CarrierPreferenceControllerTest.java
new file mode 100644
index 0000000..e119e89
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/CarrierPreferenceControllerTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.network.telephony;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.PhoneConstants;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class CarrierPreferenceControllerTest {
+    private static final int SUB_ID = 2;
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private TelephonyManager mInvalidTelephonyManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+    @Mock
+    private CarrierConfigManager mCarrierConfigManager;
+
+    private CarrierPreferenceController mController;
+    private RestrictedPreference mPreference;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
+        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+        doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        mPreference = new RestrictedPreference(mContext);
+        mController = new CarrierPreferenceController(mContext, "mobile_data");
+        mController.init(SUB_ID);
+        mController.mCarrierConfigManager = mCarrierConfigManager;
+        mPreference.setKey(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void getAvailabilityStatus_cdmaWithFlagOff_returnUnavailable() {
+        doReturn(PhoneConstants.PHONE_TYPE_CDMA).when(mTelephonyManager).getPhoneType();
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL, false);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_cdmaWithFlagOnreturnAvailable() {
+        doReturn(PhoneConstants.PHONE_TYPE_CDMA).when(mTelephonyManager).getPhoneType();
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL, true);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_gsmWithFlagOnreturnAvailable() {
+        doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mTelephonyManager).getPhoneType();
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL, true);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java
new file mode 100644
index 0000000..013fb08
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.network.telephony;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class DataUsagePreferenceControllerTest {
+    private static final int SUB_ID = 2;
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    private DataUsagePreferenceController mController;
+    private SwitchPreference mPreference;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+
+        mPreference = new SwitchPreference(mContext);
+        mController = new DataUsagePreferenceController(mContext, "data_usage");
+        mController.init(SUB_ID);
+        mPreference.setKey(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void getAvailabilityStatus_validSubId_returnAvailable() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_invalidSubId_returnUnsearchable() {
+        mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE_UNSEARCHABLE);
+    }
+
+    @Test
+    public void handlePreferenceTreeClick_needDialog_showDialog() {
+        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        mController.handlePreferenceTreeClick(mPreference);
+
+        verify(mContext).startActivity(captor.capture());
+        final Intent intent = captor.getValue();
+
+        assertThat(intent.getAction()).isEqualTo(Settings.ACTION_MOBILE_DATA_USAGE);
+        assertThat(intent.getIntExtra(Settings.EXTRA_SUB_ID, 0)).isEqualTo(SUB_ID);
+    }
+
+    @Test
+    public void updateState_invalidSubId_disabled() {
+        mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.isEnabled()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaApnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaApnPreferenceControllerTest.java
new file mode 100644
index 0000000..2aceda7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaApnPreferenceControllerTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.network.telephony.cdma;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.PersistableBundle;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.PhoneConstants;
+import com.android.settings.network.ApnSettings;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class CdmaApnPreferenceControllerTest {
+    private static final int SUB_ID = 2;
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private TelephonyManager mInvalidTelephonyManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+    @Mock
+    private CarrierConfigManager mCarrierConfigManager;
+
+    private CdmaApnPreferenceController mController;
+    private RestrictedPreference mPreference;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
+        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+        doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        mPreference = new RestrictedPreference(mContext);
+        mController = new CdmaApnPreferenceController(mContext, "mobile_data");
+        mController.init(SUB_ID);
+        mController.mPreference = mPreference;
+        mController.mCarrierConfigManager = mCarrierConfigManager;
+        mPreference.setKey(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void getAvailabilityStatus_apnSettingsNotSupported_returnUnavailable() {
+        doReturn(PhoneConstants.PHONE_TYPE_CDMA).when(mTelephonyManager).getPhoneType();
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL, false);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_apnSettingsSupportedWithCDMA_returnAvailable() {
+        doReturn(PhoneConstants.PHONE_TYPE_CDMA).when(mTelephonyManager).getPhoneType();
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL, true);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void handPreferenceTreeClick_fireIntent() {
+        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+
+        mController.handlePreferenceTreeClick(mPreference);
+
+        verify(mContext).startActivity(captor.capture());
+        final Intent intent = captor.getValue();
+        assertThat(intent.getAction()).isEqualTo(Settings.ACTION_APN_SETTINGS);
+        assertThat(intent.getIntExtra(ApnSettings.SUB_ID, 0)).isEqualTo(SUB_ID);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java
new file mode 100644
index 0000000..c938948
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.network.telephony.cdma;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.preference.ListPreference;
+import androidx.preference.PreferenceManager;
+
+import com.android.internal.telephony.Phone;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class CdmaSubscriptionPreferenceControllerTest {
+    private static final int SUB_ID = 2;
+
+    @Mock
+    private PreferenceManager mPreferenceManager;
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private TelephonyManager mInvalidTelephonyManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+
+    private CdmaSubscriptionPreferenceController mController;
+    private ListPreference mPreference;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
+        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+        doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        mPreference = new ListPreference(mContext);
+        mController = new CdmaSubscriptionPreferenceController(mContext, "mobile_data");
+        mController.init(mPreferenceManager, SUB_ID);
+        mController.mPreference = mPreference;
+        mPreference.setKey(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void onPreferenceChange_selectNV_returnNVMode() {
+        doReturn(true).when(mTelephonyManager).setCdmaSubscriptionMode(anyInt());
+
+        mController.onPreferenceChange(mPreference, Integer.toString(Phone.CDMA_SUBSCRIPTION_NV));
+
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE,
+                Phone.CDMA_SUBSCRIPTION_RUIM_SIM)).isEqualTo(Phone.CDMA_SUBSCRIPTION_NV);
+    }
+
+    @Test
+    public void updateState_stateRUIM_displayRUIM() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE, Phone.CDMA_SUBSCRIPTION_NV);
+
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.getValue()).isEqualTo(Integer.toString(Phone.CDMA_SUBSCRIPTION_NV));
+    }
+
+    @Test
+    public void updateState_stateUnknown_doNothing() {
+        mPreference.setValue(Integer.toString(Phone.CDMA_SUBSCRIPTION_NV));
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE, Phone.CDMA_SUBSCRIPTION_UNKNOWN);
+
+        mController.updateState(mPreference);
+
+        // Still NV mode
+        assertThat(mPreference.getValue()).isEqualTo(Integer.toString(Phone.CDMA_SUBSCRIPTION_NV));
+    }
+
+    @Test
+    public void deviceSupportsNvAndRuim() {
+        SystemProperties.set("ril.subscription.types", "NV,RUIM");
+        assertThat(mController.deviceSupportsNvAndRuim()).isTrue();
+
+        SystemProperties.set("ril.subscription.types", "");
+
+        assertThat(mController.deviceSupportsNvAndRuim()).isFalse();
+    }
+}