Merge "[Auto Pin Confirm]: Trigger PIN verification when auto confirm setting is being turned on or off" into udc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f593db9..f23fb5f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1126,6 +1126,10 @@
     <string name="auto_pin_confirm_user_message">Auto-confirm correct PIN</string>
     <!-- Message shown to explain the security concern if a user opts-in to the auto-pin feature. [CHAR LIMIT=NONE] -->
     <string name="auto_pin_confirm_opt_in_security_message">Confirming your PIN by tapping Enter is more secure than using auto-confirm</string>
+    <!-- Description of pin confirmation screen when auto confirm setting is turned on. [CHAR LIMIT=NONE] -->
+    <string name="auto_confirm_on_pin_verify_description">Enter device PIN to enable auto-confirm</string>
+    <!-- Description of pin confirmation screen when auto confirm setting is turned off. [CHAR LIMIT=NONE] -->
+    <string name="auto_confirm_off_pin_verify_description">Enter device PIN to disable auto-confirm</string>
 
     <!--  Main Security lock settings --><skip />
     <!--  Title for PreferenceScreen to launch picker for security method when there is none [CHAR LIMIT=22] -->
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index edd9188..2a30b42 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -911,6 +911,10 @@
                         mIsManagedProfile));
                 setNextEnabled(canInput && length >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE);
                 mSkipOrClearButton.setVisibility(toVisibility(canInput && length > 0));
+
+                // Hide the pin_confirm option when we are just asking user to confirm the pwd.
+                mAutoPinConfirmOption.setVisibility(View.GONE);
+                mAutoConfirmSecurityMessage.setVisibility(View.GONE);
             }
             final int stage = getStageType();
             if (getStageType() != Stage.TYPE_NONE) {
@@ -1017,12 +1021,14 @@
                             profileCredential);
                 }
             }
-            mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword,
-                    mChosenPassword, mCurrentCredential, mUserId);
-            // update the pin_auto_confirm setting accordingly.
+            // update the setting before triggering the password save workflow,
+            // so that pinLength information is stored accordingly when setting is turned on.
             mLockPatternUtils.setAutoPinConfirm(
                     (mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()),
                     mUserId);
+
+            mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword,
+                    mChosenPassword, mCurrentCredential, mUserId);
         }
 
         @Override
diff --git a/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceController.java b/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceController.java
index ff4a8b7..a41a0b2 100644
--- a/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceController.java
+++ b/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceController.java
@@ -16,14 +16,19 @@
 
 package com.android.settings.security.screenlock;
 
