Update co-ex error logic

KeyguardIndication (bottom text area on LS)
- show transient messages for a minimum of 2000ms not including animation
time
- if dual auth is enrolled: only show face auth errors if the user
explicitly requested face auth

In general, don't request face auth on the global actions menu
(likely left over from when the power menu had affordances for
components requiring authentication)

Test: atest SystemUITest
Fixes: 186302245
Bug: 183698582
Change-Id: I0290c66addc9981bf3fe20de24110e2d35e1f8eb
This commit is contained in:
Beverly
2021-06-25 12:55:31 -04:00
committed by Beverly Tai
parent 328ba5dcb3
commit 4a057a1844
11 changed files with 71 additions and 20 deletions

View File

@@ -173,7 +173,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
@Override
public void onSwipeUp() {
if (!mUpdateMonitor.isFaceDetectionRunning()) {
mUpdateMonitor.requestFaceAuth();
mUpdateMonitor.requestFaceAuth(true);
mKeyguardSecurityCallback.userActivity();
showMessage(null, null);
}

View File

@@ -309,6 +309,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private RingerModeTracker mRingerModeTracker;
private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
private boolean mIsFaceAuthUserRequested;
private LockPatternUtils mLockPatternUtils;
private final IDreamManager mDreamManager;
private boolean mIsDreaming;
@@ -2057,12 +2058,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
/**
* Requests face authentication if we're on a state where it's allowed.
* This will re-trigger auth in case it fails.
* @param userInitiatedRequest true if the user explicitly requested face auth
*/
public void requestFaceAuth() {
if (DEBUG) Log.d(TAG, "requestFaceAuth()");
public void requestFaceAuth(boolean userInitiatedRequest) {
if (DEBUG) Log.d(TAG, "requestFaceAuth() userInitiated=" + userInitiatedRequest);
mIsFaceAuthUserRequested |= userInitiatedRequest;
updateFaceListeningState();
}
public boolean isFaceAuthUserRequested() {
return mIsFaceAuthUserRequested;
}
/**
* In case face auth is running, cancel it.
*/
@@ -2079,6 +2086,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mHandler.removeCallbacks(mRetryFaceAuthentication);
boolean shouldListenForFace = shouldListenForFace();
if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
mIsFaceAuthUserRequested = false;
stopListeningForFace();
} else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING && shouldListenForFace) {
startListeningForFace();

View File

@@ -30,7 +30,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.internal.R;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.Utils;
import com.android.systemui.plugins.GlobalActions;
import com.android.systemui.scrim.ScrimDrawable;
@@ -51,7 +50,6 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
private final KeyguardStateController mKeyguardStateController;
private final DeviceProvisionedController mDeviceProvisionedController;
private final BlurUtils mBlurUtils;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final CommandQueue mCommandQueue;
private GlobalActionsDialogLite mGlobalActionsDialog;
private boolean mDisabled;
@@ -60,15 +58,13 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
public GlobalActionsImpl(Context context, CommandQueue commandQueue,
Lazy<GlobalActionsDialogLite> globalActionsDialogLazy, BlurUtils blurUtils,
KeyguardStateController keyguardStateController,
DeviceProvisionedController deviceProvisionedController,
KeyguardUpdateMonitor keyguardUpdateMonitor) {
DeviceProvisionedController deviceProvisionedController) {
mContext = context;
mGlobalActionsDialogLazy = globalActionsDialogLazy;
mKeyguardStateController = keyguardStateController;
mDeviceProvisionedController = deviceProvisionedController;
mCommandQueue = commandQueue;
mBlurUtils = blurUtils;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mCommandQueue.addCallback(this);
}
@@ -87,7 +83,6 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
mGlobalActionsDialog = mGlobalActionsDialogLazy.get();
mGlobalActionsDialog.showOrHideDialog(mKeyguardStateController.isShowing(),
mDeviceProvisionedController.isDeviceProvisioned());
mKeyguardUpdateMonitor.requestFaceAuth();
}
@Override

View File

@@ -40,18 +40,22 @@ public class KeyguardIndication {
private final View.OnClickListener mOnClickListener;
@Nullable
private final Drawable mBackground;
@Nullable
private final Long mMinVisibilityMillis; // in milliseconds
private KeyguardIndication(
CharSequence message,
ColorStateList textColor,
Drawable icon,
View.OnClickListener onClickListener,
Drawable background) {
Drawable background,
Long minVisibilityMillis) {
mMessage = message;
mTextColor = textColor;
mIcon = icon;
mOnClickListener = onClickListener;
mBackground = background;
mMinVisibilityMillis = minVisibilityMillis;
}
/**
@@ -89,6 +93,14 @@ public class KeyguardIndication {
return mBackground;
}
/**
* Minimum time to show text in milliseconds.
* @return null if unspecified
*/
public @Nullable Long getMinVisibilityMillis() {
return mMinVisibilityMillis;
}
@Override
public String toString() {
String str = "KeyguardIndication{";
@@ -96,6 +108,7 @@ public class KeyguardIndication {
if (mIcon != null) str += " mIcon=" + mIcon;
if (mOnClickListener != null) str += " mOnClickListener=" + mOnClickListener;
if (mBackground != null) str += " mBackground=" + mBackground;
if (mMinVisibilityMillis != null) str += " mMinVisibilityMillis=" + mMinVisibilityMillis;
str += "}";
return str;
}
@@ -109,6 +122,7 @@ public class KeyguardIndication {
private View.OnClickListener mOnClickListener;
private ColorStateList mTextColor;
private Drawable mBackground;
private Long mMinVisibilityMillis;
public Builder() { }
@@ -154,6 +168,15 @@ public class KeyguardIndication {
return this;
}
/**
* Optional. Set a required minimum visibility time in milliseconds for the text
* to show.
*/
public Builder setMinVisibilityMillis(Long minVisibilityMillis) {
this.mMinVisibilityMillis = minVisibilityMillis;
return this;
}
/**
* Build the KeyguardIndication.
*/
@@ -166,7 +189,8 @@ public class KeyguardIndication {
}
return new KeyguardIndication(
mMessage, mTextColor, mIcon, mOnClickListener, mBackground);
mMessage, mTextColor, mIcon, mOnClickListener, mBackground,
mMinVisibilityMillis);
}
}
}

