Merge "Ignore lock type in ChooseLockGeneric in non-FBE"

This commit is contained in:
Maurice Lam
2018-10-09 01:02:25 +00:00
committed by Android (Google) Code Review
8 changed files with 116 additions and 93 deletions

View File

@@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; 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.ChooseLockGeneric.ChooseLockGenericFragment;
import com.android.settings.password.SetupChooseLockGeneric; import com.android.settings.password.SetupChooseLockGeneric;
import com.android.settings.password.SetupSkipDialog; import com.android.settings.password.SetupSkipDialog;
import com.android.settings.password.StorageManagerWrapper;
public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction { public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction {
private static final String KEY_LOCK_SCREEN_PRESENT = "wasLockScreenPresent"; private static final String KEY_LOCK_SCREEN_PRESENT = "wasLockScreenPresent";
@@ -59,7 +59,7 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
protected Intent getChooseLockIntent() { protected Intent getChooseLockIntent() {
Intent intent = new Intent(this, SetupChooseLockGeneric.class); Intent intent = new Intent(this, SetupChooseLockGeneric.class);
if (StorageManagerWrapper.isFileEncryptedNativeOrEmulated()) { if (StorageManager.isFileEncryptedNativeOrEmulated()) {
intent.putExtra( intent.putExtra(
LockPatternUtils.PASSWORD_TYPE_KEY, LockPatternUtils.PASSWORD_TYPE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);

View File

@@ -435,7 +435,14 @@ public class ChooseLockGeneric extends SettingsActivity {
@VisibleForTesting @VisibleForTesting
void updatePreferencesOrFinish(boolean isRecreatingActivity) { void updatePreferencesOrFinish(boolean isRecreatingActivity) {
Intent intent = getActivity().getIntent(); 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 (quality == -1) {
// If caller didn't specify password quality, show UI and allow the user to choose. // If caller didn't specify password quality, show UI and allow the user to choose.
quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1); quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);

View File

@@ -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();
}
}

View File

@@ -30,15 +30,13 @@ import android.widget.Button;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricEnrollIntroduction; 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.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
import com.android.settings.password.SetupSkipDialog; import com.android.settings.password.SetupSkipDialog;
import com.android.settings.password.StorageManagerWrapper;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowFingerprintManager; import com.android.settings.testutils.shadow.ShadowFingerprintManager;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils; 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.ShadowUserManager;
import org.junit.After; import org.junit.After;
@@ -51,8 +49,6 @@ import org.robolectric.Robolectric;
import org.robolectric.Shadows; import org.robolectric.Shadows;
import org.robolectric.android.controller.ActivityController; import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config; 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;
import org.robolectric.shadows.ShadowActivity.IntentForResult; import org.robolectric.shadows.ShadowActivity.IntentForResult;
import org.robolectric.shadows.ShadowKeyguardManager; import org.robolectric.shadows.ShadowKeyguardManager;
@@ -61,7 +57,7 @@ import org.robolectric.shadows.ShadowKeyguardManager;
@Config(shadows = { @Config(shadows = {
ShadowFingerprintManager.class, ShadowFingerprintManager.class,
ShadowLockPatternUtils.class, ShadowLockPatternUtils.class,
ShadowStorageManagerWrapper.class, ShadowStorageManager.class,
ShadowUserManager.class ShadowUserManager.class
}) })
public class SetupFingerprintEnrollIntroductionTest { public class SetupFingerprintEnrollIntroductionTest {
@@ -89,7 +85,7 @@ public class SetupFingerprintEnrollIntroductionTest {
@After @After
public void tearDown() { public void tearDown() {
ShadowStorageManagerWrapper.reset(); ShadowStorageManager.reset();
ShadowFingerprintManager.reset(); ShadowFingerprintManager.reset();
} }
@@ -209,7 +205,7 @@ public class SetupFingerprintEnrollIntroductionTest {
@Test @Test
public void testLockPattern() { public void testLockPattern() {
ShadowStorageManagerWrapper.sIsFileEncrypted = false; ShadowStorageManager.setIsFileEncryptedNativeOrEmulated(false);
mController.create().postCreate(null).resume(); mController.create().postCreate(null).resume();
@@ -228,19 +224,4 @@ public class SetupFingerprintEnrollIntroductionTest {
private ShadowKeyguardManager getShadowKeyguardManager() { private ShadowKeyguardManager getShadowKeyguardManager() {
return Shadows.shadowOf(application.getSystemService(KeyguardManager.class)); 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;
}
}
} }

View File

@@ -16,122 +16,170 @@
package com.android.settings.password; package com.android.settings.password;
import static org.mockito.ArgumentMatchers.any; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doNothing; import static org.robolectric.RuntimeEnvironment.application;
import static org.mockito.Mockito.mock; import static org.robolectric.Shadows.shadowOf;
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 android.app.Activity; import android.app.Activity;
import android.content.Context; import android.app.admin.DevicePolicyManager;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings.Global; import android.provider.Settings.Global;
import androidx.fragment.app.FragmentActivity; import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment; import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
import com.android.settings.search.SearchFeatureProvider; import com.android.settings.search.SearchFeatureProvider;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources; 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.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment; import org.robolectric.Robolectric;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class) @RunWith(SettingsRobolectricTestRunner.class)
@Config(
shadows = {
SettingsShadowResources.class,
SettingsShadowTheme.class,
ShadowLockPatternUtils.class,
ShadowStorageManager.class,
ShadowUserManager.class,
ShadowUtils.class
})
public class ChooseLockGenericTest { public class ChooseLockGenericTest {
private Context mContext;
private ChooseLockGenericFragment mFragment; private ChooseLockGenericFragment mFragment;
private FragmentActivity mActivity; private ChooseLockGeneric mActivity;
@Before @Before
public void setUp() { public void setUp() {
mContext = RuntimeEnvironment.application; Global.putInt(
mFragment = spy(new ChooseLockGenericFragment()); application.getContentResolver(),
mActivity = mock(FragmentActivity.class); Global.DEVICE_PROVISIONED, 1);
when(mFragment.getActivity()).thenReturn(mActivity); mFragment = new ChooseLockGenericFragment();
when(mFragment.getFragmentManager()).thenReturn(mock(FragmentManager.class));
doNothing().when(mFragment).startActivity(any(Intent.class));
} }
@After @After
public void tearDown() { public void tearDown() {
Global.putInt(RuntimeEnvironment.application.getContentResolver(), Global.putInt(
application.getContentResolver(),
Global.DEVICE_PROVISIONED, 1); Global.DEVICE_PROVISIONED, 1);
ShadowStorageManager.reset();
} }
@Test @Test
@Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
public void onCreate_deviceNotProvisioned_shouldFinishActivity() { public void onCreate_deviceNotProvisioned_shouldFinishActivity() {
Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0); Global.putInt(application.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
when(mActivity.getContentResolver()).thenReturn(mContext.getContentResolver());
when(mActivity.getTheme()).thenReturn(mContext.getTheme());
when(mFragment.getArguments()).thenReturn(Bundle.EMPTY);
mFragment.onCreate(Bundle.EMPTY); initActivity(null);
verify(mActivity).finish(); assertThat(mActivity.isFinishing()).isTrue();
} }
@Test @Test
public void onActivityResult_nullIntentData_shouldNotCrash() { public void onActivityResult_nullIntentData_shouldNotCrash() {
doNothing().when(mFragment).updatePreferencesOrFinish(anyBoolean()); initActivity(null);
mFragment.onActivityResult( mFragment.onActivityResult(
ChooseLockGenericFragment.CONFIRM_EXISTING_REQUEST, Activity.RESULT_OK, ChooseLockGenericFragment.CONFIRM_EXISTING_REQUEST, Activity.RESULT_OK,
null /* data */); null /* data */);
// no crash // 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 @Test
public void onActivityResult_requestcode0_shouldNotFinish() { public void onActivityResult_requestcode0_shouldNotFinish() {
initActivity(null);
mFragment.onActivityResult( mFragment.onActivityResult(
SearchFeatureProvider.REQUEST_CODE, Activity.RESULT_OK, null /* data */); SearchFeatureProvider.REQUEST_CODE, Activity.RESULT_OK, null /* data */);
verify(mFragment, never()).finish(); assertThat(mActivity.isFinishing()).isFalse();
} }
@Test @Test
public void onActivityResult_requestcode101_shouldFinish() { public void onActivityResult_requestcode101_shouldFinish() {
initActivity(null);
mFragment.onActivityResult( mFragment.onActivityResult(
ChooseLockGenericFragment.ENABLE_ENCRYPTION_REQUEST, Activity.RESULT_OK, ChooseLockGenericFragment.ENABLE_ENCRYPTION_REQUEST, Activity.RESULT_OK,
null /* data */); null /* data */);
verify(mFragment).finish(); assertThat(mActivity.isFinishing()).isTrue();
} }
@Test @Test
public void onActivityResult_requestcode102_shouldFinish() { public void onActivityResult_requestcode102_shouldFinish() {
initActivity(null);
mFragment.onActivityResult( mFragment.onActivityResult(
ChooseLockGenericFragment.CHOOSE_LOCK_REQUEST, Activity.RESULT_OK, null /* data */); ChooseLockGenericFragment.CHOOSE_LOCK_REQUEST, Activity.RESULT_OK, null /* data */);
verify(mFragment).finish(); assertThat(mActivity.isFinishing()).isTrue();
} }
@Test @Test
public void onActivityResult_requestcode103_shouldFinish() { public void onActivityResult_requestcode103_shouldFinish() {
initActivity(null);
mFragment.onActivityResult( mFragment.onActivityResult(
ChooseLockGenericFragment.CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST, ChooseLockGenericFragment.CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST,
BiometricEnrollBase.RESULT_FINISHED, null /* data */); BiometricEnrollBase.RESULT_FINISHED, null /* data */);
verify(mFragment).finish(); assertThat(mActivity.isFinishing()).isTrue();
} }
@Test @Test
public void onActivityResult_requestcode104_shouldFinish() { public void onActivityResult_requestcode104_shouldFinish() {
initActivity(null);
mFragment.onActivityResult( mFragment.onActivityResult(
ChooseLockGenericFragment.SKIP_FINGERPRINT_REQUEST, Activity.RESULT_OK, ChooseLockGenericFragment.SKIP_FINGERPRINT_REQUEST, Activity.RESULT_OK,
null /* data */); 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();
} }
} }

View File

@@ -99,6 +99,8 @@ public class SettingsRobolectricTestRunner extends RobolectricTestRunner {
Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.cardview_cardview-nodeps/android_common/aar/res")), 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, 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) { } catch (MalformedURLException e) {
throw new RuntimeException("SettingsRobolectricTestRunner failure", e); throw new RuntimeException("SettingsRobolectricTestRunner failure", e);
} }

View File

@@ -209,6 +209,10 @@ public class SettingsShadowResources extends ShadowResources {
node.setNodeValue("@style/FingerprintLayoutTheme"); node.setNodeValue("@style/FingerprintLayoutTheme");
} else if (attributeValue.startsWith("@*android:string")) { } else if (attributeValue.startsWith("@*android:string")) {
node.setNodeValue("PLACEHOLDER"); node.setNodeValue("PLACEHOLDER");
} else if (attributeValue.startsWith("@*android:dimen")) {
node.setNodeValue("321dp");
} else if (attributeValue.startsWith("@*android:drawable")) {
node.setNodeValue("");
} }
} }
} }

View File

@@ -30,6 +30,7 @@ public class ShadowStorageManager {
private static boolean sIsUnmountCalled; private static boolean sIsUnmountCalled;
private static boolean sIsForgetCalled; private static boolean sIsForgetCalled;
private static boolean sIsFileEncryptedNativeOrEmulated = true;
public static boolean isUnmountCalled() { public static boolean isUnmountCalled() {
return sIsUnmountCalled; return sIsUnmountCalled;
@@ -43,7 +44,7 @@ public class ShadowStorageManager {
public static void reset() { public static void reset() {
sIsUnmountCalled = false; sIsUnmountCalled = false;
sIsForgetCalled = false; sIsForgetCalled = false;
sIsFileEncryptedNativeOrEmulated = true;
} }
@Implementation @Implementation
@@ -71,6 +72,15 @@ public class ShadowStorageManager {
sIsForgetCalled = true; sIsForgetCalled = true;
} }
@Implementation
protected static boolean isFileEncryptedNativeOrEmulated() {
return sIsFileEncryptedNativeOrEmulated;
}
public static void setIsFileEncryptedNativeOrEmulated(boolean encrypted) {
sIsFileEncryptedNativeOrEmulated = encrypted;
}
private VolumeInfo createVolumeInfo(String volumeId) { private VolumeInfo createVolumeInfo(String volumeId) {
final DiskInfo disk = new DiskInfo("fakeid", 0); final DiskInfo disk = new DiskInfo("fakeid", 0);
return new VolumeInfo(volumeId, 0, disk, "guid"); return new VolumeInfo(volumeId, 0, disk, "guid");