Merge "Disable smart forwarding based on subid" into sc-qpr1-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3db634b..74b8d7f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -726,6 +726,7 @@
     <string name="security_dashboard_summary">Screen lock, Find My Device, app security</string>
 
     <!-- Face enrollment and settings --><skip />
+    <!-- Note: Update FaceEnrollParentalConsent.CONSENT_STRING_RESOURCES when any _consent_ strings are added or removed. -->
     <!-- Message shown in summary field when face unlock is set up. [CHAR LIMIT=40] -->
     <string name="security_settings_face_preference_summary">Face added</string>
     <!-- Message shown in summary field when Face Unlock is not set up. [CHAR LIMIT=54] -->
@@ -879,6 +880,7 @@
     <string name="security_settings_face_settings_context_subtitle">Use Face Unlock to unlock your phone</string>
 
     <!-- Fingerprint enrollment and settings --><skip />
+    <!-- Note: Update FingerprintEnrollParentalConsent.CONSENT_STRING_RESOURCES when any _consent_ strings are added or removed. -->
     <!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
     <string name="security_settings_fingerprint_preference_title">Fingerprint</string>
     <!-- Fingerprint managment category title - configuration options for managing enrolled fingerprints [CHAR LIMIT=22] -->
diff --git a/src/com/android/settings/biometrics/ParentalConsentHelper.java b/src/com/android/settings/biometrics/ParentalConsentHelper.java
index 6c4004e..e0e082b 100644
--- a/src/com/android/settings/biometrics/ParentalConsentHelper.java
+++ b/src/com/android/settings/biometrics/ParentalConsentHelper.java
@@ -48,6 +48,10 @@
     private static final String KEY_FINGERPRINT_CONSENT = "fingerprint";
     private static final String KEY_IRIS_CONSENT = "iris";
 
+    private static final String KEY_FACE_CONSENT_STRINGS = "face_strings";
+    private static final String KEY_FINGERPRINT_CONSENT_STRINGS = "fingerprint_strings";
+    private static final String KEY_IRIS_CONSENT_STRINGS = "iris_strings";
+
     private final boolean mRequireFace;
     private final boolean mRequireFingerprint;
 
@@ -152,9 +156,14 @@
     public Bundle getConsentResult() {
         final Bundle result = new Bundle();
         result.putBoolean(KEY_FACE_CONSENT, mConsentFace != null ? mConsentFace : false);
+        result.putIntArray(KEY_FACE_CONSENT_STRINGS,
+                FaceEnrollParentalConsent.CONSENT_STRING_RESOURCES);
         result.putBoolean(KEY_FINGERPRINT_CONSENT,
                 mConsentFingerprint != null ? mConsentFingerprint : false);
+        result.putIntArray(KEY_FINGERPRINT_CONSENT_STRINGS,
+                FingerprintEnrollParentalConsent.CONSENT_STRING_RESOURCES);
         result.putBoolean(KEY_IRIS_CONSENT, false);
+        result.putIntArray(KEY_IRIS_CONSENT_STRINGS, new int[0]);
         return result;
     }
 
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java b/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java
index 183e05e..54466f9 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java
@@ -33,6 +33,21 @@
  */
 public class FaceEnrollParentalConsent extends FaceEnrollIntroduction {
 
+    /**
+     * List of string resources to log when recording the result of this activity in gms.
+     * This must be updated when any strings are added/removed.
+     */
+    public static final int[] CONSENT_STRING_RESOURCES = new int[] {
+            R.string.security_settings_face_enroll_consent_introduction_title,
+            R.string.security_settings_face_enroll_introduction_consent_message,
+            R.string.security_settings_face_enroll_introduction_info_consent_glasses,
+            R.string.security_settings_face_enroll_introduction_info_consent_looking,
+            R.string.security_settings_face_enroll_introduction_info_consent_gaze,
+            R.string.security_settings_face_enroll_introduction_how_consent_message,
+            R.string.security_settings_face_enroll_introduction_control_consent_title,
+            R.string.security_settings_face_enroll_introduction_control_consent_message
+    };
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java
index a95a912..22212f2 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java
@@ -33,6 +33,20 @@
  */
 public class FingerprintEnrollParentalConsent extends FingerprintEnrollIntroduction {
 
+    /**
+     * List of string resources to log when recording the result of this activity in gms.
+     * This must be updated when any strings are added/removed.
+     */
+    public static final int[] CONSENT_STRING_RESOURCES = new int[] {
+            R.string.security_settings_fingerprint_enroll_consent_introduction_title,
+            R.string.security_settings_fingerprint_enroll_introduction_consent_message,
+            R.string.security_settings_fingerprint_enroll_introduction_footer_title_consent_1,
+            R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_2,
+            R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_3,
+            R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_4,
+            R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_5
+    };
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
index f8d5f96..849fbe7 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
@@ -22,6 +22,8 @@
 import static com.android.settings.display.SmartAutoRotateController.hasSufficientPermission;
 import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable;
 
+import android.text.TextUtils;
+import android.app.settings.SettingsEnums;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -37,7 +39,9 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.view.RotationPolicy;
 import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
+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.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -45,12 +49,10 @@
 /**
  * SmartAutoRotatePreferenceController provides auto rotate summary in display settings
  */
-public class SmartAutoRotatePreferenceController extends BasePreferenceController
+public class SmartAutoRotatePreferenceController extends TogglePreferenceController
         implements LifecycleObserver, OnStart, OnStop {
 
-    private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
-    private Preference mPreference;
-
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
     private final SensorPrivacyManager mPrivacyManager;
     private final PowerManager mPowerManager;
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -60,12 +62,16 @@
         }
     };
 
+    private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
+    private Preference mPreference;
+
     public SmartAutoRotatePreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mPrivacyManager = SensorPrivacyManager.getInstance(context);
         mPrivacyManager
                 .addSensorPrivacyListener(CAMERA, (sensor, enabled) -> refreshSummary(mPreference));
         mPowerManager = context.getSystemService(PowerManager.class);
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
     }
 
     @Override
