[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
This commit is contained in:
Avinash Vadlamudi
2023-03-27 18:46:08 +00:00
parent cdfd4ee9b3
commit a4cf551d25
5 changed files with 64 additions and 17 deletions

View File

@@ -1126,6 +1126,10 @@
<string name="auto_pin_confirm_user_message">Auto-confirm correct PIN</string> <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] --> <!-- 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> <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 /> <!-- Main Security lock settings --><skip />
<!-- Title for PreferenceScreen to launch picker for security method when there is none [CHAR LIMIT=22] --> <!-- Title for PreferenceScreen to launch picker for security method when there is none [CHAR LIMIT=22] -->

View File

@@ -911,6 +911,10 @@ public class ChooseLockPassword extends SettingsActivity {
mIsManagedProfile)); mIsManagedProfile));
setNextEnabled(canInput && length >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE); setNextEnabled(canInput && length >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE);
mSkipOrClearButton.setVisibility(toVisibility(canInput && length > 0)); 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(); final int stage = getStageType();
if (getStageType() != Stage.TYPE_NONE) { if (getStageType() != Stage.TYPE_NONE) {
@@ -1017,12 +1021,14 @@ public class ChooseLockPassword extends SettingsActivity {
profileCredential); profileCredential);
} }
} }
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword, // update the setting before triggering the password save workflow,
mChosenPassword, mCurrentCredential, mUserId); // so that pinLength information is stored accordingly when setting is turned on.
// update the pin_auto_confirm setting accordingly.
mLockPatternUtils.setAutoPinConfirm( mLockPatternUtils.setAutoPinConfirm(
(mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()), (mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()),
mUserId); mUserId);
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword,
mChosenPassword, mCurrentCredential, mUserId);
} }
@Override @Override

View File

@@ -16,14 +16,19 @@
package com.android.settings.security.screenlock; package com.android.settings.security.screenlock;
import static com.android.internal.widget.LockPatternUtils.MIN_AUTO_PIN_REQUIREMENT_LENGTH;
import android.content.Context; import android.content.Context;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
/** /**
* Preference controller for the pin_auto_confirm setting. * Preference controller for the pin_auto_confirm setting.
@@ -32,21 +37,23 @@ public class AutoPinConfirmPreferenceController extends AbstractPreferenceContro
PreferenceControllerMixin, Preference.OnPreferenceChangeListener { PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
private static final String PREF_KEY_PIN_AUTO_CONFIRM = "auto_pin_confirm"; 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 int mUserId;
private final LockPatternUtils mLockPatternUtils; private final LockPatternUtils mLockPatternUtils;
private final ObservablePreferenceFragment mParentFragment;
public AutoPinConfirmPreferenceController(Context context, int userId, public AutoPinConfirmPreferenceController(Context context, int userId,
LockPatternUtils lockPatternUtils) { LockPatternUtils lockPatternUtils,
ObservablePreferenceFragment parentFragment) {
super(context); super(context);
mUserId = userId; mUserId = userId;
mLockPatternUtils = lockPatternUtils; mLockPatternUtils = lockPatternUtils;
mParentFragment = parentFragment;
} }
@Override @Override
public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) {
setPinAutoConfirmSettingState((boolean) newValue); launchPinConfirmActivity((boolean) newValue);
return true; return true;
} }
@@ -82,4 +89,18 @@ public class AutoPinConfirmPreferenceController extends AbstractPreferenceContro
private void setPinAutoConfirmSettingState(boolean state) { private void setPinAutoConfirmSettingState(boolean state) {
mLockPatternUtils.setAutoPinConfirm(state, mUserId); 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();
}
} }

View File

@@ -16,10 +16,14 @@
package com.android.settings.security.screenlock; package com.android.settings.security.screenlock;
import android.app.Activity;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.UserHandle; import android.os.UserHandle;
import androidx.annotation.Nullable;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
@@ -38,6 +42,10 @@ public class ScreenLockSettings extends DashboardFragment
private static final String TAG = "ScreenLockSettings"; private static final String TAG = "ScreenLockSettings";
private static final int MY_USER_ID = UserHandle.myUserId(); 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; private LockPatternUtils mLockPatternUtils;
@Override @Override
@@ -79,7 +87,7 @@ public class ScreenLockSettings extends DashboardFragment
controllers.add(new LockAfterTimeoutPreferenceController( controllers.add(new LockAfterTimeoutPreferenceController(
context, MY_USER_ID, lockPatternUtils)); context, MY_USER_ID, lockPatternUtils));
controllers.add(new AutoPinConfirmPreferenceController( controllers.add(new AutoPinConfirmPreferenceController(
context, MY_USER_ID, lockPatternUtils)); context, MY_USER_ID, lockPatternUtils, parent));
controllers.add(new OwnerInfoPreferenceController(context, parent)); controllers.add(new OwnerInfoPreferenceController(context, parent));
return controllers; return controllers;
} }
@@ -94,4 +102,17 @@ public class ScreenLockSettings extends DashboardFragment
new LockPatternUtils(context)); 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);
}
}
}
} }

View File

@@ -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 com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
@@ -33,6 +32,7 @@ import androidx.test.core.app.ApplicationProvider;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.testutils.shadow.ShadowDeviceConfig; import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -48,6 +48,8 @@ public class AutoPinConfirmPreferenceControllerTest {
private static final Integer TEST_USER_ID = 1; private static final Integer TEST_USER_ID = 1;
@Mock @Mock
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
@Mock
private ObservablePreferenceFragment mParentFragment;
private AutoPinConfirmPreferenceController mController; private AutoPinConfirmPreferenceController mController;
private SwitchPreference mPreference; private SwitchPreference mPreference;
@@ -56,7 +58,8 @@ public class AutoPinConfirmPreferenceControllerTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
mController = mController =
new AutoPinConfirmPreferenceController(context, TEST_USER_ID, mLockPatternUtils); new AutoPinConfirmPreferenceController(context, TEST_USER_ID, mLockPatternUtils,
mParentFragment);
mPreference = new SwitchPreference(context); mPreference = new SwitchPreference(context);
} }
@@ -128,12 +131,4 @@ public class AutoPinConfirmPreferenceControllerTest {
mController.updateState(mPreference); mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue(); 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);
}
} }