Merge "Make sure close button has proper color"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 9ac9110..65d9c2e 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1232,6 +1232,17 @@
         <item>LTE/TDSCDMA/GSM/WCDMA</item>
         <item>TDSCDMA/CDMA/EVDO/GSM/WCDMA </item>
         <item>LTE/TDSCDMA/CDMA/EVDO/GSM/WCDMA</item>
+        <item>NR only</item>
+        <item>NR/LTE</item>
+        <item>NR/LTE/CDMA/EvDo</item>
+        <item>NR/LTE/GSM/WCDMA</item>
+        <item>NR/LTE/CDMA/EvDo/GSM/WCDMA</item>
+        <item>NR/LTE/WCDMA</item>
+        <item>NR/LTE/TDSCDMA</item>
+        <item>NR/LTE/TDSCDMA/GSM</item>
+        <item>NR/LTE/TDSCDMA/WCDMA</item>
+        <item>NR/LTE/TDSCDMA/GSM/WCDMA</item>
+        <item>NR/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" -->
@@ -1259,6 +1270,17 @@
         <item>"20"</item>
         <item>"21"</item>
         <item>"22"</item>
+        <item>"23"</item>
+        <item>"24"</item>
+        <item>"25"</item>
+        <item>"26"</item>
+        <item>"27"</item>
+        <item>"28"</item>
+        <item>"29"</item>
+        <item>"30"</item>
+        <item>"31"</item>
+        <item>"32"</item>
+        <item>"33"</item>
     </string-array>
 
     <!-- Choices for CDMA subscription-->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 246e901..94ed966 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10839,6 +10839,8 @@
     <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>
+    <!-- LTE/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_cdma_evdo_gsm_wcdma_summary">Preferred network mode: LTE/CDMA/EvDo/GSM/WCDMA</string>
     <!-- Global [CHAR LIMIT=NONE] -->
     <string name="preferred_network_mode_global_summary">Preferred network mode: Global</string>
     <!-- LTE / WCDMA [CHAR LIMIT=NONE] -->
@@ -10867,7 +10869,37 @@
     <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>
