Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d3b07f6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Customize ChooseLockGeneric SUW options" into udc-dev

parents 019e8ceb 53c0c2f4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -746,6 +746,8 @@
    <!-- Fingerprint enrollment and settings --><skip />
    <!-- Note: Update FingerprintEnrollParentalConsent.CONSENT_STRING_RESOURCES when any _consent_ strings are added or removed. -->
    <!-- Title shown for choose lock options [CHAR LIMIT=22] -->
    <string name="security_settings_fingerprint">Fingerprint</string>
    <!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
    <string name="security_settings_fingerprint_preference_title">Fingerprint</string>
    <!-- Title for a category shown for the fingerprint settings page, followed by items that the user can toggle on/off to require/disable. [CHAR LIMIT=50] -->
+41 −3
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.service.persistentdata.PersistentDataBlockManager;
import android.text.BidiFormatter;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
@@ -56,6 +58,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
@@ -76,6 +79,7 @@ import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.safetycenter.LockScreenSafetySource;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settingslib.RestrictedPreference;
@@ -139,6 +143,9 @@ public class ChooseLockGeneric extends SettingsActivity {
         */
        public static final String EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS = "choose_lock_generic_extras";

        /** The character ' • ' to separate the setup choose options */
        public static final String SEPARATOR = " \u2022 ";

        @VisibleForTesting
        static final int CONFIRM_EXISTING_REQUEST = 100;
        @VisibleForTesting
@@ -628,10 +635,11 @@ public class ChooseLockGeneric extends SettingsActivity {
                        R.string.face_unlock_set_unlock_password);
            } else if (mForBiometrics) {
                setPreferenceTitle(ScreenLockType.PATTERN,
                        R.string.biometrics_unlock_set_unlock_pattern);
                setPreferenceTitle(ScreenLockType.PIN, R.string.biometrics_unlock_set_unlock_pin);
                        getBiometricsPreferenceTitle(ScreenLockType.PATTERN));
                setPreferenceTitle(ScreenLockType.PIN,
                        getBiometricsPreferenceTitle(ScreenLockType.PIN));
                setPreferenceTitle(ScreenLockType.PASSWORD,
                        R.string.biometrics_unlock_set_unlock_password);
                        getBiometricsPreferenceTitle(ScreenLockType.PASSWORD));
            }

            if (mManagedPasswordProvider.isSettingManagedPasswordSupported()) {
@@ -652,6 +660,36 @@ public class ChooseLockGeneric extends SettingsActivity {
            }
        }

        @VisibleForTesting
        String getBiometricsPreferenceTitle(@NonNull ScreenLockType secureType) {
            SpannableStringBuilder ssb = new SpannableStringBuilder();
            BidiFormatter bidi = BidiFormatter.getInstance();
            // Assume the flow is "Screen Lock" + "Face" + "Fingerprint"
            if (mController != null) {
                ssb.append(bidi.unicodeWrap(mController.getTitle(secureType)));
            } else {
                Log.e(TAG, "ChooseLockGenericController is null!");
            }

            if (mFaceManager != null && mFaceManager.isHardwareDetected() && isFaceSupported()) {
                ssb.append(bidi.unicodeWrap(SEPARATOR));
                ssb.append(bidi.unicodeWrap(
                        getResources().getString(R.string.keywords_face_settings)));
            }
            if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
                ssb.append(bidi.unicodeWrap(SEPARATOR));
                ssb.append(bidi.unicodeWrap(
                        getResources().getString(R.string.security_settings_fingerprint)));
            }
            return ssb.toString();
        }

        private boolean isFaceSupported() {
            return FeatureFactory.getFactory(getContext().getApplicationContext())
                    .getFaceFeatureProvider()
                    .isSetupWizardSupported(getContext().getApplicationContext());
        }

        private void setPreferenceTitle(ScreenLockType lock, @StringRes int title) {
            Preference preference = findPreference(lock.preferenceKey);
            if (preference != null) {
+65 −1
Original line number Diff line number Diff line
@@ -29,11 +29,14 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.KEY_LOCK_SETTINGS_FOOTER;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.Shadows.shadowOf;

@@ -43,6 +46,8 @@ import android.app.admin.PasswordMetrics;
import android.app.admin.PasswordPolicy;
import android.content.Context;
import android.content.Intent;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.provider.Settings.Global;

@@ -55,6 +60,7 @@ import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowStorageManager;
@@ -65,8 +71,12 @@ import com.android.settingslib.widget.FooterPreference;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@@ -86,13 +96,33 @@ import org.robolectric.shadows.ShadowPersistentDataBlockManager;
@Ignore("b/179136903: Tests failed with collapsing toolbar, plan to figure out root cause later.")
public class ChooseLockGenericTest {

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
    private FakeFeatureFactory mFakeFeatureFactory;
    private ChooseLockGenericFragment mFragment;
    private ChooseLockGeneric mActivity;
    @Mock
    private FingerprintManager mFingerprintManager;
    @Mock
    private FaceManager mFaceManager;

    @Before
    public void setUp() {
        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
        mActivity = Robolectric.buildActivity(ChooseLockGeneric.class)
                .create()
                .start()
                .postCreate(null)
                .resume()
                .get();

        Global.putInt(application.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
        mFragment = new ChooseLockGenericFragment();

        when(mFaceManager.isHardwareDetected()).thenReturn(true);
        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
        when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
                false);
    }

    @After
@@ -490,13 +520,47 @@ public class ChooseLockGenericTest {
                        new PasswordMetrics(CREDENTIAL_TYPE_NONE));
    }

    @Test
    public void updatePreferenceText_supportBiometrics_showFaceAndFingerprint() {
        ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
        final PasswordPolicy policy = new PasswordPolicy();
        policy.quality = PASSWORD_QUALITY_ALPHABETIC;
        ShadowLockPatternUtils.setRequestedProfilePasswordMetrics(policy.getMinMetrics());

        final Intent intent = new Intent().putExtra(EXTRA_KEY_FOR_BIOMETRICS, true);
        initActivity(intent);

        final Intent passwordIntent = mFragment.getLockPatternIntent();
        assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
                PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_LOW);

        final String supportFingerprint = mActivity.getResources().getString(
                R.string.security_settings_fingerprint);
        final String supportFace = mActivity.getResources().getString(
                R.string.keywords_face_settings);

        assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
                supportFingerprint);
        assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
                supportFace);
        assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
                supportFingerprint);
        assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
                supportFace);
        assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
                supportFingerprint);
        assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
                supportFace);
    }

    private void initActivity(@Nullable Intent intent) {
        if (intent == null) {
            intent = new Intent();
        }
        intent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false);
        // TODO(b/275023433) This presents the activity from being made 'visible` is workaround
        mActivity = Robolectric.buildActivity(ChooseLockGeneric.InternalActivity.class, intent)
                .setup().get();
                .create().start().postCreate(null).resume().get();
        mActivity.getSupportFragmentManager().beginTransaction().add(mFragment, null).commitNow();
    }
}
+115 −1
Original line number Diff line number Diff line
@@ -23,13 +23,22 @@ import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_R

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;

