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

Commit cdaf1091 authored by Milton Wu's avatar Milton Wu Committed by Automerger Merge Worker
Browse files

Merge "Launch Face Settings when device enrolled face" into tm-qpr-dev am:...

Merge "Launch Face Settings when device enrolled face" into tm-qpr-dev am: 1d68fbf0 am: 544feb90

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/21294281



Change-Id: I748aafeb257bfc6325f5e3a0ef724dbd0e36d697
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 40019f87 544feb90
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -185,7 +185,9 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
        mUserManager = getUserManager();
        updatePasswordQuality();

        if (!mConfirmingCredentials) {
        // Check isFinishing() because FaceEnrollIntroduction may finish self to launch
        // FaceSettings during onCreate()
        if (!mConfirmingCredentials && !isFinishing()) {
            if (!mHasPassword) {
                // No password registered, launch into enrollment wizard.
                mConfirmingCredentials = true;
+47 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.face.FaceManager;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
@@ -42,6 +43,7 @@ import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;

import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.BiometricEnrollIntroduction;
@@ -110,8 +112,26 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mFaceManager = getFaceManager();

        if (savedInstanceState == null
                && !WizardManagerHelper.isAnySetupWizard(getIntent())
                && !getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS_SUMMARY, false)
                && maxFacesEnrolled()) {
            // from tips && maxEnrolled
            Log.d(TAG, "launch face settings");
            launchFaceSettingsActivity();
            finish();
        }

        super.onCreate(savedInstanceState);

        // Wait super::onCreated() then return because SuperNotCalledExceptio will be thrown
        // if we don't wait for it.
        if (isFinishing()) {
            return;
        }

        // Apply extracted theme color to icons.
        final ImageView iconGlasses = findViewById(R.id.icon_glasses);
        final ImageView iconLooking = findViewById(R.id.icon_looking);
@@ -152,8 +172,6 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
            infoMessageRequireEyes.setText(getInfoMessageRequireEyes());
        }

        mFaceManager = getFaceManager();

        // This path is an entry point for SetNewPasswordController, e.g.
        // adb shell am start -a android.app.action.SET_NEW_PASSWORD
        if (mToken == null && BiometricUtils.containsGatekeeperPasswordHandle(getIntent())) {
@@ -191,6 +209,24 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
        Log.v(TAG, "cameraPrivacyEnabled : " + cameraPrivacyEnabled);
    }

    private void launchFaceSettingsActivity() {
        final Intent intent = new Intent(this, Settings.FaceSettingsInternalActivity.class);
        final byte[] token = getIntent().getByteArrayExtra(
                ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
        if (token != null) {
            intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
        }
        final int userId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId());
        if (userId != UserHandle.USER_NULL) {
            intent.putExtra(Intent.EXTRA_USER_ID, userId);
        }
        BiometricUtils.copyMultiBiometricExtras(getIntent(), intent);
        intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true);
        intent.putExtra(EXTRA_KEY_CHALLENGE, getIntent().getLongExtra(EXTRA_KEY_CHALLENGE, -1L));
        intent.putExtra(EXTRA_KEY_SENSOR_ID, getIntent().getIntExtra(EXTRA_KEY_SENSOR_ID, -1));
        startActivity(intent);
    }

    @VisibleForTesting
    @Nullable
    protected FaceManager getFaceManager() {
@@ -232,6 +268,15 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
    @Override
    protected void onStart() {
        super.onStart();
        listenFoldEventForPostureGuidance();
    }

    private void listenFoldEventForPostureGuidance() {
        if (maxFacesEnrolled()) {
            Log.d(TAG, "Device has enrolled face, do not show posture guidance");
            return;
        }

        if (getPostureGuidanceIntent() == null) {
            Log.d(TAG, "Device do not support posture guidance");
            return;
+99 −2
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ import androidx.test.core.app.ApplicationProvider;

import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -62,6 +64,7 @@ import com.android.settings.testutils.shadow.ShadowUtils;

import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupcompat.util.WizardManagerHelper;
import com.google.android.setupdesign.GlifLayout;
import com.google.android.setupdesign.view.BottomScrollView;

@@ -168,6 +171,7 @@ public class FaceEnrollIntroductionTest {
    @After
    public void tearDown() {
        ShadowUtils.reset();
        ShadowLockPatternUtils.reset();
    }

    private void setupActivity() {
@@ -315,7 +319,7 @@ public class FaceEnrollIntroductionTest {
    }

    @Test
    public void testFaceEnrollEducation_hasBottomScrollView() {
    public void testFaceEnrollIntroduction_hasBottomScrollView() {
        setupActivity();
        BottomScrollView scrollView = getGlifLayout(mActivity).findViewById(R.id.sud_scroll_view);

@@ -387,7 +391,7 @@ public class FaceEnrollIntroductionTest {
    }

    @Test
    public void testFaceEnrollEducation_onFoldedUpdated_folded() {
    public void testFaceEnrollIntroduction_onFoldedUpdated_folded() {
        final Configuration newConfig = new Configuration();
        newConfig.smallestScreenWidthDp = DENSITY_DEFAULT;
        setupActivityForPosture();
@@ -400,4 +404,97 @@ public class FaceEnrollIntroductionTest {

        assertThat(mSpyActivity.getDevicePostureState()).isEqualTo(DEVICE_POSTURE_CLOSED);
    }

    @Test
    public void testFaceEnrollIntroduction_maxFacesEnrolled_launchFaceSettings() {
        setFaceManagerToHave(1 /* numEnrollments */);
        final Intent intent = new Intent();
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
        mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent);
        mActivity = (TestFaceEnrollIntroduction) mController.get();
        mActivity.mOverrideFaceManager = mFaceManager;

        mController.create();

        ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
        final Intent nextStartedActivity = shadowActivity.getNextStartedActivity();
        assertThat(nextStartedActivity).isNotNull();
        assertThat(nextStartedActivity.getComponent().getClassName())
                .isEqualTo(Settings.FaceSettingsInternalActivity.class.getName());
    }

    @Test
    public void testFaceEnrollIntroduction_maxFacesEnrolled_isSuw_notLaunchFaceSettings() {
        setFaceManagerToHave(1 /* numEnrollments */);
        ShadowLockPatternUtils.setActivePasswordQuality(PASSWORD_QUALITY_NUMERIC);
        final Intent intent = new Intent();
        intent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
        mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent);
        mActivity = (TestFaceEnrollIntroduction) mController.get();
        mActivity.mOverrideFaceManager = mFaceManager;

        mController.create();

        ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
        final Intent nextStartedActivity = shadowActivity.getNextStartedActivity();
        assertThat(nextStartedActivity).isNull();
    }

    @Test
    public void testFaceEnrollIntroduction_maxFacesEnrolled_fromSettings_notLaunchFaceSettings() {
        setFaceManagerToHave(1 /* numEnrollments */);
        ShadowLockPatternUtils.setActivePasswordQuality(PASSWORD_QUALITY_NUMERIC);
        final Intent intent = new Intent();
        intent.putExtra(BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY, true);
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
        mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent);
        mActivity = (TestFaceEnrollIntroduction) mController.get();
        mActivity.mOverrideFaceManager = mFaceManager;

        mController.create();

        ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
        final Intent nextStartedActivity = shadowActivity.getNextStartedActivity();
        assertThat(nextStartedActivity).isNull();
    }

    @Test
    public void testFaceEnrollIntroduction_hasPostureCallback() {
        when(mFakeFeatureFactory.mFaceFeatureProvider.getPostureGuidanceIntent(any()))
                .thenReturn(new Intent());
        setFaceManagerToHave(0 /* numEnrollments */);
        ShadowLockPatternUtils.setActivePasswordQuality(PASSWORD_QUALITY_NUMERIC);
        final Intent intent = new Intent();
        intent.putExtra(BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY, true);
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
        mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent);
        mActivity = (TestFaceEnrollIntroduction) mController.get();
        mActivity.mOverrideFaceManager = mFaceManager;

        mController.create();
        mController.start();

        assertThat(mActivity.getPostureCallback()).isNotNull();
    }

    @Test
    public void testFaceEnrollIntroduction_maxFacesEnrolled_noPostureCallback() {
        when(mFakeFeatureFactory.mFaceFeatureProvider.getPostureGuidanceIntent(any()))
                .thenReturn(new Intent());
        setFaceManagerToHave(1 /* numEnrollments */);
        ShadowLockPatternUtils.setActivePasswordQuality(PASSWORD_QUALITY_NUMERIC);
        final Intent intent = new Intent();
        intent.putExtra(BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY, true);
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
        mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent);
        mActivity = (TestFaceEnrollIntroduction) mController.get();
        mActivity.mOverrideFaceManager = mFaceManager;

        mController.create();
        mController.start();

        assertThat(mActivity.getPostureCallback()).isNull();
    }

}
+11 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import java.util.Map;
public class ShadowLockPatternUtils {

    private static boolean sDeviceEncryptionEnabled;
    private static Map<Integer, Integer> sUserToActivePasswordQualityMap = new HashMap<>();
    private static Map<Integer, Integer> sUserToComplexityMap = new HashMap<>();
    private static Map<Integer, Integer> sUserToProfileComplexityMap = new HashMap<>();
    private static Map<Integer, PasswordMetrics> sUserToMetricsMap = new HashMap<>();
@@ -54,6 +55,7 @@ public class ShadowLockPatternUtils {

    @Resetter
    public static void reset() {
        sUserToActivePasswordQualityMap.clear();
        sUserToComplexityMap.clear();
        sUserToProfileComplexityMap.clear();
        sUserToMetricsMap.clear();
@@ -87,8 +89,12 @@ public class ShadowLockPatternUtils {

    @Implementation
    protected int getActivePasswordQuality(int userId) {
        final Integer activePasswordQuality = sUserToActivePasswordQualityMap.get(userId);
        if (activePasswordQuality == null) {
            return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
        }
        return activePasswordQuality;
    }

    @Implementation
    protected int getKeyguardStoredPasswordQuality(int userHandle) {
@@ -227,6 +233,10 @@ public class ShadowLockPatternUtils {
        sUserToProfileMetricsMap.put(UserHandle.myUserId(), metrics);
    }

    public static void setActivePasswordQuality(int quality) {
        sUserToActivePasswordQualityMap.put(UserHandle.myUserId(), quality);
    }

    @Implementation
    public boolean isLockScreenDisabled(int userId) {
        return false;