+    <!-- NR only [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_only_summary">Preferred network mode: NR only</string>
+    <!-- NR / LTE [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_summary">Preferred network mode: NR / LTE</string>
+    <!-- NR/LTE/CDMA/EvDo [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_cdma_evdo_summary">Preferred network mode: NR/LTE/CDMA/EvDo</string>
+    <!-- NR/LTE/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_gsm_wcdma_summary">Preferred network mode: NR/LTE/GSM/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_cdma_evdo_gsm_wcdma_summary">Preferred network mode: NR/LTE/CDMA/EvDo/GSM/WCDMA</string>
+    <!-- NR/LTE/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_wcdma_summary">Preferred network mode: NR/LTE/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_summary">Preferred network mode: NR/LTE/TDSCDMA</string>
+    <!-- NR/LTE/TDSCDMA/GSM [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_gsm_summary">Preferred network mode: NR/LTE/TDSCDMA/GSM</string>
+    <!-- NR/LTE/TDSCDMA/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_wcdma_summary">Preferred network mode: NR/LTE/TDSCDMA/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_gsm_wcdma_summary">Preferred network mode: NR/LTE/TDSCDMA/GSM/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
 
+    <!-- Text for Network mode recommended [CHAR LIMIT=NONE] -->
+    <string name="network_recommended">\u0020(recommended)</string>
+    <!-- Text for Network 5g [CHAR LIMIT=NONE] -->
+    <string name="network_5G" translatable="false">5G</string>
+    <!-- Text for Network lte [CHAR LIMIT=NONE] -->
+    <string name="network_lte_pure" translatable="false">LTE</string>
+    <!-- Text for Network 4g [CHAR LIMIT=NONE] -->
+    <string name="network_4G_pure" translatable="false">4G</string>
     <!-- Text for Network lte [CHAR LIMIT=NONE] -->
     <string name="network_lte">LTE (recommended)</string>
     <!-- Text for Network 4g [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index 5c6fe9c..d0c6811 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -101,28 +101,40 @@
     private static final String TAG = "RadioInfo";
 
     private static final String[] mPreferredNetworkLabels = {
-            "WCDMA preferred",
+            "GSM/WCDMA preferred",
             "GSM only",
             "WCDMA only",
-            "GSM auto (PRL)",
-            "CDMA auto (PRL)",
+            "GSM/WCDMA auto (PRL)",
+            "CDMA/EvDo auto (PRL)",
             "CDMA only",
             "EvDo only",
-            "Global auto (PRL)",
-            "LTE/CDMA auto (PRL)",
-            "LTE/UMTS auto (PRL)",
-            "LTE/CDMA/UMTS auto (PRL)",
+            "CDMA/EvDo/GSM/WCDMA (PRL)",
+            "CDMA + LTE/EvDo (PRL)",
+            "GSM/WCDMA/LTE (PRL)",
+            "LTE/CDMA/EvDo/GSM/WCDMA (PRL)",
             "LTE only",
             "LTE/WCDMA",
-            "TD-SCDMA only",
-            "TD-SCDMA/WCDMA",
-            "LTE/TD-SCDMA",
-            "TD-SCDMA/GSM",
-            "TD-SCDMA/UMTS",
-            "LTE/TD-SCDMA/WCDMA",
-            "LTE/TD-SCDMA/UMTS",
-            "TD-SCDMA/CDMA/UMTS",
-            "Global/TD-SCDMA",
+            "TDSCDMA only",
+            "TDSCDMA/WCDMA",
+            "LTE/TDSCDMA",
+            "TDSCDMA/GSM",
+            "LTE/TDSCDMA/GSM",
+            "TDSCDMA/GSM/WCDMA",
+            "LTE/TDSCDMA/WCDMA",
+            "LTE/TDSCDMA/GSM/WCDMA",
+            "TDSCDMA/CDMA/EvDo/GSM/WCDMA ",
+            "LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA",
+            "NR only",
+            "NR/LTE",
+            "NR/LTE/CDME/EvDo",
+            "NR/LTE/GSM/WCDMA",
+            "NR/LTE/CDMA/EvDo/GSM/WCDMA",
+            "NR/LTE/WCDMA",
+            "NR/LTE/TDSCDMA",
+            "NR/LTE/TDSCDMA/GSM",
+            "NR/LTE/TDSCDMA/WCDMA",
+            "NR/LTE/TDSCDMA/GSM/WCDMA",
+            "NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA",
             "Unknown"
     };
 
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index 94b1761..3abb36a 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -16,38 +16,67 @@
 
 package com.android.settings.network.telephony;
 
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
 import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
+import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
 import androidx.preference.ListPreference;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.settings.R;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Preference controller for "Enabled network mode"
  */
 public class EnabledNetworkModePreferenceController extends
         TelephonyBasePreferenceController implements
-        ListPreference.OnPreferenceChangeListener {
+        ListPreference.OnPreferenceChangeListener, LifecycleObserver {
 
+    private static final String LOG_TAG = "EnabledNetworkMode";
     private CarrierConfigManager mCarrierConfigManager;
+    private ContentObserver mPreferredNetworkModeObserver;
     private TelephonyManager mTelephonyManager;
     private boolean mIsGlobalCdma;
     @VisibleForTesting
     boolean mShow4GForLTE;
+    private Preference mPreference;
+    @VisibleForTesting
+    boolean mDisplay5gList = false;
 
     public EnabledNetworkModePreferenceController(Context context, String key) {
         super(context, key);
         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+        mPreferredNetworkModeObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+            @Override
+            public void onChange(boolean selfChange) {
+                if (mPreference != null) {
+                    updateState(mPreference);
+                }
+            }
+        };
     }
 
     @Override
@@ -61,13 +90,9 @@
         } else if (carrierConfig == null) {
             visible = false;
         } else if (carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)) {
-            visible = false;
-        } else if (carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)
-                && !telephonyManager.getServiceState().getRoaming()
-                && telephonyManager.getServiceState().getDataRegState()
-                == ServiceState.STATE_IN_SERVICE) {
+                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
+                || carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)) {
             visible = false;
         } else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
             visible = false;
@@ -78,6 +103,24 @@
         return visible ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
+    @OnLifecycleEvent(ON_START)
+    public void onStart() {
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE + mSubId), true,
+                mPreferredNetworkModeObserver);
+    }
+
+    @OnLifecycleEvent(ON_STOP)
+    public void onStop() {
+        mContext.getContentResolver().unregisterContentObserver(mPreferredNetworkModeObserver);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
@@ -102,7 +145,7 @@
         return false;
     }
 
