Merge "Improve lifecycle of ZenModeFragment & friends" into main
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 31372ca..311b56f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12238,11 +12238,11 @@
     <!-- Default title for the settings panel [CHAR LIMIT=NONE] -->
     <string name="settings_panel_title">Settings Panel</string>
 
-    <!-- Title for a toggle that enables freeform windowing experiences. Freeform windowing experiences are features involving apps running in resizable windows. [CHAR LIMIT=50] -->
-    <string name="enable_desktop_mode">Enable freeform windowing experiences</string>
+    <!-- Title for a toggle that enables freeform windows. Freeform windows enables users to freely arrange and resize overlapping apps. [CHAR LIMIT=50] -->
+    <string name="enable_desktop_mode">Enable freeform windows</string>
 
-    <!-- Title for a toggle that enables desktop mode on secondary display. [CHAR LIMIT=50] -->
-    <string name="enable_desktop_mode_on_secondary_display">Enable desktop mode on secondary display</string>
+    <!-- Title for a toggle that enables freeform windows on secondary display. Freeform windows enables users to freely arrange and resize overlapping apps. [CHAR LIMIT=50] -->
+    <string name="enable_desktop_mode_on_secondary_display">Enable freeform windows on secondary display</string>
 
     <!-- UI debug setting: enable non-resizables in multi window [CHAR LIMIT=60] -->
     <string name="enable_non_resizable_multi_window">Enable non-resizable in multi window</string>
@@ -13202,12 +13202,12 @@
     <!-- The content description for accessibility tools of the customize button. It specifies which screensaver the user is customizing [CHAR LIMIT=NONE] -->
     <string name="customize_button_description">Customize <xliff:g id="screensaver_name" example="Art Gallery">%1$s</xliff:g></string>
 
-    <!-- Dialog body text used to explain a reboot is required after enabling freeform window support for it to work. Freeform window is when an app runs in a resizable window. [CHAR LIMIT=none] -->
+    <!-- Dialog body text used to explain a reboot is required after enabling freeform window support for it to work. Freeform windows enables users to freely arrange and resize overlapping apps. [CHAR LIMIT=none] -->
     <string name="reboot_dialog_enable_freeform_support">A reboot is required to enable freeform window support.</string>
-    <!-- Dialog body text used to explain a reboot is required after updating availability of freeform windowing experiences. Freeform windowing experiences are features involving apps running in resizable windows. [CHAR LIMIT=none] -->
-    <string name="reboot_dialog_override_desktop_mode">A reboot is required to update availability of freeform windowing experiences.</string>
-    <!-- Dialog body text used to explain a reboot is required after enabling desktop mode on secondary displays. [CHAR LIMIT=none] -->
-    <string name="reboot_dialog_enable_desktop_mode_on_secondary_display">A reboot is required to enable desktop mode on secondary displays.</string>
+    <!-- Dialog body text used to explain a reboot is required after updating availability of freeform windows. Freeform windows enables users to freely arrange and resize overlapping apps. [CHAR LIMIT=none] -->
+    <string name="reboot_dialog_override_desktop_mode">A reboot is required to update availability of freeform windows.</string>
+    <!-- Dialog body text used to explain a reboot is required after enabling freeform windows on secondary displays. Freeform windows enables users to freely arrange and resize overlapping apps. [CHAR LIMIT=none] -->
+    <string name="reboot_dialog_enable_desktop_mode_on_secondary_display">A reboot is required to enable freeform windows on secondary displays.</string>
     <!-- Text on the dialog button to reboot the device now [CHAR LIMIT=50] -->
     <string name="reboot_dialog_reboot_now">Reboot now</string>
     <!-- Text on the dialog button to reboot the device later [CHAR LIMIT=50] -->
