Default setup wizard to use PIN
- Added "Screen lock options" button in PIN screen, controlled by extra EXTRA_SHOW_OPTIONS_BUTTON, which will create a dialog to ask the user to choose another screen lock type. - Extracted ScreenLockType enum and ChooseLockGenericController that can be shared by ChooseLockGeneric and the dialog ChooseLockTypeDialogFragment. - The intent extra EXTRA_SHOW_OPTIONS_BUTTON will be set if ChooseLockGeneric screen starts ChooseLockPassword / ChooseLockPattern without asking the user. (Although the extra is ignored by ChooseLockPattern currently) - Fix layout alignment for the password entry field to remove the extra 4dp padding on the sides. Test: cd tests/robotests && mma Bug: 35442933 Bug: 38002299 Change-Id: I877fbe08a0c05bb97175e1cbf0260ea6dbda22e2
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(
|
||||
manifest = TestConfig.MANIFEST_PATH,
|
||||
sdk = TestConfig.SDK_VERSION,
|
||||
shadows = {
|
||||
SettingsShadowResources.class
|
||||
})
|
||||
public class ChooseLockGenericControllerTest {
|
||||
|
||||
private ChooseLockGenericController mController;
|
||||
|
||||
@Mock
|
||||
private ManagedLockPasswordProvider mManagedLockPasswordProvider;
|
||||
|
||||
@Mock
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mController = new ChooseLockGenericController(
|
||||
application,
|
||||
0 /* userId */,
|
||||
mDevicePolicyManager,
|
||||
mManagedLockPasswordProvider);
|
||||
SettingsShadowResources.overrideResource(R.bool.config_hide_none_security_option, false);
|
||||
SettingsShadowResources.overrideResource(R.bool.config_hide_swipe_security_option, false);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
SettingsShadowResources.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockVisible_shouldRespectResourceConfig() {
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
// All locks except managed defaults to visible
|
||||
assertThat(mController.isScreenLockVisible(lock)).named(lock + " visible")
|
||||
.isEqualTo(lock != ScreenLockType.MANAGED);
|
||||
}
|
||||
|
||||
SettingsShadowResources.overrideResource(R.bool.config_hide_none_security_option, true);
|
||||
SettingsShadowResources.overrideResource(R.bool.config_hide_swipe_security_option, true);
|
||||
assertThat(mController.isScreenLockVisible(ScreenLockType.NONE)).named("NONE visible")
|
||||
.isFalse();
|
||||
assertThat(mController.isScreenLockVisible(ScreenLockType.SWIPE)).named("SWIPE visible")
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockVisible_notCurrentUser_shouldHideSwipe() {
|
||||
mController = new ChooseLockGenericController(application, 1 /* userId */);
|
||||
assertThat(mController.isScreenLockVisible(ScreenLockType.SWIPE)).named("SWIPE visible")
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockVisible_managedPasswordChoosable_shouldShowManaged() {
|
||||
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
|
||||
|
||||
assertThat(mController.isScreenLockVisible(ScreenLockType.MANAGED)).named("MANAGED visible")
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockEnabled_lowerQuality_shouldReturnFalse() {
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(mController.isScreenLockEnabled(lock, lock.maxQuality + 1))
|
||||
.named(lock + " enabled")
|
||||
.isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockEnabled_equalQuality_shouldReturnTrue() {
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(mController.isScreenLockEnabled(lock, lock.defaultQuality))
|
||||
.named(lock + " enabled")
|
||||
.isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockEnabled_higherQuality_shouldReturnTrue() {
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(mController.isScreenLockEnabled(lock, lock.maxQuality - 1))
|
||||
.named(lock + " enabled")
|
||||
.isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockDisabledByAdmin_lowerQuality_shouldReturnTrue() {
|
||||
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality + 1))
|
||||
.named(lock + " disabledByAdmin")
|
||||
.isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockDisabledByAdmin_equalQuality_shouldReturnFalse() {
|
||||
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality))
|
||||
.named(lock + " disabledByAdmin")
|
||||
.isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockDisabledByAdmin_higherQuality_shouldReturnFalse() {
|
||||
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality - 1))
|
||||
.named(lock + " disabledByAdmin")
|
||||
.isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScreenLockDisabledByAdmin_managedNotChoosable_shouldReturnTrue() {
|
||||
doReturn(false).when(mManagedLockPasswordProvider).isManagedPasswordChoosable();
|
||||
assertThat(mController.isScreenLockDisabledByAdmin(
|
||||
ScreenLockType.MANAGED, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
|
||||
.named("MANANGED disabledByAdmin")
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTitle_shouldContainEnumName() {
|
||||
doReturn("MANAGED").when(mManagedLockPasswordProvider).getPickerOptionTitle(anyBoolean());
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(mController.getTitle(lock).toString())
|
||||
.containsMatch(Pattern.compile(lock.toString(), Pattern.CASE_INSENSITIVE));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getVisibleScreenLockTypes_qualitySomething_shouldReturnPatterPinPassword() {
|
||||
assertThat(mController.getVisibleScreenLockTypes(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false))
|
||||
.isEqualTo(Arrays.asList(
|
||||
ScreenLockType.PATTERN,
|
||||
ScreenLockType.PIN,
|
||||
ScreenLockType.PASSWORD));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getVisibleScreenLockTypes_showDisabled_shouldReturnAllButManaged() {
|
||||
assertThat(mController.getVisibleScreenLockTypes(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, true))
|
||||
.isEqualTo(Arrays.asList(
|
||||
ScreenLockType.NONE,
|
||||
ScreenLockType.SWIPE,
|
||||
ScreenLockType.PATTERN,
|
||||
ScreenLockType.PIN,
|
||||
ScreenLockType.PASSWORD));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeQuality_noDpmRequirement_shouldReturnQuality() {
|
||||
doReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
|
||||
.when(mDevicePolicyManager).getPasswordQuality(any(ComponentName.class), anyInt());
|
||||
|
||||
int upgradedQuality = mController.upgradeQuality(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
|
||||
assertThat(upgradedQuality).named("upgradedQuality")
|
||||
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeQuality_dpmRequirement_shouldReturnRequiredQuality() {
|
||||
doReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC)
|
||||
.when(mDevicePolicyManager).getPasswordQuality(any(ComponentName.class), anyInt());
|
||||
|
||||
int upgradedQuality = mController.upgradeQuality(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
|
||||
assertThat(upgradedQuality).named("upgradedQuality")
|
||||
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(
|
||||
manifest = TestConfig.MANIFEST_PATH,
|
||||
sdk = TestConfig.SDK_VERSION)
|
||||
public class ScreenLockTypeTest {
|
||||
|
||||
@Test
|
||||
public void fromQuality_shouldReturnLockWithAssociatedQuality() {
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC))
|
||||
.isEqualTo(ScreenLockType.PASSWORD);
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC))
|
||||
.isEqualTo(ScreenLockType.PASSWORD);
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK))
|
||||
.isNull();
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX))
|
||||
.isEqualTo(ScreenLockType.PASSWORD);
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_MANAGED))
|
||||
.isEqualTo(ScreenLockType.MANAGED);
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC))
|
||||
.isEqualTo(ScreenLockType.PIN);
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX))
|
||||
.isEqualTo(ScreenLockType.PIN);
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING))
|
||||
.isEqualTo(ScreenLockType.PATTERN);
|
||||
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
|
||||
.isEqualTo(ScreenLockType.SWIPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromKey_shouldReturnLockWithGivenKey() {
|
||||
for (ScreenLockType lock : ScreenLockType.values()) {
|
||||
assertThat(ScreenLockType.fromKey(lock.preferenceKey)).isEqualTo(lock);
|
||||
}
|
||||
assertThat(ScreenLockType.fromKey("nonexistent")).isNull();
|
||||
}
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
|
||||
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
|
||||
import com.android.settings.password.SetupChooseLockPassword.SetupChooseLockPasswordFragment;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
|
||||
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowActivity;
|
||||
import org.robolectric.shadows.ShadowActivity.IntentForResult;
|
||||
import org.robolectric.shadows.ShadowDialog;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(
|
||||
manifest = TestConfig.MANIFEST_PATH,
|
||||
sdk = TestConfig.SDK_VERSION,
|
||||
shadows = {
|
||||
SettingsShadowResources.class,
|
||||
SettingsShadowResources.SettingsShadowTheme.class,
|
||||
ShadowDynamicIndexableContentMonitor.class,
|
||||
ShadowEventLogWriter.class,
|
||||
ShadowUtils.class
|
||||
})
|
||||
public class SetupChooseLockPasswordTest {
|
||||
|
||||
@Test
|
||||
public void createActivity_shouldNotCrash() {
|
||||
// Basic sanity test for activity created without crashing
|
||||
Robolectric.buildActivity(SetupChooseLockPassword.class,
|
||||
SetupChooseLockPassword.modifyIntentForSetup(
|
||||
application,
|
||||
new IntentBuilder(application).build()))
|
||||
.setup().get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createActivity_withShowOptionsButtonExtra_shouldShowButton() {
|
||||
Intent intent = SetupChooseLockPassword.modifyIntentForSetup(
|
||||
application,
|
||||
new IntentBuilder(application).build());
|
||||
intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true);
|
||||
SetupChooseLockPassword activity =
|
||||
Robolectric.buildActivity(SetupChooseLockPassword.class, intent).setup().get();
|
||||
|
||||
Button optionsButton = activity.findViewById(R.id.screen_lock_options);
|
||||
assertThat(optionsButton).isNotNull();
|
||||
|
||||
ShadowActivity shadowActivity = shadowOf(activity);
|
||||
optionsButton.performClick();
|
||||
|
||||
assertThat(ShadowDialog.getLatestDialog()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createActivity_clickDifferentOption_extrasShouldBePropagated() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("foo", "bar");
|
||||
|
||||
Intent intent = new IntentBuilder(application).build();
|
||||
intent.putExtra(ChooseLockGenericFragment.EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS, bundle);
|
||||
intent = SetupChooseLockPassword.modifyIntentForSetup(application, intent);
|
||||
intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true);
|
||||
|
||||
SetupChooseLockPassword activity =
|
||||
Robolectric.buildActivity(SetupChooseLockPassword.class, intent).setup().get();
|
||||
|
||||
SetupChooseLockPasswordFragment fragment =
|
||||
(SetupChooseLockPasswordFragment) activity.getFragmentManager()
|
||||
.findFragmentById(R.id.main_content);
|
||||
fragment.onLockTypeSelected(ScreenLockType.PATTERN);
|
||||
|
||||
ShadowActivity shadowActivity = shadowOf(activity);
|
||||
IntentForResult chooseLockIntent = shadowActivity.getNextStartedActivityForResult();
|
||||
assertThat(chooseLockIntent).isNotNull();
|
||||
assertThat(chooseLockIntent.requestCode)
|
||||
.isEqualTo(SetupChooseLockPasswordFragment.REQUEST_SCREEN_LOCK_OPTIONS);
|
||||
assertThat(chooseLockIntent.intent.getStringExtra("foo")).named("Foo extra")
|
||||
.isEqualTo("bar");
|
||||
}
|
||||
}
|
@@ -137,6 +137,16 @@ public class SettingsShadowResources extends ShadowResources {
|
||||
realResources, Resources.class, "getInteger", ClassParameter.from(int.class, id));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean getBoolean(int id) {
|
||||
final Object override = sResourceOverrides.get(id);
|
||||
if (override instanceof Boolean) {
|
||||
return (boolean) override;
|
||||
}
|
||||
return Shadow.directlyOn(realResources, Resources.class, "getBoolean",
|
||||
ClassParameter.from(int.class, id));
|
||||
}
|
||||
|
||||
@Implements(Theme.class)
|
||||
public static class SettingsShadowTheme extends ShadowTheme {
|
||||
|
||||
|
Reference in New Issue
Block a user