+import static com.android.internal.widget.LockPatternUtils.MIN_AUTO_PIN_REQUIREMENT_LENGTH;
+
 import android.content.Context;
 
 import androidx.preference.Preference;
 import androidx.preference.TwoStatePreference;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
 
 /**
  * Preference controller for the pin_auto_confirm setting.
@@ -32,21 +37,23 @@
         PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
 
     private static final String PREF_KEY_PIN_AUTO_CONFIRM = "auto_pin_confirm";
-    private static final long MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6L;
 
     private final int mUserId;
     private final LockPatternUtils mLockPatternUtils;
+    private final ObservablePreferenceFragment mParentFragment;
 
     public AutoPinConfirmPreferenceController(Context context, int userId,
-            LockPatternUtils lockPatternUtils) {
+            LockPatternUtils lockPatternUtils,
+            ObservablePreferenceFragment parentFragment) {
         super(context);
         mUserId = userId;
         mLockPatternUtils = lockPatternUtils;
+        mParentFragment = parentFragment;
     }
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
-        setPinAutoConfirmSettingState((boolean) newValue);
+        launchPinConfirmActivity((boolean) newValue);
         return true;
     }
 
@@ -82,4 +89,18 @@
     private void setPinAutoConfirmSettingState(boolean state) {
         mLockPatternUtils.setAutoPinConfirm(state, mUserId);
     }
+
+    private void launchPinConfirmActivity(boolean newState) {
+        new ChooseLockSettingsHelper.Builder(mParentFragment.getActivity(), mParentFragment)
+                .setUserId(mUserId)
+                .setRequestCode(newState
+                        ? ScreenLockSettings.AUTO_PIN_SETTING_ENABLING_REQUEST_CODE
+                        : ScreenLockSettings.AUTO_PIN_SETTING_DISABLING_REQUEST_CODE)
+                .setTitle(mContext.getString(R.string.lock_screen_auto_pin_confirm_title))
+                .setDescription(newState
+                        ? mContext.getString(R.string.auto_confirm_on_pin_verify_description)
+                        : mContext.getString(R.string.auto_confirm_off_pin_verify_description))
+                .setReturnCredentials(true)
+                .show();
+    }
 }
diff --git a/src/com/android/settings/security/screenlock/ScreenLockSettings.java b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
index 78edb7f..b2ee76c 100644
--- a/src/com/android/settings/security/screenlock/ScreenLockSettings.java
+++ b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
@@ -16,10 +16,14 @@
 
 package com.android.settings.security.screenlock;
 
+import android.app.Activity;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
+import android.content.Intent;
 import android.os.UserHandle;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -38,6 +42,10 @@
     private static final String TAG = "ScreenLockSettings";
 
     private static final int MY_USER_ID = UserHandle.myUserId();
+
+    static final int AUTO_PIN_SETTING_ENABLING_REQUEST_CODE = 111;
+    static final int AUTO_PIN_SETTING_DISABLING_REQUEST_CODE = 112;
+
     private LockPatternUtils mLockPatternUtils;
 
     @Override
@@ -79,7 +87,7 @@
         controllers.add(new LockAfterTimeoutPreferenceController(
                 context, MY_USER_ID, lockPatternUtils));
         controllers.add(new AutoPinConfirmPreferenceController(
-                context, MY_USER_ID, lockPatternUtils));
+                context, MY_USER_ID, lockPatternUtils, parent));
         controllers.add(new OwnerInfoPreferenceController(context, parent));
         return controllers;
     }
@@ -94,4 +102,17 @@
                             new LockPatternUtils(context));
                 }
             };
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        if (requestCode == AUTO_PIN_SETTING_ENABLING_REQUEST_CODE) {
+            if (resultCode == Activity.RESULT_OK) {
+                mLockPatternUtils.setAutoPinConfirm(/* enabled= */ true, MY_USER_ID);
+            }
+        } else if (requestCode == AUTO_PIN_SETTING_DISABLING_REQUEST_CODE) {
+            if (resultCode == Activity.RESULT_OK) {
+                mLockPatternUtils.setAutoPinConfirm(/* enabled= */ false, MY_USER_ID);
+            }
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java
index 15b2ae9..715913c 100644
--- a/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java
@@ -22,7 +22,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -33,6 +32,7 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.testutils.shadow.ShadowDeviceConfig;
+import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,6 +48,8 @@
     private static final Integer TEST_USER_ID = 1;
     @Mock
     private LockPatternUtils mLockPatternUtils;
+    @Mock
+    private ObservablePreferenceFragment mParentFragment;
     private AutoPinConfirmPreferenceController mController;
     private SwitchPreference mPreference;
 
@@ -56,7 +58,8 @@
         MockitoAnnotations.initMocks(this);
         Context context = ApplicationProvider.getApplicationContext();
         mController =
-                new AutoPinConfirmPreferenceController(context, TEST_USER_ID, mLockPatternUtils);
+                new AutoPinConfirmPreferenceController(context, TEST_USER_ID, mLockPatternUtils,
+                        mParentFragment);
         mPreference = new SwitchPreference(context);
     }
 
@@ -128,12 +131,4 @@
         mController.updateState(mPreference);
         assertThat(mPreference.isChecked()).isTrue();
     }
-
-    @Test
-    public void onPreferenceChange_shouldUpdatePinAutoConfirmSetting() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                "true", /* makeDefault */ false);
-        mController.onPreferenceChange(mPreference, /* newValue= */ true);
-        verify(mLockPatternUtils).setAutoPinConfirm(true, TEST_USER_ID);
-    }
 }