@@ -75,12 +81,28 @@
     }
 
     @Override
+    public boolean isSliceable() {
+        return TextUtils.equals(getPreferenceKey(), "auto_rotate");
+    }
+
+    @Override
+    public boolean isPublicSlice() {
+        return true;
+    }
+
+    @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mPreference = screen.findPreference(getPreferenceKey());
     }
 
     @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        refreshSummary(mPreference);
+    }
+
+    @Override
     public void onStart() {
         mContext.registerReceiver(mReceiver,
                 new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
@@ -89,7 +111,7 @@
                 @Override
                 public void onChange() {
                     if (mPreference != null) {
-                        refreshSummary(mPreference);
+                        updateState(mPreference);
                     }
                 }
             };
@@ -122,6 +144,20 @@
     }
 
     @Override
+    public boolean isChecked() {
+        return !RotationPolicy.isRotationLocked(mContext);
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        final boolean isLocked = !isChecked;
+        mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ROTATION_LOCK,
+                isLocked);
+        RotationPolicy.setRotationLock(mContext, isLocked);
+        return true;
+    }
+
+    @Override
     public CharSequence getSummary() {
         int activeStringId = R.string.auto_rotate_option_off;
         if (!RotationPolicy.isRotationLocked(mContext)) {
diff --git a/src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java b/src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java
index e17165b..26b3763 100644
--- a/src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java
+++ b/src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java
@@ -93,7 +93,8 @@
             return;
         }
         if (uri.equals(OneHandedSettingsUtils.ONE_HANDED_MODE_ENABLED_URI)
-                || uri.equals(OneHandedSettingsUtils.SHORTCUT_ENABLED_URI)) {
+                || uri.equals(OneHandedSettingsUtils.SOFTWARE_SHORTCUT_ENABLED_URI)
+                || uri.equals(OneHandedSettingsUtils.HARDWARE_SHORTCUT_ENABLED_URI)) {
             mPreference.setEnabled(OneHandedSettingsUtils.canEnableController(mContext));
         } else if (uri.equals(OneHandedSettingsUtils.SHOW_NOTIFICATION_ENABLED_URI)) {
             updateState(mPreference);
diff --git a/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java b/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java
index 9f56a14..524c135 100644
--- a/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java
+++ b/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java
@@ -93,7 +93,8 @@
             return;
         }
         if (uri.equals(OneHandedSettingsUtils.ONE_HANDED_MODE_ENABLED_URI)
-                || uri.equals(OneHandedSettingsUtils.SHORTCUT_ENABLED_URI)) {
+                || uri.equals(OneHandedSettingsUtils.SOFTWARE_SHORTCUT_ENABLED_URI)
+                || uri.equals(OneHandedSettingsUtils.HARDWARE_SHORTCUT_ENABLED_URI)) {
             mPreference.setEnabled(OneHandedSettingsUtils.canEnableController(mContext));
         } else if (uri.equals(OneHandedSettingsUtils.SHOW_NOTIFICATION_ENABLED_URI)) {
             updateState(mPreference);
diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
index f058689..04898dc 100644
--- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java
+++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
@@ -27,6 +27,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.text.TextUtils;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -45,8 +46,10 @@
             Settings.Secure.getUriFor(Settings.Secure.ONE_HANDED_MODE_ENABLED);
     static final Uri SHOW_NOTIFICATION_ENABLED_URI =
             Settings.Secure.getUriFor(Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED);
-    static final Uri SHORTCUT_ENABLED_URI =
+    static final Uri SOFTWARE_SHORTCUT_ENABLED_URI =
             Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+    static final Uri HARDWARE_SHORTCUT_ENABLED_URI =
+            Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
 
     public enum OneHandedTimeout {
         NEVER(0), SHORT(4), MEDIUM(8), LONG(12);
@@ -238,9 +241,20 @@
      * @return true if user enabled one-handed shortcut in settings, false otherwise.
      */
     public static boolean getShortcutEnabled(Context context) {
-        final String targets = Settings.Secure.getStringForUser(context.getContentResolver(),
+        // Checks SOFTWARE_SHORTCUT_KEY
+        final String targetsSW = Settings.Secure.getStringForUser(context.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, sCurrentUserId);
-        return targets != null ? targets.contains(ONE_HANDED_MODE_TARGET_NAME) : false;
+        if (!TextUtils.isEmpty(targetsSW) && targetsSW.contains(ONE_HANDED_MODE_TARGET_NAME)) {
+            return true;
+        }
+
+        // Checks HARDWARE_SHORTCUT_KEY
+        final String targetsHW = Settings.Secure.getStringForUser(context.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, sCurrentUserId);
+        if (!TextUtils.isEmpty(targetsHW) && targetsHW.contains(ONE_HANDED_MODE_TARGET_NAME)) {
+            return true;
+        }
+        return false;
     }
 
     /**
@@ -285,7 +299,8 @@
             final ContentResolver resolver = mContext.getContentResolver();
             resolver.registerContentObserver(ONE_HANDED_MODE_ENABLED_URI, true, this);
             resolver.registerContentObserver(SHOW_NOTIFICATION_ENABLED_URI, true, this);
-            resolver.registerContentObserver(SHORTCUT_ENABLED_URI, true, this);
+            resolver.registerContentObserver(SOFTWARE_SHORTCUT_ENABLED_URI, true, this);
+            resolver.registerContentObserver(HARDWARE_SHORTCUT_ENABLED_URI, true, this);
         }
 
         @Override
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index c6fe39c..efb5f8c 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -39,7 +39,6 @@
 import androidx.fragment.app.FragmentTransaction;
 import androidx.lifecycle.Lifecycle;
 
-import com.android.internal.util.CollectionUtils;
 import com.android.settings.R;
 import com.android.settings.core.SettingsBaseActivity;
 import com.android.settings.network.ProxySubscriptionManager;
@@ -48,6 +47,7 @@
 import com.android.settings.network.helper.SubscriptionAnnotation;
 
 import java.util.List;
+import java.util.function.Function;
 
 /**
  * Activity for displaying MobileNetworkSettings
@@ -64,15 +64,14 @@
     @VisibleForTesting
     ProxySubscriptionManager mProxySubscriptionMgr;
 
-    private int mCurSubscriptionId;
+    private int mCurSubscriptionId = SUB_ID_NULL;
 
     // This flag forces subscription information fragment to be re-created.
     // Otherwise, fragment will be kept when subscription id has not been changed.
     //
     // Set initial value to true allows subscription information fragment to be re-created when
     // Activity re-create occur.
-    private boolean mFragmentForceReload = true;
-    private boolean mPendingSubscriptionChange = false;
+    private boolean mPendingSubscriptionChange = true;
 
     @Override
     protected void onNewIntent(Intent intent) {
@@ -80,21 +79,25 @@
         validate(intent);
         setIntent(intent);
 
-        int updateSubscriptionIndex = SUB_ID_NULL;
+        int updateSubscriptionIndex = mCurSubscriptionId;
         if (intent != null) {
             updateSubscriptionIndex = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
         }
+        SubscriptionInfo info = getSubscriptionOrDefault(updateSubscriptionIndex);
+        if (info == null) {
+            Log.d(TAG, "Invalid subId request " + mCurSubscriptionId
+                    + " -> " + updateSubscriptionIndex);
+            return;
+        }
+
         int oldSubId = mCurSubscriptionId;
-        mCurSubscriptionId = updateSubscriptionIndex;
-        mFragmentForceReload = (mCurSubscriptionId == oldSubId);
-        final SubscriptionInfo info = getSubscription();
         updateSubscriptions(info, null);
 
         // If the subscription has changed or the new intent doesnt contain the opt in action,
         // remove the old discovery dialog. If the activity is being recreated, we will see
         // onCreate -> onNewIntent, so the dialog will first be recreated for the old subscription
         // and then removed.
-        if (updateSubscriptionIndex != oldSubId || !doesIntentContainOptInAction(intent)) {
+        if (mCurSubscriptionId != oldSubId || !doesIntentContainOptInAction(intent)) {
             removeContactDiscoveryDialog(oldSubId);
         }
         // evaluate showing the new discovery dialog if this intent contains an action to show the
@@ -135,7 +138,13 @@
         // perform registration after mCurSubscriptionId been configured.
         registerActiveSubscriptionsListener();
 
-        final SubscriptionInfo subscription = getSubscription();
+        SubscriptionInfo subscription = getSubscriptionOrDefault(mCurSubscriptionId);
+        if (subscription == null) {
+            Log.d(TAG, "Invalid subId request " + mCurSubscriptionId);
+            tryToFinishActivity();
+            return;
+        }
+
         maybeShowContactDiscoveryDialog(subscription);
 
         updateSubscriptions(subscription, null);
@@ -158,39 +167,81 @@
      * Implementation of ProxySubscriptionManager.OnActiveSubscriptionChangedListener
      */
     public void onChanged() {
+        mPendingSubscriptionChange = false;
+
+        if (mCurSubscriptionId == SUB_ID_NULL) {
+            return;
+        }
+
         if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
             mPendingSubscriptionChange = true;
             return;
         }
-        SubscriptionInfo info = getSubscription();
-        int oldSubIndex = mCurSubscriptionId;
-        updateSubscriptions(info, null);
 
-        // Remove the dialog if the subscription associated with this activity changes.
-        if (info == null) {
-            // Close the activity when subscription removed
-            if ((oldSubIndex != SUB_ID_NULL)
-                    && (!isFinishing()) && (!isDestroyed())) {
-                finish();
+        SubscriptionInfo subInfo = getSubscription(mCurSubscriptionId, null);
+        if (subInfo != null) {
+            if (mCurSubscriptionId != subInfo.getSubscriptionId()) {
+                // update based on subscription status change
+                removeContactDiscoveryDialog(mCurSubscriptionId);
+                updateSubscriptions(subInfo, null);
             }
             return;
         }
-        int subIndex = info.getSubscriptionId();
-        if (subIndex != oldSubIndex) {
-            removeContactDiscoveryDialog(oldSubIndex);
+
+        Log.w(TAG, "subId missing: " + mCurSubscriptionId);
+
+        // When UI is not the active one, avoid from destroy it immediately
+        // but wait until onResume() to see if subscription back online again.
+        // This is to avoid from glitch behavior of subscription which changes
+        // the UI when UI is considered as in the background or only partly
+        // visible.
+        if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) {
+            mPendingSubscriptionChange = true;
+            return;
+        }
+
+        // Subscription could be missing
+        tryToFinishActivity();
+    }
+
+    protected void runSubscriptionUpdate(Runnable onUpdateRemaining) {
+        SubscriptionInfo subInfo = getSubscription(mCurSubscriptionId, null);
+        if (subInfo == null) {
+            tryToFinishActivity();
+            return;
+        }
+        if (mCurSubscriptionId != subInfo.getSubscriptionId()) {
+            removeContactDiscoveryDialog(mCurSubscriptionId);
+            updateSubscriptions(subInfo, null);
+        }
+        onUpdateRemaining.run();
+    }
+
+    protected void tryToFinishActivity() {
+        if ((!isFinishing()) && (!isDestroyed())) {
+            finish();
         }
     }
 
     @Override
     protected void onStart() {
         getProxySubscriptionManager().setLifecycle(getLifecycle());
-        super.onStart();
-        // updateSubscriptions doesn't need to be called, onChanged will always be called after we
-        // register a listener.
         if (mPendingSubscriptionChange) {
             mPendingSubscriptionChange = false;
-            onChanged();
+            runSubscriptionUpdate(() -> super.onStart());
+            return;
         }
+        super.onStart();
+    }
+
+    @Override
+    protected void onResume() {
+        if (mPendingSubscriptionChange) {
+            mPendingSubscriptionChange = false;
+            runSubscriptionUpdate(() -> super.onResume());
+            return;
+        }
+        super.onResume();
     }
 
     @Override
@@ -235,30 +286,49 @@
         }
 
         mCurSubscriptionId = subscriptionIndex;
-        mFragmentForceReload = false;
+    }
+
+    /**
+     * Select one of the subscription as the default subscription.
+     * @param subAnnoList a list of {@link SubscriptionAnnotation}
+     * @return ideally the {@link SubscriptionAnnotation} as expected
+     */
+    protected SubscriptionAnnotation defaultSubscriptionSelection(
+            List<SubscriptionAnnotation> subAnnoList) {
+        return (subAnnoList == null) ? null :
+                subAnnoList.stream()
+                .filter(SubscriptionAnnotation::isDisplayAllowed)
+                .filter(SubscriptionAnnotation::isActive)
+                .findFirst().orElse(null);
+    }
+
+    protected SubscriptionInfo getSubscriptionOrDefault(int subscriptionId) {
+        return getSubscription(subscriptionId,
+                (subscriptionId != SUB_ID_NULL) ? null : (
+                    subAnnoList -> defaultSubscriptionSelection(subAnnoList)
+                ));
     }
 
     /**
      * Get the current subscription to display. First check whether intent has {@link
-     * Settings#EXTRA_SUB_ID} and if so find the subscription with that id. If not, just return the
-     * first one in the mSubscriptionInfos list since it is already sorted by sim slot.
+     * Settings#EXTRA_SUB_ID} and if so find the subscription with that id.
+     * If not, select default one based on {@link Function} provided.
+     *
+     * @param preferredSubscriptionId preferred subscription id
+     * @param selectionOfDefault when true current subscription is absent
      */
     @VisibleForTesting
-    SubscriptionInfo getSubscription() {
+    protected SubscriptionInfo getSubscription(int preferredSubscriptionId,
+            Function<List<SubscriptionAnnotation>, SubscriptionAnnotation> selectionOfDefault) {
         List<SubscriptionAnnotation> subList =
                 (new SelectableSubscriptions(this, true)).call();
-        SubscriptionAnnotation currentSubInfo = null;
-        if (mCurSubscriptionId != SUB_ID_NULL) {
-            currentSubInfo = subList.stream()
-                    .filter(SubscriptionAnnotation::isDisplayAllowed)
-                    .filter(subAnno -> (subAnno.getSubscriptionId() == mCurSubscriptionId))
-                    .findFirst().orElse(null);
-        }
-        if (currentSubInfo == null) {
-            currentSubInfo = subList.stream()
-                    .filter(SubscriptionAnnotation::isDisplayAllowed)
-                    .filter(SubscriptionAnnotation::isActive)
-                    .findFirst().orElse(null);
+        Log.d(TAG, "get subId=" + preferredSubscriptionId + " from " + subList);
+        SubscriptionAnnotation currentSubInfo = subList.stream()
+                .filter(SubscriptionAnnotation::isDisplayAllowed)
+                .filter(subAnno -> (subAnno.getSubscriptionId() == preferredSubscriptionId))
+                .findFirst().orElse(null);
+        if ((currentSubInfo == null) && (selectionOfDefault != null)) {
+            currentSubInfo = selectionOfDefault.apply(subList);
         }
         return (currentSubInfo == null) ? null : currentSubInfo.getSubInfo();
     }
@@ -285,10 +355,6 @@
 
         final String fragmentTag = buildFragmentTag(subId);
         if (fragmentManager.findFragmentByTag(fragmentTag) != null) {
-            if (!mFragmentForceReload) {
-                Log.d(TAG, "Keep current fragment: " + fragmentTag);
-                return;
-            }
             Log.d(TAG, "Construct fragment: " + fragmentTag);
         }
 
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index 6e5d4b7..ebf77a0 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -84,6 +84,8 @@
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 public class MobileNetworkUtils {
 
@@ -258,9 +260,16 @@
     public static boolean showEuiccSettings(Context context) {
         long timeForAccess = SystemClock.elapsedRealtime();
         try {
-            return ((Future<Boolean>) ThreadUtils.postOnBackgroundThread(()
-                    -> showEuiccSettingsDetecting(context))).get();
-        } catch (ExecutionException | InterruptedException exception) {
+            Boolean isShow = ((Future<Boolean>) ThreadUtils.postOnBackgroundThread(() -> {
+                        try {
+                            return showEuiccSettingsDetecting(context);
+                        } catch (Exception threadException) {
+                            Log.w(TAG, "Accessing Euicc failure", threadException);
+                        }
+                        return Boolean.FALSE;
+                    })).get(3, TimeUnit.SECONDS);
+            return ((isShow != null) && isShow.booleanValue());
+        } catch (ExecutionException | InterruptedException | TimeoutException exception) {
             timeForAccess = SystemClock.elapsedRealtime() - timeForAccess;
             Log.w(TAG, "Accessing Euicc takes too long: +" + timeForAccess + "ms");
         }
@@ -279,7 +288,7 @@
         final ContentResolver cr = context.getContentResolver();
         final boolean esimIgnoredDevice =
                 Arrays.asList(TextUtils.split(SystemProperties.get(KEY_ESIM_CID_IGNORE, ""), ","))
-                        .contains(SystemProperties.get(KEY_CID, null));
+                        .contains(SystemProperties.get(KEY_CID));
         final boolean enabledEsimUiByDefault =
                 SystemProperties.getBoolean(KEY_ENABLE_ESIM_UI_BY_DEFAULT, true);
         final boolean euiccProvisioned =
diff --git a/src/com/android/settings/password/ChooseLockGenericController.java b/src/com/android/settings/password/ChooseLockGenericController.java
index 1b951d4..cd9eb2f 100644
--- a/src/com/android/settings/password/ChooseLockGenericController.java
+++ b/src/com/android/settings/password/ChooseLockGenericController.java
@@ -190,7 +190,8 @@
      * requirements. The lock's visibility ({@link #isScreenLockVisible}) is not considered here.
      */
     public boolean isScreenLockEnabled(ScreenLockType type) {
-        return type.maxQuality >= upgradeQuality(PASSWORD_QUALITY_UNSPECIFIED);
+        return !mLockPatternUtils.isCredentialsDisabledForUser(mUserId)
+                && type.maxQuality >= upgradeQuality(PASSWORD_QUALITY_UNSPECIFIED);
     }
 
     /**
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index 252b6c0..e5457ae 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -24,6 +24,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
+import android.view.WindowManager;
 import android.widget.Toast;
 
 import androidx.fragment.app.Fragment;
@@ -59,6 +60,8 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        getWindow().addSystemFlags(
+                WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         showOrUpdateDialog();
     }
 
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java
index 049a349..996d572 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java
@@ -22,6 +22,7 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
@@ -190,6 +191,16 @@
     }
 
     @Test
+    public void isScreenLockEnabled_QualityManaged() {
+        setDevicePolicyPasswordQuality(PASSWORD_QUALITY_MANAGED);
+        assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
+        assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
+        assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
+        assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isFalse();
+        assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isFalse();
+    }
+
+    @Test
     public void isScreenLockEnabled_NoneComplexity() {
         when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
                 .thenReturn(PASSWORD_COMPLEXITY_NONE);
@@ -353,6 +364,9 @@
 
         when(mLockPatternUtils.getRequestedPasswordMetrics(anyInt(), anyBoolean()))
                 .thenReturn(policy.getMinMetrics());
+
+        when(mLockPatternUtils.isCredentialsDisabledForUser(anyInt()))
+                .thenReturn(quality == PASSWORD_QUALITY_MANAGED);
     }
 
     private ChooseLockGenericController.Builder createBuilder() {