diff --git a/src/com/android/settings/MainClear.java b/src/com/android/settings/MainClear.java
index 9dadcb9..ab7a714 100644
--- a/src/com/android/settings/MainClear.java
+++ b/src/com/android/settings/MainClear.java
@@ -188,7 +188,7 @@
                     false /* biometricsAuthenticationRequested */,
                     userId)) {
                 Utils.launchBiometricPromptForMandatoryBiometrics(this, BIOMETRICS_REQUEST,
-                        userId);
+                        userId, false /* hideBackground */);
                 return;
             }
         }
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index add5604..badcb63 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -25,6 +25,7 @@
 import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
 
 import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_AUTHENTICATORS;
+import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_HIDE_BACKGROUND;
 import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_NEGATIVE_BUTTON_TEXT;
 
 import android.app.ActionBar;
@@ -1519,12 +1520,13 @@
      * to check if all requirements for mandatory biometrics is satisfied
      * before launching biometric prompt.
      *
-     * @param fragment    corresponding fragment of the surface
-     * @param requestCode for starting the new activity
-     * @param userId      user id for the authentication request
+     * @param fragment       corresponding fragment of the surface
+     * @param requestCode    for starting the new activity
+     * @param userId         user id for the authentication request
+     * @param hideBackground if the background activity screen needs to be hidden
      */
     public static void launchBiometricPromptForMandatoryBiometrics(@NonNull Fragment fragment,
-            int requestCode, int userId) {
+            int requestCode, int userId, boolean hideBackground) {
         final Intent intent = new Intent();
         intent.putExtra(BIOMETRIC_PROMPT_AUTHENTICATORS,
                 BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
@@ -1534,6 +1536,7 @@
                 fragment.getString(R.string.mandatory_biometrics_prompt_description));
         intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_ALLOW_ANY_USER, true);
         intent.putExtra(EXTRA_USER_ID, userId);
+        intent.putExtra(BIOMETRIC_PROMPT_HIDE_BACKGROUND, hideBackground);
         intent.setClassName(SETTINGS_PACKAGE_NAME,
                 ConfirmDeviceCredentialActivity.InternalActivity.class.getName());
         fragment.startActivityForResult(intent, requestCode);
diff --git a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
index 835f3a8..11194ce 100644
--- a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
+++ b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
@@ -147,7 +147,7 @@
                 mBiometricsAuthenticationRequested, mUserId)) {
             mBiometricsAuthenticationRequested = true;
             Utils.launchBiometricPromptForMandatoryBiometrics(this, BIOMETRIC_AUTH_REQUEST,
-                    mUserId);
+                    mUserId, true /* hideBackground */);
         }
 
         updateUnlockPhonePreferenceSummary();
@@ -166,7 +166,7 @@
                 && mGkPwHandle != 0L) {
             mBiometricsAuthenticationRequested = true;
             Utils.launchBiometricPromptForMandatoryBiometrics(this, BIOMETRIC_AUTH_REQUEST,
-                    mUserId);
+                    mUserId, true /* hideBackground */);
         }
         if (!mConfirmCredential) {
             mDoNotFinishActivity = false;
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index 305d670..bcd5231 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -293,7 +293,7 @@
                 mUserId)) {
             mBiometricsAuthenticationRequested = true;
             Utils.launchBiometricPromptForMandatoryBiometrics(this, BIOMETRIC_AUTH_REQUEST,
-                    mUserId);
+                    mUserId, true /* hideBackground */);
         } else {
             mAttentionController.setToken(mToken);
             mEnrollController.setToken(mToken);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index 83bc0e6..9cda327 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -489,7 +489,7 @@
                         mUserId)) {
                     mBiometricsAuthenticationRequested = true;
                     Utils.launchBiometricPromptForMandatoryBiometrics(this, BIOMETRIC_AUTH_REQUEST,
-                            mUserId);
+                            mUserId, true /* hideBackground */);
                 } else if (!mHasFirstEnrolled) {
                     mIsEnrolling = true;
                     addFirstFingerprint(null);
@@ -784,7 +784,7 @@
                     mUserId)) {
                 mBiometricsAuthenticationRequested = true;
                 Utils.launchBiometricPromptForMandatoryBiometrics(this,
-                        BIOMETRIC_AUTH_REQUEST, mUserId);
+                        BIOMETRIC_AUTH_REQUEST, mUserId, true /* hideBackground */);
             }
         }
 
