New extra for ACTION_SET_NEW_PASSWORD to specify the min complexity

When an app that has the permission GET_AND_REQUEST_PASSWORD_COMPLEXITY
launches ACTION_SET_NEW_PASSWORD, it can use the DPM PASSWORD_COMPLEXITY_*
constants to specify the complexity it wants in a new extra
EXTRA_PASSWORD_COMPLEXITY.
The screen lock type picker would then filter out the options which
cannot fulfil the min complexity (and DPM restrictions) and will show a
footer with a brief description of the calling app and the requested type.
The same password requirements UI is used in ChooseLockPassword screen
to display the minimum requirements that can fulfil both DPM
restrictions and the min complexity.

The app must have permission GET_AND_REQUEST_PASSWORD_COMPLEXITY
otherwise the extra would be ignored.

ACTION_SET_NEW_PASSWORD is also updated to always display the calling app
name in the screen lock type picker if it is not launched by Settings,
with or without the new extra.

Bug: 111173457
Test: atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java
      atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
      atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
      atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/PasswordUtilsTest.java
      atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
      atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java
      manual test with TestDpc (ag/5901733)

Change-Id: I21a25d28669bf1223c3b02ba85c0755e59feee2e
This commit is contained in:
Bernard Chau
2018-12-17 18:03:24 +00:00
parent da70607f41
commit 92db5bf4f7
18 changed files with 1280 additions and 97 deletions

View File

@@ -16,15 +16,22 @@
package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.content.ComponentName;
import com.android.settings.R;
@@ -58,11 +65,7 @@ public class ChooseLockGenericControllerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new ChooseLockGenericController(
application,
0 /* userId */,
mDevicePolicyManager,
mManagedLockPasswordProvider);
mController = createController(PASSWORD_COMPLEXITY_NONE);
SettingsShadowResources.overrideResource(R.bool.config_hide_none_security_option, false);
SettingsShadowResources.overrideResource(R.bool.config_hide_swipe_security_option, false);
}
@@ -225,4 +228,44 @@ public class ChooseLockGenericControllerTest {
assertThat(upgradedQuality).named("upgradedQuality")
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
}
@Test
public void upgradeQuality_complexityHigh_minQualityNumericComplex() {
when(mDevicePolicyManager.getPasswordQuality(nullable(ComponentName.class), anyInt()))
.thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_HIGH);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
}
@Test
public void upgradeQuality_complexityMedium_minQualityNumericComplex() {
when(mDevicePolicyManager.getPasswordQuality(nullable(ComponentName.class), anyInt()))
.thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_MEDIUM);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
}
@Test
public void upgradeQuality_complexityLow_minQualitySomething() {
when(mDevicePolicyManager.getPasswordQuality(nullable(ComponentName.class), anyInt()))
.thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_LOW);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
}
private ChooseLockGenericController createController(
@PasswordComplexity int minPasswordComplexity) {
return new ChooseLockGenericController(
application,
0 /* userId */,
minPasswordComplexity,
mDevicePolicyManager,
mManagedLockPasswordProvider);
}
}

View File

