Loading res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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] --> Loading src/com/android/settings/password/ChooseLockPassword.java +9 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceController.java +24 −3 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; } Loading Loading @@ -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(); } } src/com/android/settings/security/screenlock/ScreenLockSettings.java +22 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; } Loading @@ -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); } } } } tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java +5 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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); } Loading Loading @@ -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); } } Loading
res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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] --> Loading
src/com/android/settings/password/ChooseLockPassword.java +9 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading
src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceController.java +24 −3 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; } Loading Loading @@ -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(); } }
src/com/android/settings/security/screenlock/ScreenLockSettings.java +22 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; } Loading @@ -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); } } } }
tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java +5 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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); } Loading Loading @@ -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); } }