-    public void init(int subId) {
+    public void init(Lifecycle lifecycle, int subId) {
         mSubId = subId;
         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
         mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
@@ -115,6 +158,12 @@
                 ? carrierConfig.getBoolean(
                 CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL)
                 : false;
+
+        final long supportedRadioBitmask = mTelephonyManager.getSupportedRadioAccessFamily();
+        mDisplay5gList = checkSupportedRadioBitmask(
+                supportedRadioBitmask, mTelephonyManager.NETWORK_TYPE_BITMASK_NR);
+
+        lifecycle.addObserver(this);
     }
 
     private int getPreferredNetworkMode() {
@@ -214,6 +263,139 @@
             preference.setEntryValues(
                     R.array.preferred_network_mode_values_world_mode);
         }
+
+        if (mDisplay5gList) {
+            add5gListItem(preference);
+        }
+    }
+
+    @VisibleForTesting
+    boolean checkSupportedRadioBitmask(long supportedRadioBitmask, long targetBitmask) {
+        Log.d(LOG_TAG, "supportedRadioBitmask: " + supportedRadioBitmask);
+        if ((targetBitmask & supportedRadioBitmask) > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /***
+     * Preferred network list add 5G item.
+     *
+     * @string/enabled_networks_cdma_choices
+     *         Before            |        After
+     * @string/network_lte   , 8 |@string/network_5G + @string/network_recommended , 25
+     * @string/network_3G    , 4 |@string/network_lte_pure, 8
+     * @string/network_1x    , 5 |@string/network_3G      , 4
+     * @string/network_global, 10|@string/network_1x      , 5
+     *                           |@string/network_global  , 27
+     *
+     * @string/enabled_networks_cdma_only_lte_choices
+     *         Before            |        After
+     * @string/network_lte   , 8 |@string/network_5G + @string/network_recommended , 25
+     * @string/network_global, 10|@string/network_lte_pure, 8
+     *                           |@string/network_global  , 27
+     *
+     * @string/enabled_networks_tdscdma_choices
+     *         Before         |        After
+     * @string/network_lte, 22|@string/network_5G + @string/network_recommended , 33
+     * @string/network_3G , 18|@string/network_lte_pure, 22
+     * @string/network_2G , 1 |@string/network_3G      , 18
+     *                        |@string/network_2G      , 1
+     *
+     * @string/enabled_networks_except_gsm_4g_choices
+     *         Before         |        After
+     * @string/network_4G , 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_4G_pure , 9
+     *                        |@string/network_3G      , 0
+     *
+     * @string/enabled_networks_except_gsm_choices
+     *         Before         |        After
+     * @string/network_lte, 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_lte_pure, 9
+     *                        |@string/network_3G      , 0
+     *
+     * @string/enabled_networks_4g_choices
+     *         Before         |        After
+     * @string/network_4G , 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_4G_pure , 9
+     * @string/network_2G , 1 |@string/network_3G      , 0
+     *                        |@string/network_2G      , 1
+     *
+     * @string/enabled_networks_choices
+     *         Before         |        After
+     * @string/network_lte, 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_lte_pure, 9
+     * @string/network_2G , 1 |@string/network_3G      , 0
+     *                        |@string/network_2G      , 1
+     *
+     * @string/preferred_network_mode_choices_world_mode
+     *         Before         |        After
+     * "Global"           , 10|@string/network_global  , 27
+     * "LTE / CDMA"       , 8 |"LTE / CDMA"            , 8
+     * "LTE / GSM / UMTS" , 9 |"LTE / GSM / UMTS"      , 9
+     */
+    @VisibleForTesting
+    void add5gListItem(ListPreference preference) {
+        final CharSequence[] oldEntries = preference.getEntries();
+        final CharSequence[] oldEntryValues = preference.getEntryValues();
+        List<CharSequence> newEntries = new ArrayList<>();
+        List<CharSequence> newEntryValues = new ArrayList<>();
+
+        CharSequence oldEntry;
+        CharSequence oldEntryValue;
+        CharSequence new5gEntry;
+        CharSequence new5gEntryValue;
+
+        for (int i = 0; i < oldEntries.length; i++) {
+            oldEntry = oldEntries[i];
+            oldEntryValue = oldEntryValues[i];
+            new5gEntry = "";
+            new5gEntryValue = "";
+
+            if (mContext.getString(R.string.network_lte).equals(oldEntry)) {
+                oldEntry = mContext.getString(R.string.network_lte_pure);
+                new5gEntry = mContext.getString(R.string.network_5G)
+                        + mContext.getString(R.string.network_recommended);
+                new5gEntryValue = transformLteEntryValueTo5gEntryValue(oldEntryValue);
+            } else if (mContext.getString(R.string.network_4G).equals(oldEntry)) {
+                oldEntry = mContext.getString(R.string.network_4G_pure);
+                new5gEntry = mContext.getString(R.string.network_5G)
+                        + mContext.getString(R.string.network_recommended);
+                new5gEntryValue = transformLteEntryValueTo5gEntryValue(oldEntryValue);
+            } else if (mContext.getString(R.string.network_global).equals(oldEntry)) {
+                //oldEntry: network_global
+                //oldEntryValue: TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA
+                oldEntryValue = Integer.toString(
+                        TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
+            }
+
+            if (!TextUtils.isEmpty(new5gEntry)) {
+                newEntries.add(new5gEntry);
+                newEntryValues.add(new5gEntryValue);
+            }
+            newEntries.add(oldEntry);
+            newEntryValues.add(oldEntryValue);
+        }
+
+        preference.setEntries(newEntries.toArray(new CharSequence[newEntries.size()]));
+        preference.setEntryValues(newEntryValues.toArray(new CharSequence[newEntryValues.size()]));
+    }
+
+    /**
+     * LTE network mode transform to 5G network mode.
+     *
+     * @param networkMode this is LTE network mode.
+     * @return 5G network mode.
+     */
+    private CharSequence transformLteEntryValueTo5gEntryValue(CharSequence networkMode) {
+        int networkModeInt = Integer.valueOf(networkMode.toString());
+        return Integer.toString(addNrToNetworkType(networkModeInt));
+    }
+
+    private int addNrToNetworkType(int networkType) {
+        long networkTypeBitmasks = RadioAccessFamily.getRafFromNetworkType(networkType);
+        networkTypeBitmasks |= mTelephonyManager.NETWORK_TYPE_BITMASK_NR;
+        return RadioAccessFamily.getNetworkTypeFromRaf((int) networkTypeBitmasks);
     }
 
     private void updatePreferenceValueAndSummary(ListPreference preference, int networkMode) {
@@ -277,7 +459,8 @@
                 } else {
                     preference.setValue(
                             Integer.toString(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO));
-                    preference.setSummary(R.string.network_lte);
+                    preference.setSummary(
+                            mDisplay5gList ? R.string.network_lte_pure : R.string.network_lte);
                 }
                 break;
             case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
@@ -312,7 +495,8 @@
                     preference.setValue(
                             Integer.toString(TelephonyManager
                                     .NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
-                    preference.setSummary(R.string.network_lte);
+                    preference.setSummary(
+                            mDisplay5gList ? R.string.network_lte_pure : R.string.network_lte);
                 } else {
                     preference.setValue(
                             Integer.toString(TelephonyManager
@@ -322,11 +506,34 @@
                             || MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
                         preference.setSummary(R.string.network_global);
                     } else {
-                        preference.setSummary(mShow4GForLTE
-                                ? R.string.network_4G : R.string.network_lte);
+                        if (mDisplay5gList) {
+                            preference.setSummary(mShow4GForLTE
+                                    ? R.string.network_4G_pure : R.string.network_lte_pure);
+                        } else {
+                            preference.setSummary(mShow4GForLTE
+                                    ? R.string.network_4G : R.string.network_lte);
+                        }
                     }
                 }
                 break;
+            case TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO:
+            case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                preference.setValue(Integer.toString(networkMode));
+                preference.setSummary(mContext.getString(R.string.network_5G)
+                        + mContext.getString(R.string.network_recommended));
+                break;
+            case TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
+                preference.setValue(
+                        Integer.toString(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA));
+                if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+                        || mIsGlobalCdma
+                        || MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
+                    preference.setSummary(R.string.network_global);
+                } else {
+                    preference.setSummary(mContext.getString(R.string.network_5G)
+                            + mContext.getString(R.string.network_recommended));
+                }
+                break;
             default:
                 preference.setSummary(
                         mContext.getString(R.string.mobile_network_mode_error, networkMode));
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index c8e2247..8d83ef2 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -150,7 +150,7 @@
         use(CarrierPreferenceController.class).init(mSubId);
         use(DataUsagePreferenceController.class).init(mSubId);
         use(PreferredNetworkModePreferenceController.class).init(mSubId);
-        use(EnabledNetworkModePreferenceController.class).init(mSubId);
+        use(EnabledNetworkModePreferenceController.class).init(getLifecycle(), mSubId);
         use(DataServiceSetupPreferenceController.class).init(mSubId);
         if (!FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
             use(EuiccPreferenceController.class).init(mSubId);
diff --git a/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
index 294f05f..7b24a93 100644
--- a/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
@@ -58,13 +58,9 @@
         } else if (carrierConfig == null) {
             visible = false;
         } else if (carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)) {
-            visible = false;
-        } else if (carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)
-                && !telephonyManager.getServiceState().getRoaming()
-                && telephonyManager.getServiceState().getDataRegState()
-                == ServiceState.STATE_IN_SERVICE) {
+                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
+                || carrierConfig.getBoolean(
+                CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)) {
             visible = false;
         } else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
             visible = true;
diff --git a/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
index ba8be90..773041d 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.network.telephony;
 
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
 
@@ -23,19 +25,27 @@
 
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.net.Uri;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
+import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.ListPreference;
+import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,6 +58,7 @@
 @RunWith(RobolectricTestRunner.class)
 public class EnabledNetworkModePreferenceControllerTest {
     private static final int SUB_ID = 2;
+    public static final String KEY = "enabled_network";
 
     @Mock
     private TelephonyManager mTelephonyManager;
@@ -55,16 +66,21 @@
     private TelephonyManager mInvalidTelephonyManager;
     @Mock
     private CarrierConfigManager mCarrierConfigManager;
+    @Mock
+    private ServiceState mServiceState;
 
     private PersistableBundle mPersistableBundle;
     private EnabledNetworkModePreferenceController mController;
     private ListPreference mPreference;
     private Context mContext;
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
         mContext = spy(RuntimeEnvironment.application);
         doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
         doReturn(mTelephonyManager).when(mContext).getSystemService(TelephonyManager.class);
@@ -73,14 +89,15 @@
         doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         doReturn(mContext).when(mContext).createPackageContext(anyString(), anyInt());
+        doReturn(mServiceState).when(mTelephonyManager).getServiceState();
         mPersistableBundle = new PersistableBundle();
         doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
 
         mPreference = new ListPreference(mContext);
         mPreference.setEntries(R.array.enabled_networks_choices);
         mPreference.setEntryValues(R.array.enabled_networks_values);
-        mController = new EnabledNetworkModePreferenceController(mContext, "enabled_network");
-        mController.init(SUB_ID);
+        mController = new EnabledNetworkModePreferenceController(mContext, KEY);
+        mController.init(mLifecycle, SUB_ID);
         mPreference.setKey(mController.getPreferenceKey());
     }
 
@@ -93,6 +110,25 @@
     }
 
     @Test
+    public void getAvailabilityStatus_hidePreferredNetworkType_returnUnavailable() {
+        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL,
+                true);
+
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+
+        when(mServiceState.getRoaming()).thenReturn(false);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+
+        when(mServiceState.getRoaming()).thenReturn(true);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
     public void getAvailabilityStatus_notWorldPhone_returnAvailable() {
         mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
                 false);
@@ -106,12 +142,32 @@
         mPersistableBundle.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL,
                 true);
 