@@ -16,6 +16,15 @@
package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.application;
@@ -27,8 +36,10 @@ import android.content.Intent;
import android.provider.Settings.Global;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
import com.android.settings.search.SearchFeatureProvider;
@@ -36,6 +47,7 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowStorageManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.widget.FooterPreference;
import org.junit.After;
import org.junit.Before;
@@ -112,6 +124,70 @@ public class ChooseLockGenericTest {
assertThat(shadowOf(mActivity).getNextStartedActivity()).isNull();
}
@Test
public void updatePreferencesOrFinish_footerPreferenceAddedHighComplexityText() {
ShadowStorageManager.setIsFileEncryptedNativeOrEmulated(false);
Intent intent = new Intent()
.putExtra(EXTRA_KEY_CALLER_APP_NAME, "app name")
.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
initActivity(intent);
CharSequence expectedTitle =
mActivity.getString(R.string.unlock_footer_high_complexity_requested, "app name");
mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */);
FooterPreference footer = mFragment.findPreference(FooterPreference.KEY_FOOTER);
assertThat(footer.getTitle()).isEqualTo(expectedTitle);
}
@Test
public void updatePreferencesOrFinish_footerPreferenceAddedMediumComplexityText() {
ShadowStorageManager.setIsFileEncryptedNativeOrEmulated(false);
Intent intent = new Intent()
.putExtra(EXTRA_KEY_CALLER_APP_NAME, "app name")
.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_MEDIUM);
initActivity(intent);
CharSequence expectedTitle =
mActivity.getString(R.string.unlock_footer_medium_complexity_requested, "app name");
mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */);
FooterPreference footer = mFragment.findPreference(FooterPreference.KEY_FOOTER);
assertThat(footer.getTitle()).isEqualTo(expectedTitle);
}
@Test
public void updatePreferencesOrFinish_footerPreferenceAddedLowComplexityText() {
ShadowStorageManager.setIsFileEncryptedNativeOrEmulated(false);
Intent intent = new Intent()
.putExtra(EXTRA_KEY_CALLER_APP_NAME, "app name")
.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_LOW);
initActivity(intent);
CharSequence expectedTitle =
mActivity.getString(R.string.unlock_footer_low_complexity_requested, "app name");
mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */);
FooterPreference footer = mFragment.findPreference(FooterPreference.KEY_FOOTER);
assertThat(footer.getTitle()).isEqualTo(expectedTitle);
}
@Test
public void updatePreferencesOrFinish_footerPreferenceAddedNoneComplexityText() {
ShadowStorageManager.setIsFileEncryptedNativeOrEmulated(false);
Intent intent = new Intent()
.putExtra(EXTRA_KEY_CALLER_APP_NAME, "app name")
.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
initActivity(intent);
CharSequence expectedTitle =
mActivity.getString(R.string.unlock_footer_none_complexity_requested, "app name");
mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */);
FooterPreference footer = mFragment.findPreference(FooterPreference.KEY_FOOTER);
assertThat(footer.getTitle()).isEqualTo(expectedTitle);
}
@Test
public void onActivityResult_requestcode0_shouldNotFinish() {
initActivity(null);
@@ -165,6 +241,48 @@ public class ChooseLockGenericTest {
assertThat(mActivity.isFinishing()).isTrue();
}
@Test
public void onPreferenceTreeClick_fingerprintPassesMinComplexityInfoOntoNextActivity() {
Intent intent = new Intent(ACTION_SET_NEW_PASSWORD)
.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH)
.putExtra(EXTRA_KEY_CALLER_APP_NAME, "app name");
initActivity(intent);
Preference fingerprintPref = new Preference(application);
fingerprintPref.setKey("unlock_skip_fingerprint");
boolean result = mFragment.onPreferenceTreeClick(fingerprintPref);
assertThat(result).isTrue();
Intent actualIntent = shadowOf(mActivity).getNextStartedActivityForResult().intent;
assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue();
assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
.isEqualTo(PASSWORD_COMPLEXITY_HIGH);
assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME))
.isEqualTo("app name");
}
@Test
public void onPreferenceTreeClick_facePassesMinComplexityInfoOntoNextActivity() {
Intent intent = new Intent(ACTION_SET_NEW_PASSWORD)
.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH)
.putExtra(EXTRA_KEY_CALLER_APP_NAME, "app name");
initActivity(intent);
Preference facePref = new Preference(application);
facePref.setKey("unlock_skip_face");
boolean result = mFragment.onPreferenceTreeClick(facePref);
assertThat(result).isTrue();
Intent actualIntent = shadowOf(mActivity).getNextStartedActivityForResult().intent;
assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue();
assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
.isEqualTo(PASSWORD_COMPLEXITY_HIGH);
assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME))
.isEqualTo("app name");
}
private void initActivity(@Nullable Intent intent) {
if (intent == null) {
intent = new Intent();

View File

@@ -16,19 +16,37 @@
package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY;
import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.content.Intent;
import android.os.UserHandle;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment;
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.google.android.setupdesign.GlifLayout;
@@ -44,13 +62,21 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowDrawable;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {SettingsShadowResources.class, ShadowUtils.class})
@Config(shadows = {
SettingsShadowResources.class,
ShadowUtils.class,
ShadowDevicePolicyManager.class,
})
public class ChooseLockPasswordTest {
private ShadowDevicePolicyManager mShadowDpm;
@Before
public void setUp() {
SettingsShadowResources.overrideResource(
com.android.internal.R.string.config_headlineFontFamily, "");
mShadowDpm = ShadowDevicePolicyManager.getShadow();
mShadowDpm.setPasswordMaximumLength(16);
}
@After
@@ -72,7 +98,7 @@ public class ChooseLockPasswordTest {
assertThat(intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
.named("EXTRA_KEY_PASSWORD")
.isEqualTo("password");
assertThat(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, 0))
assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0))
.named("PASSWORD_TYPE_KEY")
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0))
@@ -84,7 +110,7 @@ public class ChooseLockPasswordTest {
public void intentBuilder_setChallenge_shouldAddExtras() {
Intent intent = new IntentBuilder(application)
.setChallenge(12345L)
.setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC)
.setPasswordQuality(PASSWORD_QUALITY_ALPHANUMERIC)
.setUserId(123)
.build();
@@ -94,14 +120,213 @@ public class ChooseLockPasswordTest {
assertThat(intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L))
.named("EXTRA_KEY_CHALLENGE")
.isEqualTo(12345L);
assertThat(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, 0))
assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0))
.named("PASSWORD_TYPE_KEY")
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
.isEqualTo(PASSWORD_QUALITY_ALPHANUMERIC);
assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0))
.named("EXTRA_USER_ID")
.isEqualTo(123);
}
@Test
public void intentBuilder_setMinComplexityMedium_hasMinComplexityExtraMedium() {
Intent intent = new IntentBuilder(application)
.setRequestedMinComplexity(PASSWORD_COMPLEXITY_MEDIUM)
.build();
assertThat(intent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue();
assertThat(intent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
.isEqualTo(PASSWORD_COMPLEXITY_MEDIUM);
}
@Test
public void intentBuilder_setMinComplexityNotCalled() {
Intent intent = new IntentBuilder(application).build();
assertThat(intent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
}
@Test
public void processAndValidatePasswordRequirements_noMinPasswordComplexity() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_ALPHABETIC);
mShadowDpm.setPasswordMinimumLength(10);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
"Must contain at least 1 letter",
"Must be at least 10 characters");
}
@Test
public void processAndValidatePasswordRequirements_minPasswordComplexityStricter_pin() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_SOMETHING);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "",
"PIN must be at least 8 digits");
}
@Test
public void processAndValidatePasswordRequirements_minPasswordComplexityStricter_password() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_SOMETHING);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
"Must contain at least 1 letter",
"Must be at least 4 characters");
}
@Test
public void processAndValidatePasswordRequirements_dpmRestrictionsStricter_password() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_ALPHANUMERIC);
mShadowDpm.setPasswordMinimumLength(9);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_LOW,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
"Must contain at least 1 letter",
"Must contain at least 1 numerical digit",
"Must be at least 9 characters");
}
@Test
public void processAndValidatePasswordRequirements_dpmLengthLonger_pin() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC);
mShadowDpm.setPasswordMinimumLength(11);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "",
"PIN must be at least 11 digits");
}
@Test
public void processAndValidatePasswordRequirements_dpmQualityComplex() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_COMPLEX);
mShadowDpm.setPasswordMinimumSymbols(2);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
"Must contain at least 2 special symbols",
"Must be at least 6 characters");
}
@Test
@Config(shadows = ShadowLockPatternUtils.class)
public void processAndValidatePasswordRequirements_numericComplexNoMinComplexity_pinRequested() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "12345678",
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@Test
@Config(shadows = ShadowLockPatternUtils.class)
public void processAndValidatePasswordRequirements_numericComplexNoMinComplexity_passwordRequested() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "12345678",
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@Test
@Config(shadows = ShadowLockPatternUtils.class)
public void processAndValidatePasswordRequirements_numericComplexHighComplexity_pinRequested() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "12345678",
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@Test
@Config(shadows = ShadowLockPatternUtils.class)
public void processAndValidatePasswordRequirements_numericHighComplexity_pinRequested() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "12345678",
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@Test
@Config(shadows = ShadowLockPatternUtils.class)
public void processAndValidatePasswordRequirements_numericComplexLowComplexity_passwordRequested() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_LOW,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "12345678",
"Must contain at least 1 letter");
}
@Test
public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_empty() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
"Must contain at least 1 letter",
"Must be at least 6 characters");
}
@Test
public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_numeric() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "1",
"Must contain at least 1 letter",
"Must be at least 6 characters");
}
@Test
public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_alphabetic() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "b",
"Must be at least 6 characters");
}
@Test
public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_alphanumeric() {
mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "b1",
"Must be at least 6 characters");
}
@Test
public void assertThat_chooseLockIconChanged_WhenFingerprintExtraSet() {
ShadowDrawable drawable = setActivityAndGetIconDrawable(true);
@@ -132,4 +357,18 @@ public class ChooseLockPasswordTest {
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
return Shadows.shadowOf(((GlifLayout) fragment.getView()).getIcon());
}
private void assertPasswordValidationResult(@PasswordComplexity int minComplexity,
int passwordType, String userEnteredPassword, String... expectedValidationResult) {
Intent intent = new Intent();
intent.putExtra(CONFIRM_CREDENTIALS, false);
intent.putExtra(PASSWORD_TYPE_KEY, passwordType);
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, minComplexity);
ChooseLockPassword activity = buildChooseLockPasswordActivity(intent);
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(activity);
int validateResult = fragment.validatePassword(userEnteredPassword);
String[] messages = fragment.convertErrorCodeToMessages(validateResult);
assertThat(messages).asList().containsExactly((Object[]) expectedValidationResult);
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2019 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.password;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.settings.password.PasswordUtils.getCallingAppLabel;
import static com.android.settings.password.PasswordUtils.isCallingAppPermitted;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.IActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.settings.testutils.shadow.ShadowActivityManager;
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;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowActivityManager.class})
public class PasswordUtilsTest {
private static final String PACKAGE_NAME = "com.android.app";
private static final String PERMISSION = "com.testing.permission";
private static final int UID = 1234;
@Mock
private PackageManager mPackageManager;
@Mock
private ApplicationInfo mApplicationInfo;
@Mock
private IActivityManager mActivityService;
@Mock
private IBinder mActivityToken;
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
ShadowActivityManager.setService(mActivityService);
}
@Test
public void getCallingAppLabel_activityServiceThrowsRemoteException_returnsNull()
throws Exception {
when(mActivityService.getLaunchedFromPackage(mActivityToken))
.thenThrow(new RemoteException());
assertThat(getCallingAppLabel(mContext, mActivityToken)).isNull();
}
@Test
public void getCallingAppLabel_activityServiceReturnsSettingsApp_returnsNull()
throws Exception {
when(mActivityService.getLaunchedFromPackage(mActivityToken))
.thenReturn("com.android.settings");
assertThat(getCallingAppLabel(mContext, mActivityToken)).isNull();
}
@Test
public void getCallingAppLabel_packageManagerThrowsNameNotFound_returnsNull() throws Exception {
when(mActivityService.getLaunchedFromPackage(mActivityToken))
.thenReturn(PACKAGE_NAME);
when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
.thenThrow(new NameNotFoundException());
assertThat(getCallingAppLabel(mContext, mActivityToken)).isNull();
}
@Test
public void getCallingAppLabel_returnsLabel() throws Exception {
when(mActivityService.getLaunchedFromPackage(mActivityToken))
.thenReturn(PACKAGE_NAME);
when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
.thenReturn(mApplicationInfo);
when(mApplicationInfo.loadLabel(mPackageManager)).thenReturn("label");
assertThat(getCallingAppLabel(mContext, mActivityToken)).isEqualTo("label");
}
@Test
public void isCallingAppPermitted_permissionGranted_returnsTrue() throws Exception {
when(mActivityService.getLaunchedFromUid(mActivityToken)).thenReturn(UID);
when(mContext.checkPermission(PERMISSION, -1, UID)).thenReturn(PERMISSION_GRANTED);
assertThat(isCallingAppPermitted(mContext, mActivityToken, PERMISSION)).isTrue();
}
@Test
public void isCallingAppPermitted_permissionDenied_returnsFalse() throws Exception {
when(mActivityService.getLaunchedFromUid(mActivityToken)).thenReturn(UID);
when(mContext.checkPermission(PERMISSION, -1, UID)).thenReturn(PERMISSION_DENIED);
assertThat(isCallingAppPermitted(mContext, mActivityToken, PERMISSION)).isFalse();
}
@Test
public void isCallingAppPermitted_throwsRemoteException_returnsFalse() throws Exception {
when(mActivityService.getLaunchedFromUid(mActivityToken)).thenThrow(new RemoteException());
assertThat(isCallingAppPermitted(mContext, mActivityToken, PERMISSION)).isFalse();
}
}