View File

@@ -167,12 +167,14 @@ public class KeyguardIndicationRotateTextViewController extends
* - can be presented with an "error" color if isError is true
*/
public void showTransient(CharSequence newIndication, boolean isError) {
final long inAnimationDuration = 600L; // see KeyguardIndicationTextView.getYInDuration
updateIndication(INDICATION_TYPE_TRANSIENT,
new KeyguardIndication.Builder()
.setMessage(newIndication)
.setTextColor(isError
? Utils.getColorError(getContext())
: mInitialTextColorState)
.setMinVisibilityMillis(2000L + inAnimationDuration)
.build(),
/* showImmediately */true);
}

View File

@@ -885,6 +885,11 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
return;
}
if (biometricSourceType == BiometricSourceType.FACE && shouldSuppressFaceMsg()) {
return;
}
boolean showSwipeToUnlock =
msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
@@ -912,7 +917,8 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
// The face timeout message is not very actionable, let's ask the user to
// manually retry.
if (!mStatusBarKeyguardViewManager.isBouncerShowing()
&& mKeyguardUpdateMonitor.isUdfpsEnrolled()) {
&& mKeyguardUpdateMonitor.isUdfpsEnrolled()
&& mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
// suggest trying fingerprint
showTransientIndication(R.string.keyguard_try_fingerprint);
} else {
@@ -952,7 +958,18 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
|| msgId == FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED);
}
private boolean shouldSuppressFaceMsg() {
// For dual biometric, don't show face auth messages unless face auth was explicitly
// requested by the user.
return mKeyguardUpdateMonitor.isUdfpsEnrolled()
&& mKeyguardUpdateMonitor.isFingerprintDetectionRunning()
&& !mKeyguardUpdateMonitor.isFaceAuthUserRequested();
}
private boolean shouldSuppressFaceError(int msgId, KeyguardUpdateMonitor updateMonitor) {
if (shouldSuppressFaceMsg()) {
return true;
}
// Only checking if unlocking with Biometric is allowed (no matter strong or non-strong
// as long as primary auth, i.e. PIN/pattern/password, is not required), so it's ok to
// pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the

View File

@@ -38,7 +38,7 @@ import java.util.LinkedList;
* A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open").
*/
public class KeyguardIndicationTextView extends TextView {
private static final long MSG_DURATION_MILLIS = 1500;
private static final long MSG_MIN_DURATION_MILLIS_DEFAULT = 1500;
private long mNextAnimationTime = 0;
private boolean mAnimationsEnabled = true;
private LinkedList<CharSequence> mMessages = new LinkedList<>();
@@ -104,8 +104,13 @@ public class KeyguardIndicationTextView extends TextView {
long delay = Math.max(0, mNextAnimationTime - timeInMillis);
setNextAnimationTime(timeInMillis + delay + getFadeOutDuration());
final long minDurationMillis =
(indication != null && indication.getMinVisibilityMillis() != null)
? indication.getMinVisibilityMillis()
: MSG_MIN_DURATION_MILLIS_DEFAULT;
if (!text.equals("") || hasIcon) {
setNextAnimationTime(mNextAnimationTime + MSG_DURATION_MILLIS);
setNextAnimationTime(mNextAnimationTime + minDurationMillis);
animSetBuilder.before(getInAnimator());
}

View File

@@ -53,7 +53,7 @@ class KeyguardLiftController constructor(
// Not listening anymore since trigger events unregister themselves
isListening = false
updateListeningState()
keyguardUpdateMonitor.requestFaceAuth()
keyguardUpdateMonitor.requestFaceAuth(true)
}
}

View File

@@ -2038,7 +2038,7 @@ public class NotificationPanelViewController extends PanelViewController {
// When expanding QS, let's authenticate the user if possible,
// this will speed up notification actions.
if (height == 0) {
mStatusBar.requestFaceAuth();
mStatusBar.requestFaceAuth(false);
}
}
@@ -3176,7 +3176,7 @@ public class NotificationPanelViewController extends PanelViewController {
case KEYGUARD:
if (!mDozingOnDown) {
if (mKeyguardBypassController.getBypassEnabled()) {
mUpdateMonitor.requestFaceAuth();
mUpdateMonitor.requestFaceAuth(true);
} else {
mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT,
0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);

View File

@@ -1723,9 +1723,9 @@ public class StatusBar extends SystemUI implements DemoMode,
/**
* Asks {@link KeyguardUpdateMonitor} to run face auth.
*/
public void requestFaceAuth() {
public void requestFaceAuth(boolean userInitiatedRequest) {
if (!mKeyguardStateController.canDismissLockScreen()) {
mKeyguardUpdateMonitor.requestFaceAuth();
mKeyguardUpdateMonitor.requestFaceAuth(userInitiatedRequest);
}
}

View File

@@ -569,7 +569,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
// Stop scanning when bouncer becomes visible
setKeyguardBouncerVisibility(true);
clearInvocations(mFaceManager);
mKeyguardUpdateMonitor.requestFaceAuth();
mKeyguardUpdateMonitor.requestFaceAuth(true);
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
}