diff --git a/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java b/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java
index 0d3d835..2bce9ad 100644
--- a/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java
+++ b/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java
@@ -67,6 +67,12 @@
         Settings.Global.putInt(mContext.getContentResolver(),
                 DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
                 isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
+        // Update freeform window support on device.
+        // DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT setting enables freeform support on device
+        // where it's not present by default.
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT,
+                isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
         if (isEnabled && mFragment != null) {
             RebootConfirmationDialogFragment.show(
                     mFragment, R.string.reboot_dialog_enable_desktop_mode_on_secondary_display,
diff --git a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
index ba12b9a..12b7278 100644
--- a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
@@ -38,7 +38,8 @@
  * containing links to each individual mode. This is a central controller that populates and updates
  * all the preferences that then lead to a mode configuration page.
  */
-class ZenModesListPreferenceController extends BasePreferenceController {
+class ZenModesListPreferenceController extends BasePreferenceController
+        implements BasePreferenceController.UiBlocker {
     protected static final String KEY = "zen_modes_list";
 
     protected ZenModesBackend mBackend;
@@ -49,11 +50,6 @@
     }
 
     @Override
-    public String getPreferenceKey() {
-        return KEY;
-    }
-
-    @Override
     @AvailabilityStatus
     public int getAvailabilityStatus() {
         return Flags.modesUi() ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
@@ -97,6 +93,8 @@
         for (String key : originalPreferences.keySet()) {
             category.removePreferenceRecursively(key);
         }
+
+        setUiBlockerFinished(true);
     }
 
     // Provide search data for the modes, which will allow users to reach the modes page if they
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index d5d079e..34c0731 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -495,7 +495,7 @@
                         mBiometricsAuthSuccessful, mWaitingForConfirmation, mUserId)) {
                     mWaitingForConfirmation = true;
                     Utils.launchBiometricPromptForMandatoryBiometrics(this, BIOMETRIC_AUTH_REQUEST,
-                            mUserId);
+                            mUserId, true /* hideBackground */);
                 }
             } else if (requestCode == BIOMETRIC_AUTH_REQUEST) {
                 if (resultCode == Activity.RESULT_OK) {
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index c0b3093..4f35532 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -80,6 +80,8 @@
     public static final String BIOMETRIC_PROMPT_AUTHENTICATORS = "biometric_prompt_authenticators";
     public static final String BIOMETRIC_PROMPT_NEGATIVE_BUTTON_TEXT =
             "biometric_prompt_negative_button_text";
+    public static final String BIOMETRIC_PROMPT_HIDE_BACKGROUND =
+            "biometric_prompt_hide_background";
 
     public static class InternalActivity extends ConfirmDeviceCredentialActivity {
     }
@@ -165,15 +167,20 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
-        getWindow().setStatusBarColor(Color.TRANSPARENT);
+        final Intent intent = getIntent();
+        if (intent.getBooleanExtra(BIOMETRIC_PROMPT_HIDE_BACKGROUND, false)) {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+            getWindow().setDimAmount(1);
+            intent.removeExtra(BIOMETRIC_PROMPT_HIDE_BACKGROUND);
+        } else {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+            getWindow().setStatusBarColor(Color.TRANSPARENT);
+        }
 
         mDevicePolicyManager = getSystemService(DevicePolicyManager.class);
         mUserManager = UserManager.get(this);
         mTrustManager = getSystemService(TrustManager.class);
         mLockPatternUtils = new LockPatternUtils(this);
-
-        Intent intent = getIntent();
         mContext = this;
         mCheckDevicePolicyManager = intent
                 .getBooleanExtra(KeyguardManager.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, false);
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index b36e9d6..2aeb906 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -22,6 +22,7 @@
 
 import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
 import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_AUTHENTICATORS;
+import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_HIDE_BACKGROUND;
 import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_NEGATIVE_BUTTON_TEXT;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -581,7 +582,8 @@
 
         final int requestCode = 1;
         final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
-        Utils.launchBiometricPromptForMandatoryBiometrics(mFragment, requestCode, USER_ID);
+        Utils.launchBiometricPromptForMandatoryBiometrics(mFragment, requestCode, USER_ID,
+                false /* hideBackground */);
 
         verify(mFragment).startActivityForResult(intentArgumentCaptor.capture(), eq(requestCode));
 
@@ -593,6 +595,8 @@
         assertThat(intent.getExtra(KeyguardManager.EXTRA_DESCRIPTION)).isNotNull();
         assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_ALLOW_ANY_USER, false))
                 .isTrue();