View File

@@ -16,6 +16,16 @@
package com.android.settings.password;
import static android.Manifest.permission.GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY;
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD;
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
@@ -23,6 +33,8 @@ import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -31,11 +43,14 @@ import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
@RunWith(RobolectricTestRunner.class)
public class SetNewPasswordActivityTest {
private static final String APP_LABEL = "label";
private int mProvisioned;
@Before
@@ -48,6 +63,7 @@ public class SetNewPasswordActivityTest {
public void tearDown() {
Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, mProvisioned);
ShadowPasswordUtils.reset();
}
@Test
@@ -77,4 +93,106 @@ public class SetNewPasswordActivityTest {
assertThat(intent.getComponent())
.isEqualTo(new ComponentName(activity, SetupChooseLockGeneric.class));
}
@Test
@Config(shadows = {ShadowPasswordUtils.class})
public void testLaunchChooseLock_setNewPasswordExtraWithoutPermission() {
ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
Intent intent = new Intent(ACTION_SET_NEW_PASSWORD);
intent.putExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
SetNewPasswordActivity activity =
Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getNextStartedActivityForResult()).isNull();
}
@Test
@Config(shadows = {ShadowPasswordUtils.class})
public void testLaunchChooseLock_setNewPasswordExtraWithPermission() {
ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
Intent intent = new Intent(ACTION_SET_NEW_PASSWORD);
intent.putExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
SetNewPasswordActivity activity =
Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent;
assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD);
assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue();
assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
.isEqualTo(PASSWORD_COMPLEXITY_HIGH);
assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
}
@Test
@Config(shadows = {ShadowPasswordUtils.class})
public void testLaunchChooseLock_setNewPasswordExtraInvalidValue() {
ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
Intent intent = new Intent(ACTION_SET_NEW_PASSWORD);
intent.putExtra(EXTRA_PASSWORD_COMPLEXITY, -1);
SetNewPasswordActivity activity =
Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent;
assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD);
assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
}
@Test
@Config(shadows = {ShadowPasswordUtils.class})
public void testLaunchChooseLock_setNewPasswordExtraNoneComplexity() {
ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
Intent intent = new Intent(ACTION_SET_NEW_PASSWORD);
intent.putExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
SetNewPasswordActivity activity =
Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent;
assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD);
assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
}
@Test
@Config(shadows = {ShadowPasswordUtils.class})
public void testLaunchChooseLock_setNewParentProfilePasswordExtraWithPermission() {
ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
Intent intent = new Intent(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD);
intent.putExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
SetNewPasswordActivity activity =
Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent;
assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD);
assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2019 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.password;
import static android.Manifest.permission.GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.Intent;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowUserManager.class,
ShadowUtils.class,
ShadowLockPatternUtils.class,
})
public class SetupChooseLockGenericTest {
@After
public void tearDown() {
ShadowPasswordUtils.reset();
}
@Test
public void setupChooseLockGenericPasswordComplexityExtraWithoutPermission() {
Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN");
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
SetupChooseLockGeneric activity =
Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).create().get();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.isFinishing()).isTrue();
}
@Test
@Config(shadows = {ShadowPasswordUtils.class})
public void setupChooseLockGenericPasswordComplexityExtraWithPermission() {
ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN");
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
SetupChooseLockGeneric activity =
Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).create().get();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.isFinishing()).isFalse();
}
}

