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";
@Override
protected Intent getChooseLockIntent() {
- Intent intent = new Intent(this, SetupChooseLockGeneric.class)
- .putExtra(
- LockPatternUtils.PASSWORD_TYPE_KEY,
- DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
- intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true);
+ 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;
}
--- /dev/null
+/*
+ * 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();
+ }
+}
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;
sdk = TestConfig.SDK_VERSION,
shadows = {
ShadowEventLogWriter.class,
+ ShadowFingerprintManager.class,
ShadowLockPatternUtils.class,
+ ShadowStorageManagerWrapper.class,
ShadowUserManager.class
})
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);
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;
+ }
+ }
}
--- /dev/null
+/*
+ * 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));
+ }
+}