+        assertThat(intent.getBooleanExtra(BIOMETRIC_PROMPT_HIDE_BACKGROUND, true))
+                .isFalse();
         assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0)).isEqualTo(USER_ID);
         assertThat(intent.getComponent().getPackageName()).isEqualTo(SETTINGS_PACKAGE_NAME);
         assertThat(intent.getComponent().getClassName()).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java
index 5931004..3691d12 100644
--- a/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.development;
 
+import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 
 import static com.android.settings.development.DesktopModeSecondaryDisplayPreferenceController.SETTING_VALUE_OFF;
@@ -55,6 +56,7 @@
 
     private static final String ENG_BUILD_TYPE = "eng";
     private static final String USER_BUILD_TYPE = "user";
+    private static final int SETTING_VALUE_INVALID = -1;
 
     @Mock
     private SwitchPreference mPreference;
@@ -102,21 +104,41 @@
 
     @Test
     public void onPreferenceChange_switchEnabled_enablesDesktopModeOnSecondaryDisplay() {
-        mController.onPreferenceChange(mPreference, true /* new value */);
+        mController.onPreferenceChange(mPreference, /* newValue= */ true);
 
         final int mode = Settings.Global.getInt(mContext.getContentResolver(),
-                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+                /* def= */ SETTING_VALUE_INVALID);
         assertThat(mode).isEqualTo(SETTING_VALUE_ON);
 
         verify(mTransaction).add(any(RebootConfirmationDialogFragment.class), any());
     }
 
     @Test
-    public void onPreferenceChange_switchDisabled_disablesDesktopModeOnSecondaryDisplay() {
-        mController.onPreferenceChange(mPreference, false /* new value */);
+    public void onPreferenceChange_switchEnabled_enablesFreeformSupport() {
+        mController.onPreferenceChange(mPreference, /* newValue= */ true);
 
         final int mode = Settings.Global.getInt(mContext.getContentResolver(),
-                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
+                DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, /* def= */ SETTING_VALUE_INVALID);
+        assertThat(mode).isEqualTo(SETTING_VALUE_ON);
+    }
+
+    @Test
+    public void onPreferenceChange_switchDisabled_disablesDesktopModeOnSecondaryDisplay() {
+        mController.onPreferenceChange(mPreference, /* newValue= */ false);
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+                /* def= */ SETTING_VALUE_INVALID);
+        assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
+    }
+
+    @Test
+    public void onPreferenceChange_switchDisabled_disablesFreeformSupport() {
+        mController.onPreferenceChange(mPreference, /* newValue= */ false);
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, /* def= */ SETTING_VALUE_INVALID);
         assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
     }
 
@@ -145,7 +167,8 @@
         mController.onDeveloperOptionsSwitchDisabled();
 
         final int mode = Settings.Global.getInt(mContext.getContentResolver(),
-                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+                /* def= */ SETTING_VALUE_INVALID);
         assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
         verify(mPreference).setEnabled(false);
     }