-        mController.init(SUB_ID);
+        mController.init(mLifecycle, SUB_ID);
 
         assertThat(mController.mShow4GForLTE).isTrue();
     }
 
     @Test
+    public void init_initDisplay5gList_returnTrue() {
+        long testBitmask = TelephonyManager.NETWORK_TYPE_BITMASK_NR
+                | TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+        doReturn(testBitmask).when(mTelephonyManager).getSupportedRadioAccessFamily();
+
+        mController.init(mLifecycle, SUB_ID);
+
+        assertThat(mController.mDisplay5gList).isTrue();
+    }
+
+    @Test
+    public void checkSupportedRadioBitmask_nrBitmask_returnTrue() {
+        long testBitmask = TelephonyManager.NETWORK_TYPE_BITMASK_NR
+                | TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+
+        assertThat(mController.checkSupportedRadioBitmask(testBitmask,
+                TelephonyManager.NETWORK_TYPE_BITMASK_NR)).isTrue();
+    }
+
+    @Test
     public void updateState_updateByNetworkMode() {
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
@@ -136,6 +192,203 @@
                 String.valueOf(TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA));
     }
 
+    /**
+     * @string/enabled_networks_cdma_choices
+     *         Before            |        After
+     * @string/network_lte   , 8 |@string/network_5G + @string/network_recommended , 25
+     * @string/network_3G    , 4 |@string/network_lte_pure, 8
+     * @string/network_1x    , 5 |@string/network_3G      , 4
+     * @string/network_global, 10|@string/network_1x      , 5
+     *                           |@string/network_global  , 27
+     *
+     * @string/enabled_networks_cdma_only_lte_choices
+     *         Before            |        After
+     * @string/network_lte   , 8 |@string/network_5G + @string/network_recommended , 25
+     * @string/network_global, 10|@string/network_lte_pure, 8
+     *                           |@string/network_global  , 27
+     */
+    @Test
+    public void add5gListItem_lteCdma_5gLteCdma() {
+        //case#1
+        mPreference.setEntries(R.array.enabled_networks_cdma_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_cdma_values);
+        CharSequence[] testEntries = {mContext.getString(R.string.network_5G)
+                + mContext.getString(R.string.network_recommended)
+                , mContext.getString(R.string.network_lte_pure)
+                , mContext.getString(R.string.network_3G)
+                , mContext.getString(R.string.network_1x)
+                , mContext.getString(R.string.network_global)};
+        CharSequence[] testEntryValues = {"25", "8", "4", "5", "27"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues);
+
+        //case#2
+        mPreference.setEntries(R.array.enabled_networks_cdma_only_lte_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_cdma_only_lte_values);
+        CharSequence[] testEntries1 = {mContext.getString(R.string.network_5G)
+                + mContext.getString(R.string.network_recommended)
+                , mContext.getString(R.string.network_lte_pure)
+                , mContext.getString(R.string.network_global)};
+        CharSequence[] testEntryValues1 = {"25", "8", "27"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries1);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues1);
+    }
+
+    /**
+     * @string/enabled_networks_except_gsm_4g_choices
+     *         Before         |        After
+     * @string/network_4G , 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_4G_pure , 9
+     *                        |@string/network_3G      , 0
+     *
+     * @string/enabled_networks_except_gsm_choices
+     *         Before         |        After
+     * @string/network_lte, 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_lte_pure, 9
+     *                        |@string/network_3G      , 0
+     *
+     * @string/enabled_networks_4g_choices
+     *         Before         |        After
+     * @string/network_4G , 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_4G_pure , 9
+     * @string/network_2G , 1 |@string/network_3G      , 0
+     *                        |@string/network_2G      , 1
+     *
+     * @string/enabled_networks_choices
+     *         Before         |        After
+     * @string/network_lte, 9 |@string/network_5G + @string/network_recommended , 26
+     * @string/network_3G , 0 |@string/network_lte_pure, 9
+     * @string/network_2G , 1 |@string/network_3G      , 0
+     *                        |@string/network_2G      , 1
+     */
+    @Test
+    public void add5gListItem_lteGsm_5gLteGsm() {
+        //csae#1
+        mPreference.setEntries(R.array.enabled_networks_except_gsm_4g_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_except_gsm_values);
+        CharSequence[] testEntries = {mContext.getString(R.string.network_5G)
+                + mContext.getString(R.string.network_recommended)
+                , mContext.getString(R.string.network_4G_pure)
+                , mContext.getString(R.string.network_3G)};
+        CharSequence[] testEntryValues = {"26", "9", "0"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues);
+
+        //case#2
+        mPreference.setEntries(R.array.enabled_networks_except_gsm_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_except_gsm_values);
+        CharSequence[] testEntries1 = {mContext.getString(R.string.network_5G)
+                + mContext.getString(R.string.network_recommended)
+                , mContext.getString(R.string.network_lte_pure)
+                , mContext.getString(R.string.network_3G)};
+        CharSequence[] testEntryValues1 = {"26", "9", "0"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries1);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues1);
+
+        //case#3
+        mPreference.setEntries(R.array.enabled_networks_4g_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_values);
+        CharSequence[] testEntries2 = {mContext.getString(R.string.network_5G)
+                + mContext.getString(R.string.network_recommended)
+                , mContext.getString(R.string.network_4G_pure)
+                , mContext.getString(R.string.network_3G)
+                , mContext.getString(R.string.network_2G)};
+        CharSequence[] testEntryValues2 = {"26", "9", "0", "1"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries2);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues2);
+
+        //case#4
+        mPreference.setEntries(R.array.enabled_networks_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_values);
+        CharSequence[] testEntries3 = {mContext.getString(R.string.network_5G)
+                + mContext.getString(R.string.network_recommended)
+                , mContext.getString(R.string.network_lte_pure)
+                , mContext.getString(R.string.network_3G)
+                , mContext.getString(R.string.network_2G)};
+        CharSequence[] testEntryValues3 = {"26", "9", "0", "1"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries3);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues3);
+    }
+
+    /**
+     * @string/preferred_network_mode_choices_world_mode
+     *         Before         |        After
+     * "Global"           , 10|@string/network_global  , 27
+     * "LTE / CDMA"       , 8 |"LTE / CDMA"            , 8
+     * "LTE / GSM / UMTS" , 9 |"LTE / GSM / UMTS"      , 9
+     */
+    @Test
+    public void add5gListItem_worldPhone_Global() {
+        mPreference.setEntries(R.array.preferred_network_mode_choices_world_mode);
+        mPreference.setEntryValues(R.array.preferred_network_mode_values_world_mode);
+        CharSequence[] testEntries = {mContext.getString(R.string.network_global)
+                , "LTE / CDMA"
+                , "LTE / GSM / UMTS"};
+        CharSequence[] testEntryValues = {"27", "8", "9"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues);
+    }
+
+    /**
+     * @string/enabled_networks_tdscdma_choices
+     *         Before         |        After
+     * @string/network_lte, 22|@string/network_5G + @string/network_recommended , 33
+     * @string/network_3G , 18|@string/network_lte_pure, 22
+     * @string/network_2G , 1 |@string/network_3G      , 18
+     *                        |@string/network_2G      , 1
+     */
+    @Test
+    public void add5gListItem_td_5gTd() {
+        mPreference.setEntries(R.array.enabled_networks_tdscdma_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_tdscdma_values);
+        CharSequence[] testEntries = {mContext.getString(R.string.network_5G)
+                + mContext.getString(R.string.network_recommended)
+                , mContext.getString(R.string.network_lte_pure)
+                , mContext.getString(R.string.network_3G)
+                , mContext.getString(R.string.network_2G)};
+        CharSequence[] testEntryValues = {"33", "22", "18", "1"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues);
+    }
+
+    @Test
+    public void add5gListItem_noLte_no5g() {
+        mPreference.setEntries(R.array.enabled_networks_except_lte_choices);
+        mPreference.setEntryValues(R.array.enabled_networks_except_lte_values);
+        CharSequence[] testEntries = {mContext.getString(R.string.network_3G)
+                , mContext.getString(R.string.network_2G)};
+        CharSequence[] testEntryValues = {"0", "1"};
+
+        mController.add5gListItem(mPreference);
+
+        assertThat(mPreference.getEntries()).isEqualTo(testEntries);
+        assertThat(mPreference.getEntryValues()).isEqualTo(testEntryValues);
+    }
+
     @Test
     public void onPreferenceChange_updateSuccess() {
         doReturn(true).when(mTelephonyManager).setPreferredNetworkType(SUB_ID,
@@ -161,4 +414,31 @@
                 Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID, 0)).isNotEqualTo(
                 TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA);
     }
