Merge "Update vis of face acquisition + err messages" into tm-d1-dev am: b87eac3000
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18437709 Change-Id: I3a2b866b5e8c0c97ff14da1de2bbf85de732accd Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -614,6 +614,12 @@
|
|||||||
2 - Override the setting to never bypass keyguard -->
|
2 - Override the setting to never bypass keyguard -->
|
||||||
<integer name="config_face_unlock_bypass_override">0</integer>
|
<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 -->
|
<!-- Whether the communal service should be enabled -->
|
||||||
<bool name="config_communalServiceEnabled">false</bool>
|
<bool name="config_communalServiceEnabled">false</bool>
|
||||||
|
|
||||||
|
|||||||
@@ -275,7 +275,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
HashMap<Integer, SimData> mSimDatas = new HashMap<>();
|
HashMap<Integer, SimData> mSimDatas = new HashMap<>();
|
||||||
HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
|
HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
|
||||||
|
|
||||||
private int mRingMode;
|
|
||||||
private int mPhoneState;
|
private int mPhoneState;
|
||||||
private boolean mKeyguardIsVisible;
|
private boolean mKeyguardIsVisible;
|
||||||
private boolean mCredentialAttempted;
|
private boolean mCredentialAttempted;
|
||||||
|
|||||||
@@ -49,12 +49,14 @@ import android.hardware.biometrics.BiometricSourceType;
|
|||||||
import android.hardware.face.FaceManager;
|
import android.hardware.face.FaceManager;
|
||||||
import android.hardware.fingerprint.FingerprintManager;
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.Formatter;
|
import android.text.format.Formatter;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -92,6 +94,8 @@ import com.android.systemui.util.wakelock.WakeLock;
|
|||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -112,12 +116,12 @@ public class KeyguardIndicationController {
|
|||||||
|
|
||||||
private static final String TAG = "KeyguardIndication";
|
private static final String TAG = "KeyguardIndication";
|
||||||
private static final boolean DEBUG_CHARGING_SPEED = false;
|
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_HIDE_TRANSIENT = 1;
|
||||||
private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2;
|
private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2;
|
||||||
private static final int MSG_HIDE_BIOMETRIC_MESSAGE = 3;
|
private static final int MSG_HIDE_BIOMETRIC_MESSAGE = 3;
|
||||||
private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
|
private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
|
||||||
private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final BroadcastDispatcher mBroadcastDispatcher;
|
private final BroadcastDispatcher mBroadcastDispatcher;
|
||||||
@@ -166,6 +170,7 @@ public class KeyguardIndicationController {
|
|||||||
private boolean mBatteryPresent = true;
|
private boolean mBatteryPresent = true;
|
||||||
private long mChargingTimeRemaining;
|
private long mChargingTimeRemaining;
|
||||||
private String mMessageToShowOnScreenOn;
|
private String mMessageToShowOnScreenOn;
|
||||||
|
private final Set<Integer> mCoExFaceHelpMsgIdsToShow;
|
||||||
private boolean mInited;
|
private boolean mInited;
|
||||||
|
|
||||||
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
|
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
|
||||||
@@ -234,6 +239,22 @@ public class KeyguardIndicationController {
|
|||||||
mScreenLifecycle = screenLifecycle;
|
mScreenLifecycle = screenLifecycle;
|
||||||
mScreenLifecycle.addObserver(mScreenObserver);
|
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) {
|
mHandler = new Handler(mainLooper) {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
@@ -924,6 +945,7 @@ public class KeyguardIndicationController {
|
|||||||
mTopIndicationView == null ? null : mTopIndicationView.getText()));
|
mTopIndicationView == null ? null : mTopIndicationView.getText()));
|
||||||
pw.println(" computePowerIndication(): " + computePowerIndication());
|
pw.println(" computePowerIndication(): " + computePowerIndication());
|
||||||
pw.println(" trustGrantedIndication: " + getTrustGrantedIndication());
|
pw.println(" trustGrantedIndication: " + getTrustGrantedIndication());
|
||||||
|
pw.println(" mCoExFaceHelpMsgIdsToShow=" + mCoExFaceHelpMsgIdsToShow);
|
||||||
mRotateTextViewController.dump(pw, args);
|
mRotateTextViewController.dump(pw, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,9 +1004,20 @@ public class KeyguardIndicationController {
|
|||||||
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
|
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean showActionToUnlock =
|
boolean showActionToUnlock =
|
||||||
msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
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,
|
mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
|
||||||
mInitialTextColorState);
|
mInitialTextColorState);
|
||||||
} else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
|
} else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
|
||||||
@@ -1001,14 +1034,20 @@ public class KeyguardIndicationController {
|
|||||||
if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
|
if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
|
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
|
// The face timeout message is not very actionable, let's ask the user to
|
||||||
// manually retry.
|
// manually retry.
|
||||||
if (!mStatusBarKeyguardViewManager.isBouncerShowing()
|
if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
|
||||||
&& mKeyguardUpdateMonitor.isUdfpsEnrolled()
|
|
||||||
&& mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
|
|
||||||
showFaceFailedTryFingerprintMsg(msgId, errString);
|
|
||||||
} else if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
|
|
||||||
mStatusBarKeyguardViewManager.showBouncerMessage(
|
mStatusBarKeyguardViewManager.showBouncerMessage(
|
||||||
mContext.getResources().getString(R.string.keyguard_try_fingerprint),
|
mContext.getResources().getString(R.string.keyguard_try_fingerprint),
|
||||||
mInitialTextColorState
|
mInitialTextColorState
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import static org.mockito.Mockito.clearInvocations;
|
|||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.reset;
|
import static org.mockito.Mockito.reset;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.hardware.biometrics.BiometricFaceConstants;
|
||||||
import android.hardware.biometrics.BiometricSourceType;
|
import android.hardware.biometrics.BiometricSourceType;
|
||||||
import android.hardware.face.FaceManager;
|
import android.hardware.face.FaceManager;
|
||||||
import android.hardware.fingerprint.FingerprintManager;
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
@@ -106,6 +108,9 @@ import org.mockito.MockitoAnnotations;
|
|||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@@ -577,6 +582,80 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
verify(mStatusBarKeyguardViewManager).showBouncerMessage(eq(message), any());
|
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
|
@Test
|
||||||
public void updateMonitor_listenerUpdatesIndication() {
|
public void updateMonitor_listenerUpdatesIndication() {
|
||||||
createController();
|
createController();
|
||||||
@@ -850,6 +929,19 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
mBroadcastReceiver.onReceive(mContext, new Intent());
|
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) {
|
private void verifyIndicationMessage(int type, String message) {
|
||||||
verify(mRotateTextViewController).updateIndication(eq(type),
|
verify(mRotateTextViewController).updateIndication(eq(type),
|
||||||
mKeyguardIndicationCaptor.capture(), anyBoolean());
|
mKeyguardIndicationCaptor.capture(), anyBoolean());
|
||||||
|
|||||||
Reference in New Issue
Block a user