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

Commit 72d2aa2b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Update vis of face acquisition + err messages" into tm-d1-dev am: b87eac30 am: 7cb1c219

parents e79e146e 7cb1c219
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -614,6 +614,12 @@
         2 - Override the setting to never bypass keyguard -->
    <integer name="config_face_unlock_bypass_override">0</integer>

    <!-- Which face help messages to surface when fingerprint is also enrolled.
         Message ids correspond with the acquired ids in BiometricFaceConstants -->
    <integer-array name="config_face_help_msgs_when_fingerprint_enrolled">
        <!-- for example: <item>26</item> for FACE_ACQUIRED_MOUTH_COVERING_DETECTED -->
    </integer-array>

    <!-- Whether the communal service should be enabled -->
    <bool name="config_communalServiceEnabled">false</bool>

+0 −1
Original line number Diff line number Diff line
@@ -275,7 +275,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    HashMap<Integer, SimData> mSimDatas = new HashMap<>();
    HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();

    private int mRingMode;
    private int mPhoneState;
    private boolean mKeyguardIsVisible;
    private boolean mCredentialAttempted;
+46 −7
Original line number Diff line number Diff line
@@ -49,12 +49,14 @@ import android.hardware.biometrics.BiometricSourceType;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
@@ -92,6 +94,8 @@ import com.android.systemui.util.wakelock.WakeLock;

import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.HashSet;
import java.util.Set;

import javax.inject.Inject;

@@ -112,12 +116,12 @@ public class KeyguardIndicationController {

    private static final String TAG = "KeyguardIndication";
    private static final boolean DEBUG_CHARGING_SPEED = false;
    private static final boolean DEBUG = Build.IS_DEBUGGABLE;

    private static final int MSG_HIDE_TRANSIENT = 1;
    private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2;
    private static final int MSG_HIDE_BIOMETRIC_MESSAGE = 3;
    private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
    private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;

    private final Context mContext;
    private final BroadcastDispatcher mBroadcastDispatcher;
@@ -166,6 +170,7 @@ public class KeyguardIndicationController {
    private boolean mBatteryPresent = true;
    private long mChargingTimeRemaining;
    private String mMessageToShowOnScreenOn;
    private final Set<Integer> mCoExFaceHelpMsgIdsToShow;
    private boolean mInited;

    private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
@@ -234,6 +239,22 @@ public class KeyguardIndicationController {
        mScreenLifecycle = screenLifecycle;
        mScreenLifecycle.addObserver(mScreenObserver);

        mCoExFaceHelpMsgIdsToShow = new HashSet<>();
        final String msgsToShowOverride = Settings.Global.getString(mContext.getContentResolver(),
                "coex_face_help_msgs"); // TODO: remove after UX testing b/231733975
        if (msgsToShowOverride != null) {
            final String[] msgIds = msgsToShowOverride.split("\\|");
            for (String msgId : msgIds) {
                mCoExFaceHelpMsgIdsToShow.add(Integer.parseInt(msgId));
            }
        } else {
            int[] msgIds = context.getResources().getIntArray(
                    com.android.systemui.R.array.config_face_help_msgs_when_fingerprint_enrolled);
            for (int msgId : msgIds) {
                mCoExFaceHelpMsgIdsToShow.add(msgId);
            }
        }

        mHandler = new Handler(mainLooper) {
            @Override
            public void handleMessage(Message msg) {
@@ -924,6 +945,7 @@ public class KeyguardIndicationController {
                mTopIndicationView == null ? null : mTopIndicationView.getText()));
        pw.println("  computePowerIndication(): " + computePowerIndication());
        pw.println("  trustGrantedIndication: " + getTrustGrantedIndication());
        pw.println("    mCoExFaceHelpMsgIdsToShow=" + mCoExFaceHelpMsgIdsToShow);
        mRotateTextViewController.dump(pw, args);
    }

@@ -982,9 +1004,20 @@ public class KeyguardIndicationController {
                    .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
                return;
            }

            boolean showActionToUnlock =
                    msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
            if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
            if (biometricSourceType == BiometricSourceType.FACE
                    && !showActionToUnlock
                    && mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
                            KeyguardUpdateMonitor.getCurrentUser())
                    && !mCoExFaceHelpMsgIdsToShow.contains(msgId)) {
                if (DEBUG) {
                    Log.d(TAG, "skip showing msgId=" + msgId + " helpString=" + helpString
                            + ", due to co-ex logic");
                }
                return;
            } else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
                        mInitialTextColorState);
            } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
