From a4cf551d256e94f72c4b591ce157f33d0a05e77f Mon Sep 17 00:00:00 2001 From: Avinash Vadlamudi Date: Mon, 27 Mar 2023 18:46:08 +0000 Subject: [PATCH] [Auto Pin Confirm]: Trigger PIN verification when auto confirm setting is being turned on or off - Fix the logic to set the pin_auto_confirm setting before triggering the password save workflow in ChooseLockPassword Bug: 275385372 Test: atest AutoPinConfirmPreferenceControllerTest Test: Manual Test Change-Id: Id6774bc9afcd6d3161e023dc52911ae3e1f556c9 --- res/values/strings.xml | 4 +++ .../settings/password/ChooseLockPassword.java | 12 ++++++--- .../AutoPinConfirmPreferenceController.java | 27 ++++++++++++++++--- .../screenlock/ScreenLockSettings.java | 23 +++++++++++++++- ...utoPinConfirmPreferenceControllerTest.java | 15 ++++------- 5 files changed, 64 insertions(+), 17 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index f593db9e544..f23fb5f7437 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1126,6 +1126,10 @@ Auto-confirm correct PIN Confirming your PIN by tapping Enter is more secure than using auto-confirm + + Enter device PIN to enable auto-confirm + + Enter device PIN to disable auto-confirm diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java index edd9188548d..2a30b42196c 100644 --- a/src/com/android/settings/password/ChooseLockPassword.java +++ b/src/com/android/settings/password/ChooseLockPassword.java @@ -911,6 +911,10 @@ public class ChooseLockPassword extends SettingsActivity { 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 @@ public class ChooseLockPassword extends SettingsActivity { 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 ff4a8b7924c..a41a0b2f7ee 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 @@ public class AutoPinConfirmPreferenceController extends AbstractPreferenceContro 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 @@ public class AutoPinConfirmPreferenceController extends AbstractPreferenceContro 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 78edb7f8c36..b2ee76c7929 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 @@ public class ScreenLockSettings extends DashboardFragment 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 @@ public class ScreenLockSettings extends DashboardFragment 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 @@ public class ScreenLockSettings extends DashboardFragment 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 15b2ae94901..715913cf353 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.android.internal.widget.LockPatternUtils.FLAG_ENABLE_AUTO_PIN_ 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 androidx.test.core.app.ApplicationProvider; 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 @@ public class AutoPinConfirmPreferenceControllerTest { 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 @@ public class AutoPinConfirmPreferenceControllerTest { 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 @@ public class AutoPinConfirmPreferenceControllerTest { 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); - } }