Loading src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java +9 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.settings.SetupWizardUtils; import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment; import com.android.settings.password.SetupChooseLockGeneric; import com.android.settings.password.SetupSkipDialog; import com.android.settings.password.StorageManagerWrapper; public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction { private static final String KEY_LOCK_SCREEN_PRESENT = "wasLockScreenPresent"; Loading @@ -56,11 +57,14 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu @Override protected Intent getChooseLockIntent() { Intent intent = new Intent(this, SetupChooseLockGeneric.class) .putExtra( Intent intent = new Intent(this, SetupChooseLockGeneric.class); if (StorageManagerWrapper.isFileEncryptedNativeOrEmulated()) { intent.putExtra( LockPatternUtils.PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true); } SetupWizardUtils.copySetupExtras(getIntent(), intent); return intent; } Loading src/com/android/settings/password/StorageManagerWrapper.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * 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 android.os.storage.StorageManager; /** * Wrapper class to allow Robolectric to shadow methods introduced in newer API */ public class StorageManagerWrapper { public static boolean isFileEncryptedNativeOrEmulated() { return StorageManager.isFileEncryptedNativeOrEmulated(); } } tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -23,28 +23,38 @@ import static org.robolectric.RuntimeEnvironment.application; import android.app.KeyguardManager; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.view.View; import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.fingerprint.SetupFingerprintEnrollIntroductionTest .ShadowStorageManagerWrapper; import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment; import com.android.settings.password.SetupSkipDialog; import com.android.settings.password.StorageManagerWrapper; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowEventLogWriter; import com.android.settings.testutils.shadow.ShadowFingerprintManager; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowUserManager; 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.Robolectric; import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowActivity; import org.robolectric.shadows.ShadowActivity.IntentForResult; import org.robolectric.shadows.ShadowKeyguardManager; import org.robolectric.util.ActivityController; Loading @@ -54,7 +64,9 @@ import org.robolectric.util.ActivityController; sdk = TestConfig.SDK_VERSION, shadows = { ShadowEventLogWriter.class, ShadowFingerprintManager.class, ShadowLockPatternUtils.class, ShadowStorageManagerWrapper.class, ShadowUserManager.class }) public class SetupFingerprintEnrollIntroductionTest { Loading @@ -68,12 +80,22 @@ public class SetupFingerprintEnrollIntroductionTest { public void setUp() { MockitoAnnotations.initMocks(this); RuntimeEnvironment.getRobolectricPackageManager() .setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true); ShadowFingerprintManager.addToServiceMap(); final Intent intent = new Intent(); mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent); ShadowUserManager.getShadow().setUserInfo(0, mUserInfo); } @After public void tearDown() { ShadowStorageManagerWrapper.reset(); ShadowFingerprintManager.reset(); } @Test public void testKeyguardNotSecure_shouldFinishWithSetupSkipDialogResultSkip() { getShadowKeyguardManager().setIsKeyguardSecure(false); Loading Loading @@ -188,8 +210,41 @@ public class SetupFingerprintEnrollIntroductionTest { assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull(); } @Test public void testLockPattern() { ShadowStorageManagerWrapper.sIsFileEncrypted = false; mController.create().postCreate(null).resume(); SetupFingerprintEnrollIntroduction activity = mController.get(); final Button nextButton = activity.findViewById(R.id.fingerprint_next_button); nextButton.performClick(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult(); assertThat(startedActivity).isNotNull(); assertThat(startedActivity.intent.hasExtra( SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isFalse(); } private ShadowKeyguardManager getShadowKeyguardManager() { return Shadows.shadowOf(application.getSystemService(KeyguardManager.class)); } @Implements(StorageManagerWrapper.class) public static class ShadowStorageManagerWrapper { private static boolean sIsFileEncrypted = true; public static void reset() { sIsFileEncrypted = true; } @Implementation public static boolean isFileEncryptedNativeOrEmulated() { return sIsFileEncrypted; } } } tests/robotests/src/com/android/settings/testutils/shadow/ShadowFingerprintManager.java 0 → 100644 +102 −0 Original line number Diff line number Diff line /* * 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.testutils.shadow; import android.content.Context; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.support.annotation.NonNull; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; import org.robolectric.internal.ShadowExtractor; import org.robolectric.shadows.ShadowContextImpl; import org.robolectric.util.ReflectionHelpers; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.IntStream; @Implements(FingerprintManager.class) public class ShadowFingerprintManager { private static Map<String, String> getSystemServiceMap() { return ReflectionHelpers.getStaticField(ShadowContextImpl.class, "SYSTEM_SERVICE_MAP"); } /** * Call this in @Before of a test to add FingerprintManager to Robolectric's system service * map. Otherwise getSystemService(FINGERPRINT_SERVICE) will return null. */ public static void addToServiceMap() { getSystemServiceMap().put(Context.FINGERPRINT_SERVICE, FingerprintManager.class.getName()); } @Resetter public static void reset() { getSystemServiceMap().remove(Context.FINGERPRINT_SERVICE); } public boolean hardwareDetected = true; @NonNull private List<Fingerprint> mFingerprints = Collections.emptyList(); @Implementation public boolean isHardwareDetected() { return hardwareDetected; } @Implementation public boolean hasEnrolledFingerprints() { return !mFingerprints.isEmpty(); } @Implementation public List<Fingerprint> getEnrolledFingerprints() { return mFingerprints; } @Implementation public List<Fingerprint> getEnrolledFingerprints(int userId) { return mFingerprints; } public void setEnrolledFingerprints(Fingerprint... fingerprints) { mFingerprints = Arrays.asList(fingerprints); } public void setDefaultFingerprints(int num) { setEnrolledFingerprints( IntStream.range(0, num) .mapToObj(i -> new Fingerprint( "Fingerprint " + i, 0, /* groupId */ i, /* fingerId */ 0 /* deviceId */)) .toArray(Fingerprint[]::new)); } public static ShadowFingerprintManager get() { return (ShadowFingerprintManager) ShadowExtractor.extract( RuntimeEnvironment.application.getSystemService(FingerprintManager.class)); } } Loading
src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java +9 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.settings.SetupWizardUtils; import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment; import com.android.settings.password.SetupChooseLockGeneric; import com.android.settings.password.SetupSkipDialog; import com.android.settings.password.StorageManagerWrapper; public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction { private static final String KEY_LOCK_SCREEN_PRESENT = "wasLockScreenPresent"; Loading @@ -56,11 +57,14 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu @Override protected Intent getChooseLockIntent() { Intent intent = new Intent(this, SetupChooseLockGeneric.class) .putExtra( Intent intent = new Intent(this, SetupChooseLockGeneric.class); if (StorageManagerWrapper.isFileEncryptedNativeOrEmulated()) { intent.putExtra( LockPatternUtils.PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true); } SetupWizardUtils.copySetupExtras(getIntent(), intent); return intent; } Loading
src/com/android/settings/password/StorageManagerWrapper.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * 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 android.os.storage.StorageManager; /** * Wrapper class to allow Robolectric to shadow methods introduced in newer API */ public class StorageManagerWrapper { public static boolean isFileEncryptedNativeOrEmulated() { return StorageManager.isFileEncryptedNativeOrEmulated(); } }
tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -23,28 +23,38 @@ import static org.robolectric.RuntimeEnvironment.application; import android.app.KeyguardManager; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.view.View; import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.fingerprint.SetupFingerprintEnrollIntroductionTest .ShadowStorageManagerWrapper; import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment; import com.android.settings.password.SetupSkipDialog; import com.android.settings.password.StorageManagerWrapper; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowEventLogWriter; import com.android.settings.testutils.shadow.ShadowFingerprintManager; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowUserManager; 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.Robolectric; import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowActivity; import org.robolectric.shadows.ShadowActivity.IntentForResult; import org.robolectric.shadows.ShadowKeyguardManager; import org.robolectric.util.ActivityController; Loading @@ -54,7 +64,9 @@ import org.robolectric.util.ActivityController; sdk = TestConfig.SDK_VERSION, shadows = { ShadowEventLogWriter.class, ShadowFingerprintManager.class, ShadowLockPatternUtils.class, ShadowStorageManagerWrapper.class, ShadowUserManager.class }) public class SetupFingerprintEnrollIntroductionTest { Loading @@ -68,12 +80,22 @@ public class SetupFingerprintEnrollIntroductionTest { public void setUp() { MockitoAnnotations.initMocks(this); RuntimeEnvironment.getRobolectricPackageManager() .setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true); ShadowFingerprintManager.addToServiceMap(); final Intent intent = new Intent(); mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent); ShadowUserManager.getShadow().setUserInfo(0, mUserInfo); } @After public void tearDown() { ShadowStorageManagerWrapper.reset(); ShadowFingerprintManager.reset(); } @Test public void testKeyguardNotSecure_shouldFinishWithSetupSkipDialogResultSkip() { getShadowKeyguardManager().setIsKeyguardSecure(false); Loading Loading @@ -188,8 +210,41 @@ public class SetupFingerprintEnrollIntroductionTest { assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull(); } @Test public void testLockPattern() { ShadowStorageManagerWrapper.sIsFileEncrypted = false; mController.create().postCreate(null).resume(); SetupFingerprintEnrollIntroduction activity = mController.get(); final Button nextButton = activity.findViewById(R.id.fingerprint_next_button); nextButton.performClick(); ShadowActivity shadowActivity = Shadows.shadowOf(activity); IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult(); assertThat(startedActivity).isNotNull(); assertThat(startedActivity.intent.hasExtra( SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isFalse(); } private ShadowKeyguardManager getShadowKeyguardManager() { return Shadows.shadowOf(application.getSystemService(KeyguardManager.class)); } @Implements(StorageManagerWrapper.class) public static class ShadowStorageManagerWrapper { private static boolean sIsFileEncrypted = true; public static void reset() { sIsFileEncrypted = true; } @Implementation public static boolean isFileEncryptedNativeOrEmulated() { return sIsFileEncrypted; } } }
tests/robotests/src/com/android/settings/testutils/shadow/ShadowFingerprintManager.java 0 → 100644 +102 −0 Original line number Diff line number Diff line /* * 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.testutils.shadow; import android.content.Context; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.support.annotation.NonNull; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; import org.robolectric.internal.ShadowExtractor; import org.robolectric.shadows.ShadowContextImpl; import org.robolectric.util.ReflectionHelpers; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.IntStream; @Implements(FingerprintManager.class) public class ShadowFingerprintManager { private static Map<String, String> getSystemServiceMap() { return ReflectionHelpers.getStaticField(ShadowContextImpl.class, "SYSTEM_SERVICE_MAP"); } /** * Call this in @Before of a test to add FingerprintManager to Robolectric's system service * map. Otherwise getSystemService(FINGERPRINT_SERVICE) will return null. */ public static void addToServiceMap() { getSystemServiceMap().put(Context.FINGERPRINT_SERVICE, FingerprintManager.class.getName()); } @Resetter public static void reset() { getSystemServiceMap().remove(Context.FINGERPRINT_SERVICE); } public boolean hardwareDetected = true; @NonNull private List<Fingerprint> mFingerprints = Collections.emptyList(); @Implementation public boolean isHardwareDetected() { return hardwareDetected; } @Implementation public boolean hasEnrolledFingerprints() { return !mFingerprints.isEmpty(); } @Implementation public List<Fingerprint> getEnrolledFingerprints() { return mFingerprints; } @Implementation public List<Fingerprint> getEnrolledFingerprints(int userId) { return mFingerprints; } public void setEnrolledFingerprints(Fingerprint... fingerprints) { mFingerprints = Arrays.asList(fingerprints); } public void setDefaultFingerprints(int num) { setEnrolledFingerprints( IntStream.range(0, num) .mapToObj(i -> new Fingerprint( "Fingerprint " + i, 0, /* groupId */ i, /* fingerId */ 0 /* deviceId */)) .toArray(Fingerprint[]::new)); } public static ShadowFingerprintManager get() { return (ShadowFingerprintManager) ShadowExtractor.extract( RuntimeEnvironment.application.getSystemService(FingerprintManager.class)); } }