@@ -1001,14 +1034,20 @@ public class KeyguardIndicationController {
            if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
                return;
            }

            if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
                if (mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
                        KeyguardUpdateMonitor.getCurrentUser())) {
                    // no message if fingerprint is also enrolled
                    if (DEBUG) {
                        Log.d(TAG, "skip showing FACE_ERROR_TIMEOUT due to co-ex logic");
                    }
                    return;
                }

                // The face timeout message is not very actionable, let's ask the user to
                // manually retry.
                if (!mStatusBarKeyguardViewManager.isBouncerShowing()
                        && mKeyguardUpdateMonitor.isUdfpsEnrolled()
                        && mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
                    showFaceFailedTryFingerprintMsg(msgId, errString);
                } else if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
                if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
                    mStatusBarKeyguardViewManager.showBouncerMessage(
                            mContext.getResources().getString(R.string.keyguard_try_fingerprint),
                            mInitialTextColorState
+92 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@@ -59,6 +60,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.graphics.Color;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
@@ -106,6 +108,9 @@ import org.mockito.MockitoAnnotations;

import java.text.NumberFormat;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -577,6 +582,80 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
        verify(mStatusBarKeyguardViewManager).showBouncerMessage(eq(message), any());
    }

    @Test
    public void faceErrorTimeout_whenFingerprintEnrolled_doesNotShowMessage() {
        createController();
        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
                0)).thenReturn(true);
        String message = "A message";

        mController.setVisible(true);
        mController.getKeyguardCallback().onBiometricError(
                FaceManager.FACE_ERROR_TIMEOUT, message, BiometricSourceType.FACE);
        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
    }

    @Test
    public void doNotSendFaceHelpMessages_fingerprintEnrolled() {
        createController();

        // GIVEN fingerprint enrolled
        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
                0)).thenReturn(true);

        // WHEN help messages received
        final String helpString = "helpString";
        final int[] msgIds = new int[]{
                BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED,
                BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK
        };
        for (int msgId : msgIds) {
            mKeyguardUpdateMonitorCallback.onBiometricHelp(
                    msgId,  helpString + msgId, BiometricSourceType.FACE);
        }

        // THEN no messages shown
        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
    }

    @Test
    public void sendAllFaceHelpMessages_fingerprintNotEnrolled() {
        createController();

        // GIVEN fingerprint NOT enrolled
        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
                0)).thenReturn(false);

        // WHEN help messages received
        final Set<CharSequence> helpStrings = new HashSet<>();
        final String helpString = "helpString";
        final int[] msgIds = new int[]{
                BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED,
                BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
                BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK
        };
        for (int msgId : msgIds) {
            final String numberedHelpString = helpString + msgId;
            mKeyguardUpdateMonitorCallback.onBiometricHelp(
                    msgId,  numberedHelpString, BiometricSourceType.FACE);
            helpStrings.add(numberedHelpString);
        }

        // THEN message shown for each call
        verifyIndicationMessages(INDICATION_TYPE_BIOMETRIC_MESSAGE, helpStrings);
    }

    @Test
    public void updateMonitor_listenerUpdatesIndication() {
        createController();
@@ -850,6 +929,19 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
        mBroadcastReceiver.onReceive(mContext, new Intent());
    }

    private void verifyIndicationMessages(int type, Set<CharSequence> messages) {
        verify(mRotateTextViewController, times(messages.size())).updateIndication(eq(type),
                mKeyguardIndicationCaptor.capture(), anyBoolean());
        List<KeyguardIndication> kis = mKeyguardIndicationCaptor.getAllValues();

        for (KeyguardIndication ki : kis) {
            final CharSequence msg = ki.getMessage();
            assertTrue(messages.contains(msg)); // check message is shown
            messages.remove(msg);
        }
        assertThat(messages.size()).isEqualTo(0); // check that all messages accounted for (removed)
    }

    private void verifyIndicationMessage(int type, String message) {
        verify(mRotateTextViewController).updateIndication(eq(type),
                mKeyguardIndicationCaptor.capture(), anyBoolean());