Merge "Handle 5G meteredness in telephony framework" into qt-qpr1-dev-plus-aosp
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0c5faff..1e4d010 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -39,6 +39,7 @@
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
+    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
@@ -71,7 +72,7 @@
     <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />
     <uses-permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_MODE" />
     <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
-    <uses-permission android:name="android.permission.SET_TIME" />
+    <uses-permission android:name="android.permission.SUGGEST_MANUAL_TIME_AND_ZONE" />
     <uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" />
     <uses-permission android:name="android.permission.REBOOT" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index ef75d03..b9a1939 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -465,6 +465,7 @@
         <item>1xRTT</item>
         <item>IS95B</item>
         <item>IS95A</item>
+        <item>NR</item>
     </string-array>
 
     <string-array translatable="false" name="bearer_values">
@@ -500,6 +501,8 @@
         <item>5</item>
         <!-- Do not translate. -->
         <item>4</item>
+        <!-- Do not translate. -->
+        <item>20</item>
     </string-array>
 
     <!-- MVNO Info used in APN editor -->
diff --git a/res/values/config.xml b/res/values/config.xml
index 5eb55ae..e4b4812 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -417,4 +417,7 @@
 
     <!-- "Show work policy info" intent action. TODO(b/134391103): Replace with final SystemAPI intent when it's available. -->
     <string name="config_work_policy_info_intent_action" translatable="false"/>
+
+    <!-- RTT setting intent action -->
+    <string name="config_rtt_setting_intent_action" translatable="false"></string>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 31a1592..5ee7171 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -218,8 +218,8 @@
     <dimen name="fingerprint_finish_max_size">288dp</dimen>
 
     <!-- Face -->
-    <dimen name="face_preview_translate_y">0dp</dimen>
-    <dimen name="face_preview_translate_x">0dp</dimen>
+    <item name="face_preview_translate_y" format="float" type="dimen">0</item>
+    <item name="face_preview_translate_x" format="float" type="dimen">0</item>
     <item name="face_preview_scale" format="float" type="dimen">1.0</item>
 
     <!-- Confirm device credentials -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 70e998b..123482a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -11280,5 +11280,13 @@
     <string name="work_policy_privacy_settings">Your work policy info</string>
     <!-- Summary for Enterprise Privacy settings, explaining what the user can expect to find under it [CHAR LIMIT=NONE]-->
     <string name="work_policy_privacy_settings_summary">Settings managed by your IT admin</string>
+    <!-- Title for RTT setting. [CHAR LIMIT=NONE] -->
+    <string name="rtt_settings_title"></string>
+    <!-- Subtext for showing the option of RTT setting. [CHAR LIMIT=NONE] -->
+    <string name="rtt_settings_no_visible"></string>
+    <!-- Subtext for showing the option of RTT setting. [CHAR LIMIT=NONE] -->
+    <string name="rtt_settings_visible_during_call"></string>
+    <!-- Subtext for showing the option of RTT setting. [CHAR LIMIT=NONE] -->
+    <string name="rtt_settings_always_visible"></string>
 
 </resources>
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index 3ac6f42..1dd609e 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -22,13 +22,6 @@
     android:title="@string/privacy_dashboard_title"
     settings:initialExpandedChildrenCount="4">
 
-    <!-- This preference isn't searchable, and user won't see title in this preference.
-         So, we just set empty text for title. -->
-    <com.android.settingslib.widget.BarChartPreference
-        android:key="permission_bar_chart"
-        android:title="@string/summary_placeholder"
-        settings:controller="com.android.settings.privacy.PermissionBarChartPreferenceController"/>
-
     <!-- Work Policy info -->
     <Preference
         android:key="work_policy_info"
diff --git a/res/xml/security_settings_face.xml b/res/xml/security_settings_face.xml
index 7d59f30..e613470 100644
--- a/res/xml/security_settings_face.xml
+++ b/res/xml/security_settings_face.xml
@@ -64,7 +64,11 @@
             android:summary="@string/security_settings_face_settings_require_confirmation_details"
             app:keywords="@string/keywords_face_unlock"
             app:controller="com.android.settings.biometrics.face.FaceSettingsConfirmPreferenceController"/>
+    </PreferenceCategory>
 
+    <PreferenceCategory
+        android:key="security_settings_face_button_category"
+        android:title="@string/security_settings_face_preference_title">
         <com.android.settingslib.widget.LayoutPreference
             android:key="security_settings_face_delete_faces_container"
             android:selectable="false"
@@ -73,7 +77,7 @@
         <com.android.settingslib.widget.LayoutPreference
             android:key="security_settings_face_enroll_faces_container"
             android:selectable="false"
-            android:layout="@layout/face_enroll_button " />
+            android:layout="@layout/face_enroll_button" />
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
index dde7ce0..a843a04 100644
--- a/src/com/android/settings/AirplaneModeEnabler.java
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -19,28 +19,34 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.telephony.PhoneStateListener;
+import android.telephony.SubscriptionInfo;
+import android.telephony.TelephonyManager;
+import android.util.Log;
 
-import com.android.internal.telephony.PhoneStateIntentReceiver;
-import com.android.internal.telephony.TelephonyProperties;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.network.GlobalSettingsChangeListener;
+import com.android.settings.network.ProxySubscriptionManager;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.WirelessUtils;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
-public class AirplaneModeEnabler {
+import java.util.List;
 
-    private static final int EVENT_SERVICE_STATE_CHANGED = 3;
+/**
+ * Monitor and update configuration of airplane mode settings
+ */
+public class AirplaneModeEnabler extends GlobalSettingsChangeListener {
+
+    private static final String LOG_TAG = "AirplaneModeEnabler";
+    private static final boolean DEBUG = false;
 
     private final Context mContext;
     private final MetricsFeatureProvider mMetricsFeatureProvider;
 
-    private PhoneStateIntentReceiver mPhoneStateReceiver;
-
     private OnAirplaneModeChangedListener mOnAirplaneModeChangedListener;
 
     public interface OnAirplaneModeChangedListener {
@@ -52,46 +58,50 @@
         void onAirplaneModeChanged(boolean isAirplaneModeOn);
     }
 
-    private Handler mHandler = new Handler(Looper.getMainLooper()) {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_SERVICE_STATE_CHANGED:
-                    onAirplaneModeChanged();
-                    break;
-            }
-        }
-    };
+    private TelephonyManager mTelephonyManager;
+    @VisibleForTesting
+    PhoneStateListener mPhoneStateListener;
 
-    private ContentObserver mAirplaneModeObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange) {
-            onAirplaneModeChanged();
-        }
-    };
+    private GlobalSettingsChangeListener mAirplaneModeObserver;
 
-    public AirplaneModeEnabler(Context context, MetricsFeatureProvider metricsFeatureProvider,
-            OnAirplaneModeChangedListener listener) {
+    public AirplaneModeEnabler(Context context, OnAirplaneModeChangedListener listener) {
+        super(context, Settings.Global.AIRPLANE_MODE_ON);
 
         mContext = context;
-        mMetricsFeatureProvider = metricsFeatureProvider;
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
         mOnAirplaneModeChangedListener = listener;
 
-        mPhoneStateReceiver = new PhoneStateIntentReceiver(mContext, mHandler);
-        mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
+        mTelephonyManager = context.getSystemService(TelephonyManager.class);
+
+        mPhoneStateListener = new PhoneStateListener() {
+            @Override
+            public void onRadioPowerStateChanged(int state) {
+                if (DEBUG) {
+                    Log.d(LOG_TAG, "RadioPower: " + state);
+                }
+                onAirplaneModeChanged();
+            }
+        };
+    }
+
+    /**
+     * Implementation of GlobalSettingsChangeListener.onChanged
+     */
+    public void onChanged(String field) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "Airplane mode configuration update");
+        }
+        onAirplaneModeChanged();
     }
 
     public void resume() {
-        mPhoneStateReceiver.registerIntent();
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
-                mAirplaneModeObserver);
+        mTelephonyManager.listen(mPhoneStateListener,
+                PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED);
     }
 
     public void pause() {
-        mPhoneStateReceiver.unregisterIntent();
-        mContext.getContentResolver().unregisterContentObserver(mAirplaneModeObserver);
+        mTelephonyManager.listen(mPhoneStateListener,
+                PhoneStateListener.LISTEN_NONE);
     }
 
     private void setAirplaneModeOn(boolean enabling) {
@@ -105,7 +115,7 @@
         }
 
         // Post the intent
-        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+        final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         intent.putExtra("state", enabling);
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
     }
@@ -124,10 +134,36 @@
         }
     }
 
