Add setting to disable PIN animation and password

Test: Unit - atest SettingsRoboTests
Test: Manual - Set PIN lock and enabled/disabled the setting to observe animation change during PIN entry
Bug: b/204799468
Merged-In: I587b993ef5515a075442e82ebafae88bebdffc20
Change-Id: I587b993ef5515a075442e82ebafae88bebdffc20
This commit is contained in:
Andreas Miko
2023-02-08 17:26:17 +00:00
committed by Chaohui Wang
parent 91eab671d1
commit 30bf66db42
8 changed files with 186 additions and 19 deletions

View File

@@ -4805,6 +4805,9 @@
<string name="lockpattern_settings_enable_summary">Must draw pattern to unlock screen</string>
<!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the users move their finger around while drawing the unlock pattern. If checked, this line is drawn. If unchecked, there is nothing drawn so the users do not reveal their pattern while they unlock the phone.-->
<string name="lockpattern_settings_enable_visible_pattern_title">Make pattern visible</string>
<!-- Security & location settings screen, setting check box title. This setting disables animations when entering the PIN.-->
<string name="lockpattern_settings_enhanced_pin_privacy_title">Enhanced PIN privacy</string>
<string name="lockpattern_settings_enhanced_pin_privacy_summary">Disable animations while entering the PIN</string>
<!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the users move their finger around while drawing the profile unlock pattern. If checked, this line is drawn. If unchecked, there is nothing drawn so the users do not reveal their pattern while they unlock the profile.-->
<string name="lockpattern_settings_enable_visible_pattern_title_profile">Make profile pattern visible</string>
<!-- Security & location settings screen, setting check box title. This setting controls whether tactile feedback will be produced when the user draws the pattern.-->

View File

@@ -27,6 +27,12 @@
android:key="visiblepattern"
android:title="@string/lockpattern_settings_enable_visible_pattern_title" />
<!-- available in pin -->
<SwitchPreference
android:key="enhancedPinPrivacy"
android:title="@string/lockpattern_settings_enhanced_pin_privacy_title"
android:summary="@string/lockpattern_settings_enhanced_pin_privacy_summary" />
<!-- available in pin/pattern/password -->
<com.android.settings.display.TimeoutListPreference
android:key="lock_after_timeout"

View File

@@ -17,29 +17,22 @@
package com.android.settings.security.screenlock;
import android.content.Context;
import android.os.UserHandle;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnResume;
public class LockScreenPreferenceController extends BasePreferenceController implements
LifecycleObserver, OnResume {
private static final int MY_USER_ID = UserHandle.myUserId();
private final LockPatternUtils mLockPatternUtils;
private Preference mPreference;
public LockScreenPreferenceController(Context context, String key) {
super(context, key);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider().getLockPatternUtils(context);
}
@Override

View File

@@ -16,7 +16,6 @@
package com.android.settings.security.screenlock;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import androidx.preference.Preference;
@@ -58,9 +57,8 @@ public class PatternVisiblePreferenceController extends AbstractPreferenceContro
}
private boolean isPatternLock() {
return mLockPatternUtils.isSecure(mUserId)
&& mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)
== DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
return mLockPatternUtils.getCredentialTypeForUser(mUserId)
== LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
}
@Override

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security.screenlock
import android.content.Context
import android.provider.Settings
import androidx.preference.Preference
import androidx.preference.TwoStatePreference
import com.android.internal.widget.LockPatternUtils
import com.android.internal.widget.LockPatternUtils.*
import com.android.settings.core.PreferenceControllerMixin
import com.android.settingslib.core.AbstractPreferenceController
class PinPrivacyPreferenceController(
context: Context,
private val userId: Int,
private val lockPatternUtils: LockPatternUtils
) : AbstractPreferenceController(context), PreferenceControllerMixin,
Preference.OnPreferenceChangeListener {
companion object {
private const val PREF_KEY = "enhancedPinPrivacy"
}
override fun isAvailable(): Boolean {
val credentialType = lockPatternUtils.getCredentialTypeForUser(userId)
return credentialType == CREDENTIAL_TYPE_PIN
}
override fun getPreferenceKey(): String {
return PREF_KEY
}
override fun onPreferenceChange(preference: Preference?, value: Any?): Boolean {
lockPatternUtils.setPinEnhancedPrivacyEnabled((value as Boolean), userId)
return true
}
override fun updateState(preference: Preference) {
(preference as TwoStatePreference).isChecked = getCurrentPreferenceState()
}
private fun getCurrentPreferenceState(): Boolean {
return lockPatternUtils.isPinEnhancedPrivacyEnabled(userId)
}
}

View File

@@ -68,9 +68,12 @@ public class ScreenLockSettings extends DashboardFragment
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
DashboardFragment parent, LockPatternUtils lockPatternUtils) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new PatternVisiblePreferenceController(
context, MY_USER_ID, lockPatternUtils));
controllers.add(new PinPrivacyPreferenceController(
context, MY_USER_ID, lockPatternUtils));
controllers.add(new PowerButtonInstantLockPreferenceController(
context, MY_USER_ID, lockPatternUtils));
controllers.add(new LockAfterTimeoutPreferenceController(

View File

@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import androidx.preference.SwitchPreference;
@@ -52,24 +51,22 @@ public class PatternVisiblePreferenceControllerTest {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController =
new PatternVisiblePreferenceController(mContext, TEST_USER_ID, mLockPatternUtils);
new PatternVisiblePreferenceController(mContext, TEST_USER_ID, mLockPatternUtils);
mPreference = new SwitchPreference(mContext);
}
@Test
public void isAvailable_lockSetToPattern_shouldReturnTrue() {
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
.thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_lockSetToPin_shouldReturnFalse() {
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
when(mLockPatternUtils.getKeyguardStoredPasswordQuality(TEST_USER_ID))
.thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID)).thenReturn(
LockPatternUtils.CREDENTIAL_TYPE_PIN);
assertThat(mController.isAvailable()).isFalse();
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security.screenlock;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_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;
import androidx.preference.SwitchPreference;
import com.android.internal.widget.LockPatternUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class PinPrivacyPreferenceControllerTest {
private static final int TEST_USER_ID = 0;
@Mock
private LockPatternUtils mLockPatternUtils;
private Context mContext;
private PinPrivacyPreferenceController mController;
private SwitchPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController =
new PinPrivacyPreferenceController(mContext, TEST_USER_ID, mLockPatternUtils);
mPreference = new SwitchPreference(mContext);
}
@Test
public void isAvailable_lockSetToPin_shouldReturnTrue() {
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID)).thenReturn(
CREDENTIAL_TYPE_PIN);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_lockSetToPinOrPw_shouldReturnTrue() {
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID)).thenReturn(
CREDENTIAL_TYPE_PASSWORD_OR_PIN);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_lockSetToOther_shouldReturnFalse() {
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID)).thenReturn(
CREDENTIAL_TYPE_PATTERN);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void updateState_shouldSetPref() {
when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(TEST_USER_ID)).thenReturn(true);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_shouldSetPref_false() {
when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(TEST_USER_ID)).thenReturn(false);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void onPreferenceChange_shouldUpdateLockPatternUtils() {
mController.onPreferenceChange(mPreference, true);
verify(mLockPatternUtils).setPinEnhancedPrivacyEnabled(true, TEST_USER_ID);
}
@Test
public void getPreferenceKey_returnsConst() {
assertThat(mController.getPreferenceKey().equals("enhancedPinPrivacy")).isTrue();
}
}