diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java index 54775f84a9e..2e9440412ec 100644 --- a/src/com/android/settings/biometrics/face/FaceSettings.java +++ b/src/com/android/settings/biometrics/face/FaceSettings.java @@ -237,6 +237,8 @@ public class FaceSettings extends DashboardFragment { public void onStart() { super.onStart(); final boolean hasEnrolled = mFaceManager.hasEnrolledTemplates(mUserId); + mEnrollButton.setVisible(!hasEnrolled); + mRemoveButton.setVisible(hasEnrolled); // When the user has face id registered but failed enrolling in device lock state, // lead users directly to the confirm deletion dialog in Face Unlock settings. diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java index fb3319c3ff6..9a4d63204e2 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java @@ -169,7 +169,8 @@ public class FingerprintSettings extends SubSettings { private static final String KEY_LAUNCHED_CONFIRM = "launched_confirm"; private static final String KEY_HAS_FIRST_ENROLLED = "has_first_enrolled"; private static final String KEY_IS_ENROLLING = "is_enrolled"; - private static final String KEY_REQUIRE_SCREEN_ON_TO_AUTH = + @VisibleForTesting + static final String KEY_REQUIRE_SCREEN_ON_TO_AUTH = "security_settings_require_screen_on_to_auth"; private static final String KEY_FINGERPRINTS_ENROLLED_CATEGORY = "security_settings_fingerprints_enrolled"; @@ -536,10 +537,6 @@ public class FingerprintSettings extends SubSettings { private void addFingerprintPreferences(PreferenceGroup root) { final String fpPrefKey = addFingerprintItemPreferences(root); - if (isSfps()) { - scrollToPreference(fpPrefKey); - addFingerprintUnlockCategory(); - } for (AbstractPreferenceController controller : mControllers) { if (controller instanceof FingerprintSettingsPreferenceController) { ((FingerprintSettingsPreferenceController) controller).setUserId(mUserId); @@ -547,6 +544,14 @@ public class FingerprintSettings extends SubSettings { ((FingerprintUnlockCategoryController) controller).setUserId(mUserId); } } + + // This needs to be after setting ids, otherwise + // |mRequireScreenOnToAuthPreferenceController.isChecked| is always checking the primary + // user instead of the user with |mUserId|. + if (isSfps()) { + scrollToPreference(fpPrefKey); + addFingerprintUnlockCategory(); + } createFooterPreference(root); } diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java index dc36220afef..a2fd986dd0b 100644 --- a/src/com/android/settings/password/ChooseLockPattern.java +++ b/src/com/android/settings/password/ChooseLockPattern.java @@ -442,7 +442,8 @@ public class ChooseLockPattern extends SettingsActivity { protected boolean mForFace; protected boolean mForBiometrics; - private static final String KEY_UI_STAGE = "uiStage"; + @VisibleForTesting + static final String KEY_UI_STAGE = "uiStage"; private static final String KEY_PATTERN_CHOICE = "chosenPattern"; private static final String KEY_CURRENT_PATTERN = "currentPattern"; @@ -718,10 +719,6 @@ public class ChooseLockPattern extends SettingsActivity { final GlifLayout layout = getActivity().findViewById(R.id.setup_wizard_layout); mUiStage = stage; - if (stage == Stage.Introduction) { - layout.setDescriptionText(stage.headerMessage); - } - // header text, footer text, visibility and // enabled state all known from the stage if (stage == Stage.ChoiceTooShort) { @@ -744,16 +741,13 @@ public class ChooseLockPattern extends SettingsActivity { Theme theme = getActivity().getTheme(); theme.resolveAttribute(R.attr.colorError, typedValue, true); mHeaderText.setTextColor(typedValue.data); + } else if (mDefaultHeaderColorList != null) { + mHeaderText.setTextColor(mDefaultHeaderColorList); + } - } else { - if (mDefaultHeaderColorList != null) { - mHeaderText.setTextColor(mDefaultHeaderColorList); - } - if (stage == Stage.NeedToConfirm) { - mHeaderText.setText(stage.headerMessage); - layout.setHeaderText(R.string.lockpassword_draw_your_pattern_again_header); - } + if (stage == Stage.ConfirmWrong || stage == Stage.NeedToConfirm) { + layout.setHeaderText(R.string.lockpassword_draw_your_pattern_again_header); } updateFooterLeftButton(stage); diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java index 1998d56b1ca..8b70550f5a9 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java @@ -16,12 +16,14 @@ package com.android.settings.biometrics.fingerprint; +import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON; import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL; import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment; import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.ADD_FINGERPRINT_REQUEST; import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.CHOOSE_LOCK_GENERIC_REQUEST; import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.KEY_FINGERPRINT_ADD; +import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.KEY_REQUIRE_SCREEN_ON_TO_AUTH; import static com.google.common.truth.Truth.assertThat; @@ -39,12 +41,16 @@ import static org.mockito.Mockito.verify; import android.content.Context; import android.content.Intent; +import android.content.pm.UserInfo; import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.SensorProperties; import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Bundle; import android.os.CancellationSignal; +import android.os.UserHandle; +import android.provider.Settings; import android.view.LayoutInflater; import android.view.ViewGroup; @@ -62,6 +68,7 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settingslib.RestrictedSwitchPreference; import org.junit.After; import org.junit.Before; @@ -83,6 +90,9 @@ import java.util.ArrayList; @Config(shadows = {ShadowSettingsPreferenceFragment.class, ShadowUtils.class, ShadowFragment.class, ShadowUserManager.class, ShadowLockPatternUtils.class}) public class FingerprintSettingsFragmentTest { + private static final int PRIMARY_USER_ID = 0; + private static final int GUEST_USER_ID = 10; + private FingerprintSettingsFragment mFragment; private Context mContext; private FragmentActivity mActivity; @@ -106,9 +116,14 @@ public class FingerprintSettingsFragmentTest { @Before public void setUp() { - doReturn(true).when(mFingerprintManager).isHardwareDetected(); ShadowUtils.setFingerprintManager(mFingerprintManager); FakeFeatureFactory.setupForTest(); + + mContext = spy(ApplicationProvider.getApplicationContext()); + mFragment = spy(new FingerprintSettingsFragment()); + doReturn(mContext).when(mFragment).getContext(); + + doReturn(true).when(mFingerprintManager).isHardwareDetected(); } @After @@ -186,19 +201,43 @@ public class FingerprintSettingsFragmentTest { assertThat(mFingerprintAuthenticateSidecar.isCancelled()).isTrue(); } + @Test + public void testGuestUserRequireScreenOnToAuth() { + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED, + 0, + UserHandle.of(PRIMARY_USER_ID).getIdentifier()); + + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED, + 1, + UserHandle.of(GUEST_USER_ID).getIdentifier()); + + setUpFragment(false, GUEST_USER_ID, TYPE_POWER_BUTTON); + + final RestrictedSwitchPreference requireScreenOnToAuthPreference = mFragment.findPreference( + KEY_REQUIRE_SCREEN_ON_TO_AUTH); + assertThat(requireScreenOnToAuthPreference.isChecked()).isTrue(); + } + private void setUpFragment(boolean showChooseLock) { + setUpFragment(showChooseLock, PRIMARY_USER_ID, TYPE_UDFPS_OPTICAL); + } + + private void setUpFragment(boolean showChooseLock, int userId, + @FingerprintSensorProperties.SensorType int sensorType) { + ShadowUserManager.getShadow().addProfile(new UserInfo(userId, "", 0)); + Intent intent = new Intent(); if (!showChooseLock) { intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, 1L); } - + intent.putExtra(Intent.EXTRA_USER_ID, userId); mActivity = spy(Robolectric.buildActivity(FragmentActivity.class, intent).get()); - mContext = spy(ApplicationProvider.getApplicationContext()); - - mFragment = spy(new FingerprintSettingsFragment()); doReturn(mActivity).when(mFragment).getActivity(); - doReturn(mContext).when(mFragment).getContext(); FragmentManager fragmentManager = mock(FragmentManager.class); doReturn(mFragmentTransaction).when(fragmentManager).beginTransaction(); @@ -212,7 +251,7 @@ public class FingerprintSettingsFragmentTest { doNothing().when(mFragment).startActivityForResult(any(Intent.class), anyInt()); - setSensor(); + setSensor(sensorType); // Start fragment mFragment.onAttach(mContext); @@ -221,14 +260,14 @@ public class FingerprintSettingsFragmentTest { mFragment.onResume(); } - private void setSensor() { + private void setSensor(@FingerprintSensorProperties.SensorType int sensorType) { final ArrayList props = new ArrayList<>(); props.add(new FingerprintSensorPropertiesInternal( 0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 1 /* maxEnrollmentsPerUser */, new ArrayList(), - TYPE_UDFPS_OPTICAL, + sensorType, true /* resetLockoutRequiresHardwareAuthToken */)); doReturn(props).when(mFingerprintManager).getSensorPropertiesInternal(); } diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java index 442d021fd31..301a6db8ecd 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java @@ -18,12 +18,15 @@ package com.android.settings.password; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; +import static com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment.KEY_UI_STAGE; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.robolectric.RuntimeEnvironment.application; import android.content.Intent; +import android.os.Bundle; import android.os.UserHandle; import android.view.View; @@ -34,6 +37,8 @@ import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment import com.android.settings.password.ChooseLockPattern.IntentBuilder; import com.android.settings.testutils.shadow.ShadowUtils; +import com.google.android.setupdesign.GlifLayout; + import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -119,6 +124,21 @@ public class ChooseLockPatternTest { assertThat(flags & FLAG_SECURE).isEqualTo(FLAG_SECURE); } + @Test + public void headerText_stageConfirmWrong() { + ChooseLockPattern activity = createActivity(true); + ChooseLockPatternFragment fragment = (ChooseLockPatternFragment) + activity.getSupportFragmentManager().findFragmentById(R.id.main_content); + final GlifLayout layout = fragment.getView().findViewById(R.id.setup_wizard_layout); + Bundle savedInstanceState = new Bundle(); + savedInstanceState.putInt(KEY_UI_STAGE, + ChooseLockPatternFragment.Stage.ConfirmWrong.ordinal()); + + fragment.onViewCreated(layout, savedInstanceState); + assertThat(layout.getHeaderText().toString()).isEqualTo(activity.getResources().getString( + R.string.lockpassword_draw_your_pattern_again_header)); + } + private ChooseLockPattern createActivity(boolean addFingerprintExtra) { return Robolectric.buildActivity( ChooseLockPattern.class,