View File

@@ -17,6 +17,7 @@
package com.android.settings.testutils.shadow;
import android.app.ActivityManager;
import android.app.IActivityManager;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -24,6 +25,7 @@ import org.robolectric.annotation.Implements;
@Implements(ActivityManager.class)
public class ShadowActivityManager {
private static int sCurrentUserId = 0;
private static IActivityManager sService = null;
@Implementation
protected static int getCurrentUser() {
@@ -33,4 +35,13 @@ public class ShadowActivityManager {
public static void setCurrentUser(int userId) {
sCurrentUserId = userId;
}
@Implementation
public static IActivityManager getService() {
return sService;
}
public static void setService(IActivityManager service) {
sService = service;
}
}

View File

@@ -1,5 +1,7 @@
package com.android.settings.testutils.shadow;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -23,6 +25,10 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev
private boolean mIsAdminActiveAsUser = false;
private ComponentName mDeviceOwnerComponentName;
private int mDeviceOwnerUserId = -1;
private int mPasswordMinQuality = PASSWORD_QUALITY_UNSPECIFIED;
private int mPasswordMaxLength = 16;
private int mPasswordMinLength = 0;
private int mPasswordMinSymbols = 0;
public void setShortSupportMessageForUser(ComponentName admin, int userHandle, String message) {
mSupportMessagesMap.put(Objects.hash(admin, userHandle), message);
@@ -70,6 +76,42 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev
mDeviceOwnerComponentName = admin;
}
@Implementation
public int getPasswordQuality(ComponentName admin, int userHandle) {
return mPasswordMinQuality;
}
public void setPasswordQuality(int quality) {
mPasswordMinQuality = quality;
}
@Implementation
public int getPasswordMinimumLength(ComponentName admin, int userHandle) {
return mPasswordMinLength;
}
public void setPasswordMinimumLength(int length) {
mPasswordMinLength = length;
}
@Implementation
public int getPasswordMinimumSymbols(ComponentName admin, int userHandle) {
return mPasswordMinSymbols;
}
public void setPasswordMinimumSymbols(int numOfSymbols) {
mPasswordMinSymbols = numOfSymbols;
}
@Implementation
public int getPasswordMaximumLength(int quality) {
return mPasswordMaxLength;
}
public void setPasswordMaximumLength(int length) {
mPasswordMaxLength = length;
}
public static ShadowDevicePolicyManager getShadow() {
return (ShadowDevicePolicyManager) Shadow.extract(
RuntimeEnvironment.application.getSystemService(DevicePolicyManager.class));

View File

@@ -59,4 +59,14 @@ public class ShadowLockPatternUtils {
public static void setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled) {
sDeviceEncryptionEnabled = deviceEncryptionEnabled;
}
@Implementation
protected byte[] getPasswordHistoryHashFactor(String currentPassword, int userId) {
return null;
}
@Implementation
protected boolean checkPasswordHistory(String passwordToCheck, byte[] hashFactor, int userId) {
return false;
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2019 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.testutils.shadow;
import android.content.Context;
import android.os.IBinder;
import com.android.settings.password.PasswordUtils;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@Implements(PasswordUtils.class)
public class ShadowPasswordUtils {
private static String sCallingAppLabel;
private static Set<String> sGrantedPermissions;
public static void reset() {
sCallingAppLabel = null;
sGrantedPermissions = null;
}
@Implementation
protected static boolean isCallingAppPermitted(Context context, IBinder activityToken,
String permission) {
if (sGrantedPermissions == null) {
return false;
}
return sGrantedPermissions.contains(permission);
}
public static void addGrantedPermission(String... permissions) {
if (sGrantedPermissions == null) {
sGrantedPermissions = new HashSet<>();
}
sGrantedPermissions.addAll(Arrays.asList(permissions));
}
@Implementation
protected static String getCallingAppLabel(Context context, IBinder activityToken) {
return sCallingAppLabel;
}
public static void setCallingAppLabel(String label) {
sCallingAppLabel = label;
}
}