import android.content.Intent;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.provider.Settings;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import com.android.settings.R;
import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -38,8 +47,13 @@ import com.android.settings.testutils.shadow.ShadowUtils;
import com.google.android.setupdesign.GlifPreferenceLayout;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
@@ -56,6 +70,28 @@ import java.util.List;
})
public class SetupChooseLockGenericTest {

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
    @Mock
    private FakeFeatureFactory mFakeFeatureFactory;
    @Mock
    private FingerprintManager mFingerprintManager;
    @Mock
    private FaceManager mFaceManager;

    @Before
    public void setUp() {
        ShadowUtils.setFingerprintManager(mFingerprintManager);
        ShadowUtils.setFaceManager(mFaceManager);
        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();

        Settings.Global.putInt(application.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,
                0);

        when(mFaceManager.isHardwareDetected()).thenReturn(true);
        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
    }

    @After
    public void tearDown() {
        ShadowPasswordUtils.reset();
@@ -102,13 +138,91 @@ public class SetupChooseLockGenericTest {
        assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText());
    }

    @Test
    public void updatePreferenceTextShowScreenLockAndFingerprint() {
        when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
                false);
        SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);

        final String supportFingerprint = fragment.getResources().getString(
                R.string.security_settings_fingerprint);
        final String supportFace = fragment.getResources().getString(
                R.string.keywords_face_settings);

        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).doesNotContain(
                supportFace);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).doesNotContain(
                supportFace);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).doesNotContain(
                supportFace);
    }

    @Test
    public void updatePreferenceTextShowScreenLockAndShowFaceAndShowFingerprint() {
        when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
                true);
        SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);

        final String supportFingerprint = fragment.getResources().getString(
                R.string.security_settings_fingerprint);
        final String supportFace = fragment.getResources().getString(
                R.string.keywords_face_settings);

        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
                supportFace);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
                supportFace);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
                supportFace);
    }

    @Test
    public void updatePreferenceTextShowScreenLockAndShowFingerprint() {
        when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
                false);
        SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);

        final String supportFingerprint = fragment.getResources().getString(
                R.string.security_settings_fingerprint);
        final String supportFace = fragment.getResources().getString(
                R.string.keywords_face_settings);

        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).doesNotContain(
                supportFace);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).doesNotContain(
                supportFace);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
                supportFingerprint);
        assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).doesNotContain(
                supportFace);
    }

    private SetupChooseLockGenericFragment getFragmentOfSetupChooseLockGeneric(boolean biometric) {
        ShadowPasswordUtils.addGrantedPermission(REQUEST_PASSWORD_COMPLEXITY);
        Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN");
        intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, biometric);
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, biometric);
        // TODO(b/275023433) This presents the activity from being made 'visible` is workaround
        SetupChooseLockGeneric activity =
                Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).setup().get();
                Robolectric.buildActivity(SetupChooseLockGeneric.class,
                        intent).create().start().postCreate(null).resume().get();

        List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
        assertThat(fragments).isNotNull();