+
+    @Test
+    public void preferredNetworkModeNotification_preferenceUpdates() {
+        PreferenceScreen screen = mock(PreferenceScreen.class);
+        doReturn(mPreference).when(screen).findPreference(KEY);
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
+                TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
+        mController.displayPreference(screen);
+        mController.updateState(mPreference);
+        mLifecycle.handleLifecycleEvent(ON_START);
+
+        assertThat(Integer.parseInt(mPreference.getValue())).isEqualTo(
+                TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
+        assertThat(mPreference.getSummary()).isEqualTo("3G");
+
+
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
+                TelephonyManager.NETWORK_MODE_GSM_ONLY);
+        final Uri uri = Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID);
+        mContext.getContentResolver().notifyChange(uri, null);
+
+        assertThat(Integer.parseInt(mPreference.getValue())).isEqualTo(
+                TelephonyManager.NETWORK_MODE_GSM_ONLY);
+        assertThat(mPreference.getSummary()).isEqualTo("2G");
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java
index 6807ab6..9c03389 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java
@@ -23,11 +23,13 @@
 
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
@@ -54,6 +56,8 @@
     private TelephonyManager mInvalidTelephonyManager;
     @Mock
     private CarrierConfigManager mCarrierConfigManager;
+    @Mock
+    private ServiceState mServiceState;
 
     private PersistableBundle mPersistableBundle;
     private PreferredNetworkModePreferenceController mController;
@@ -71,6 +75,7 @@
         doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
         doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        doReturn(mServiceState).when(mTelephonyManager).getServiceState();
         mPersistableBundle = new PersistableBundle();
         doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
 
@@ -100,6 +105,25 @@
     }
 
     @Test
+    public void getAvailabilityStatus_hidePreferredNetworkType_returnUnavailable() {
+        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL,
+                true);
+
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+
+        when(mServiceState.getRoaming()).thenReturn(false);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+
+        when(mServiceState.getRoaming()).thenReturn(true);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
     public void updateState_updateByNetworkMode() {
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,