diff --git a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java index 6ffc096ce41..08f5c7e061b 100644 --- a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java @@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager; import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; +import android.os.storage.StorageManager; import android.widget.Button; import android.widget.TextView; @@ -32,7 +33,6 @@ 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"; @@ -59,7 +59,7 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu protected Intent getChooseLockIntent() { Intent intent = new Intent(this, SetupChooseLockGeneric.class); - if (StorageManagerWrapper.isFileEncryptedNativeOrEmulated()) { + if (StorageManager.isFileEncryptedNativeOrEmulated()) { intent.putExtra( LockPatternUtils.PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java index df2d3cd32ab..7f04bde801f 100644 --- a/src/com/android/settings/password/ChooseLockGeneric.java +++ b/src/com/android/settings/password/ChooseLockGeneric.java @@ -435,7 +435,14 @@ public class ChooseLockGeneric extends SettingsActivity { @VisibleForTesting void updatePreferencesOrFinish(boolean isRecreatingActivity) { Intent intent = getActivity().getIntent(); - int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1); + int quality = -1; + if (StorageManager.isFileEncryptedNativeOrEmulated()) { + quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1); + } else { + // For non-file encrypted devices we need to show encryption interstitial, so always + // show the lock type picker and ignore PASSWORD_TYPE_KEY. + Log.i(TAG, "Ignoring PASSWORD_TYPE_KEY because device is not file encrypted"); + } if (quality == -1) { // If caller didn't specify password quality, show UI and allow the user to choose. quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1); diff --git a/src/com/android/settings/password/StorageManagerWrapper.java b/src/com/android/settings/password/StorageManagerWrapper.java deleted file mode 100644 index 5adfaf2e51c..00000000000 --- a/src/com/android/settings/password/StorageManagerWrapper.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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(); - } -} diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroductionTest.java index c85a56952e1..6689518e3a7 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroductionTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroductionTest.java @@ -30,15 +30,13 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollIntroduction; -import com.android.settings.biometrics.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.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowFingerprintManager; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; +import com.android.settings.testutils.shadow.ShadowStorageManager; import com.android.settings.testutils.shadow.ShadowUserManager; import org.junit.After; @@ -51,8 +49,6 @@ import org.robolectric.Robolectric; import org.robolectric.Shadows; import org.robolectric.android.controller.ActivityController; 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; @@ -61,7 +57,7 @@ import org.robolectric.shadows.ShadowKeyguardManager; @Config(shadows = { ShadowFingerprintManager.class, ShadowLockPatternUtils.class, - ShadowStorageManagerWrapper.class, + ShadowStorageManager.class, ShadowUserManager.class }) public class SetupFingerprintEnrollIntroductionTest { @@ -89,7 +85,7 @@ public class SetupFingerprintEnrollIntroductionTest { @After public void tearDown() { - ShadowStorageManagerWrapper.reset(); + ShadowStorageManager.reset(); ShadowFingerprintManager.reset(); } @@ -209,7 +205,7 @@ public class SetupFingerprintEnrollIntroductionTest { @Test public void testLockPattern() { - ShadowStorageManagerWrapper.sIsFileEncrypted = false; + ShadowStorageManager.setIsFileEncryptedNativeOrEmulated(false); mController.create().postCreate(null).resume(); @@ -228,19 +224,4 @@ public class SetupFingerprintEnrollIntroductionTest { 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; - } - } } diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java index 9eaf217a4f7..b2cd0439c93 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java @@ -16,122 +16,170 @@ package com.android.settings.password; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static com.google.common.truth.Truth.assertThat; + +import static org.robolectric.RuntimeEnvironment.application; +import static org.robolectric.Shadows.shadowOf; import android.app.Activity; -import android.content.Context; +import android.app.admin.DevicePolicyManager; import android.content.Intent; -import android.os.Bundle; import android.provider.Settings.Global; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; +import androidx.annotation.Nullable; +import com.android.internal.widget.LockPatternUtils; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment; import com.android.settings.search.SearchFeatureProvider; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.testutils.shadow.SettingsShadowResources.SettingsShadowTheme; +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 org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RuntimeEnvironment; +import org.robolectric.Robolectric; import org.robolectric.annotation.Config; @RunWith(SettingsRobolectricTestRunner.class) +@Config( + shadows = { + SettingsShadowResources.class, + SettingsShadowTheme.class, + ShadowLockPatternUtils.class, + ShadowStorageManager.class, + ShadowUserManager.class, + ShadowUtils.class + }) public class ChooseLockGenericTest { - private Context mContext; private ChooseLockGenericFragment mFragment; - private FragmentActivity mActivity; + private ChooseLockGeneric mActivity; @Before public void setUp() { - mContext = RuntimeEnvironment.application; - mFragment = spy(new ChooseLockGenericFragment()); - mActivity = mock(FragmentActivity.class); - when(mFragment.getActivity()).thenReturn(mActivity); - when(mFragment.getFragmentManager()).thenReturn(mock(FragmentManager.class)); - doNothing().when(mFragment).startActivity(any(Intent.class)); + Global.putInt( + application.getContentResolver(), + Global.DEVICE_PROVISIONED, 1); + mFragment = new ChooseLockGenericFragment(); } @After public void tearDown() { - Global.putInt(RuntimeEnvironment.application.getContentResolver(), + Global.putInt( + application.getContentResolver(), Global.DEVICE_PROVISIONED, 1); + ShadowStorageManager.reset(); } @Test - @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class) public void onCreate_deviceNotProvisioned_shouldFinishActivity() { - Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0); - when(mActivity.getContentResolver()).thenReturn(mContext.getContentResolver()); - when(mActivity.getTheme()).thenReturn(mContext.getTheme()); - when(mFragment.getArguments()).thenReturn(Bundle.EMPTY); + Global.putInt(application.getContentResolver(), Global.DEVICE_PROVISIONED, 0); - mFragment.onCreate(Bundle.EMPTY); - verify(mActivity).finish(); + initActivity(null); + assertThat(mActivity.isFinishing()).isTrue(); } @Test public void onActivityResult_nullIntentData_shouldNotCrash() { - doNothing().when(mFragment).updatePreferencesOrFinish(anyBoolean()); - + initActivity(null); mFragment.onActivityResult( ChooseLockGenericFragment.CONFIRM_EXISTING_REQUEST, Activity.RESULT_OK, null /* data */); // no crash } + @Test + public void updatePreferencesOrFinish_passwordTypeSetPin_shouldStartChooseLockPassword() { + Intent intent = new Intent().putExtra( + LockPatternUtils.PASSWORD_TYPE_KEY, + DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); + initActivity(intent); + + mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */); + + assertThat(shadowOf(mActivity).getNextStartedActivity()).isNotNull(); + } + + @Test + public void updatePreferencesOrFinish_passwordTypeSetPinNotFbe_shouldNotStartChooseLock() { + ShadowStorageManager.setIsFileEncryptedNativeOrEmulated(false); + Intent intent = new Intent().putExtra( + LockPatternUtils.PASSWORD_TYPE_KEY, + DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); + initActivity(intent); + + mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */); + + assertThat(shadowOf(mActivity).getNextStartedActivity()).isNull(); + } + @Test public void onActivityResult_requestcode0_shouldNotFinish() { + initActivity(null); + mFragment.onActivityResult( SearchFeatureProvider.REQUEST_CODE, Activity.RESULT_OK, null /* data */); - verify(mFragment, never()).finish(); + assertThat(mActivity.isFinishing()).isFalse(); } @Test public void onActivityResult_requestcode101_shouldFinish() { + initActivity(null); + mFragment.onActivityResult( ChooseLockGenericFragment.ENABLE_ENCRYPTION_REQUEST, Activity.RESULT_OK, null /* data */); - verify(mFragment).finish(); + assertThat(mActivity.isFinishing()).isTrue(); } @Test public void onActivityResult_requestcode102_shouldFinish() { + initActivity(null); + mFragment.onActivityResult( ChooseLockGenericFragment.CHOOSE_LOCK_REQUEST, Activity.RESULT_OK, null /* data */); - verify(mFragment).finish(); + assertThat(mActivity.isFinishing()).isTrue(); } @Test public void onActivityResult_requestcode103_shouldFinish() { + initActivity(null); + mFragment.onActivityResult( ChooseLockGenericFragment.CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST, BiometricEnrollBase.RESULT_FINISHED, null /* data */); - verify(mFragment).finish(); + assertThat(mActivity.isFinishing()).isTrue(); } @Test public void onActivityResult_requestcode104_shouldFinish() { + initActivity(null); + mFragment.onActivityResult( ChooseLockGenericFragment.SKIP_FINGERPRINT_REQUEST, Activity.RESULT_OK, null /* data */); - verify(mFragment).finish(); + assertThat(mActivity.isFinishing()).isTrue(); + } + + private void initActivity(@Nullable Intent intent) { + if (intent == null) { + intent = new Intent(); + } + intent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false); + mActivity = Robolectric.buildActivity(ChooseLockGeneric.InternalActivity.class, intent) + .setup().get(); + mActivity.getSupportFragmentManager().beginTransaction().add(mFragment, null).commitNow(); } } diff --git a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java index 9507f4e7b6f..49197e831c0 100644 --- a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java +++ b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java @@ -98,7 +98,9 @@ public class SettingsRobolectricTestRunner extends RobolectricTestRunner { paths.add(new ResourcePath(null, Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.cardview_cardview-nodeps/android_common/aar/res")), null)); paths.add(new ResourcePath(null, - Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.slice_slice-view-nodeps/android_common/aar/res")), null)); + Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.slice_slice-view-nodeps/android_common/aar/res")), null)); + paths.add(new ResourcePath(null, + Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.preference_preference-nodeps/android_common/aar/res")), null)); } catch (MalformedURLException e) { throw new RuntimeException("SettingsRobolectricTestRunner failure", e); } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java index 37b863574bc..a68c5d38bac 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java @@ -209,6 +209,10 @@ public class SettingsShadowResources extends ShadowResources { node.setNodeValue("@style/FingerprintLayoutTheme"); } else if (attributeValue.startsWith("@*android:string")) { node.setNodeValue("PLACEHOLDER"); + } else if (attributeValue.startsWith("@*android:dimen")) { + node.setNodeValue("321dp"); + } else if (attributeValue.startsWith("@*android:drawable")) { + node.setNodeValue(""); } } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowStorageManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowStorageManager.java index 4b60c1672ee..366dd915eb9 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowStorageManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowStorageManager.java @@ -30,6 +30,7 @@ public class ShadowStorageManager { private static boolean sIsUnmountCalled; private static boolean sIsForgetCalled; + private static boolean sIsFileEncryptedNativeOrEmulated = true; public static boolean isUnmountCalled() { return sIsUnmountCalled; @@ -43,7 +44,7 @@ public class ShadowStorageManager { public static void reset() { sIsUnmountCalled = false; sIsForgetCalled = false; - + sIsFileEncryptedNativeOrEmulated = true; } @Implementation @@ -71,6 +72,15 @@ public class ShadowStorageManager { sIsForgetCalled = true; } + @Implementation + protected static boolean isFileEncryptedNativeOrEmulated() { + return sIsFileEncryptedNativeOrEmulated; + } + + public static void setIsFileEncryptedNativeOrEmulated(boolean encrypted) { + sIsFileEncryptedNativeOrEmulated = encrypted; + } + private VolumeInfo createVolumeInfo(String volumeId) { final DiskInfo disk = new DiskInfo("fakeid", 0); return new VolumeInfo(volumeId, 0, disk, "guid");