+    /**
+     * Check the status of ECM mode
+     *
+     * @return any subscription within device is under ECM mode
+     */
+    public boolean isInEcmMode() {
+        if (mTelephonyManager.getEmergencyCallbackMode()) {
+            return true;
+        }
+        final List<SubscriptionInfo> subInfoList =
+                ProxySubscriptionManager.getInstance(mContext).getActiveSubscriptionsInfo();
+        if (subInfoList == null) {
+            return false;
+        }
+        for (SubscriptionInfo subInfo : subInfoList) {
+            final TelephonyManager telephonyManager =
+                    mTelephonyManager.createForSubscriptionId(subInfo.getSubscriptionId());
+            if (telephonyManager != null) {
+                if (telephonyManager.getEmergencyCallbackMode()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     public void setAirplaneMode(boolean isAirplaneModeOn) {
-        if (Boolean.parseBoolean(
-                SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
+        if (isInEcmMode()) {
             // In ECM mode, do not update database at this point
+            Log.d(LOG_TAG, "ECM airplane mode=" + isAirplaneModeOn);
         } else {
             mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AIRPLANE_TOGGLE,
                     isAirplaneModeOn);
@@ -136,6 +172,7 @@
     }
 
     public void setAirplaneModeInECM(boolean isECMExit, boolean isAirplaneModeOn) {
+        Log.d(LOG_TAG, "Exist ECM=" + isECMExit + ", with airplane mode=" + isAirplaneModeOn);
         if (isECMExit) {
             // update database based on the current checkbox state
             setAirplaneModeOn(isAirplaneModeOn);
diff --git a/src/com/android/settings/IccLockSettings.java b/src/com/android/settings/IccLockSettings.java
index 605f483..8880001 100644
--- a/src/com/android/settings/IccLockSettings.java
+++ b/src/com/android/settings/IccLockSettings.java
@@ -29,8 +29,6 @@
 import android.os.Handler;
 import android.os.Message;
 import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Gravity;
@@ -55,6 +53,9 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.settings.network.ProxySubscriptionManager;
+
+import java.util.List;
 
 /**
  * Implements the preference screen to enable/disable ICC lock and
@@ -112,6 +113,7 @@
     private ListView mListView;
 
     private Phone mPhone;
+    private ProxySubscriptionManager mProxySubscriptionMgr;
 
     private EditPinPreference mPinDialog;
     private SwitchPreference mPinToggle;
@@ -129,7 +131,7 @@
     // For replies from IccCard interface
     private Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
-            AsyncResult ar = (AsyncResult) msg.obj;
+            final AsyncResult ar = (AsyncResult) msg.obj;
             switch (msg.what) {
                 case MSG_ENABLE_ICC_PIN_COMPLETE:
                     iccLockChanged(ar.exception == null, msg.arg1, ar.exception);
@@ -161,8 +163,8 @@
     }
 
     static String getSummary(Context context) {
-        Resources res = context.getResources();
-        String summary = isIccLockEnabled()
+        final Resources res = context.getResources();
+        final String summary = isIccLockEnabled()
                 ? res.getString(R.string.sim_lock_on)
                 : res.getString(R.string.sim_lock_off);
         return summary;
@@ -177,6 +179,11 @@
             return;
         }
 
+        // enable ProxySubscriptionMgr with Lifecycle support for all controllers
+        // live within this fragment
+        mProxySubscriptionMgr = ProxySubscriptionManager.getInstance(getContext());
+        mProxySubscriptionMgr.setLifecycle(getLifecycle());
+
         addPreferencesFromResource(R.xml.sim_lock_settings);
 
         mPinDialog = (EditPinPreference) findPreference(PIN_DIALOG);
@@ -217,14 +224,12 @@
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
 
-        final TelephonyManager tm =
-                (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
-        final int numSims = tm.getSimCount();
+        final int numSims = mProxySubscriptionMgr.getActiveSubscriptionInfoCountMax();
         if (numSims > 1) {
-            View view = inflater.inflate(R.layout.icc_lock_tabs, container, false);
+            final View view = inflater.inflate(R.layout.icc_lock_tabs, container, false);
             final ViewGroup prefs_container = (ViewGroup) view.findViewById(R.id.prefs_container);
             Utils.prepareCustomPreferencesList(container, view, prefs_container, false);
-            View prefs = super.onCreateView(inflater, prefs_container, savedInstanceState);
+            final View prefs = super.onCreateView(inflater, prefs_container, savedInstanceState);
             prefs_container.addView(prefs);
 
             mTabHost = (TabHost) view.findViewById(android.R.id.tabhost);
@@ -235,18 +240,19 @@
             mTabHost.setOnTabChangedListener(mTabListener);
             mTabHost.clearAllTabs();
 
-            SubscriptionManager sm = SubscriptionManager.from(getContext());
+            final List<SubscriptionInfo> subInfoList =
+                    mProxySubscriptionMgr.getActiveSubscriptionsInfo();
             for (int i = 0; i < numSims; ++i) {
-                final SubscriptionInfo subInfo = sm.getActiveSubscriptionInfoForSimSlotIndex(i);
+                final SubscriptionInfo subInfo =
+                        getActiveSubscriptionInfoForSimSlotIndex(subInfoList, i);
                 mTabHost.addTab(buildTabSpec(String.valueOf(i),
                         String.valueOf(subInfo == null
                             ? getContext().getString(R.string.sim_editor_title, i + 1)
                             : subInfo.getDisplayName())));
             }
-            final SubscriptionInfo sir = sm.getActiveSubscriptionInfoForSimSlotIndex(0);
+            final SubscriptionInfo sir = getActiveSubscriptionInfoForSimSlotIndex(subInfoList, 0);
 
-            mPhone = (sir == null) ? null
-                : PhoneFactory.getPhone(SubscriptionManager.getPhoneId(sir.getSubscriptionId()));
+            mPhone = (sir == null) ? null : PhoneFactory.getPhone(sir.getSimSlotIndex());
 
             if (savedInstanceState != null && savedInstanceState.containsKey(CURRENT_TAB)) {
                 mTabHost.setCurrentTabByTag(savedInstanceState.getString(CURRENT_TAB));
@@ -456,7 +462,7 @@
     private void tryChangeIccLockState() {
         // Try to change icc lock. If it succeeds, toggle the lock state and
         // reset dialog state. Else inject error message and show dialog again.
-        Message callback = Message.obtain(mHandler, MSG_ENABLE_ICC_PIN_COMPLETE);
+        final Message callback = Message.obtain(mHandler, MSG_ENABLE_ICC_PIN_COMPLETE);
         mPhone.getIccCard().setIccLockEnabled(mToState, mPin, callback);
         // Disable the setting till the response is received.
         mPinToggle.setEnabled(false);
@@ -467,7 +473,8 @@
             mPinToggle.setChecked(mToState);
         } else {
             if (exception instanceof CommandException) {
-                CommandException.Error err = ((CommandException)(exception)).getCommandError();
+                final CommandException.Error err =
+                        ((CommandException) exception).getCommandError();
                 if (err == CommandException.Error.PASSWORD_INCORRECT) {
                     createCustomTextToast(getPinPasswordErrorMessage(attemptsRemaining));
                 } else {
@@ -490,9 +497,9 @@
         // The window type of Toast is set by NotificationManagerService.
         // It can't be overwritten by LayoutParams.type.
         // Ovarlay a custom window with LayoutParams (TYPE_STATUS_BAR_PANEL) on PUK unlock screen.
-        View v = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE))
+        final View v = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                 .inflate(com.android.internal.R.layout.transient_notification, null);
-        TextView tv = (TextView) v.findViewById(com.android.internal.R.id.message);
+        final TextView tv = (TextView) v.findViewById(com.android.internal.R.id.message);
         tv.setText(errorMessage);
 
         final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
@@ -521,7 +528,7 @@
                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 
-        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
+        final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
         wm.addView(v, params);
 
         mHandler.postDelayed(new Runnable() {
@@ -545,7 +552,7 @@
     }
 
     private void tryChangePin() {
-        Message callback = Message.obtain(mHandler, MSG_CHANGE_ICC_PIN_COMPLETE);
+        final Message callback = Message.obtain(mHandler, MSG_CHANGE_ICC_PIN_COMPLETE);
         mPhone.getIccCard().changeIccLockPassword(mOldPin,
                 mNewPin, callback);
     }
@@ -583,15 +590,27 @@
         mDialogState = OFF_MODE;
     }
 
+    private static SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(
+            List<SubscriptionInfo> subInfoList, int slotId) {
+        if (subInfoList == null) {
+            return null;
+        }
+        for (SubscriptionInfo subInfo : subInfoList) {
+            if (subInfo.getSimSlotIndex() == slotId) {
+                return subInfo;
+            }
+        }
+        return null;
+    }
+
     private OnTabChangeListener mTabListener = new OnTabChangeListener() {
         @Override
         public void onTabChanged(String tabId) {
             final int slotId = Integer.parseInt(tabId);
-            final SubscriptionInfo sir = SubscriptionManager.from(getActivity().getBaseContext())
-                    .getActiveSubscriptionInfoForSimSlotIndex(slotId);
+            final SubscriptionInfo sir = getActiveSubscriptionInfoForSimSlotIndex(
+                    mProxySubscriptionMgr.getActiveSubscriptionsInfo(), slotId);
 
-            mPhone = (sir == null) ? null
-                : PhoneFactory.getPhone(SubscriptionManager.getPhoneId(sir.getSubscriptionId()));
+            mPhone = (sir == null) ? null : PhoneFactory.getPhone(sir.getSimSlotIndex());
 
             // The User has changed tab; update the body.
             updatePreferences();
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index beb0528..c4e4baf 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -47,7 +47,6 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
 
-import com.android.ims.ImsManager;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.settings.core.InstrumentedFragment;
 import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
@@ -104,15 +103,16 @@
             p2pFactoryReset(mContext);
 
             TelephonyManager telephonyManager = (TelephonyManager)
-                    mContext.getSystemService(Context.TELEPHONY_SERVICE);
+                    mContext.getSystemService(TelephonyManager.class)
+                            .createForSubscriptionId(mSubId);
             if (telephonyManager != null) {
-                telephonyManager.factoryReset(mSubId);
+                telephonyManager.resetSettings();
             }
 
             NetworkPolicyManager policyManager = (NetworkPolicyManager)
                     mContext.getSystemService(Context.NETWORK_POLICY_SERVICE);
             if (policyManager != null) {
-                String subscriberId = telephonyManager.getSubscriberId(mSubId);
+                String subscriberId = telephonyManager.getSubscriberId();
                 policyManager.factoryReset(subscriberId);
             }
 
@@ -125,8 +125,6 @@
                 }
             }
 
-            ImsManager.getInstance(mContext,
-                    SubscriptionManager.getPhoneId(mSubId)).factoryReset();
             restoreDefaultApn(mContext);
             if (mEraseEsim) {
                 return RecoverySystem.wipeEuiccData(mContext, mPackageName);
diff --git a/src/com/android/settings/SettingsDumpService.java b/src/com/android/settings/SettingsDumpService.java
index a57e983..487ccf5 100644
--- a/src/com/android/settings/SettingsDumpService.java
+++ b/src/com/android/settings/SettingsDumpService.java
@@ -103,12 +103,14 @@
         DataUsageController controller = new DataUsageController(this);
         ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);
         SubscriptionManager manager = SubscriptionManager.from(this);
-        TelephonyManager telephonyManager = TelephonyManager.from(this);
+        TelephonyManager telephonyManager = this.getSystemService(TelephonyManager.class);
         if (connectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) {
             JSONArray array = new JSONArray();
             for (SubscriptionInfo info : manager.getAllSubscriptionInfoList()) {
+                telephonyManager = telephonyManager
+                        .createForSubscriptionId(info.getSubscriptionId());
                 NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
-                        telephonyManager.getSubscriberId(info.getSubscriptionId()));
+                        telephonyManager.getSubscriberId());
                 final JSONObject usage = dumpDataUsage(mobileAll, controller);
                 usage.put("subId", info.getSubscriptionId());
                 array.put(usage);
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java b/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java
index 8806712..853ca7c 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollPreviewFragment.java
@@ -18,6 +18,7 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
+import android.graphics.Matrix;
 import android.graphics.SurfaceTexture;
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCaptureSession;
@@ -316,14 +317,19 @@
         scaleX = scaleX / smaller;
         scaleY = scaleY / smaller;
 
-        // Apply the transformation/scale
-        mTextureView.setTranslationX(getResources().getDimension(R.dimen.face_preview_translate_x));
-        mTextureView.setTranslationY(getResources().getDimension(R.dimen.face_preview_translate_y));
-
+        final TypedValue tx = new TypedValue();
+        final TypedValue ty = new TypedValue();
         final TypedValue scale = new TypedValue();
+        getResources().getValue(R.dimen.face_preview_translate_x, tx, true /* resolveRefs */);
+        getResources().getValue(R.dimen.face_preview_translate_y, ty, true /* resolveRefs */);
         getResources().getValue(R.dimen.face_preview_scale, scale, true /* resolveRefs */);
-        mTextureView.setScaleX(scaleX * scale.getFloat());
-        mTextureView.setScaleY(scaleY * scale.getFloat());
+
+        // Apply the transformation/scale
+        final Matrix transform = new Matrix();
+        mTextureView.getTransform(transform);
+        transform.setScale(scaleX * scale.getFloat(), scaleY * scale.getFloat());
+        transform.postTranslate(tx.getFloat(), ty.getFloat());
+        mTextureView.setTransform(transform);
     }
 
     private void closeCamera() {
diff --git a/src/com/android/settings/datausage/DataUsageBaseFragment.java b/src/com/android/settings/datausage/DataUsageBaseFragment.java
index f6e88cc..299ce43 100644
--- a/src/com/android/settings/datausage/DataUsageBaseFragment.java
+++ b/src/com/android/settings/datausage/DataUsageBaseFragment.java
@@ -51,7 +51,7 @@
 
         services.mPolicyEditor = new NetworkPolicyEditor(services.mPolicyManager);
 
-        services.mTelephonyManager = TelephonyManager.from(context);
+        services.mTelephonyManager = context.getSystemService(TelephonyManager.class);
         services.mSubscriptionManager = SubscriptionManager.from(context);
         services.mUserManager = UserManager.get(context);
     }
diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java
index 0e400a2..ef3e7b6 100644
--- a/src/com/android/settings/datausage/DataUsageUtils.java
+++ b/src/com/android/settings/datausage/DataUsageUtils.java
@@ -33,7 +33,6 @@
 import android.text.format.Formatter.BytesResult;
 import android.util.Log;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -72,7 +71,7 @@
             return false;
         }
 
-        final TelephonyManager telephonyManager = TelephonyManager.from(context);
+        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
         final NetworkStatsManager networkStatsManager =
                 context.getSystemService(NetworkStatsManager.class);
         boolean hasEthernetUsage = false;
@@ -115,7 +114,7 @@
             }
             return false;
         }
-        final TelephonyManager tele = TelephonyManager.from(context);
+        final TelephonyManager tele = context.getSystemService(TelephonyManager.class);
         // require both supported network and ready SIM
         boolean isReady = true;
         for (SubscriptionInfo subInfo : subInfoList) {
diff --git a/src/com/android/settings/development/compat/PlatformCompatDashboard.java b/src/com/android/settings/development/compat/PlatformCompatDashboard.java
index dab45f2..53c6e9f 100644
--- a/src/com/android/settings/development/compat/PlatformCompatDashboard.java
+++ b/src/com/android/settings/development/compat/PlatformCompatDashboard.java
@@ -16,7 +16,9 @@
 
 package com.android.settings.development.compat;
 
+import static com.android.settings.development.AppPicker.EXTRA_DEBUGGABLE;
 import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_COMPAT_CHANGE_APP;
+import static com.android.internal.compat.OverrideAllowedState.ALLOWED;
 
 import android.app.Activity;
 import android.app.settings.SettingsEnums;
@@ -25,7 +27,9 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -37,9 +41,12 @@
 import androidx.preference.PreferenceCategory;
 import androidx.preference.SwitchPreference;
 
+import com.android.internal.compat.AndroidBuildClassifier;
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.compat.CompatibilityChangeInfo;
 import com.android.internal.compat.IPlatformCompat;
+import com.android.internal.compat.IOverrideValidator;
+import com.android.internal.compat.OverrideAllowedState;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.development.AppPicker;
@@ -61,6 +68,8 @@
 
     private CompatibilityChangeInfo[] mChanges;
 
+    private AndroidBuildClassifier mAndroidBuildClassifier = new AndroidBuildClassifier();
+
     @VisibleForTesting
     String mSelectedApp;
 
@@ -114,17 +123,21 @@
         if (requestCode == REQUEST_COMPAT_CHANGE_APP) {
             if (resultCode == Activity.RESULT_OK) {
                 mSelectedApp = data.getAction();
-                addPreferences();
+                try {
+                    final ApplicationInfo applicationInfo = getApplicationInfo();
+                    addPreferences(applicationInfo);
+                } catch (PackageManager.NameNotFoundException e) {
+                    startAppPicker();
+                }
             }
             return;
         }
         super.onActivityResult(requestCode, resultCode, data);
     }
 
-    private void addPreferences() {
+    private void addPreferences(ApplicationInfo applicationInfo) {
         getPreferenceScreen().removeAll();
-        getPreferenceScreen().addPreference(
-                createAppPreference(getApplicationInfo().loadIcon(getPackageManager())));
+        getPreferenceScreen().addPreference(createAppPreference(applicationInfo));
         // Differentiate compatibility changes into default enabled, default disabled and enabled
         // after target sdk.
         final CompatibilityChangeConfig configMappings = getAppChangeMappings();
@@ -161,7 +174,7 @@
         try {
             final ApplicationInfo applicationInfo = getApplicationInfo();
             return getPlatformCompat().getAppConfig(applicationInfo);
-        } catch (RemoteException e) {
+        } catch (RemoteException | PackageManager.NameNotFoundException e) {
             throw new RuntimeException("Could not get app config!", e);
         }
     }
@@ -180,7 +193,15 @@
                 change.getName() != null ? change.getName() : "Change_" + change.getId();
         item.setSummary(changeName);
         item.setKey(changeName);
-        item.setEnabled(true);
+        boolean shouldEnable = true;
+        try {
+            shouldEnable = getPlatformCompat().getOverrideValidator()
+                           .getOverrideAllowedState(change.getId(), mSelectedApp)
+                           .state == ALLOWED;
+        } catch (RemoteException e) {
+            throw new RuntimeException("Could not check if change can be overridden for app.", e);
+        }
+        item.setEnabled(shouldEnable);
         item.setChecked(currentValue);
         item.setOnPreferenceChangeListener(
                 new CompatChangePreferenceChangeListener(change.getId()));
@@ -192,12 +213,8 @@
      *
      * @return an {@link ApplicationInfo} instance.
      */
-    ApplicationInfo getApplicationInfo() {
-        try {
-            return getPackageManager().getApplicationInfo(mSelectedApp, 0);
-        } catch (PackageManager.NameNotFoundException e) {
-            throw new RuntimeException("Could not get ApplicationInfo for selected app!", e);
-        }
+    ApplicationInfo getApplicationInfo() throws PackageManager.NameNotFoundException {
+        return getPackageManager().getApplicationInfo(mSelectedApp, 0);
     }
 
     /**
@@ -206,9 +223,10 @@
      * <p>The {@link Preference} contains the icon, package name and target SDK for the selected
      * app. Selecting this preference will also re-trigger the app selection dialog.</p>
      */
-    Preference createAppPreference(Drawable icon) {
-        final ApplicationInfo applicationInfo = getApplicationInfo();
-        final Preference appPreference = new Preference(getPreferenceScreen().getContext());
+    Preference createAppPreference(ApplicationInfo applicationInfo) {
+        final Context context = getPreferenceScreen().getContext();
+        final Drawable icon = applicationInfo.loadIcon(context.getPackageManager());
+        final Preference appPreference = new Preference(context);
         appPreference.setIcon(icon);
         appPreference.setSummary(mSelectedApp
                 + " SDK "
@@ -243,6 +261,11 @@
 
     private void startAppPicker() {
         final Intent intent = new Intent(getContext(), AppPicker.class);
+        // If build is neither userdebug nor eng, only include debuggable apps
+        final boolean debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild();
+        if (!debuggableBuild) {
+            intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true /* value */);
+        }
         startActivityForResult(intent, REQUEST_COMPAT_CHANGE_APP);
     }
 
diff --git a/src/com/android/settings/deviceinfo/MigrateEstimateTask.java b/src/com/android/settings/deviceinfo/MigrateEstimateTask.java
index c41ebe0..a5790b3 100644
--- a/src/com/android/settings/deviceinfo/MigrateEstimateTask.java
+++ b/src/com/android/settings/deviceinfo/MigrateEstimateTask.java
@@ -29,7 +29,7 @@
 import android.os.UserManager;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
-import android.telecom.Log;
+import android.util.Log;
 import android.text.format.DateUtils;
 import android.text.format.Formatter;
 
diff --git a/src/com/android/settings/deviceinfo/OWNERS b/src/com/android/settings/deviceinfo/OWNERS
new file mode 100644
index 0000000..bedbe16
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/OWNERS
@@ -0,0 +1,6 @@
+# Default reviewers for this and subdirectories.
+andychou@google.com
+bonianchen@google.com
+allenwtsu@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index 0751141..26d8e2b 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -25,6 +25,7 @@
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.os.UserHandle;
+import android.telephony.Annotation;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellSignalStrength;
 import android.telephony.PhoneStateListener;
@@ -35,12 +36,14 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.internal.telephony.PhoneConstants;
 import com.android.settings.R;
 import com.android.settingslib.DeviceInfoUtils;
 import com.android.settingslib.Utils;
@@ -50,6 +53,7 @@
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
 import java.util.List;
+import java.util.Map;
 
 public class SimStatusDialogController implements LifecycleObserver, OnResume, OnPause {
 
@@ -82,6 +86,8 @@
     @VisibleForTesting
     final static int ICCID_INFO_VALUE_ID = R.id.icc_id_value;
     @VisibleForTesting
+    final static int EID_INFO_LABEL_ID = R.id.esim_id_label;
+    @VisibleForTesting
     final static int EID_INFO_VALUE_ID = R.id.esim_id_value;
     @VisibleForTesting
     final static int IMS_REGISTRATION_STATE_LABEL_ID = R.id.ims_reg_state_label;
@@ -100,15 +106,18 @@
                 public void onSubscriptionsChanged() {
                     mSubscriptionInfo = mSubscriptionManager.getActiveSubscriptionInfo(
                             mSubscriptionInfo.getSubscriptionId());
+                    mTelephonyManager = mTelephonyManager.createForSubscriptionId(
+                            mSubscriptionInfo.getSubscriptionId());
                     updateNetworkProvider();
                 }
             };
 
     private SubscriptionInfo mSubscriptionInfo;
-    private int mSlotIndex;
+
+    private final int mSlotIndex;
+    private TelephonyManager mTelephonyManager;
 
     private final SimStatusDialogFragment mDialog;
-    private final TelephonyManager mTelephonyManager;
     private final SubscriptionManager mSubscriptionManager;
     private final CarrierConfigManager mCarrierConfigManager;
     private final EuiccManager mEuiccManager;
@@ -166,11 +175,13 @@
         mPhoneStateListener = getPhoneStateListener();
         updateNetworkProvider();
 
-        final ServiceState serviceState = getCurrentServiceState();
+        final ServiceState serviceState = mTelephonyManager.getServiceState();
+        final SignalStrength signalStrength = mTelephonyManager.getSignalStrength();
+
         updatePhoneNumber();
         updateLatestAreaInfo();
         updateServiceState(serviceState);
-        updateSignalStrength(getSignalStrength());
+        updateSignalStrength(signalStrength);
         updateNetworkType();
         updateRoamingStatus(serviceState);
         updateIccidNumber();
@@ -182,12 +193,12 @@
         if (mSubscriptionInfo == null) {
             return;
         }
-
-        mTelephonyManager.createForSubscriptionId(mSubscriptionInfo.getSubscriptionId())
-                .listen(mPhoneStateListener,
-                        PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
-                                | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
-                                | PhoneStateListener.LISTEN_SERVICE_STATE);
+        mTelephonyManager = mTelephonyManager.createForSubscriptionId(
+                mSubscriptionInfo.getSubscriptionId());
+        mTelephonyManager.listen(mPhoneStateListener,
+                PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+                        | PhoneStateListener.LISTEN_SERVICE_STATE);
         mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
 
         if (mShowLatestAreaInfo) {
@@ -209,8 +220,7 @@
         }
 
         mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
-        mTelephonyManager.createForSubscriptionId(mSubscriptionInfo.getSubscriptionId())
-                .listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
 
         if (mShowLatestAreaInfo) {
             mContext.unregisterReceiver(mAreaInfoReceiver);
@@ -313,7 +323,7 @@
             return;
         }
 
-        ServiceState serviceState = getCurrentServiceState();
+        ServiceState serviceState = mTelephonyManager.getServiceState();
         if (serviceState == null || !Utils.isInService(serviceState)) {
             return;
         }
@@ -342,13 +352,13 @@
         String dataNetworkTypeName = null;
         String voiceNetworkTypeName = null;
         final int subId = mSubscriptionInfo.getSubscriptionId();
-        final int actualDataNetworkType = mTelephonyManager.getDataNetworkType(subId);
-        final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType(subId);
+        final int actualDataNetworkType = mTelephonyManager.getDataNetworkType();
+        final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType();
         if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualDataNetworkType) {
-            dataNetworkTypeName = mTelephonyManager.getNetworkTypeName(actualDataNetworkType);
+            dataNetworkTypeName = getNetworkTypeName(actualDataNetworkType);
         }
         if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualVoiceNetworkType) {
-            voiceNetworkTypeName = mTelephonyManager.getNetworkTypeName(actualVoiceNetworkType);
+            voiceNetworkTypeName = getNetworkTypeName(actualVoiceNetworkType);
         }
 
         boolean show4GForLTE = false;
@@ -393,15 +403,48 @@
             mDialog.removeSettingFromScreen(ICCID_INFO_LABEL_ID);
             mDialog.removeSettingFromScreen(ICCID_INFO_VALUE_ID);
         } else {
-            mDialog.setText(ICCID_INFO_VALUE_ID, getSimSerialNumber(subscriptionId));
+            mDialog.setText(ICCID_INFO_VALUE_ID, mTelephonyManager.getSimSerialNumber());
         }
     }
 
     private void updateEid() {
-        if (mEuiccManager.isEnabled()) {
-            mDialog.setText(EID_INFO_VALUE_ID, mEuiccManager.getEid());
-        } else {
+        boolean shouldHaveEid = false;
+        String eid = null;
+
+        if (mTelephonyManager.getPhoneCount() > PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM) {
+            // Get EID per-SIM in multi-SIM mode
+            Map<Integer, Integer> mapping = mTelephonyManager.getLogicalToPhysicalSlotMapping();
+            int pSlotId = mapping.getOrDefault(mSlotIndex,
+                    SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+
+            if (pSlotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+                List<UiccCardInfo> infos = mTelephonyManager.getUiccCardsInfo();
+
+                for (UiccCardInfo info : infos) {
+                    if (info.getSlotIndex() == pSlotId) {
+                        if (info.isEuicc()) {
+                            shouldHaveEid = true;
+                            eid = info.getEid();
+
+                            if (TextUtils.isEmpty(eid)) {
+                                eid = mEuiccManager.createForCardId(info.getCardId()).getEid();
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+        } else if (mEuiccManager.isEnabled()) {
+            // Get EID of default eSIM in single-SIM mode
+            shouldHaveEid = true;
+            eid = mEuiccManager.getEid();
+        }
+
+        if (!shouldHaveEid) {
+            mDialog.removeSettingFromScreen(EID_INFO_LABEL_ID);
             mDialog.removeSettingFromScreen(EID_INFO_VALUE_ID);
+        } else if (!TextUtils.isEmpty(eid)) {
+            mDialog.setText(EID_INFO_VALUE_ID, eid);
         }
     }
 
@@ -426,12 +469,6 @@
         return SubscriptionManager.from(mContext).getActiveSubscriptionInfoForSimSlotIndex(slotId);
     }
 
-    @VisibleForTesting
-    ServiceState getCurrentServiceState() {
-        return mTelephonyManager.getServiceStateForSubscriber(
-                mSubscriptionInfo.getSubscriptionId());
-    }
-
     private int getDbm(SignalStrength signalStrength) {
         List<CellSignalStrength> cellSignalStrengthList = signalStrength.getCellSignalStrengths();
         int dbm = -1;
@@ -490,12 +527,50 @@
     }
 
     @VisibleForTesting
-    SignalStrength getSignalStrength() {
-        return mTelephonyManager.getSignalStrength();
-    }
-
-    @VisibleForTesting
-    String getSimSerialNumber(int subscriptionId) {
-        return mTelephonyManager.getSimSerialNumber(subscriptionId);
+    static String getNetworkTypeName(@Annotation.NetworkType int type) {
+        switch (type) {
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+                return "GPRS";
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+                return "EDGE";
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+                return "UMTS";
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+                return "HSDPA";
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+                return "HSUPA";
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+                return "HSPA";
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+                return "CDMA";
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+                return "CDMA - EvDo rev. 0";
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+                return "CDMA - EvDo rev. A";
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+                return "CDMA - EvDo rev. B";
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+                return "CDMA - 1xRTT";
+            case TelephonyManager.NETWORK_TYPE_LTE:
+                return "LTE";
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+                return "CDMA - eHRPD";
+            case TelephonyManager.NETWORK_TYPE_IDEN:
+                return "iDEN";
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+                return "HSPA+";
+            case TelephonyManager.NETWORK_TYPE_GSM:
+                return "GSM";
+            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
+                return "TD_SCDMA";
+            case TelephonyManager.NETWORK_TYPE_IWLAN:
+                return "IWLAN";
+            case TelephonyManager.NETWORK_TYPE_LTE_CA:
+                return "LTE_CA";
+            case TelephonyManager.NETWORK_TYPE_NR:
+                return "NR";
+            default:
+                return "UNKNOWN";
+        }
     }
 }
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index fa23101..5e6c54b 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -33,6 +33,7 @@
 
 import com.android.settings.R;
 import com.android.settings.accounts.AvatarViewMixin;
+import com.android.settings.core.HideNonSystemOverlayMixin;
 import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
 import com.android.settings.overlay.FeatureFactory;
 
@@ -54,8 +55,8 @@
                 .initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
 
         final ImageView avatarView = findViewById(R.id.account_avatar);
-        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(this, avatarView);
-        getLifecycle().addObserver(avatarViewMixin);
+        getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
+        getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
 
         if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
             // Only allow contextual feature on high ram devices.
diff --git a/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java b/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java
index 36a3980..1b7f003 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java
@@ -17,15 +17,21 @@
 
 import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
 
+import static android.provider.Settings.Global.LOW_POWER_MODE;
+
 import android.annotation.ColorInt;
 import android.app.PendingIntent;
 import android.app.UiModeManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.PowerManager;
+import android.provider.Settings;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -39,6 +45,9 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
+import com.android.settings.slices.SliceBackgroundWorker;
+
+import java.io.IOException;
 
 public class DarkThemeSlice implements CustomSliceable {
     private static final String TAG = "DarkThemeSlice";
@@ -53,10 +62,12 @@
 
     private final Context mContext;
     private final UiModeManager mUiModeManager;
+    private final PowerManager mPowerManager;
 
     public DarkThemeSlice(Context context) {
         mContext = context;
         mUiModeManager = context.getSystemService(UiModeManager.class);
+        mPowerManager = context.getSystemService(PowerManager.class);
     }
 
     @Override
@@ -67,15 +78,18 @@
             sActiveUiSession = currentUiSession;
             sKeepSliceShow = false;
         }
-        if (!sKeepSliceShow && !isAvailable(mContext)) {
-            return null;
+        // Dark theme slice will disappear when battery saver is ON.
+        if (mPowerManager.isPowerSaveMode() || (!sKeepSliceShow && !isAvailable(mContext))) {
+            return new ListBuilder(mContext, CustomSliceRegistry.DARK_THEME_SLICE_URI,
+                    ListBuilder.INFINITY)
+                    .setIsError(true)
+                    .build();
         }
         sKeepSliceShow = true;
         final PendingIntent toggleAction = getBroadcastIntent(mContext);
         @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
         final IconCompat icon =
                 IconCompat.createWithResource(mContext, R.drawable.dark_theme);
-        final boolean isChecked = mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_YES;
         return new ListBuilder(mContext, CustomSliceRegistry.DARK_THEME_SLICE_URI,
                 ListBuilder.INFINITY)
                 .setAccentColor(color)
@@ -85,7 +99,7 @@
                         .setSubtitle(mContext.getText(R.string.dark_theme_slice_subtitle))
                         .setPrimaryAction(
                                 SliceAction.createToggle(toggleAction, null /* actionTitle */,
-                                        isChecked)))
+                                        isDarkThemeMode(mContext))))
                 .build();
     }
 
@@ -100,8 +114,7 @@
                 false);
         // make toggle transition more smooth before dark theme takes effect
         new Handler(Looper.getMainLooper()).postDelayed(() -> {
-            mUiModeManager.setNightMode(
-                isChecked ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO);
+            mUiModeManager.setNightModeActivated(isChecked);
         }, DELAY_TIME_EXECUTING_DARK_THEME);
     }
 
@@ -110,10 +123,15 @@
         return null;
     }
 
+    @Override
+    public Class getBackgroundWorkerClass() {
+        return DarkThemeWorker.class;
+    }
+
     @VisibleForTesting
     boolean isAvailable(Context context) {
         // checking dark theme mode.
-        if (mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_YES) {
+        if (isDarkThemeMode(context)) {
             return false;
         }
 
@@ -121,7 +139,47 @@
         final BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
         final int level = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
         Log.d(TAG, "battery level=" + level);
-
         return level <= BATTERY_LEVEL_THRESHOLD;
     }
+
+    @VisibleForTesting
+    boolean isDarkThemeMode(Context context) {
+        final int currentNightMode =
+                context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+        return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
+    }
+
+    public static class DarkThemeWorker extends SliceBackgroundWorker<Void> {
+        private final Context mContext;
+        private final ContentObserver mContentObserver =
+                new ContentObserver(new Handler(Looper.getMainLooper())) {
+                    @Override
+                    public void onChange(boolean bChanged) {
+                        if (mContext.getSystemService(PowerManager.class).isPowerSaveMode()) {
+                            notifySliceChange();
+                        }
+                    }
+                };
+
+        public DarkThemeWorker(Context context, Uri uri) {
+            super(context, uri);
+            mContext = context;
+        }
+
+        @Override
+        protected void onSlicePinned() {
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(LOW_POWER_MODE), false /* notifyForDescendants */,
+                    mContentObserver);
+        }
+
+        @Override
+        protected void onSliceUnpinned() {
+            mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+        }
+
+        @Override
+        public void close() throws IOException {
+        }
+    }
 }
diff --git a/src/com/android/settings/network/ActiveSubsciptionsListener.java b/src/com/android/settings/network/ActiveSubsciptionsListener.java
new file mode 100644
index 0000000..3e4272d
--- /dev/null
+++ b/src/com/android/settings/network/ActiveSubsciptionsListener.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2019 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;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.Looper;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.telephony.TelephonyIntents;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A listener for active subscription change
+ */
+public abstract class ActiveSubsciptionsListener
+        extends SubscriptionManager.OnSubscriptionsChangedListener
+        implements AutoCloseable {
+
+    private static final String TAG = "ActiveSubsciptions";
+    private static final boolean DEBUG = false;
+
+    /**
+     * Constructor
+     *
+     * @param looper {@code Looper} of this listener
+     * @param context {@code Context} of this listener
+     */
+    public ActiveSubsciptionsListener(Looper looper, Context context) {
+        mLooper = looper;
+        mContext = context;
+
+        mCacheState = new AtomicInteger(STATE_NOT_LISTENING);
+        mMaxActiveSubscriptionInfos = new AtomicInteger(MAX_SUBSCRIPTION_UNKNOWN);
+
+        mSubscriptionChangeIntentFilter = new IntentFilter();
+        mSubscriptionChangeIntentFilter.addAction(
+                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        mSubscriptionChangeIntentFilter.addAction(
+                TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+        mSubscriptionChangeIntentFilter.addAction(
+                TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED);
+    }
+
+    @VisibleForTesting
+    BroadcastReceiver getSubscriptionChangeReceiver() {
+        return new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (isInitialStickyBroadcast()) {
+                    return;
+                }
+                final String action = intent.getAction();
+                if (TextUtils.isEmpty(action)) {
+                    return;
+                }
+                if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) {
+                    final int subId = intent.getIntExtra(
+                            CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
+                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+                    if (!clearCachedSubId(subId)) {
+                        return;
+                    }
+                }
+                onSubscriptionsChanged();
+            }
+        };
+    }
+
+    private Looper mLooper;
+    private Context mContext;
+
+    private static final int STATE_NOT_LISTENING = 0;
+    private static final int STATE_STOPPING      = 1;
+    private static final int STATE_PREPARING     = 2;
+    private static final int STATE_LISTENING     = 3;
+    private static final int STATE_DATA_CACHED   = 4;
+
+    private AtomicInteger mCacheState;
+    private SubscriptionManager mSubscriptionManager;
+
+    private IntentFilter mSubscriptionChangeIntentFilter;
+    private BroadcastReceiver mSubscriptionChangeReceiver;
+
+    private static final int MAX_SUBSCRIPTION_UNKNOWN = -1;
+
+    private AtomicInteger mMaxActiveSubscriptionInfos;
+    private List<SubscriptionInfo> mCachedActiveSubscriptionInfo;
+
+    /**
+     * Active subscriptions got changed
+     */
+    public abstract void onChanged();
+
+    @Override
+    public void onSubscriptionsChanged() {
+        // clear value in cache
+        clearCache();
+        listenerNotify();
+    }
+
+    /**
+     * Start listening subscriptions change
+     */
+    public void start() {
+        monitorSubscriptionsChange(true);
+    }
+
+    /**
+     * Stop listening subscriptions change
+     */
+    public void stop() {
+        monitorSubscriptionsChange(false);
+    }
+
+    /**
+     * Implementation of {@code AutoCloseable}
+     */
+    public void close() {
+        stop();
+    }
+
+    /**
+     * Get SubscriptionManager
+     *
+     * @return a SubscriptionManager
+     */
+    public SubscriptionManager getSubscriptionManager() {
+        if (mSubscriptionManager == null) {
+            mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
+        }
+        return mSubscriptionManager;
+    }
+
+    /**
+     * Get current max. number active subscription info(s) been setup within device
+     *
+     * @return max. number of active subscription info(s)
+     */
+    public int getActiveSubscriptionInfoCountMax() {
+        int cacheState = mCacheState.get();
+        if (cacheState < STATE_LISTENING) {
+            return getSubscriptionManager().getActiveSubscriptionInfoCountMax();
+        }
+
+        mMaxActiveSubscriptionInfos.compareAndSet(MAX_SUBSCRIPTION_UNKNOWN,
+                getSubscriptionManager().getActiveSubscriptionInfoCountMax());
+        return mMaxActiveSubscriptionInfos.get();
+    }
+
+    /**
+     * Get a list of active subscription info
+     *
+     * @return A list of active subscription info
+     */
+    public List<SubscriptionInfo> getActiveSubscriptionsInfo() {
+        if (mCacheState.get() >= STATE_DATA_CACHED) {
+            return mCachedActiveSubscriptionInfo;
+        }
+        mCachedActiveSubscriptionInfo = getSubscriptionManager().getActiveSubscriptionInfoList();
+        mCacheState.compareAndSet(STATE_LISTENING, STATE_DATA_CACHED);
+
+        if (DEBUG) {
+            if ((mCachedActiveSubscriptionInfo == null)
+                    || (mCachedActiveSubscriptionInfo.size() <= 0)) {
+                Log.d(TAG, "active subscriptions: " + mCachedActiveSubscriptionInfo);
+            } else {
+                final StringBuilder logString = new StringBuilder("active subscriptions:");
+                for (SubscriptionInfo subInfo : mCachedActiveSubscriptionInfo) {
+                    logString.append(" " + subInfo.getSubscriptionId());
+                }
+                Log.d(TAG, logString.toString());
+            }
+        }
+
+        return mCachedActiveSubscriptionInfo;
+    }
+
+    /**
+     * Get an active subscription info with given subscription ID
+     *
+     * @param subId target subscription ID
+     * @return A subscription info which is active list
+     */
+    public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
+        final List<SubscriptionInfo> subInfoList = getActiveSubscriptionsInfo();
+        if (subInfoList == null) {
+            return null;
+        }
+        for (SubscriptionInfo subInfo : subInfoList) {
+            if (subInfo.getSubscriptionId() == subId) {
+                return subInfo;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get a list of all subscription info which accessible by Settings app
+     *
+     * @return A list of accessible subscription info
+     */
+    public List<SubscriptionInfo> getAccessibleSubscriptionsInfo() {
+        return getSubscriptionManager().getAvailableSubscriptionInfoList();
+    }
+
+    /**
+     * Get an accessible subscription info with given subscription ID
+     *
+     * @param subId target subscription ID
+     * @return A subscription info which is accessible list
+     */
+    public SubscriptionInfo getAccessibleSubscriptionInfo(int subId) {
+        // Always check if subId is part of activeSubscriptions
+        // since there's cache design within SubscriptionManager.
+        // That give us a chance to avoid from querying ContentProvider.
+        final SubscriptionInfo activeSubInfo = getActiveSubscriptionInfo(subId);
+        if (activeSubInfo != null) {
+            return activeSubInfo;
+        }
+
+        final List<SubscriptionInfo> subInfoList = getAccessibleSubscriptionsInfo();
+        if (subInfoList == null) {
+            return null;
+        }
+        for (SubscriptionInfo subInfo : subInfoList) {
+            if (subInfo.getSubscriptionId() == subId) {
+                return subInfo;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Clear data cached within listener
+     */
+    public void clearCache() {
+        mMaxActiveSubscriptionInfos.set(MAX_SUBSCRIPTION_UNKNOWN);
+        mCacheState.compareAndSet(STATE_DATA_CACHED, STATE_LISTENING);
+        mCachedActiveSubscriptionInfo = null;
+    }
+
+    private void monitorSubscriptionsChange(boolean on) {
+        if (on) {
+            if (!mCacheState.compareAndSet(STATE_NOT_LISTENING, STATE_PREPARING)) {
+                return;
+            }
+
+            if (mSubscriptionChangeReceiver == null) {
+                mSubscriptionChangeReceiver = getSubscriptionChangeReceiver();
+            }
+            mContext.registerReceiver(mSubscriptionChangeReceiver,
+                    mSubscriptionChangeIntentFilter, null, new Handler(mLooper));
+            getSubscriptionManager().addOnSubscriptionsChangedListener(this);
+            mCacheState.compareAndSet(STATE_PREPARING, STATE_LISTENING);
+            return;
+        }
+
+        final int currentState = mCacheState.getAndSet(STATE_STOPPING);
+        if (currentState <= STATE_STOPPING) {
+            mCacheState.compareAndSet(STATE_STOPPING, currentState);
+            return;
+        }
+        if (mSubscriptionChangeReceiver != null) {
+            mContext.unregisterReceiver(mSubscriptionChangeReceiver);
+        }
+        getSubscriptionManager().removeOnSubscriptionsChangedListener(this);
+        clearCache();
+        mCacheState.compareAndSet(STATE_STOPPING, STATE_NOT_LISTENING);
+    }
+
+    private void listenerNotify() {
+        if (mCacheState.get() < STATE_LISTENING) {
+            return;
+        }
+        onChanged();
+    }
+
+    private boolean clearCachedSubId(int subId) {
+        if (mCacheState.get() < STATE_DATA_CACHED) {
+            return false;
+        }
+        if (mCachedActiveSubscriptionInfo == null) {
+            return false;
+        }
+        for (SubscriptionInfo subInfo : mCachedActiveSubscriptionInfo) {
+            if (subInfo.getSubscriptionId() == subId) {
+                clearCache();
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index 5c1913b..d7da909 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.os.SystemProperties;
 
 import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
@@ -28,12 +27,9 @@
 import androidx.preference.SwitchPreference;
 
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
 import com.android.settings.AirplaneModeEnabler;
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
@@ -47,14 +43,15 @@
     private static final String EXIT_ECM_RESULT = "exit_ecm_result";
 
     private Fragment mFragment;
-    private final MetricsFeatureProvider mMetricsFeatureProvider;
     private AirplaneModeEnabler mAirplaneModeEnabler;
     private SwitchPreference mAirplaneModePreference;
 
     public AirplaneModePreferenceController(Context context, String key) {
         super(context, key);
-        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-        mAirplaneModeEnabler = new AirplaneModeEnabler(mContext, mMetricsFeatureProvider, this);
+
+        if (isAvailable(mContext)) {
+            mAirplaneModeEnabler = new AirplaneModeEnabler(mContext, this);
+        }
     }
 
     public void setFragment(Fragment hostFragment) {
@@ -63,8 +60,8 @@
 
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
-        if (KEY_AIRPLANE_MODE.equals(preference.getKey()) && Boolean.parseBoolean(
-                SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
+        if (KEY_AIRPLANE_MODE.equals(preference.getKey())
+                && mAirplaneModeEnabler.isInEcmMode()) {
             // In ECM mode launch ECM app dialog
             if (mFragment != null) {
                 mFragment.startActivityForResult(
@@ -80,9 +77,7 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        if (isAvailable()) {
-            mAirplaneModePreference = screen.findPreference(getPreferenceKey());
-        }
+        mAirplaneModePreference = screen.findPreference(getPreferenceKey());
     }
 
     public static boolean isAvailable(Context context) {
@@ -117,7 +112,7 @@
 
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == REQUEST_CODE_EXIT_ECM) {
-            Boolean isChoiceYes = data.getBooleanExtra(EXIT_ECM_RESULT, false);
+            final boolean isChoiceYes = data.getBooleanExtra(EXIT_ECM_RESULT, false);
             // Set Airplane mode based on the return value and checkbox state
             mAirplaneModeEnabler.setAirplaneModeInECM(isChoiceYes,
                     mAirplaneModePreference.isChecked());
diff --git a/src/com/android/settings/network/ApnEditor.java b/src/com/android/settings/network/ApnEditor.java
index 1451a40..84e6b1d 100644
--- a/src/com/android/settings/network/ApnEditor.java
+++ b/src/com/android/settings/network/ApnEditor.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.network;
 
-import static android.content.Context.TELEPHONY_SERVICE;
-
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.ContentValues;
@@ -29,7 +27,7 @@
 import android.os.PersistableBundle;
 import android.provider.Telephony;
 import android.telephony.CarrierConfigManager;
-import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -60,6 +58,7 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 public class ApnEditor extends SettingsPreferenceFragment
@@ -131,7 +130,7 @@
 
     private boolean mNewApn;
     private int mSubId;
-    private TelephonyManager mTelephonyManager;
+    private ProxySubscriptionManager mProxySubscriptionMgr;
     private int mBearerInitialVal = 0;
     private String mMvnoTypeStr;
     private String mMvnoMatchDataStr;
@@ -209,6 +208,11 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        // enable ProxySubscriptionMgr with Lifecycle support for all controllers
+        // live within this fragment
+        mProxySubscriptionMgr = ProxySubscriptionManager.getInstance(getContext());
+        mProxySubscriptionMgr.setLifecycle(getLifecycle());
+
         addPreferencesFromResource(R.xml.apn_editor);
 
         sNotSet = getResources().getString(R.string.apn_not_set);
@@ -246,10 +250,10 @@
         mReadOnlyApnTypes = null;
         mReadOnlyApnFields = null;
 
-        CarrierConfigManager configManager = (CarrierConfigManager)
+        final CarrierConfigManager configManager = (CarrierConfigManager)
                 getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager != null) {
-            PersistableBundle b = configManager.getConfigForSubId(mSubId);
+            final PersistableBundle b = configManager.getConfigForSubId(mSubId);
             if (b != null) {
                 mReadOnlyApnTypes = b.getStringArray(
                         CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY);
@@ -300,10 +304,8 @@
             mApnData = new ApnData(sProjection.length);
         }
 
-        mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
-
-        boolean isUserEdited = mApnData.getInteger(EDITED_INDEX, Telephony.Carriers.USER_EDITED)
-                == Telephony.Carriers.USER_EDITED;
+        final boolean isUserEdited = mApnData.getInteger(EDITED_INDEX,
+                Telephony.Carriers.USER_EDITED) == Telephony.Carriers.USER_EDITED;
 
         Log.d(TAG, "onCreate: EDITED " + isUserEdited);
         // if it's not a USER_EDITED apn, check if it's read-only
@@ -353,7 +355,7 @@
             return false;
         }
 
-        List apnList = Arrays.asList(apnTypes);
+        final List apnList = Arrays.asList(apnTypes);
         if (apnList.contains(PhoneConstants.APN_TYPE_ALL)) {
             Log.d(TAG, "hasAllApns: true because apnList.contains(PhoneConstants.APN_TYPE_ALL)");
             return true;
@@ -384,8 +386,8 @@
             return true;
         }
 
-        List apnTypesList1 = Arrays.asList(apnTypesArray1);
-        String[] apnTypesArray2 = apnTypes2.split(",");
+        final List apnTypesList1 = Arrays.asList(apnTypesArray1);
+        final String[] apnTypesArray2 = apnTypes2.split(",");
 
         for (String apn : apnTypesArray2) {
             if (apnTypesList1.contains(apn.trim())) {
@@ -457,7 +459,7 @@
      */
     private void disableFields(String[] apnFields) {
         for (String apnField : apnFields) {
-            Preference preference = getPreferenceFromFieldName(apnField);
+            final Preference preference = getPreferenceFromFieldName(apnField);
             if (preference != null) {
                 preference.setEnabled(false);
             }
@@ -513,13 +515,15 @@
             mMnc.setText(mApnData.getString(MNC_INDEX));
             mApnType.setText(mApnData.getString(TYPE_INDEX));
             if (mNewApn) {
-                String numeric = mTelephonyManager.getSimOperator(mSubId);
-                // MCC is first 3 chars and then in 2 - 3 chars of MNC
-                if (numeric != null && numeric.length() > 4) {
-                    // Country code
-                    String mcc = numeric.substring(0, 3);
-                    // Network code
-                    String mnc = numeric.substring(3);
+                final SubscriptionInfo subInfo =
+                        mProxySubscriptionMgr.getActiveSubscriptionInfo(mSubId);
+
+                // Country code
+                final String mcc = (subInfo == null) ? null : subInfo.getMccString();
+                // Network code
+                final String mnc = (subInfo == null) ? null : subInfo.getMncString();
+
+                if ((!TextUtils.isEmpty(mcc)) && (!TextUtils.isEmpty(mcc))) {
                     // Auto populate MNC and MCC for new entries, based on what SIM reports
                     mMcc.setText(mcc);
                     mMnc.setText(mnc);
@@ -527,7 +531,7 @@
                     mCurMcc = mcc;
                 }
             }
-            int authVal = mApnData.getInteger(AUTH_TYPE_INDEX, -1);
+            final int authVal = mApnData.getInteger(AUTH_TYPE_INDEX, -1);
             if (authVal != -1) {
                 mAuthType.setValueIndex(authVal);
             } else {
@@ -539,7 +543,7 @@
             mCarrierEnabled.setChecked(mApnData.getInteger(CARRIER_ENABLED_INDEX, 1) == 1);
             mBearerInitialVal = mApnData.getInteger(BEARER_INDEX, 0);
 
-            HashSet<String> bearers = new HashSet<String>();
+            final HashSet<String> bearers = new HashSet<String>();
             int bearerBitmask = mApnData.getInteger(BEARER_BITMASK_INDEX, 0);
             if (bearerBitmask == 0) {
                 if (mBearerInitialVal == 0) {
@@ -585,12 +589,12 @@
         mMnc.setSummary(formatInteger(checkNull(mMnc.getText())));
         mApnType.setSummary(checkNull(mApnType.getText()));
 
-        String authVal = mAuthType.getValue();
+        final String authVal = mAuthType.getValue();
         if (authVal != null) {
-            int authValIndex = Integer.parseInt(authVal);
+            final int authValIndex = Integer.parseInt(authVal);
             mAuthType.setValueIndex(authValIndex);
 
-            String[] values = getResources().getStringArray(R.array.apn_auth_entries);
+            final String[] values = getResources().getStringArray(R.array.apn_auth_entries);
             mAuthType.setSummary(values[authValIndex]);
         } else {
             mAuthType.setSummary(sNotSet);
@@ -605,7 +609,8 @@
                 checkNull(mvnoDescription(mMvnoType.getValue())));
         mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText()));
         // allow user to edit carrier_enabled for some APN
-        boolean ceEditable = getResources().getBoolean(R.bool.config_allow_edit_carrier_enabled);
+        final boolean ceEditable = getResources().getBoolean(
+                R.bool.config_allow_edit_carrier_enabled);
         if (ceEditable) {
             mCarrierEnabled.setEnabled(true);
         } else {
@@ -619,11 +624,11 @@
      * return null.
      */
     private String protocolDescription(String raw, ListPreference protocol) {
-        int protocolIndex = protocol.findIndexOfValue(raw);
+        final int protocolIndex = protocol.findIndexOfValue(raw);
         if (protocolIndex == -1) {
             return null;
         } else {
-            String[] values = getResources().getStringArray(R.array.apn_protocol_entries);
+            final String[] values = getResources().getStringArray(R.array.apn_protocol_entries);
             try {
                 return values[protocolIndex];
             } catch (ArrayIndexOutOfBoundsException e) {
@@ -633,8 +638,8 @@
     }
 
     private String bearerMultiDescription(Set<String> raw) {
-        String[] values = getResources().getStringArray(R.array.bearer_entries);
-        StringBuilder retVal = new StringBuilder();
+        final String[] values = getResources().getStringArray(R.array.bearer_entries);
+        final StringBuilder retVal = new StringBuilder();
         boolean first = true;
         for (String bearer : raw) {
             int bearerIndex = mBearerMulti.findIndexOfValue(bearer);
@@ -649,7 +654,7 @@
                 // ignore
             }
         }
-        String val = retVal.toString();
+        final String val = retVal.toString();
         if (!TextUtils.isEmpty(val)) {
             return val;
         }
@@ -657,26 +662,45 @@
     }
 
     private String mvnoDescription(String newValue) {
-        int mvnoIndex = mMvnoType.findIndexOfValue(newValue);
-        String oldValue = mMvnoType.getValue();
+        final int mvnoIndex = mMvnoType.findIndexOfValue(newValue);
+        final String oldValue = mMvnoType.getValue();
 
         if (mvnoIndex == -1) {
             return null;
         } else {
-            String[] values = getResources().getStringArray(R.array.mvno_type_entries);
-            boolean mvnoMatchDataUneditable =
+            final String[] values = getResources().getStringArray(R.array.mvno_type_entries);
+            final boolean mvnoMatchDataUneditable =
                     mReadOnlyApn || (mReadOnlyApnFields != null
                             && Arrays.asList(mReadOnlyApnFields)
                             .contains(Telephony.Carriers.MVNO_MATCH_DATA));
             mMvnoMatchData.setEnabled(!mvnoMatchDataUneditable && mvnoIndex != 0);
             if (newValue != null && newValue.equals(oldValue) == false) {
                 if (values[mvnoIndex].equals("SPN")) {
-                    mMvnoMatchData.setText(mTelephonyManager.getSimOperatorName());
+                    TelephonyManager telephonyManager = (TelephonyManager)
+                            getContext().getSystemService(TelephonyManager.class);
+                    final TelephonyManager telephonyManagerForSubId =
+                            telephonyManager.createForSubscriptionId(mSubId);
+                    if (telephonyManagerForSubId != null) {
+                        telephonyManager = telephonyManagerForSubId;
+                    }
+                    mMvnoMatchData.setText(telephonyManager.getSimOperatorName());
                 } else if (values[mvnoIndex].equals("IMSI")) {
-                    String numeric = mTelephonyManager.getSimOperator(mSubId);
-                    mMvnoMatchData.setText(numeric + "x");
+                    final SubscriptionInfo subInfo =
+                            mProxySubscriptionMgr.getAccessibleSubscriptionInfo(mSubId);
+                    final String mcc = (subInfo == null) ? "" :
+                            Objects.toString(subInfo.getMccString(), "");
+                    final String mnc = (subInfo == null) ? "" :
+                            Objects.toString(subInfo.getMncString(), "");
+                    mMvnoMatchData.setText(mcc + mnc + "x");
                 } else if (values[mvnoIndex].equals("GID")) {
-                    mMvnoMatchData.setText(mTelephonyManager.getGroupIdLevel1());
+                    TelephonyManager telephonyManager = (TelephonyManager)
+                            getContext().getSystemService(TelephonyManager.class);
+                    final TelephonyManager telephonyManagerForSubId =
+                            telephonyManager.createForSubscriptionId(mSubId);
+                    if (telephonyManagerForSubId != null) {
+                        telephonyManager = telephonyManagerForSubId;
+                    }
+                    mMvnoMatchData.setText(telephonyManager.getGroupIdLevel1());
                 }
             }
 
@@ -692,37 +716,37 @@
         String key = preference.getKey();
         if (KEY_AUTH_TYPE.equals(key)) {
             try {
-                int index = Integer.parseInt((String) newValue);
+                final int index = Integer.parseInt((String) newValue);
                 mAuthType.setValueIndex(index);
 
-                String[] values = getResources().getStringArray(R.array.apn_auth_entries);
+                final String[] values = getResources().getStringArray(R.array.apn_auth_entries);
                 mAuthType.setSummary(values[index]);
             } catch (NumberFormatException e) {
                 return false;
             }
         } else if (KEY_PROTOCOL.equals(key)) {
-            String protocol = protocolDescription((String) newValue, mProtocol);
+            final String protocol = protocolDescription((String) newValue, mProtocol);
             if (protocol == null) {
                 return false;
             }
             mProtocol.setSummary(protocol);
             mProtocol.setValue((String) newValue);
         } else if (KEY_ROAMING_PROTOCOL.equals(key)) {
-            String protocol = protocolDescription((String) newValue, mRoamingProtocol);
+            final String protocol = protocolDescription((String) newValue, mRoamingProtocol);
             if (protocol == null) {
                 return false;
             }
             mRoamingProtocol.setSummary(protocol);
             mRoamingProtocol.setValue((String) newValue);
         } else if (KEY_BEARER_MULTI.equals(key)) {
-            String bearer = bearerMultiDescription((Set<String>) newValue);
+            final String bearer = bearerMultiDescription((Set<String>) newValue);
             if (bearer == null) {
                 return false;
             }
             mBearerMulti.setValues((Set<String>) newValue);
             mBearerMulti.setSummary(bearer);
         } else if (KEY_MVNO_TYPE.equals(key)) {
-            String mvno = mvnoDescription((String) newValue);
+            final String mvno = mvnoDescription((String) newValue);
             if (mvno == null) {
                 return false;
             }
@@ -815,14 +839,14 @@
      */
     boolean setStringValueAndCheckIfDiff(
             ContentValues cv, String key, String value, boolean assumeDiff, int index) {
-        String valueFromLocalCache = mApnData.getString(index);
+        final String valueFromLocalCache = mApnData.getString(index);
         if (VDBG) {
             Log.d(TAG, "setStringValueAndCheckIfDiff: assumeDiff: " + assumeDiff
                     + " key: " + key
                     + " value: '" + value
                     + "' valueFromDb: '" + valueFromLocalCache + "'");
         }
-        boolean isDiff = assumeDiff
+        final boolean isDiff = assumeDiff
                 || !((TextUtils.isEmpty(value) && TextUtils.isEmpty(valueFromLocalCache))
                 || (value != null && value.equals(valueFromLocalCache)));
 
@@ -841,7 +865,7 @@
      */
     boolean setIntValueAndCheckIfDiff(
             ContentValues cv, String key, int value, boolean assumeDiff, int index) {
-        Integer valueFromLocalCache = mApnData.getInteger(index);
+        final Integer valueFromLocalCache = mApnData.getInteger(index);
         if (VDBG) {
             Log.d(TAG, "setIntValueAndCheckIfDiff: assumeDiff: " + assumeDiff
                     + " key: " + key
@@ -849,7 +873,7 @@
                     + "' valueFromDb: '" + valueFromLocalCache + "'");
         }
 
-        boolean isDiff = assumeDiff || value != valueFromLocalCache;
+        final boolean isDiff = assumeDiff || value != valueFromLocalCache;
         if (isDiff) {
             cv.put(key, value);
         }
@@ -871,18 +895,18 @@
             return true;
         }
 
-        String name = checkNotSet(mName.getText());
-        String apn = checkNotSet(mApn.getText());
-        String mcc = checkNotSet(mMcc.getText());
-        String mnc = checkNotSet(mMnc.getText());
+        final String name = checkNotSet(mName.getText());
+        final String apn = checkNotSet(mApn.getText());
+        final String mcc = checkNotSet(mMcc.getText());
+        final String mnc = checkNotSet(mMnc.getText());
 
-        String errorMsg = validateApnData();
+        final String errorMsg = validateApnData();
         if (errorMsg != null) {
             showError();
             return false;
         }
 
-        ContentValues values = new ContentValues();
+        final ContentValues values = new ContentValues();
         // call update() if it's a new APN. If not, check if any field differs from the db value;
         // if any diff is found update() should be called
         boolean callUpdate = mNewApn;
@@ -946,7 +970,7 @@
                 callUpdate,
                 MMSC_INDEX);
 
-        String authVal = mAuthType.getValue();
+        final String authVal = mAuthType.getValue();
         if (authVal != null) {
             callUpdate = setIntValueAndCheckIfDiff(values,
                     Telephony.Carriers.AUTH_TYPE,
@@ -993,14 +1017,14 @@
             }
         }
 
-        Set<String> bearerSet = mBearerMulti.getValues();
+        final Set<String> bearerSet = mBearerMulti.getValues();
         int bearerBitmask = 0;
         for (String bearer : bearerSet) {
             if (Integer.parseInt(bearer) == 0) {
                 bearerBitmask = 0;
                 break;
             } else {
-                bearerBitmask |= ServiceState.getBitmaskForTech(Integer.parseInt(bearer));
+                bearerBitmask |= getBitmaskForTech(Integer.parseInt(bearer));
             }
         }
         callUpdate = setIntValueAndCheckIfDiff(values,
@@ -1012,7 +1036,7 @@
         int bearerVal;
         if (bearerBitmask == 0 || mBearerInitialVal == 0) {
             bearerVal = 0;
-        } else if (ServiceState.bitmaskHasTech(bearerBitmask, mBearerInitialVal)) {
+        } else if (bitmaskHasTech(bearerBitmask, mBearerInitialVal)) {
             bearerVal = mBearerInitialVal;
         } else {
             // bearer field was being used but bitmask has changed now and does not include the
@@ -1081,10 +1105,10 @@
     String validateApnData() {
         String errorMsg = null;
 
-        String name = checkNotSet(mName.getText());
-        String apn = checkNotSet(mApn.getText());
-        String mcc = checkNotSet(mMcc.getText());
-        String mnc = checkNotSet(mMnc.getText());
+        final String name = checkNotSet(mName.getText());
+        final String apn = checkNotSet(mApn.getText());
+        final String mcc = checkNotSet(mMcc.getText());
+        final String mnc = checkNotSet(mMnc.getText());
 
         if (TextUtils.isEmpty(name)) {
             errorMsg = getResources().getString(R.string.error_name_empty);
@@ -1101,7 +1125,7 @@
             // those
             if (!ArrayUtils.isEmpty(mReadOnlyApnTypes)
                     && apnTypesMatch(mReadOnlyApnTypes, getUserEnteredApnType())) {
-                StringBuilder stringBuilder = new StringBuilder();
+                final StringBuilder stringBuilder = new StringBuilder();
                 for (String type : mReadOnlyApnTypes) {
                     stringBuilder.append(type).append(", ");
                     Log.d(TAG, "validateApnData: appending type: " + type);
@@ -1134,7 +1158,7 @@
         if (value == null || value.length() == 0) {
             return sNotSet;
         } else {
-            char[] password = new char[value.length()];
+            final char[] password = new char[value.length()];
             for (int i = 0; i < password.length; i++) {
                 password[i] = '*';
             }
@@ -1173,8 +1197,8 @@
                 apnTypeList = mDefaultApnTypes;
             }
 
-            StringBuilder editableApnTypes = new StringBuilder();
-            List<String> readOnlyApnTypes = Arrays.asList(mReadOnlyApnTypes);
+            final StringBuilder editableApnTypes = new StringBuilder();
+            final List<String> readOnlyApnTypes = Arrays.asList(mReadOnlyApnTypes);
             boolean first = true;
             for (String apnType : apnTypeList) {
                 // add APN type if it is not read-only and is not wild-cardable
@@ -1201,14 +1225,14 @@
     public static class ErrorDialog extends InstrumentedDialogFragment {
 
         public static void showError(ApnEditor editor) {
-            ErrorDialog dialog = new ErrorDialog();
+            final ErrorDialog dialog = new ErrorDialog();
             dialog.setTargetFragment(editor, 0);
             dialog.show(editor.getFragmentManager(), "error");
         }
 
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
-            String msg = ((ApnEditor) getTargetFragment()).validateApnData();
+            final String msg = ((ApnEditor) getTargetFragment()).validateApnData();
 
             return new AlertDialog.Builder(getContext())
                     .setTitle(R.string.error_title)
@@ -1296,7 +1320,7 @@
         }
 
         Integer getInteger(int index, Integer defaultValue) {
-            Integer val = getInteger(index);
+            final Integer val = getInteger(index);
             return val == null ? defaultValue : val;
         }
 
@@ -1304,4 +1328,20 @@
             return (String) mData[index];
         }
     }
+
+    private static int getBitmaskForTech(int radioTech) {
+        if (radioTech >= 1) {
+            return (1 << (radioTech - 1));
+        }
+        return 0;
+    }
+
+    private static boolean bitmaskHasTech(int bearerBitmask, int radioTech) {
+        if (bearerBitmask == 0) {
+            return true;
+        } else if (radioTech >= 1) {
+            return ((bearerBitmask & (1 << (radioTech - 1))) != 0);
+        }
+        return false;
+    }
 }
diff --git a/src/com/android/settings/network/ApnSettings.java b/src/com/android/settings/network/ApnSettings.java
index 137abadf..94d7bca 100755
--- a/src/com/android/settings/network/ApnSettings.java
+++ b/src/com/android/settings/network/ApnSettings.java
@@ -54,7 +54,6 @@
 
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.uicc.UiccController;
 import com.android.settings.R;
 import com.android.settings.RestrictedSettingsFragment;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -114,7 +113,6 @@
     private SubscriptionInfo mSubscriptionInfo;
     private int mSubId;
     private int mPhoneId;
-    private UiccController mUiccController;
     private String mMvnoType;
     private String mMvnoMatchData;
 
@@ -193,7 +191,6 @@
         setIfOnlyAvailableForAdmins(true);
 
         mSubscriptionInfo = getSubscriptionInfo(mSubId);
-        mUiccController = UiccController.getInstance();
 
         CarrierConfigManager configManager = (CarrierConfigManager)
                 getSystemService(Context.CARRIER_CONFIG_SERVICE);
diff --git a/src/com/android/settings/network/GlobalSettingsChangeListener.java b/src/com/android/settings/network/GlobalSettingsChangeListener.java
new file mode 100644
index 0000000..4c58c60
--- /dev/null
+++ b/src/com/android/settings/network/GlobalSettingsChangeListener.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY;
+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.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A listener for Settings.Global configuration change, with support of Lifecycle
+ */
+public abstract class GlobalSettingsChangeListener extends ContentObserver
+        implements LifecycleObserver, AutoCloseable {
+
+    /**
+     * Constructor
+     *
+     * @param context {@code Context} of this listener
+     * @param field field of Global Settings
+     */
+    public GlobalSettingsChangeListener(Context context, String field) {
+        this(Looper.getMainLooper(), context, field);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param looper {@code Looper} for processing callback
+     * @param context {@code Context} of this listener
+     * @param field field of Global Settings
+     */
+    public GlobalSettingsChangeListener(Looper looper, Context context, String field) {
+        super(new Handler(looper));
+        mContext = context;
+        mField = field;
+        mUri = Settings.Global.getUriFor(field);
+        mListening = new AtomicBoolean(false);
+        monitorUri(true);
+    }
+
+    private Context mContext;
+    private String mField;
+    private Uri mUri;
+    private AtomicBoolean mListening;
+    private Lifecycle mLifecycle;
+
+    /**
+     * Observed Settings got changed
+     */
+    public abstract void onChanged(String field);
+
+    /**
+     * Notify change of Globals.Setting based on given Lifecycle
+     *
+     * @param lifecycle life cycle to reference
+     */
+    public void notifyChangeBasedOn(Lifecycle lifecycle) {
+        if (mLifecycle != null) {
+            mLifecycle.removeObserver(this);
+        }
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+        mLifecycle = lifecycle;
+    }
+
+    public void onChange(boolean selfChange) {
+        if (!mListening.get()) {
+            return;
+        }
+        onChanged(mField);
+    }
+
+    @OnLifecycleEvent(ON_START)
+    void onStart() {
+        monitorUri(true);
+    }
+
+    @OnLifecycleEvent(ON_STOP)
+    void onStop() {
+        monitorUri(false);
+    }
+
+    @OnLifecycleEvent(ON_DESTROY)
+    void onDestroy() {
+        close();
+    }
+
+    /**
+     * Implementation of AutoCloseable
+     */
+    public void close() {
+        monitorUri(false);
+        notifyChangeBasedOn(null);
+    }
+
+    private void monitorUri(boolean on) {
+        if (!mListening.compareAndSet(!on, on)) {
+            return;
+        }
+
+        if (on) {
+            mContext.getContentResolver().registerContentObserver(mUri, false, this);
+            return;
+        }
+
+        mContext.getContentResolver().unregisterContentObserver(this);
+    }
+}
diff --git a/src/com/android/settings/network/MobileDataContentObserver.java b/src/com/android/settings/network/MobileDataContentObserver.java
index b8a1c8c..0aab75f 100644
--- a/src/com/android/settings/network/MobileDataContentObserver.java
+++ b/src/com/android/settings/network/MobileDataContentObserver.java
@@ -33,9 +33,13 @@
         super(handler);
     }
 
-    public static Uri getObservableUri(int subId) {
+    /**
+     * Return a URI of mobile data(ON vs OFF)
+     */
+    public static Uri getObservableUri(Context context, int subId) {
         Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
-        if (TelephonyManager.getDefault().getSimCount() != 1) {
+        TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+        if (telephonyManager.getActiveModemCount() != 1) {
             uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
         }
         return uri;
@@ -54,7 +58,7 @@
     }
 
     public void register(Context context, int subId) {
-        final Uri uri = getObservableUri(subId);
+        final Uri uri = getObservableUri(context, subId);
         context.getContentResolver().registerContentObserver(uri, false, this);
 
     }
diff --git a/src/com/android/settings/network/OWNERS b/src/com/android/settings/network/OWNERS
new file mode 100644
index 0000000..bedbe16
--- /dev/null
+++ b/src/com/android/settings/network/OWNERS
@@ -0,0 +1,6 @@
+# Default reviewers for this and subdirectories.
+andychou@google.com
+bonianchen@google.com
+allenwtsu@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/src/com/android/settings/network/ProxySubscriptionManager.java b/src/com/android/settings/network/ProxySubscriptionManager.java
new file mode 100644
index 0000000..0306b55
--- /dev/null
+++ b/src/com/android/settings/network/ProxySubscriptionManager.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY;
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import android.content.Context;
+import android.os.Looper;
+import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A proxy to the subscription manager
+ */
+public class ProxySubscriptionManager implements LifecycleObserver {
+
+    /**
+     * Interface for monitor active subscriptions list changing
+     */
+    public interface OnActiveSubscriptionChangedListener {
+        /**
+         * When active subscriptions list get changed
+         */
+        void onChanged();
+        /**
+         * get Lifecycle of listener
+         *
+         * @return Returns Lifecycle.
+         */
+        default Lifecycle getLifecycle() {
+            return null;
+        }
+    }
+
+    /**
+     * Get proxy instance to subscription manager
+     *
+     * @return proxy to subscription manager
+     */
+    public static ProxySubscriptionManager getInstance(Context context) {
+        if (sSingleton != null) {
+            return sSingleton;
+        }
+        sSingleton = new ProxySubscriptionManager(context.getApplicationContext());
+        return sSingleton;
+    }
+
+    private static ProxySubscriptionManager sSingleton;
+
+    private ProxySubscriptionManager(Context context) {
+        final Looper looper = Looper.getMainLooper();
+
+        mActiveSubscriptionsListeners =
+                new ArrayList<OnActiveSubscriptionChangedListener>();
+
+        mSubscriptionMonitor = new ActiveSubsciptionsListener(looper, context) {
+            public void onChanged() {
+                notifyAllListeners();
+            }
+        };
+        mAirplaneModeMonitor = new GlobalSettingsChangeListener(looper,
+                context, Settings.Global.AIRPLANE_MODE_ON) {
+            public void onChanged(String field) {
+                mSubscriptionMonitor.clearCache();
+                notifyAllListeners();
+            }
+        };
+
+        mSubscriptionMonitor.start();
+    }
+
+    private Lifecycle mLifecycle;
+    private ActiveSubsciptionsListener mSubscriptionMonitor;
+    private GlobalSettingsChangeListener mAirplaneModeMonitor;
+
+    private List<OnActiveSubscriptionChangedListener> mActiveSubscriptionsListeners;
+
+    private void notifyAllListeners() {
+        for (OnActiveSubscriptionChangedListener listener : mActiveSubscriptionsListeners) {
+            final Lifecycle lifecycle = listener.getLifecycle();
+            if ((lifecycle == null)
+                    || (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED))) {
+                listener.onChanged();
+            }
+        }
+    }
+
+    /**
+     * Lifecycle for data within proxy
+     *
+     * @param lifecycle life cycle to reference
+     */
+    public void setLifecycle(Lifecycle lifecycle) {
+        if (mLifecycle == lifecycle) {
+            return;
+        }
+        if (mLifecycle != null) {
+            mLifecycle.removeObserver(this);
+        }
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+        mLifecycle = lifecycle;
+        mAirplaneModeMonitor.notifyChangeBasedOn(lifecycle);
+    }
+
+    @OnLifecycleEvent(ON_START)
+    void onStart() {
+        mSubscriptionMonitor.start();
+    }
+
+    @OnLifecycleEvent(ON_STOP)
+    void onStop() {
+        mSubscriptionMonitor.stop();
+    }
+
+    @OnLifecycleEvent(ON_DESTROY)
+    void onDestroy() {
+        mSubscriptionMonitor.close();
+        mAirplaneModeMonitor.close();
+
+        if (mLifecycle != null) {
+            mLifecycle.removeObserver(this);
+            mLifecycle = null;
+
+            sSingleton = null;
+        }
+    }
+
+    /**
+     * Get SubscriptionManager
+     *
+     * @return a SubscriptionManager
+     */
+    public SubscriptionManager get() {
+        return mSubscriptionMonitor.getSubscriptionManager();
+    }
+
+    /**
+     * Get current max. number active subscription info(s) been setup within device
+     *
+     * @return max. number of active subscription info(s)
+     */
+    public int getActiveSubscriptionInfoCountMax() {
+        return mSubscriptionMonitor.getActiveSubscriptionInfoCountMax();
+    }
+
+    /**
+     * Get a list of active subscription info
+     *
+     * @return A list of active subscription info
+     */
+    public List<SubscriptionInfo> getActiveSubscriptionsInfo() {
+        return mSubscriptionMonitor.getActiveSubscriptionsInfo();
+    }
+
+    /**
+     * Get an active subscription info with given subscription ID
+     *
+     * @param subId target subscription ID
+     * @return A subscription info which is active list
+     */
+    public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
+        return mSubscriptionMonitor.getActiveSubscriptionInfo(subId);
+    }
+
+    /**
+     * Get a list of accessible subscription info
+     *
+     * @return A list of accessible subscription info
+     */
+    public List<SubscriptionInfo> getAccessibleSubscriptionsInfo() {
+        return mSubscriptionMonitor.getAccessibleSubscriptionsInfo();
+    }
+
+    /**
+     * Get an accessible subscription info with given subscription ID
+     *
+     * @param subId target subscription ID
+     * @return A subscription info which is accessible list
+     */
+    public SubscriptionInfo getAccessibleSubscriptionInfo(int subId) {
+        return mSubscriptionMonitor.getAccessibleSubscriptionInfo(subId);
+    }
+
+    /**
+     * Clear data cached within proxy
+     */
+    public void clearCache() {
+        mSubscriptionMonitor.clearCache();
+    }
+
+    /**
+     * Add listener to active subscriptions monitor list
+     *
+     * @param listener listener to active subscriptions change
+     */
+    public void addActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener) {
+        if (mActiveSubscriptionsListeners.contains(listener)) {
+            return;
+        }
+        mActiveSubscriptionsListeners.add(listener);
+    }
+
+    /**
+     * Remove listener from active subscriptions monitor list
+     *
+     * @param listener listener to active subscriptions change
+     */
+    public void removeActiveSubscriptionsListener(OnActiveSubscriptionChangedListener listener) {
+        mActiveSubscriptionsListeners.remove(listener);
+    }
+}
diff --git a/src/com/android/settings/network/telephony/DataServiceSetupPreferenceController.java b/src/com/android/settings/network/telephony/DataServiceSetupPreferenceController.java
index d1fbd73..46f398c 100644
--- a/src/com/android/settings/network/telephony/DataServiceSetupPreferenceController.java
+++ b/src/com/android/settings/network/telephony/DataServiceSetupPreferenceController.java
@@ -63,7 +63,8 @@
 
     public void init(int subId) {
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
     }
 
     @Override
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index 3abb36a..675a1ba 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -27,7 +27,6 @@
 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;
@@ -148,7 +147,8 @@
     public void init(Lifecycle lifecycle, int subId) {
         mSubId = subId;
         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
 
         final boolean isLteOnCdma =
                 mTelephonyManager.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
diff --git a/src/com/android/settings/network/telephony/EuiccPreferenceController.java b/src/com/android/settings/network/telephony/EuiccPreferenceController.java
index ecd20ed..68f4370 100644
--- a/src/com/android/settings/network/telephony/EuiccPreferenceController.java
+++ b/src/com/android/settings/network/telephony/EuiccPreferenceController.java
@@ -50,7 +50,8 @@
 
     public void init(int subId) {
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
     }
 
     @Override
diff --git a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.java b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.java
index 4d3986b..00f5ebc 100644
--- a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.java
+++ b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.java
@@ -82,7 +82,8 @@
 
     public void init(int subId) {
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
     }
 
     @Override
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index c06b78b..daee6ab 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -138,13 +138,14 @@
     public void init(FragmentManager fragmentManager, int subId) {
         mFragmentManager = fragmentManager;
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
     }
 
     @VisibleForTesting
     boolean isDialogNeeded() {
         final boolean enableData = !isChecked();
-        final boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
+        final boolean isMultiSim = (mTelephonyManager.getActiveModemCount() > 1);
         final int defaultSubId = mSubscriptionManager.getDefaultDataSubscriptionId();
         final boolean needToDisableOthers = mSubscriptionManager
                 .isActiveSubscriptionId(defaultSubId) && defaultSubId != mSubId;
diff --git a/src/com/android/settings/network/telephony/MobileDataSlice.java b/src/com/android/settings/network/telephony/MobileDataSlice.java
index 152028c..c70ae1a 100644
--- a/src/com/android/settings/network/telephony/MobileDataSlice.java
+++ b/src/com/android/settings/network/telephony/MobileDataSlice.java
@@ -252,7 +252,7 @@
             }
 
             public void register(Context context, int subId) {
-                final Uri uri = MobileDataContentObserver.getObservableUri(subId);
+                final Uri uri = MobileDataContentObserver.getObservableUri(context, subId);
                 context.getContentResolver().registerContentObserver(uri, false, this);
             }
 
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index f1e0819..004291a 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -187,7 +187,8 @@
         final Context context = getContext();
 
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        mTelephonyManager = TelephonyManager.from(context).createForSubscriptionId(mSubId);
+        mTelephonyManager = context.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
 
         onRestoreInstance(icicle);
     }
diff --git a/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
index 7b24a93..89e2d5b8 100644
--- a/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
@@ -20,7 +20,6 @@
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
-import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
@@ -97,7 +96,8 @@
     public void init(int subId) {
         mSubId = subId;
         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
 
         final boolean isLteOnCdma =
                 mTelephonyManager.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
diff --git a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
index 2085cdf..a0c9859 100644
--- a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
+++ b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
@@ -149,7 +149,8 @@
         }
 
         final TextView operatorName = view.findViewById(R.id.operator_name_value);
-        final ServiceState serviceState = mTelephonyManager.getServiceStateForSubscriber(mSubId);
+        mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
+        final ServiceState serviceState = mTelephonyManager.getServiceState();
         operatorName.setText(serviceState.getOperatorAlphaLong());
 
         final TextView phoneTitle = view.findViewById(R.id.number_label);
diff --git a/src/com/android/settings/network/telephony/RoamingDialogFragment.java b/src/com/android/settings/network/telephony/RoamingDialogFragment.java
index 1298445..bf22fba 100644
--- a/src/com/android/settings/network/telephony/RoamingDialogFragment.java
+++ b/src/com/android/settings/network/telephony/RoamingDialogFragment.java
@@ -42,7 +42,7 @@
 
     public static RoamingDialogFragment newInstance(int subId) {
         final RoamingDialogFragment dialogFragment = new RoamingDialogFragment();
-        Bundle args = new Bundle();
+        final Bundle args = new Bundle();
         args.putInt(SUB_ID_KEY, subId);
         dialogFragment.setArguments(args);
 
@@ -52,17 +52,17 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        Bundle args = getArguments();
+        final Bundle args = getArguments();
         mSubId = args.getInt(SUB_ID_KEY);
         mCarrierConfigManager = new CarrierConfigManager(context);
     }
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
-        int title = R.string.roaming_alert_title;
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+        final int title = R.string.roaming_alert_title;
         int message = R.string.roaming_warning;
-        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+        final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
         if (carrierConfig != null && carrierConfig.getBoolean(
                 CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
             message = R.string.roaming_check_price_warning;
@@ -84,8 +84,13 @@
     public void onClick(DialogInterface dialog, int which) {
         // let the host know that the positive button has been clicked
         if (which == dialog.BUTTON_POSITIVE) {
-            TelephonyManager.from(getContext()).createForSubscriptionId(
-                    mSubId).setDataRoamingEnabled(true);
+            final TelephonyManager telephonyManager =
+                    getContext().getSystemService(TelephonyManager.class)
+                    .createForSubscriptionId(mSubId);
+            if (telephonyManager == null) {
+                return;
+            }
+            telephonyManager.setDataRoamingEnabled(true);
         }
     }
 }
diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.java b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
index dd5fd0e..08fe323 100644
--- a/src/com/android/settings/network/telephony/RoamingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
@@ -17,22 +17,20 @@
 package com.android.settings.network.telephony;
 
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.fragment.app.FragmentManager;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.network.GlobalSettingsChangeListener;
 import com.android.settingslib.RestrictedSwitchPreference;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -44,31 +42,59 @@
 public class RoamingPreferenceController extends TelephonyTogglePreferenceController implements
         LifecycleObserver, OnStart, OnStop {
 
+    private static final String TAG = "RoamingController";
     private static final String DIALOG_TAG = "MobileDataDialog";
 
     private RestrictedSwitchPreference mSwitchPreference;
     private TelephonyManager mTelephonyManager;
     private CarrierConfigManager mCarrierConfigManager;
-    private DataContentObserver mDataContentObserver;
-    @VisibleForTesting
-    boolean mNeedDialog;
+
+    /**
+     * There're 2 listeners both activated at the same time.
+     * For project that access DATA_ROAMING, only first listener is functional.
+     * For project that access "DATA_ROAMING + subId", first listener will be stopped when receiving
+     * any onChange from second listener.
+     */
+    private GlobalSettingsChangeListener mListener;
+    private GlobalSettingsChangeListener mListenerForSubId;
+
     @VisibleForTesting
     FragmentManager mFragmentManager;
 
     public RoamingPreferenceController(Context context, String key) {
         super(context, key);
         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
-        mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
     }
 
     @Override
     public void onStart() {
-        mDataContentObserver.register(mContext, mSubId);
+        if (mListener == null) {
+            mListener = new GlobalSettingsChangeListener(mContext,
+                    Settings.Global.DATA_ROAMING) {
+                public void onChanged(String field) {
+                    updateState(mSwitchPreference);
+                }
+            };
+        }
+        stopMonitorSubIdSpecific();
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return;
+        }
+
+        mListenerForSubId = new GlobalSettingsChangeListener(mContext,
+                Settings.Global.DATA_ROAMING + mSubId) {
+            public void onChanged(String field) {
+                stopMonitor();
+                updateState(mSwitchPreference);
+            }
+        };
     }
 
     @Override
     public void onStop() {
-        mDataContentObserver.unRegister(mContext);
+        stopMonitor();
+        stopMonitorSubIdSpecific();
     }
 
     @Override
@@ -87,7 +113,7 @@
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
-            if (mNeedDialog) {
+            if (isDialogNeeded()) {
                 showDialog();
             }
             return true;
@@ -98,9 +124,7 @@
 
     @Override
     public boolean setChecked(boolean isChecked) {
-        mNeedDialog = isDialogNeeded();
-
-        if (!mNeedDialog) {
+        if (!isDialogNeeded()) {
             // Update data directly if we don't need dialog
             mTelephonyManager.setDataRoamingEnabled(isChecked);
             return true;
@@ -141,7 +165,18 @@
     public void init(FragmentManager fragmentManager, int subId) {
         mFragmentManager = fragmentManager;
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return;
+        }
+        final TelephonyManager telephonyManager = mTelephonyManager
+                .createForSubscriptionId(mSubId);
+        if (telephonyManager == null) {
+            Log.w(TAG, "fail to init in sub" + mSubId);
+            mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            return;
+        }
+        mTelephonyManager = telephonyManager;
     }
 
     private void showDialog() {
@@ -150,32 +185,17 @@
         dialogFragment.show(mFragmentManager, DIALOG_TAG);
     }
 
-    /**
-     * Listener that listens data roaming change
-     */
-    public class DataContentObserver extends ContentObserver {
-
-        public DataContentObserver(Handler handler) {
-            super(handler);
+    private void stopMonitor() {
+        if (mListener != null) {
+            mListener.close();
+            mListener = null;
         }
+    }
 
-        @Override
-        public void onChange(boolean selfChange) {
-            super.onChange(selfChange);
-            updateState(mSwitchPreference);
-        }
-
-        public void register(Context context, int subId) {
-            Uri uri = Settings.Global.getUriFor(Settings.Global.DATA_ROAMING);
-            if (TelephonyManager.getDefault().getSimCount() != 1) {
-                uri = Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + subId);
-            }
-            context.getContentResolver().registerContentObserver(uri, false, this);
-
-        }
-
-        public void unRegister(Context context) {
-            context.getContentResolver().unregisterContentObserver(this);
+    private void stopMonitorSubIdSpecific() {
+        if (mListenerForSubId != null) {
+            mListenerForSubId.close();
+            mListenerForSubId = null;
         }
     }
 }
diff --git a/src/com/android/settings/network/telephony/cdma/CdmaBasePreferenceController.java b/src/com/android/settings/network/telephony/cdma/CdmaBasePreferenceController.java
index ea7d82f..07805b0 100644
--- a/src/com/android/settings/network/telephony/cdma/CdmaBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/cdma/CdmaBasePreferenceController.java
@@ -73,7 +73,8 @@
     public void init(PreferenceManager preferenceManager, int subId) {
         mPreferenceManager = preferenceManager;
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
     }
 
     public void init(int subId) {
diff --git a/src/com/android/settings/network/telephony/cdma/CdmaListPreference.java b/src/com/android/settings/network/telephony/cdma/CdmaListPreference.java
index 14c7169..2cb1840 100644
--- a/src/com/android/settings/network/telephony/cdma/CdmaListPreference.java
+++ b/src/com/android/settings/network/telephony/cdma/CdmaListPreference.java
@@ -41,6 +41,7 @@
     }
 
     public void setSubId(int subId) {
-        mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(subId);
+        mTelephonyManager = getContext().getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(subId);
     }
 }
diff --git a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
index 56d0b2d..626390a 100644
--- a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
+++ b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
@@ -144,7 +144,8 @@
 
     public AutoSelectPreferenceController init(int subId) {
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
         final PersistableBundle carrierConfig = mContext.getSystemService(
                 CarrierConfigManager.class).getConfigForSubId(mSubId);
         mOnlyAutoSelectInHome = carrierConfig != null
@@ -187,4 +188,4 @@
     public interface OnNetworkSelectModeListener {
         void onNetworkSelectModeChanged();
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java b/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java
index d679373..8c3928d 100644
--- a/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java
+++ b/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java
@@ -29,7 +29,6 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.network.telephony.MobileNetworkUtils;
 import com.android.settings.network.telephony.NetworkSelectSettings;
@@ -100,7 +99,8 @@
 
     public OpenNetworkSelectPagePreferenceController init(int subId) {
         mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mSubId);
         return this;
     }
 
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
index 749a46e..8693186 100644
--- a/src/com/android/settings/panel/SettingsPanelActivity.java
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.core.HideNonSystemOverlayMixin;
 
 /**
  * Dialog Activity to host Settings Slices.
@@ -62,6 +63,7 @@
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         createOrUpdatePanel(true /* shouldForceCreation */);
+        getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
     }
 
     @Override
diff --git a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
deleted file mode 100644
index 28533df..0000000
--- a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2019 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.privacy;
-
-import static android.Manifest.permission_group.CAMERA;
-import static android.Manifest.permission_group.LOCATION;
-import static android.Manifest.permission_group.MICROPHONE;
-
-import static java.util.concurrent.TimeUnit.DAYS;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.permission.PermissionControllerManager;
-import android.permission.RuntimePermissionUsageInfo;
-import android.provider.DeviceConfig;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.Utils;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnCreate;
-import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.widget.BarChartInfo;
-import com.android.settingslib.widget.BarChartPreference;
-import com.android.settingslib.widget.BarViewInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-public class PermissionBarChartPreferenceController extends BasePreferenceController implements
-        PermissionControllerManager.OnPermissionUsageResultCallback, LifecycleObserver, OnCreate,
-        OnStart, OnSaveInstanceState {
-
-    private static final String TAG = "BarChartPreferenceCtl";
-    private static final String KEY_PERMISSION_USAGE = "usage_infos";
-
-    @VisibleForTesting
-    List<RuntimePermissionUsageInfo> mOldUsageInfos;
-    private PackageManager mPackageManager;
-    private PrivacyDashboardFragment mParent;
-    private BarChartPreference mBarChartPreference;
-
-    public PermissionBarChartPreferenceController(Context context, String preferenceKey) {
-        super(context, preferenceKey);
-        mOldUsageInfos = new ArrayList<>();
-        mPackageManager = context.getPackageManager();
-    }
-
-    public void setFragment(PrivacyDashboardFragment fragment) {
-        mParent = fragment;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        if (savedInstanceState != null) {
-            mOldUsageInfos = savedInstanceState.getParcelableArrayList(KEY_PERMISSION_USAGE);
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        outState.putParcelableList(KEY_PERMISSION_USAGE, mOldUsageInfos);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return UNSUPPORTED_ON_DEVICE;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mBarChartPreference = screen.findPreference(getPreferenceKey());
-
-        final BarChartInfo info = new BarChartInfo.Builder()
-                .setTitle(R.string.permission_bar_chart_title)
-                .setDetails(R.string.permission_bar_chart_details)
-                .setEmptyText(R.string.permission_bar_chart_empty_text)
-                .setDetailsOnClickListener((View v) -> {
-                    final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
-                    intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1));
-                    mContext.startActivity(intent);
-                })
-                .build();
-
-        mBarChartPreference.initializeBarChart(info);
-        if (!mOldUsageInfos.isEmpty()) {
-            mBarChartPreference.setBarViewInfos(createBarViews(mOldUsageInfos));
-        }
-    }
-
-    @Override
-    public void onStart() {
-        if (!isAvailable()) {
-            return;
-        }
-
-        // We don't hide chart when we have existing data.
-        mBarChartPreference.updateLoadingState(mOldUsageInfos.isEmpty() /* isLoading */);
-        // But we still need to hint user with progress bar that we are updating new usage data.
-        mParent.setLoadingEnabled(true /* enabled */);
-        retrievePermissionUsageData();
-    }
-
-    @Override
-    public void onPermissionUsageResult(@NonNull List<RuntimePermissionUsageInfo> usageInfos) {
-        usageInfos.sort((x, y) -> {
-            int usageDiff = y.getAppAccessCount() - x.getAppAccessCount();
-            if (usageDiff != 0) {
-                return usageDiff;
-            }
-            String xName = x.getName();
-            String yName = y.getName();
-            if (xName.equals(LOCATION)) {
-                return -1;
-            } else if (yName.equals(LOCATION)) {
-                return 1;
-            } else if (xName.equals(MICROPHONE)) {
-                return -1;
-            } else if (yName.equals(MICROPHONE)) {
-                return 1;
-            } else if (xName.equals(CAMERA)) {
-                return -1;
-            } else if (yName.equals(CAMERA)) {
-                return 1;
-            }
-            return x.getName().compareTo(y.getName());
-        });
-
-        // If the result is different, we need to update bar views.
-        if (!areSamePermissionGroups(usageInfos)) {
-            mBarChartPreference.setBarViewInfos(createBarViews(usageInfos));
-            mOldUsageInfos = usageInfos;
-        }
-
-        mBarChartPreference.updateLoadingState(false /* isLoading */);
-        mParent.setLoadingEnabled(false /* enabled */);
-    }
-
-    private void retrievePermissionUsageData() {
-        mContext.getSystemService(PermissionControllerManager.class).getPermissionUsages(
-                false /* countSystem */, (int) DAYS.toMillis(1),
-                mContext.getMainExecutor() /* executor */, this /* callback */);
-    }
-
-    private BarViewInfo[] createBarViews(List<RuntimePermissionUsageInfo> usageInfos) {
-        if (usageInfos.isEmpty()) {
-            return null;
-        }
-
-        final BarViewInfo[] barViewInfos = new BarViewInfo[
-                Math.min(BarChartPreference.MAXIMUM_BAR_VIEWS, usageInfos.size())];
-
-        for (int index = 0; index < barViewInfos.length; index++) {
-            final RuntimePermissionUsageInfo permissionGroupInfo = usageInfos.get(index);
-            final int count = permissionGroupInfo.getAppAccessCount();
-            final CharSequence permLabel = getPermissionGroupLabel(permissionGroupInfo.getName());
-
-            barViewInfos[index] = new BarViewInfo(
-                    getPermissionGroupIcon(permissionGroupInfo.getName()), count, permLabel,
-                    mContext.getResources().getQuantityString(R.plurals.permission_bar_chart_label,
-                            count, count), permLabel);
-
-            // Set the click listener for each bar view.
-            // The listener will navigate user to permission usage app.
-            barViewInfos[index].setClickListener((View v) -> {
-                final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
-                intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, permissionGroupInfo.getName());
-                intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1));
-                mContext.startActivity(intent);
-            });
-        }
-
-        return barViewInfos;
-    }
-
-    private Drawable getPermissionGroupIcon(String permissionGroup) {
-        Drawable icon = null;
-        try {
-            icon = mPackageManager.getPermissionGroupInfo(permissionGroup, 0)
-                    .loadIcon(mPackageManager);
-            icon.setTintList(Utils.getColorAttr(mContext, android.R.attr.textColorSecondary));
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(TAG, "Cannot find group icon for " + permissionGroup, e);
-        }
-
-        return icon;
-    }
-
-    private CharSequence getPermissionGroupLabel(String permissionGroup) {
-        CharSequence label = null;
-        try {
-            label = mPackageManager.getPermissionGroupInfo(permissionGroup, 0)
-                    .loadLabel(mPackageManager);
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(TAG, "Cannot find group label for " + permissionGroup, e);
-        }
-
-        return label;
-    }
-
-    private boolean areSamePermissionGroups(List<RuntimePermissionUsageInfo> newUsageInfos) {
-        if (newUsageInfos.size() != mOldUsageInfos.size()) {
-            return false;
-        }
-
-        for (int index = 0; index < newUsageInfos.size(); index++) {
-            final RuntimePermissionUsageInfo newInfo = newUsageInfos.get(index);
-            final RuntimePermissionUsageInfo oldInfo = mOldUsageInfos.get(index);
-
-            if (!newInfo.getName().equals(oldInfo.getName()) ||
-                    newInfo.getAppAccessCount() != oldInfo.getAppAccessCount()) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index fa21f9d..1869cff 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -18,14 +18,12 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.os.Bundle;
 import android.provider.SearchIndexableResource;
 import android.view.View;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
-import com.android.settings.Utils;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.notification.LockScreenNotificationPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -75,34 +73,6 @@
         return buildPreferenceControllers(context, getSettingsLifecycle());
     }
 
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        use(PermissionBarChartPreferenceController.class).setFragment(this /* fragment */);
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
-        initLoadingBar();
-    }
-
-    @VisibleForTesting
-    void initLoadingBar() {
-        mProgressHeader = setPinnedHeaderView(R.layout.progress_header);
-        mProgressAnimation = mProgressHeader.findViewById(R.id.progress_bar_animation);
-        setLoadingEnabled(false);
-    }
-
-    @VisibleForTesting
-    void setLoadingEnabled(boolean enabled) {
-        if (mProgressHeader != null && mProgressAnimation != null) {
-            mProgressHeader.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
-            mProgressAnimation.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
-        }
-    }
-
     private static List<AbstractPreferenceController> buildPreferenceControllers(
             Context context, Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
diff --git a/src/com/android/settings/sim/CallsSimListDialogFragment.java b/src/com/android/settings/sim/CallsSimListDialogFragment.java
index 7d3de44..6dd262b 100644
--- a/src/com/android/settings/sim/CallsSimListDialogFragment.java
+++ b/src/com/android/settings/sim/CallsSimListDialogFragment.java
@@ -47,8 +47,7 @@
             return result;
         }
         for (PhoneAccountHandle handle : phoneAccounts) {
-            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
-            final int subId = telephonyManager.getSubIdForPhoneAccount(phoneAccount);
+            final int subId = telephonyManager.getSubscriptionId(handle);
 
             if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                 continue;
diff --git a/src/com/android/settings/sim/OWNERS b/src/com/android/settings/sim/OWNERS
new file mode 100644
index 0000000..bedbe16
--- /dev/null
+++ b/src/com/android/settings/sim/OWNERS
@@ -0,0 +1,6 @@
+# Default reviewers for this and subdirectories.
+andychou@google.com
+bonianchen@google.com
+allenwtsu@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index d24dbf5..0ae294e 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -176,8 +176,7 @@
         final TelephonyManager telephonyManager = getSystemService(TelephonyManager.class);
 
         for (PhoneAccountHandle handle : telecomManager.getCallCapablePhoneAccounts()) {
-            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
-            if (subId == telephonyManager.getSubIdForPhoneAccount(phoneAccount)) {
+            if (subId == telephonyManager.getSubscriptionId(handle)) {
                 return handle;
             }
         }
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index 7c2992c..45da776 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -240,6 +240,8 @@
         searchDestination.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key)
                 .setAction("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
                 .setComponent(null);
+        searchDestination.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+
         return searchDestination;
     }
 
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 4762403..ceda8a7 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -310,7 +310,7 @@
         mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS);
 
         if (mFilterWifiTracker == null) {
-            mFilterWifiTracker = new FilterWifiTracker(getActivity(), getSettingsLifecycle());
+            mFilterWifiTracker = new FilterWifiTracker(getContext(), getSettingsLifecycle());
         }
         mFilterWifiTracker.onResume();
     }
@@ -476,11 +476,13 @@
     private final class FilterWifiTracker {
         private final List<String> mAccessPointKeys;
         private final WifiTracker mWifiTracker;
+        private final Context mContext;
 
         public FilterWifiTracker(Context context, Lifecycle lifecycle) {
             mWifiTracker = WifiTrackerFactory.create(context, mWifiListener,
                     lifecycle, /* includeSaved */ true, /* includeScans */ true);
             mAccessPointKeys = new ArrayList<>();
+            mContext = context;
         }
 
         /**
@@ -489,7 +491,7 @@
          */
         public void updateKeys(List<ScanResult> scanResults) {
             for (ScanResult scanResult : scanResults) {
-                final String key = AccessPoint.getKey(scanResult);
+                final String key = AccessPoint.getKey(mContext, scanResult);
                 if (!mAccessPointKeys.contains(key)) {
                     mAccessPointKeys.add(key);
                 }
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 0aae89a..c924aaf 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -583,35 +583,6 @@
         }
     }
 
-    /**
-     * Special handling for WPA2/WPA3 and OWE in Transition mode: The key
-     * SECURITY_PSK_SAE_TRANSITION and SECURITY_OWE_TRANSITION are pseudo keys which result by the
-     * scan results, but never appears in the saved networks.
-     * A saved network is either WPA3 for supporting devices or WPA2 for non-supporting devices,
-     * or, OWE for supporting devices or Open for non-supporting devices.
-     *
-     * @param accessPointSecurity Access point current security type
-     * @return Converted security type (if required)
-     */
-    private int convertSecurityTypeForMatching(int accessPointSecurity) {
-        if (accessPointSecurity == AccessPoint.SECURITY_PSK_SAE_TRANSITION) {
-            if (mWifiManager.isWpa3SaeSupported()) {
-                return AccessPoint.SECURITY_SAE;
-            } else {
-                return AccessPoint.SECURITY_PSK;
-            }
-        }
-        if (accessPointSecurity == AccessPoint.SECURITY_OWE_TRANSITION) {
-            if (mWifiManager.isEnhancedOpenSupported()) {
-                return AccessPoint.SECURITY_OWE;
-            } else {
-                return AccessPoint.SECURITY_NONE;
-            }
-        }
-
-        return accessPointSecurity;
-    }
-
     public WifiConfiguration getConfig() {
         if (mMode == WifiConfigUiBase.MODE_VIEW) {
             return null;
@@ -634,8 +605,6 @@
 
         config.shared = mSharedCheckBox.isChecked();
 
-        mAccessPointSecurity = convertSecurityTypeForMatching(mAccessPointSecurity);
-
         switch (mAccessPointSecurity) {
             case AccessPoint.SECURITY_NONE:
                 config.allowedKeyManagement.set(KeyMgmt.NONE);
@@ -960,8 +929,7 @@
 
     private void showSecurityFields(boolean refreshEapMethods, boolean refreshCertificates) {
         if (mAccessPointSecurity == AccessPoint.SECURITY_NONE ||
-                mAccessPointSecurity == AccessPoint.SECURITY_OWE ||
-                mAccessPointSecurity == AccessPoint.SECURITY_OWE_TRANSITION) {
+                mAccessPointSecurity == AccessPoint.SECURITY_OWE) {
             mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
             return;
         }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 8c4bfa2..4d3f230 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -494,9 +494,7 @@
                 if (isSavedNetwork) {
                     connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
                 } else if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
-                        (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE) ||
-                        (mSelectedAccessPoint.getSecurity()
-                                == AccessPoint.SECURITY_OWE_TRANSITION)) {
+                        (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
                     /** Bypass dialog for unsecured networks */
                     mSelectedAccessPoint.generateOpenNetworkConfig();
                     connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
@@ -750,8 +748,7 @@
                 preference.setOrder(index);
                 if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr())
                         && (accessPoint.getSecurity() != AccessPoint.SECURITY_NONE &&
-                        accessPoint.getSecurity() != AccessPoint.SECURITY_OWE &&
-                        accessPoint.getSecurity() != AccessPoint.SECURITY_OWE_TRANSITION)) {
+                        accessPoint.getSecurity() != AccessPoint.SECURITY_OWE)) {
                     if (!accessPoint.isSaved() || isDisabledByWrongPassword(accessPoint)) {
                         onPreferenceTreeClick(preference);
                         mOpenSsid = null;
diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java
index c4df567..9b3c1b3 100644
--- a/src/com/android/settings/wifi/WifiUtils.java
+++ b/src/com/android/settings/wifi/WifiUtils.java
@@ -268,8 +268,7 @@
         if (accessPoint.isOsuProvider()) {
             return CONNECT_TYPE_OSU_PROVISION;
         } else if ((accessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
-                (accessPoint.getSecurity() == AccessPoint.SECURITY_OWE) ||
-                (accessPoint.getSecurity() == AccessPoint.SECURITY_OWE_TRANSITION)) {
+                (accessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
             return CONNECT_TYPE_OPEN_NETWORK;
         } else if (accessPoint.isSaved() && config != null
                 && config.getNetworkSelectionStatus() != null
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index 2a958e8..fc1bc25 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -206,7 +206,7 @@
         setConfiguratorIntentExtra(intent, wifiManager, wifiConfiguration);
 
         // For a transition mode Wi-Fi AP, creates a QR code that's compatible with more devices
-        if (accessPoint.getSecurity() == AccessPoint.SECURITY_PSK_SAE_TRANSITION) {
+        if (accessPoint.isPskSaeTransitionMode()) {
             intent.putExtra(EXTRA_WIFI_SECURITY, WifiQrCode.SECURITY_WPA_PSK);
         }
 
@@ -406,7 +406,6 @@
                 }
                 break;
             case AccessPoint.SECURITY_PSK:
-            case AccessPoint.SECURITY_PSK_SAE_TRANSITION:
                 return true;
             default:
         }
@@ -419,8 +418,6 @@
             case AccessPoint.SECURITY_PSK:
             case AccessPoint.SECURITY_WEP:
             case AccessPoint.SECURITY_NONE:
-            case AccessPoint.SECURITY_PSK_SAE_TRANSITION:
-            case AccessPoint.SECURITY_OWE_TRANSITION:
                 return true;
             case AccessPoint.SECURITY_SAE:
                 if (wifiManager.isWpa3SaeSupported()) {
diff --git a/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java b/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java
new file mode 100644
index 0000000..24abac9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.telephony.TelephonyManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+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;
+import org.robolectric.shadows.ShadowSettings;
+
+
+@RunWith(AndroidJUnit4.class)
+public final class AirplaneModeEnablerTest {
+
+    private Context mContext;
+
+    @Mock
+    private AirplaneModeChangedListener mAirplaneModeChangedListener;
+    private AirplaneModeEnabler mAirplaneModeEnabler;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application.getBaseContext();
+        mAirplaneModeEnabler = new AirplaneModeEnabler(mContext,
+                mAirplaneModeChangedListener);
+    }
+
+    @Test
+    public void onRadioPowerStateChanged_beenInvoke_invokeOnAirplaneModeChanged() {
+        mAirplaneModeEnabler.resume();
+
+        ShadowSettings.setAirplaneMode(true);
+
+        mAirplaneModeEnabler.mPhoneStateListener.onRadioPowerStateChanged(
+                TelephonyManager.RADIO_POWER_OFF);
+
+        verify(mAirplaneModeChangedListener, times(1)).onAirplaneModeChanged(true);
+    }
+
+    private class AirplaneModeChangedListener
+            implements AirplaneModeEnabler.OnAirplaneModeChangedListener {
+        public void onAirplaneModeChanged(boolean isAirplaneModeOn) {}
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java b/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java
index 693ed45..d0cb97a 100644
--- a/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java
+++ b/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java
@@ -16,16 +16,23 @@
 
 package com.android.settings.development.compat;
 
+import static com.android.internal.compat.OverrideAllowedState.ALLOWED;
+import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
 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.compat.Compatibility.ChangeConfig;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
@@ -38,7 +45,9 @@
 
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.compat.CompatibilityChangeInfo;
+import com.android.internal.compat.IOverrideValidator;
 import com.android.internal.compat.IPlatformCompat;
+import com.android.internal.compat.OverrideAllowedState;
 import com.android.settings.R;
 
 import org.junit.Before;
@@ -66,6 +75,10 @@
     private ApplicationInfo mApplicationInfo;
     @Mock
     private PreferenceManager mPreferenceManager;
+    @Mock
+    private IOverrideValidator mOverrideValidator;
+    @Mock
+    private PackageManager mPackageManager;
 
     private Context mContext;
     private CompatibilityChangeInfo[] mChanges;
@@ -81,7 +94,11 @@
         mChanges[3] = new CompatibilityChangeInfo(4L, "Enabled_After_SDK_1_2", 1, false, "");
         mChanges[4] = new CompatibilityChangeInfo(5L, "Enabled_After_SDK_2", 2, false, "");
         when(mPlatformCompat.listAllChanges()).thenReturn(mChanges);
-        mContext = RuntimeEnvironment.application;
+        when(mPlatformCompat.getOverrideValidator()).thenReturn(mOverrideValidator);
+        // By default, allow any change
+        when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString()))
+            .thenReturn(new OverrideAllowedState(ALLOWED, -1, -1));
+        mContext = spy(RuntimeEnvironment.application);
         mPreferenceManager = new PreferenceManager(mContext);
         mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
         mApplicationInfo.packageName = APP_NAME;
@@ -91,6 +108,7 @@
         doReturn(mPlatformCompat).when(mDashboard).getPlatformCompat();
         doReturn(mPreferenceScreen).when(mDashboard).getPreferenceScreen();
         doReturn(mPreferenceManager).when(mDashboard).getPreferenceManager();
+        doReturn(mPackageManager).when(mContext).getPackageManager();
     }
 
     @Test
@@ -107,8 +125,10 @@
     @Test
     public void createAppPreference_targetSdkEquals1_summaryReturnsAppNameAndTargetSdk() {
         mApplicationInfo.targetSdkVersion = 1;
+        Drawable icon = mock(Drawable.class);
+        when(mApplicationInfo.loadIcon(any(PackageManager.class))).thenReturn(icon);
 
-        Preference appPreference = mDashboard.createAppPreference(any(Drawable.class));
+        Preference appPreference = mDashboard.createAppPreference(mApplicationInfo);
 
         assertThat(appPreference.getSummary()).isEqualTo(APP_NAME + " SDK 1");
     }
@@ -128,6 +148,7 @@
         assertThat(enabledPreference.getSummary()).isEqualTo(mChanges[0].getName());
         assertThat(enabledPreference instanceof SwitchPreference).isTrue();
         assertThat(enabledSwitchPreference.isChecked()).isTrue();
+        assertThat(enabledSwitchPreference.isEnabled()).isTrue();
     }
 
     @Test
@@ -139,10 +160,32 @@
 
         Preference disabledPreference = mDashboard.createPreferenceForChange(mContext,
                 disabledChange, config);
-        
+
         assertThat(disabledPreference.getSummary()).isEqualTo(mChanges[1].getName());
         SwitchPreference disabledSwitchPreference = (SwitchPreference) disabledPreference;
         assertThat(disabledSwitchPreference.isChecked()).isFalse();
+        assertThat(disabledSwitchPreference.isEnabled()).isTrue();
+    }
+
+    @Test
+    public void createPreferenceForChange_cannotOverride_createDisabledEntry()
+                    throws RemoteException {
+        CompatibilityChangeInfo enabledChange = mChanges[0];
+        CompatibilityChangeConfig config = new CompatibilityChangeConfig(
+                new ChangeConfig(new HashSet<Long>(Arrays.asList(enabledChange.getId())),
+                        new HashSet<Long>()));
+        when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString()))
+            .thenReturn(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1));
+
+        Preference preference = mDashboard.createPreferenceForChange(mContext, enabledChange,
+                config);
+
+        SwitchPreference switchPreference = (SwitchPreference) preference;
+
+        assertThat(preference.getSummary()).isEqualTo(mChanges[0].getName());
+        assertThat(preference instanceof SwitchPreference).isTrue();
+        assertThat(switchPreference.isChecked()).isTrue();
+        assertThat(switchPreference.isEnabled()).isFalse();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
index 2c0b4fc..782fb25 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.CELL_DATA_NETWORK_TYPE_VALUE_ID;
 import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.CELL_VOICE_NETWORK_TYPE_VALUE_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.EID_INFO_LABEL_ID;
 import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.EID_INFO_VALUE_ID;
 import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.ICCID_INFO_LABEL_ID;
 import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.ICCID_INFO_VALUE_ID;
@@ -55,10 +56,12 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
 import android.telephony.euicc.EuiccManager;
 
 import androidx.lifecycle.LifecycleOwner;
 
+import com.android.internal.telephony.PhoneConstants;
 import com.android.settings.R;
 import com.android.settings.testutils.shadow.ShadowDeviceInfoUtils;
 import com.android.settingslib.DeviceInfoUtils;
@@ -79,7 +82,9 @@
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowDeviceInfoUtils.class})
@@ -117,6 +122,9 @@
     private LifecycleOwner mLifecycleOwner;
     private Lifecycle mLifecycle;
 
+    private static final String TEST_EID_FROM_CARD = "11111111111111111111111111111111";
+    private static final String TEST_EID_FROM_MANAGER = "22222222222222222222222222222222";
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -126,7 +134,6 @@
         mLifecycle = new Lifecycle(mLifecycleOwner);
         mController = spy(new SimStatusDialogController(mDialog, mLifecycle, 0 /* phone id */));
         ShadowDeviceInfoUtils.setPhoneNumber("");
-        doReturn(mServiceState).when(mController).getCurrentServiceState();
         //CellSignalStrength setup
         doReturn(0).when(mCellSignalStrengthCdma).getDbm();
         doReturn(0).when(mCellSignalStrengthCdma).getAsuLevel();
@@ -137,20 +144,31 @@
 
         doReturn(null).when(mSignalStrength).getCellSignalStrengths();
         doReturn(mPhoneStateListener).when(mController).getPhoneStateListener();
-        doReturn(mSignalStrength).when(mController).getSignalStrength();
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
 
-        when(mEuiccManager.isEnabled()).thenReturn(true);
-        when(mEuiccManager.getEid()).thenReturn("");
         ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
         ReflectionHelpers.setField(mController, "mCarrierConfigManager", mCarrierConfigManager);
         ReflectionHelpers.setField(mController, "mSubscriptionInfo", mSubscriptionInfo);
         ReflectionHelpers.setField(mController, "mEuiccManager", mEuiccManager);
         ReflectionHelpers.setField(mController, "mSubscriptionManager", mSubscriptionManager);
+
+        when(mTelephonyManager.getPhoneCount()).thenReturn(
+                PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(new ArrayList<UiccCardInfo>());
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(
+                new HashMap<Integer, Integer>());
+
+        when(mEuiccManager.isEnabled()).thenReturn(false);
+        when(mEuiccManager.getEid()).thenReturn("");
+        when(mEuiccManager.createForCardId(anyInt())).thenReturn(mEuiccManager);
+
         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mPersistableBundle);
         when(mPersistableBundle.getBoolean(
                 CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL))
                 .thenReturn(true);
+        when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
+        doReturn(mServiceState).when(mTelephonyManager).getServiceState();
+        doReturn(mSignalStrength).when(mTelephonyManager).getSignalStrength();
 
         final ShadowPackageManager shadowPackageManager =
                 Shadows.shadowOf(RuntimeEnvironment.application.getPackageManager());
@@ -313,25 +331,25 @@
     @Test
     @Ignore
     public void initialize_updateVoiceNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
-        when(mTelephonyManager.getVoiceNetworkType(anyInt())).thenReturn(
+        when(mTelephonyManager.getVoiceNetworkType()).thenReturn(
                 TelephonyManager.NETWORK_TYPE_EDGE);
 
         mController.initialize();
 
         verify(mDialog).setText(CELL_VOICE_NETWORK_TYPE_VALUE_ID,
-                TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
+                SimStatusDialogController.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
     }
 
     @Test
     @Ignore
     public void initialize_updateDataNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
-        when(mTelephonyManager.getDataNetworkType(anyInt())).thenReturn(
+        when(mTelephonyManager.getDataNetworkType()).thenReturn(
                 TelephonyManager.NETWORK_TYPE_EDGE);
 
         mController.initialize();
 
         verify(mDialog).setText(CELL_DATA_NETWORK_TYPE_VALUE_ID,
-                TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
+                SimStatusDialogController.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
     }
 
     @Test
@@ -400,7 +418,7 @@
         final String iccid = "12351351231241";
         when(mPersistableBundle.getBoolean(
                 CarrierConfigManager.KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL)).thenReturn(true);
-        doReturn(iccid).when(mController).getSimSerialNumber(anyInt());
+        doReturn(iccid).when(mTelephonyManager).getSimSerialNumber();
 
         mController.initialize();
 
@@ -408,25 +426,283 @@
     }
 
     @Test
-    @Ignore
-    public void initialize_showEid_shouldSetEidToSetting() {
-        final String eid = "12351351231241";
-        when(mEuiccManager.getEid()).thenReturn(eid);
+    public void initialize_updateEid_shouldNotSetEid() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
+                false,                                  // isEuicc
+                0,                                      // cardId
+                null,                                   // eid
+                "123451234567890",                      // iccid
+                0,                                      // slotIndex
+                true);                                  // isRemovable
+        uiccCardInfos.add(uiccCardInfo1);
+        UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
+                true,                                   // isEuicc
+                1,                                      // cardId
+                null,                                   // eid (unavailable)
+                null,                                   // iccid
+                1,                                      // slotIndex
+                false);                                 // isRemovable
+        uiccCardInfos.add(uiccCardInfo2);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 1);
+        slotMapping.put(1, 0);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(true);
+        when(mEuiccManager.getEid()).thenReturn(null);
 
         mController.initialize();
 
-        verify(mDialog).setText(EID_INFO_VALUE_ID, eid);
+        // Keep 'Not available' if neither the card nor the associated manager can provide EID.
+        verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
         verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
     }
 
     @Test
-    @Ignore
-    public void initialize_showEid_euiccManagerIsNotEnabled() {
-        when(mEuiccManager.isEnabled()).thenReturn(false);
+    public void initialize_updateEid_shouldSetEidFromCard() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
+                true,                                   // isEuicc
+                0,                                      // cardId
+                TEST_EID_FROM_CARD,                     // eid
+                null,                                   // iccid
+                0,                                      // slotIndex
+                false);                                 // isRemovable
+        uiccCardInfos.add(uiccCardInfo1);
+        UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
+                false,                                  // isEuicc
+                1,                                      // cardId
+                null,                                   // eid
+                "123451234567890",                      // iccid
+                1,                                      // slotIndex
+                true);                                  // isRemovable
+        uiccCardInfos.add(uiccCardInfo2);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 0);
+        slotMapping.put(1, 1);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(true);
+        when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
 
         mController.initialize();
 
+        // Set EID retrieved from the card.
+        verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_CARD);
+        verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
+    }
+
+    @Test
+    public void initialize_updateEid_shouldSetEidFromManager() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
+                false,                                  // isEuicc
+                0,                                      // cardId
+                null,                                   // eid
+                "123451234567890",                      // iccid
+                0,                                      // slotIndex
+                true);                                  // isRemovable
+        uiccCardInfos.add(uiccCardInfo1);
+        UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
+                true,                                   // isEuicc
+                1,                                      // cardId
+                null,                                   // eid (unavailable)
+                null,                                   // iccid
+                1,                                      // slotIndex
+                false);                                 // isRemovable
+        uiccCardInfos.add(uiccCardInfo2);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 1);
+        slotMapping.put(1, 0);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(true);
+        when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+        when(mEuiccManager.createForCardId(0)).thenThrow(
+                new RuntimeException("Unexpected card ID was specified"));
+        when(mEuiccManager.createForCardId(1)).thenReturn(mEuiccManager);
+
+        mController.initialize();
+
+        // Set EID retrieved from the manager associated with the card which cannot provide EID.
+        verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER);
+        verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
+    }
+
+    @Test
+    public void initialize_updateEid_shouldRemoveEid() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
+                false,                                  // isEuicc
+                0,                                      // cardId
+                null,                                   // eid
+                "123451234567890",                      // iccid
+                0,                                      // slotIndex
+                true);                                  // isRemovable
+        uiccCardInfos.add(uiccCardInfo1);
+        UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
+                true,                                   // isEuicc
+                1,                                      // cardId
+                TEST_EID_FROM_CARD,                     // eid
+                null,                                   // iccid
+                1,                                      // slotIndex
+                false);                                 // isRemovable
+        uiccCardInfos.add(uiccCardInfo2);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 0);
+        slotMapping.put(1, 1);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(true);
+        when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+
+        mController.initialize();
+
+        // Remove EID if the card is not eUICC.
         verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
+        verify(mDialog).removeSettingFromScreen(eq(EID_INFO_LABEL_ID));
+        verify(mDialog).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
+    }
+
+    @Test
+    public void initialize_updateEid_shouldNotSetEidInSingleSimMode() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(
+                PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo = new UiccCardInfo(
+                true,                                   // isEuicc
+                0,                                      // cardId
+                TEST_EID_FROM_CARD,                     // eid (not used)
+                null,                                   // iccid
+                0,                                      // slotIndex
+                false);                                 // isRemovable
+        uiccCardInfos.add(uiccCardInfo);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 0);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(true);
+        when(mEuiccManager.getEid()).thenReturn(null);
+
+        mController.initialize();
+
+        // Keep 'Not available' if the default eUICC manager cannot provide EID in Single SIM mode.
+        verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
+        verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
+    }
+
+    @Test
+    public void initialize_updateEid_shouldSetEidInSingleSimModeWithEnabledEuicc() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(
+                PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo = new UiccCardInfo(
+                true,                                   // isEuicc (eUICC slot is selected)
+                0,                                      // cardId
+                TEST_EID_FROM_CARD,                     // eid (not used)
+                null,                                   // iccid
+                0,                                      // slotIndex
+                false);                                 // isRemovable
+        uiccCardInfos.add(uiccCardInfo);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 0);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(true);
+        when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+        when(mEuiccManager.createForCardId(anyInt())).thenThrow(
+                new RuntimeException("EID shall be retrieved from the default eUICC manager"));
+
+        mController.initialize();
+
+        // Set EID retrieved from the default eUICC manager in Single SIM mode.
+        verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER);
+        verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
+    }
+
+    @Test
+    public void initialize_updateEid_shouldSetEidInSingleSimModeWithDisabledEuicc() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(
+                PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo = new UiccCardInfo(
+                false,                                  // isEuicc (eUICC slot is not selected)
+                0,                                      // cardId
+                null,                                   // eid
+                "123451234567890",                      // iccid
+                0,                                      // slotIndex
+                true);                                  // isRemovable
+        uiccCardInfos.add(uiccCardInfo);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 0);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(true);
+        when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
+        when(mEuiccManager.createForCardId(anyInt())).thenThrow(
+                new RuntimeException("EID shall be retrieved from the default eUICC manager"));
+
+        mController.initialize();
+
+        // Set EID retrieved from the default eUICC manager in Single SIM mode.
+        verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER);
+        verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
+    }
+
+    @Test
+    public void initialize_updateEid_shouldRemoveEidInSingleSimMode() {
+        when(mTelephonyManager.getPhoneCount()).thenReturn(
+                PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM);
+
+        ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
+        UiccCardInfo uiccCardInfo = new UiccCardInfo(
+                false,                                  // isEuicc
+                0,                                      // cardId
+                null,                                   // eid
+                "123451234567890",                      // iccid
+                0,                                      // slotIndex
+                true);                                  // isRemovable
+        uiccCardInfos.add(uiccCardInfo);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
+
+        Map<Integer, Integer> slotMapping = new HashMap<>();
+        slotMapping.put(0, 0);
+        when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
+
+        when(mEuiccManager.isEnabled()).thenReturn(false);
+        when(mEuiccManager.getEid()).thenReturn(null);
+
+        mController.initialize();
+
+        // Remove EID if the default eUICC manager indicates that eSIM is not enabled.
+        verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
+        verify(mDialog).removeSettingFromScreen(eq(EID_INFO_LABEL_ID));
         verify(mDialog).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
     }
 
@@ -482,7 +758,7 @@
     @Test
     @Ignore
     public void initialize_nullSignalStrength_noCrash() {
-        doReturn(null).when(mController).getSignalStrength();
+        doReturn(null).when(mTelephonyManager).getSignalStrength();
         // we should not crash when running the following line
         mController.initialize();
     }
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index dcb32c4..db12580 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -16,20 +16,42 @@
 
 package com.android.settings.homepage;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Build;
 import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
 import android.widget.FrameLayout;
 
 import com.android.settings.R;
+import com.android.settings.core.HideNonSystemOverlayMixin;
+import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class SettingsHomepageActivityTest {
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
 
     @Test
     public void setHomepageContainerPaddingTop_shouldBeSetPaddingTop() {
@@ -55,4 +77,55 @@
 
         assertThat(frameLayout.getLayoutTransition()).isNotNull();
     }
+
+    @Test
+    @Config(shadows = {
+            BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
+            BatteryFixSliceTest.ShadowBatteryTipLoader.class
+    })
+    public void onStart_isNotDebuggable_shouldHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsHomepageActivity> activityController =
+                Robolectric.buildActivity(SettingsHomepageActivity.class).create();
+        final SettingsHomepageActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+    }
+
+    @Test
+    @Config(shadows = {
+            BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
+            BatteryFixSliceTest.ShadowBatteryTipLoader.class,
+    })
+    public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsHomepageActivity> activityController =
+                Robolectric.buildActivity(SettingsHomepageActivity.class).create();
+        final SettingsHomepageActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        when(window.getAttributes()).thenReturn(layoutParams);
+
+        activityController.stop();
+        final ArgumentCaptor<WindowManager.LayoutParams> paramCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+
+        verify(window).setAttributes(paramCaptor.capture());
+        assertThat(paramCaptor.getValue().privateFlags
+                & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
index bb21332..1af7b2b 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
@@ -22,10 +22,10 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
-import android.app.UiModeManager;
 import android.content.Context;
 import android.net.Uri;
 import android.os.BatteryManager;
+import android.os.PowerManager;
 
 import androidx.slice.Slice;
 import androidx.slice.SliceMetadata;
@@ -48,9 +48,9 @@
 @RunWith(RobolectricTestRunner.class)
 public class DarkThemeSliceTest {
     @Mock
-    private UiModeManager mUiModeManager;
-    @Mock
     private BatteryManager mBatteryManager;
+    @Mock
+    private PowerManager mPowerManager;
 
     private Context mContext;
     private DarkThemeSlice mDarkThemeSlice;
@@ -63,11 +63,12 @@
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mFeatureFactory.slicesFeatureProvider = new SlicesFeatureProviderImpl();
         mFeatureFactory.slicesFeatureProvider.newUiSession();
-        doReturn(mUiModeManager).when(mContext).getSystemService(UiModeManager.class);
+        doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
+        when(mPowerManager.isPowerSaveMode()).thenReturn(false);
 
         // Set-up specs for SliceMetadata.
         SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
-        mDarkThemeSlice = new DarkThemeSlice(mContext);
+        mDarkThemeSlice = spy(new DarkThemeSlice(mContext));
         mDarkThemeSlice.sKeepSliceShow = false;
     }
 
@@ -80,7 +81,7 @@
 
     @Test
     public void isAvailable_inDarkThemeMode_returnFalse() {
-        when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+        doReturn(true).when(mDarkThemeSlice).isDarkThemeMode(mContext);
 
         assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse();
     }
@@ -100,23 +101,36 @@
     }
 
     @Test
-    public void getSlice_notAvailable_returnNull() {
-        when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+    public void getSlice_batterySaver_returnErrorSlice() {
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
 
-        assertThat(mDarkThemeSlice.getSlice()).isNull();
+        final Slice mediaSlice = mDarkThemeSlice.getSlice();
+        final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+        assertThat(metadata.isErrorSlice()).isTrue();
     }
 
     @Test
-    public void getSlice_newSession_notAvailable_returnNull() {
+    public void getSlice_notAvailable_returnErrorSlice() {
+        doReturn(true).when(mDarkThemeSlice).isDarkThemeMode(mContext);
+
+        final Slice mediaSlice = mDarkThemeSlice.getSlice();
+        final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+        assertThat(metadata.isErrorSlice()).isTrue();
+    }
+
+    @Test
+    public void getSlice_newSession_notAvailable_returnErrorSlice() {
         // previous displayed: yes
         mDarkThemeSlice.sKeepSliceShow = true;
         // Session: use original value + 1 to become a new session
         mDarkThemeSlice.sActiveUiSession =
                 mFeatureFactory.slicesFeatureProvider.getUiSessionToken() + 1;
 
-        when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+        doReturn(true).when(mDarkThemeSlice).isDarkThemeMode(mContext);
 
-        assertThat(mDarkThemeSlice.getSlice()).isNull();
+        final Slice mediaSlice = mDarkThemeSlice.getSlice();
+        final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+        assertThat(metadata.isErrorSlice()).isTrue();
     }
 
     @Test
@@ -149,7 +163,7 @@
     }
 
     private void setBatteryCapacityLevel(int power_level) {
-        when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_NO);
+        doReturn(false).when(mDarkThemeSlice).isDarkThemeMode(mContext);
         doReturn(mBatteryManager).when(mContext).getSystemService(BatteryManager.class);
         when(mBatteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY))
                 .thenReturn(power_level);
diff --git a/tests/robotests/src/com/android/settings/network/ActiveSubsciptionsListenerTest.java b/tests/robotests/src/com/android/settings/network/ActiveSubsciptionsListenerTest.java
new file mode 100644
index 0000000..4c7b55b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/ActiveSubsciptionsListenerTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Looper;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.telephony.TelephonyIntents;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowBroadcastReceiver;
+import org.robolectric.shadows.ShadowContextImpl;
+import org.robolectric.shadows.ShadowSubscriptionManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@RunWith(AndroidJUnit4.class)
+public class ActiveSubsciptionsListenerTest {
+    private static final int SUB_ID1 = 3;
+    private static final int SUB_ID2 = 7;
+
+    private static final Intent INTENT_RADIO_TECHNOLOGY_CHANGED =
+            new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+
+    private static final Intent INTENT_MULTI_SIM_CONFIG_CHANGED =
+            new Intent(TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED);
+
+    private static final Intent INTENT_CARRIER_CONFIG_CHANGED =
+            new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+
+    private Context mContext;
+    private ShadowContextImpl mShadowContextImpl;
+    private SubscriptionManager mSubscriptionManager;
+    private ShadowSubscriptionManager mShadowSubscriptionManager;
+    private List<SubscriptionInfo> mActiveSubscriptions;
+
+    private ActiveSubsciptionsListenerImpl mListener;
+    private BroadcastReceiver mReceiver;
+    private ShadowBroadcastReceiver mShadowReceiver;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application.getBaseContext();
+        mShadowContextImpl = Shadow.extract(mContext);
+
+        mSubscriptionManager = spy(mContext.getSystemService(SubscriptionManager.class));
+        mShadowSubscriptionManager = shadowOf(mSubscriptionManager);
+
+        mActiveSubscriptions = new ArrayList<SubscriptionInfo>();
+        mActiveSubscriptions.add(ShadowSubscriptionManager.SubscriptionInfoBuilder
+                .newBuilder().setId(SUB_ID1).buildSubscriptionInfo());
+        mActiveSubscriptions.add(ShadowSubscriptionManager.SubscriptionInfoBuilder
+                .newBuilder().setId(SUB_ID2).buildSubscriptionInfo());
+        mShadowSubscriptionManager.setActiveSubscriptionInfoList(mActiveSubscriptions);
+
+        mListener = spy(new ActiveSubsciptionsListenerImpl(Looper.getMainLooper(), mContext));
+        doReturn(mSubscriptionManager).when(mListener).getSubscriptionManager();
+        mReceiver = mListener.getSubscriptionChangeReceiver();
+        mShadowReceiver = shadowOf(mReceiver);
+        doReturn(mReceiver).when(mListener).getSubscriptionChangeReceiver();
+    }
+
+    @After
+    public void cleanUp() {
+        mListener.close();
+    }
+
+    private class ActiveSubsciptionsListenerImpl extends ActiveSubsciptionsListener {
+        private ActiveSubsciptionsListenerImpl(Looper looper, Context context) {
+            super(looper, context);
+        }
+        public void onChanged() {}
+    }
+
+    private void sendIntentToReceiver(Intent intent) {
+        mShadowReceiver.onReceive(mContext, intent, new AtomicBoolean(false));
+    }
+
+    @Test
+    public void constructor_noListeningWasSetup() {
+        verify(mListener, never()).onChanged();
+    }
+
+    @Test
+    public void start_configChangedIntent_onChangedShouldBeCalled() {
+        sendIntentToReceiver(INTENT_RADIO_TECHNOLOGY_CHANGED);
+        sendIntentToReceiver(INTENT_MULTI_SIM_CONFIG_CHANGED);
+        verify(mListener, never()).onChanged();
+
+        mListener.start();
+
+        sendIntentToReceiver(INTENT_RADIO_TECHNOLOGY_CHANGED);
+        verify(mListener, times(1)).onChanged();
+
+        sendIntentToReceiver(INTENT_MULTI_SIM_CONFIG_CHANGED);
+        verify(mListener, times(2)).onChanged();
+
+        mListener.stop();
+
+        sendIntentToReceiver(INTENT_RADIO_TECHNOLOGY_CHANGED);
+        sendIntentToReceiver(INTENT_MULTI_SIM_CONFIG_CHANGED);
+        verify(mListener, times(2)).onChanged();
+    }
+
+    @Test
+    public void start_carrierConfigChangedIntent_onChangedWhenSubIdBeenCached() {
+        sendIntentToReceiver(INTENT_CARRIER_CONFIG_CHANGED);
+        verify(mListener, never()).onChanged();
+
+        mListener.start();
+
+        mListener.getActiveSubscriptionsInfo();
+
+        sendIntentToReceiver(INTENT_CARRIER_CONFIG_CHANGED);
+        verify(mListener, never()).onChanged();
+
+        INTENT_CARRIER_CONFIG_CHANGED.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
+                SUB_ID2);
+        sendIntentToReceiver(INTENT_CARRIER_CONFIG_CHANGED);
+        verify(mListener, times(1)).onChanged();
+
+        mListener.stop();
+
+        sendIntentToReceiver(INTENT_CARRIER_CONFIG_CHANGED);
+        verify(mListener, times(1)).onChanged();
+    }
+
+
+    @Test
+    public void start_alwaysFetchAndCacheResult() {
+        mListener.start();
+
+        List<SubscriptionInfo> subInfoList = null;
+        int numberOfAccess = 0;
+        for (int numberOfSubInfo = mActiveSubscriptions.size(); numberOfSubInfo >= 0;
+                numberOfSubInfo--) {
+            if (mActiveSubscriptions.size() > numberOfSubInfo) {
+                mActiveSubscriptions.remove(numberOfSubInfo);
+            }
+            mShadowSubscriptionManager.setActiveSubscriptionInfoList(mActiveSubscriptions);
+
+            // fetch twice and test if they generated access to SubscriptionManager only once
+            subInfoList = mListener.getActiveSubscriptionsInfo();
+            subInfoList = mListener.getActiveSubscriptionsInfo();
+
+            numberOfAccess++;
+            verify(mSubscriptionManager, times(numberOfAccess)).getActiveSubscriptionInfoList();
+
+            mListener.clearCache();
+        }
+
+        mShadowSubscriptionManager.setActiveSubscriptionInfoList(null);
+
+        // fetch twice and test if they generated access to SubscriptionManager only once
+        subInfoList = mListener.getActiveSubscriptionsInfo();
+        subInfoList = mListener.getActiveSubscriptionsInfo();
+
+        numberOfAccess++;
+        verify(mSubscriptionManager, times(numberOfAccess)).getActiveSubscriptionInfoList();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
index dc14418..3aa6a6f 100644
--- a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
+++ b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
@@ -30,6 +30,7 @@
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.Intent;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
@@ -46,6 +47,7 @@
 
 import com.android.settings.R;
 import com.android.settings.network.ApnEditor.ApnData;
+import com.android.settings.testutils.shadow.ShadowFragment;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,6 +60,7 @@
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
 public class ApnEditorTest {
@@ -96,27 +99,33 @@
     @Mock
     private Cursor mCursor;
 
+    @Mock
+    private FragmentActivity mActivity;
+
     @Captor
     private ArgumentCaptor<Uri> mUriCaptor;
 
     private ApnEditor mApnEditorUT;
-    private FragmentActivity mActivity;
+    private Context mContext;
     private Resources mResources;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mActivity = spy(Robolectric.setupActivity(FragmentActivity.class));
-        mResources = mActivity.getResources();
+        mContext = spy(RuntimeEnvironment.application);
+
+        mResources = mContext.getResources();
         mApnEditorUT = spy(new ApnEditor());
 
         doReturn(mActivity).when(mApnEditorUT).getActivity();
         doReturn(mResources).when(mApnEditorUT).getResources();
         doNothing().when(mApnEditorUT).finish();
         doNothing().when(mApnEditorUT).showError();
-        when(mApnEditorUT.getContext()).thenReturn(RuntimeEnvironment.application);
+        doReturn(mContext).when(mApnEditorUT).getContext();
+        doReturn(mContext.getTheme()).when(mActivity).getTheme();
+        doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
 
-        setMockPreference(mActivity);
+        setMockPreference(mContext);
         mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
         mApnEditorUT.sNotSet = "Not Set";
     }
@@ -317,7 +326,7 @@
 
         // WHEN press the back button
         final KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
-        mApnEditorUT.onKey(new View(mActivity), KeyEvent.KEYCODE_BACK, event);
+        mApnEditorUT.onKey(new View(mContext), KeyEvent.KEYCODE_BACK, event);
 
         // THEN the apn data is saved and the apn editor is closed
         verify(mApnEditorUT).validateAndSaveApnData();
@@ -455,7 +464,9 @@
     }
 
     @Test
+    @Config(shadows = ShadowFragment.class)
     public void onCreate_noAction_shouldFinishAndNoCrash() {
+        doReturn(new Intent()).when(mActivity).getIntent();
         doNothing().when(mApnEditorUT).addPreferencesFromResource(anyInt());
 
         mApnEditorUT.onCreate(null);
diff --git a/tests/robotests/src/com/android/settings/network/GlobalSettingsChangeListenerTest.java b/tests/robotests/src/com/android/settings/network/GlobalSettingsChangeListenerTest.java
new file mode 100644
index 0000000..e419071
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/GlobalSettingsChangeListenerTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class GlobalSettingsChangeListenerTest {
+
+    @Mock
+    private Lifecycle mLifecycle;
+
+    private Context mContext;
+    private GlobalSettingsChangeListener mListener;
+
+    private static final String SETTINGS_FIELD = Settings.Global.AIRPLANE_MODE_ON;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mListener = spy(new GlobalSettingsChangeListener(Looper.getMainLooper(),
+                mContext, SETTINGS_FIELD) {
+            public void onChanged(String field) {}
+        });
+
+        doNothing().when(mLifecycle).addObserver(mListener);
+        doNothing().when(mLifecycle).removeObserver(mListener);
+    }
+
+    @Test
+    public void whenChanged_onChangedBeenCalled() {
+        mListener.onChange(false);
+        verify(mListener, times(1)).onChanged(SETTINGS_FIELD);
+    }
+
+    @Test
+    public void whenNotifyChangeBasedOnLifecycle_onStopEvent_onChangedNotCalled() {
+        mListener.notifyChangeBasedOn(mLifecycle);
+        mListener.onStart();
+
+        mListener.onChange(false);
+        verify(mListener, times(1)).onChanged(SETTINGS_FIELD);
+
+        mListener.onStop();
+
+        mListener.onChange(false);
+        verify(mListener, times(1)).onChanged(SETTINGS_FIELD);
+
+        mListener.onStart();
+
+        mListener.onChange(false);
+        verify(mListener, times(2)).onChanged(SETTINGS_FIELD);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
index 51f8ec0..6fd94c3 100644
--- a/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -63,6 +64,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowSubscriptionManager;
 
@@ -107,7 +109,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(Robolectric.setupActivity(Activity.class));
+        mContext = spy(RuntimeEnvironment.application);
         mLifecycleOwner = () -> mLifecycle;
         mLifecycle = new Lifecycle(mLifecycleOwner);
         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
@@ -257,14 +259,14 @@
      */
     private void runPreferenceClickTest(final int subscriptionCount, final int selectedPrefIndex) {
         final List<SubscriptionInfo> subs = setupMockSubscriptions(subscriptionCount);
-        mController.displayPreference(mScreen);
         final ArgumentCaptor<Preference> prefCaptor = ArgumentCaptor.forClass(Preference.class);
+        mController.displayPreference(mScreen);
         verify(mPreferenceCategory, times(subscriptionCount)).addPreference(prefCaptor.capture());
         final List<Preference> prefs = prefCaptor.getAllValues();
         final Preference pref = prefs.get(selectedPrefIndex);
-        pref.getOnPreferenceClickListener().onPreferenceClick(pref);
         final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
-        verify(mContext).startActivity(intentCaptor.capture());
+        doNothing().when(mContext).startActivity(intentCaptor.capture());
+        pref.getOnPreferenceClickListener().onPreferenceClick(pref);
         final Intent intent = intentCaptor.getValue();
         assertThat(intent).isNotNull();
         assertThat(intent.hasExtra(Settings.EXTRA_SUB_ID)).isTrue();
diff --git a/tests/robotests/src/com/android/settings/network/telephony/ApnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/ApnPreferenceControllerTest.java
index ce4c9a2..d362837 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/ApnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/ApnPreferenceControllerTest.java
@@ -21,6 +21,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -47,6 +48,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class ApnPreferenceControllerTest {
@@ -69,7 +71,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = spy(Robolectric.setupActivity(Activity.class));
+        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);
@@ -138,10 +140,10 @@
     @Test
     public void handPreferenceTreeClick_fireIntent() {
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        doNothing().when(mContext).startActivity(captor.capture());
 
         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/DataServiceSetupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DataServiceSetupPreferenceControllerTest.java
index 8907164..46e6978 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/DataServiceSetupPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/DataServiceSetupPreferenceControllerTest.java
@@ -21,6 +21,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -49,6 +50,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class DataServiceSetupPreferenceControllerTest {
@@ -72,7 +74,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = spy(Robolectric.setupActivity(Activity.class));
+        mContext = spy(RuntimeEnvironment.application);
         doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
         doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
         doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
@@ -125,11 +127,10 @@
     @Test
     public void handlePreferenceTreeClick_startActivity() {
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        doNothing().when(mContext).startActivity(captor.capture());
 
         mController.handlePreferenceTreeClick(mPreference);
 
-        verify(mContext).startActivity(captor.capture());
-
         final Intent intent = captor.getValue();
         assertThat(intent.getAction()).isEqualTo(Intent.ACTION_VIEW);
         assertThat(intent.getData()).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java
index 7a097e7..7681f44 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.network.telephony;
 
 import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -40,6 +41,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.Shadows;
 import org.robolectric.shadows.ShadowTelephonyManager;
 import org.robolectric.util.ReflectionHelpers;
@@ -58,7 +60,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = spy(Robolectric.setupActivity(Activity.class));
+        mContext = spy(RuntimeEnvironment.application);
 
         final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
         final ShadowTelephonyManager shadowTelephonyManager = Shadows.shadowOf(telephonyManager);
@@ -91,9 +93,10 @@
     @Test
     public void handlePreferenceTreeClick_needDialog_showDialog() {
         final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        doNothing().when(mContext).startActivity(captor.capture());
+
         mController.handlePreferenceTreeClick(mPreference);
 
-        verify(mContext).startActivity(captor.capture());
         final Intent intent = captor.getValue();
 
         assertThat(intent.getAction()).isEqualTo(Settings.ACTION_MOBILE_DATA_USAGE);
diff --git a/tests/robotests/src/com/android/settings/network/telephony/EuiccPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/EuiccPreferenceControllerTest.java
index 7fbddb4..bb60fd6 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/EuiccPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/EuiccPreferenceControllerTest.java
@@ -18,33 +18,32 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccManager;
 
 import androidx.preference.Preference;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 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.Robolectric;
-import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowTelephonyManager;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class EuiccPreferenceControllerTest {
     private static final int SUB_ID = 2;
 
-    @Mock
     private TelephonyManager mTelephonyManager;
+    private ShadowTelephonyManager mShadowTelephonyManager;
 
     private EuiccPreferenceController mController;
     private Preference mPreference;
@@ -54,9 +53,11 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = spy(Robolectric.setupActivity(Activity.class));
-        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
-        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+        mContext = spy(RuntimeEnvironment.application.getBaseContext());
+
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        mShadowTelephonyManager = shadowOf(mTelephonyManager);
+        mShadowTelephonyManager.setTelephonyManagerForSubscriptionId(SUB_ID, mTelephonyManager);
 
         mPreference = new Preference(mContext);
         mController = new EuiccPreferenceController(mContext, "euicc");
@@ -67,10 +68,10 @@
     @Test
     public void handlePreferenceTreeClick_startActivity() {
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        doNothing().when(mContext).startActivity(captor.capture());
 
         mController.handlePreferenceTreeClick(mPreference);
 
-        verify(mContext).startActivity(captor.capture());
         assertThat(captor.getValue().getAction()).isEqualTo(
                 EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS);
     }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 86f2355..1a11c49 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -99,7 +99,7 @@
         doReturn(true).when(mTelephonyManager).isDataEnabled();
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
-        doReturn(1).when(mTelephonyManager).getSimCount();
+        doReturn(1).when(mTelephonyManager).getActiveModemCount();
 
         assertThat(mController.isDialogNeeded()).isFalse();
     }
@@ -110,7 +110,7 @@
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
         doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID_OTHER);
         ShadowSubscriptionManager.setDefaultDataSubscriptionId(SUB_ID_OTHER);
-        doReturn(2).when(mTelephonyManager).getSimCount();
+        doReturn(2).when(mTelephonyManager).getActiveModemCount();
 
         assertThat(mController.isDialogNeeded()).isTrue();
         assertThat(mController.mDialogType).isEqualTo(
@@ -131,7 +131,7 @@
         doReturn(true).when(mTelephonyManager).isDataEnabled();
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
-        doReturn(1).when(mTelephonyManager).getSimCount();
+        doReturn(1).when(mTelephonyManager).getActiveModemCount();
 
         mController.onPreferenceChange(mPreference, true);
 
@@ -143,7 +143,7 @@
         doReturn(true).when(mTelephonyManager).isDataEnabled();
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
-        doReturn(2).when(mTelephonyManager).getSimCount();
+        doReturn(2).when(mTelephonyManager).getActiveModemCount();
 
         mController.onPreferenceChange(mPreference, true);
 
diff --git a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
index 53b4f00..0d94928 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
@@ -86,7 +86,8 @@
 
         final ServiceState serviceState = mock(ServiceState.class);
         when(serviceState.getOperatorAlphaLong()).thenReturn("fake carrier name");
-        when(mTelephonyMgr.getServiceStateForSubscriber(mSubscriptionId)).thenReturn(serviceState);
+        when(mTelephonyMgr.createForSubscriptionId(anyInt())).thenReturn(mTelephonyMgr);
+        when(mTelephonyMgr.getServiceState()).thenReturn(serviceState);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java
index a883c51..0abd6d5 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java
@@ -80,7 +80,7 @@
         doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
 
         mPreference = spy(new RestrictedSwitchPreference(mContext));
-        mController = new RoamingPreferenceController(mContext, "roaming");
+        mController = spy(new RoamingPreferenceController(mContext, "roaming"));
         mController.init(mFragmentManager, SUB_ID);
         mPreference.setKey(mController.getPreferenceKey());
     }
@@ -118,7 +118,7 @@
 
     @Test
     public void handlePreferenceTreeClick_needDialog_showDialog() {
-        mController.mNeedDialog = true;
+        doReturn(true).when(mController).isDialogNeeded();
 
         mController.handlePreferenceTreeClick(mPreference);
 
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 8ad2156..a4b7aa5 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.panel;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import static com.android.settings.panel.SettingsPanelActivity.KEY_MEDIA_PACKAGE_NAME;
 import static com.android.settings.panel.SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT;
 
@@ -28,17 +30,23 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.settings.SettingsEnums;
 import android.content.Intent;
-import android.view.MotionEvent;
+import android.os.Build;
+import android.view.Window;
+import android.view.WindowManager;
 
+import com.android.settings.core.HideNonSystemOverlayMixin;
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class SettingsPanelActivityTest {
@@ -50,6 +58,7 @@
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
         mSettingsPanelActivity = spy(
                 Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get());
@@ -87,4 +96,47 @@
         assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT))
                 .isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT");
     }
+
+    @Test
+    public void onStart_isNotDebuggable_shouldHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsPanelActivity> activityController =
+                Robolectric.buildActivity(SettingsPanelActivity.class).create();
+        final SettingsPanelActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+    }
+
+    @Test
+    public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsPanelActivity> activityController =
+                Robolectric.buildActivity(SettingsPanelActivity.class).create();
+        final SettingsPanelActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        when(window.getAttributes()).thenReturn(layoutParams);
+
+        activityController.stop();
+        final ArgumentCaptor<WindowManager.LayoutParams> paramCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+
+        verify(window).setAttributes(paramCaptor.capture());
+        assertThat(paramCaptor.getValue().privateFlags
+                & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
deleted file mode 100644
index 1335db5..0000000
--- a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2019 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.privacy;
-
-import static android.Manifest.permission_group.CALENDAR;
-import static android.Manifest.permission_group.CAMERA;
-import static android.Manifest.permission_group.CONTACTS;
-import static android.Manifest.permission_group.LOCATION;
-import static android.Manifest.permission_group.MICROPHONE;
-import static android.Manifest.permission_group.PHONE;
-import static android.Manifest.permission_group.SMS;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
-import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.UserManager;
-import android.permission.RuntimePermissionUsageInfo;
-import android.provider.DeviceConfig;
-import android.view.accessibility.AccessibilityManager;
-
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.Utils;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
-import com.android.settings.testutils.shadow.ShadowPermissionControllerManager;
-import com.android.settings.testutils.shadow.ShadowUserManager;
-import com.android.settingslib.widget.BarChartInfo;
-import com.android.settingslib.widget.BarChartPreference;
-import com.android.settingslib.widget.BarViewInfo;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowAccessibilityManager;
-import org.robolectric.shadows.androidx.fragment.FragmentController;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowDeviceConfig.class, ShadowUserManager.class,
-        ShadowPermissionControllerManager.class})
-public class PermissionBarChartPreferenceControllerTest {
-
-    @Mock
-    private PreferenceScreen mScreen;
-    @Mock
-    private LockPatternUtils mLockPatternUtils;
-
-    private PermissionBarChartPreferenceController mController;
-    private BarChartPreference mPreference;
-    private PrivacyDashboardFragment mFragment;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        final Context context = RuntimeEnvironment.application;
-        final UserManager userManager = context.getSystemService(UserManager.class);
-        final ShadowUserManager shadowUserManager = Shadow.extract(userManager);
-        final ShadowAccessibilityManager accessibilityManager = Shadow.extract(
-                AccessibilityManager.getInstance(context));
-        accessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
-        shadowUserManager.addProfile(new UserInfo(123, null, 0));
-        when(FakeFeatureFactory.setupForTest().securityFeatureProvider.getLockPatternUtils(
-                any(Context.class))).thenReturn(mLockPatternUtils);
-
-        mController = spy(new PermissionBarChartPreferenceController(context, "test_key"));
-        mFragment = spy(FragmentController.of(new PrivacyDashboardFragment())
-                .create().start().get());
-        mController.setFragment(mFragment);
-        mPreference = spy(new BarChartPreference(context));
-        when(mScreen.findPreference(mController.getPreferenceKey()))
-                .thenReturn((BarChartPreference) mPreference);
-    }
-
-    @After
-    public void tearDown() {
-        ShadowDeviceConfig.reset();
-    }
-
-    @Test
-    public void getAvailabilityStatus_permissionHubNotSet_shouldReturnUnsupported() {
-        // We have not yet set the property to show the Permissions Hub.
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
deleted file mode 100644
index 80f3900..0000000
--- a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 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.privacy;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.permission.PermissionControllerManager;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowPermissionControllerManager;
-import com.android.settings.testutils.shadow.ShadowUserManager;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowAccessibilityManager;
-import org.robolectric.shadows.androidx.fragment.FragmentController;
-
-import java.util.ArrayList;
-
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowUserManager.class, ShadowPermissionControllerManager.class})
-public class PrivacyDashboardFragmentTest {
-
-    @Mock
-    private LockPatternUtils mLockPatternUtils;
-    @Mock
-    private PermissionControllerManager mPCM;
-
-    private Context mContext;
-    private PrivacyDashboardFragment mFragment;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        final UserManager userManager = mContext.getSystemService(UserManager.class);
-        final ShadowUserManager shadowUserManager = Shadow.extract(userManager);
-        final ShadowAccessibilityManager accessibilityManager = Shadow.extract(
-                AccessibilityManager.getInstance(mContext));
-        accessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
-        shadowUserManager.addProfile(new UserInfo(123, null, 0));
-        when(FakeFeatureFactory.setupForTest().securityFeatureProvider.getLockPatternUtils(
-                any(Context.class))).thenReturn(mLockPatternUtils);
-        mFragment = spy(FragmentController.of(new PrivacyDashboardFragment())
-                .create().start().get());
-    }
-
-    @Test
-    public void onViewCreated_shouldSetActionBarShadowAnimation() {
-        mFragment.onViewCreated(new View(mContext), new Bundle());
-
-        assertThat(mFragment.getActivity().getActionBar().getElevation()).isEqualTo(0.f);
-    }
-
-    @Test
-    public void onViewCreated_shouldInitLinearProgressBar() {
-        mFragment.onViewCreated(new View(mContext), new Bundle());
-
-        verify(mFragment).initLoadingBar();
-    }
-
-    @Test
-    public void updateLinearProgressbar_isVisible_shouldShowProgressBar() {
-        mFragment.setLoadingEnabled(true /* enabled */);
-
-        assertThat(mFragment.mProgressHeader.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mFragment.mProgressAnimation.getVisibility()).isEqualTo(View.VISIBLE);
-    }
-
-    @Test
-    public void updateLinearProgressbar_isInVisible_shouldHideProgressBar() {
-        mFragment.setLoadingEnabled(false /* enabled */);
-
-        assertThat(mFragment.mProgressHeader.getVisibility()).isEqualTo(View.INVISIBLE);
-        assertThat(mFragment.mProgressAnimation.getVisibility()).isEqualTo(View.INVISIBLE);
-    }
-}