Indicating fingerprint error messages on the bouncer now
Also ensure that error messages are surfaced when the screen comes on such that the user knows why his fingerprint is not working. Bug: 22035466 Bug: 22524101 Change-Id: I00b0e833cdb8a3475545ba75b8cb7bf7a419dfd4
This commit is contained in:
@@ -234,6 +234,12 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String message, int color) {
|
||||
mSecurityMessageDisplay.setNextMessageColor(color);
|
||||
mSecurityMessageDisplay.setMessage(message, true /* important */);
|
||||
}
|
||||
|
||||
protected abstract int getPromtReasonStringRes(int reason);
|
||||
|
||||
// Cause a VIRTUAL_KEY vibration
|
||||
|
||||
@@ -170,6 +170,10 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
|
||||
mSecurityContainer.showPromptReason(reason);
|
||||
}
|
||||
|
||||
public void showMessage(String message, int color) {
|
||||
mSecurityContainer.showMessage(message, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the keyguard by going to the next screen or making it gone.
|
||||
*
|
||||
|
||||
@@ -39,15 +39,18 @@ class KeyguardMessageArea extends TextView implements SecurityMessageDisplay {
|
||||
* lift-to-type from interrupting itself.
|
||||
*/
|
||||
private static final long ANNOUNCEMENT_DELAY = 250;
|
||||
private static final int DEFAULT_COLOR = -1;
|
||||
|
||||
private static final int SECURITY_MESSAGE_DURATION = 5000;
|
||||
|
||||
private final KeyguardUpdateMonitor mUpdateMonitor;
|
||||
private final Handler mHandler;
|
||||
private final int mDefaultColor;
|
||||
|
||||
// Timeout before we reset the message to show charging/owner info
|
||||
long mTimeout = SECURITY_MESSAGE_DURATION;
|
||||
CharSequence mMessage;
|
||||
private int mNextMessageColor = DEFAULT_COLOR;
|
||||
|
||||
private final Runnable mClearMessageRunnable = new Runnable() {
|
||||
@Override
|
||||
@@ -78,9 +81,15 @@ class KeyguardMessageArea extends TextView implements SecurityMessageDisplay {
|
||||
mUpdateMonitor.registerCallback(mInfoCallback);
|
||||
mHandler = new Handler(Looper.myLooper());
|
||||
|
||||
mDefaultColor = getCurrentTextColor();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextMessageColor(int color) {
|
||||
mNextMessageColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessage(CharSequence msg, boolean important) {
|
||||
if (!TextUtils.isEmpty(msg) && important) {
|
||||
@@ -151,6 +160,12 @@ class KeyguardMessageArea extends TextView implements SecurityMessageDisplay {
|
||||
CharSequence status = mMessage;
|
||||
setVisibility(TextUtils.isEmpty(status) ? INVISIBLE : VISIBLE);
|
||||
setText(status);
|
||||
int color = mDefaultColor;
|
||||
if (mNextMessageColor != DEFAULT_COLOR) {
|
||||
color = mNextMessageColor;
|
||||
mNextMessageColor = DEFAULT_COLOR;
|
||||
}
|
||||
setTextColor(color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
*/
|
||||
package com.android.keyguard;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.AsyncTask;
|
||||
@@ -28,7 +24,6 @@ import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.RenderNodeAnimator;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
@@ -341,6 +336,12 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String message, int color) {
|
||||
mSecurityMessageDisplay.setNextMessageColor(color);
|
||||
mSecurityMessageDisplay.setMessage(message, true /* important */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startAppearAnimation() {
|
||||
enableClipping(false);
|
||||
|
||||
@@ -518,6 +518,13 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void showMessage(String message, int color) {
|
||||
if (mCurrentSecuritySelection != SecurityMode.None) {
|
||||
getSecurityView(mCurrentSecuritySelection).showMessage(message, color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showUsabilityHint() {
|
||||
mSecurityViewFlipper.showUsabilityHint();
|
||||
|
||||
@@ -76,6 +76,14 @@ public interface KeyguardSecurityView {
|
||||
*/
|
||||
void showPromptReason(int reason);
|
||||
|
||||
/**
|
||||
* Show a message on the security view with a specified color
|
||||
*
|
||||
* @param message the message to show
|
||||
* @param color the color to use
|
||||
*/
|
||||
void showMessage(String message, int color);
|
||||
|
||||
/**
|
||||
* Instruct the view to show usability hints, if any.
|
||||
*
|
||||
|
||||
@@ -138,6 +138,14 @@ public class KeyguardSecurityViewFlipper extends ViewFlipper implements Keyguard
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String message, int color) {
|
||||
KeyguardSecurityView ksv = getSecurityView();
|
||||
if (ksv != null) {
|
||||
ksv.showMessage(message, color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showUsabilityHint() {
|
||||
KeyguardSecurityView ksv = getSecurityView();
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
package com.android.keyguard;
|
||||
|
||||
public interface SecurityMessageDisplay {
|
||||
public void setMessage(CharSequence msg, boolean important);
|
||||
|
||||
public void setMessage(int resId, boolean important);
|
||||
void setNextMessageColor(int color);
|
||||
|
||||
public void setMessage(int resId, boolean important, Object... formatArgs);
|
||||
void setMessage(CharSequence msg, boolean important);
|
||||
|
||||
public void setTimeout(int timeout_ms);
|
||||
void setMessage(int resId, boolean important);
|
||||
|
||||
void setMessage(int resId, boolean important, Object... formatArgs);
|
||||
|
||||
void setTimeout(int timeout_ms);
|
||||
}
|
||||
|
||||
@@ -16,18 +16,13 @@
|
||||
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.Handler;
|
||||
@@ -40,8 +35,16 @@ import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
|
||||
import com.android.systemui.statusbar.phone.LockIcon;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
|
||||
/**
|
||||
* Controls the little text indicator on the keyguard.
|
||||
* Controls the indications and error messages shown on the Keyguard
|
||||
*/
|
||||
public class KeyguardIndicationController {
|
||||
|
||||
@@ -49,6 +52,8 @@ public class KeyguardIndicationController {
|
||||
private static final boolean DEBUG_CHARGING_CURRENT = false;
|
||||
|
||||
private static final int MSG_HIDE_TRANSIENT = 1;
|
||||
private static final int MSG_CLEAR_FP_MSG = 2;
|
||||
private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
|
||||
|
||||
private final Context mContext;
|
||||
private final KeyguardIndicationTextView mTextView;
|
||||
@@ -56,6 +61,8 @@ public class KeyguardIndicationController {
|
||||
|
||||
private final int mSlowThreshold;
|
||||
private final int mFastThreshold;
|
||||
private final LockIcon mLockIcon;
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
|
||||
private String mRestingIndication;
|
||||
private String mTransientIndication;
|
||||
@@ -66,10 +73,13 @@ public class KeyguardIndicationController {
|
||||
private boolean mPowerCharged;
|
||||
private int mChargingSpeed;
|
||||
private int mChargingCurrent;
|
||||
private String mMessageToShowOnScreenOn;
|
||||
|
||||
public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView) {
|
||||
public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView,
|
||||
LockIcon lockIcon) {
|
||||
mContext = context;
|
||||
mTextView = textView;
|
||||
mLockIcon = lockIcon;
|
||||
|
||||
Resources res = context.getResources();
|
||||
mSlowThreshold = res.getInteger(R.integer.config_chargingSlowlyThreshold);
|
||||
@@ -216,6 +226,64 @@ public class KeyguardIndicationController {
|
||||
mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
|
||||
updateIndication();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintHelp(int msgId, String helpString) {
|
||||
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
|
||||
if (!updateMonitor.isUnlockingWithFingerprintAllowed()) {
|
||||
return;
|
||||
}
|
||||
int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
|
||||
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||
mStatusBarKeyguardViewManager.showBouncerMessage(helpString, errorColor);
|
||||
} else if (updateMonitor.isDeviceInteractive()) {
|
||||
mLockIcon.setTransientFpError(true);
|
||||
showTransientIndication(helpString, errorColor);
|
||||
mHandler.removeMessages(MSG_CLEAR_FP_MSG);
|
||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_FP_MSG),
|
||||
TRANSIENT_FP_ERROR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintError(int msgId, String errString) {
|
||||
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
|
||||
if (!updateMonitor.isUnlockingWithFingerprintAllowed()
|
||||
|| msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
|
||||
return;
|
||||
}
|
||||
int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
|
||||
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||
mStatusBarKeyguardViewManager.showBouncerMessage(errString, errorColor);
|
||||
} else if (updateMonitor.isDeviceInteractive()) {
|
||||
showTransientIndication(errString, errorColor);
|
||||
// We want to keep this message around in case the screen was off
|
||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
||||
hideTransientIndicationDelayed(5000);
|
||||
} else {
|
||||
mMessageToShowOnScreenOn = errString;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenTurnedOn() {
|
||||
if (mMessageToShowOnScreenOn != null) {
|
||||
int errorColor = mContext.getResources().getColor(R.color.system_warning_color,
|
||||
null);
|
||||
showTransientIndication(mMessageToShowOnScreenOn, errorColor);
|
||||
// We want to keep this message around in case the screen was off
|
||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
||||
hideTransientIndicationDelayed(5000);
|
||||
mMessageToShowOnScreenOn = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintRunningStateChanged(boolean running) {
|
||||
if (running) {
|
||||
mMessageToShowOnScreenOn = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@@ -233,7 +301,15 @@ public class KeyguardIndicationController {
|
||||
if (msg.what == MSG_HIDE_TRANSIENT && mTransientIndication != null) {
|
||||
mTransientIndication = null;
|
||||
updateIndication();
|
||||
} else if (msg.what == MSG_CLEAR_FP_MSG) {
|
||||
mLockIcon.setTransientFpError(false);
|
||||
hideTransientIndication();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void setStatusBarKeyguardViewManager(
|
||||
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
|
||||
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -86,7 +85,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
|
||||
private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
|
||||
private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
|
||||
private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
|
||||
|
||||
private KeyguardAffordanceView mCameraImageView;
|
||||
private KeyguardAffordanceView mLeftAffordanceView;
|
||||
@@ -528,7 +526,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
return mCameraPreview;
|
||||
}
|
||||
|
||||
public KeyguardAffordanceView getLockIcon() {
|
||||
public LockIcon getLockIcon() {
|
||||
return mLockIcon;
|
||||
}
|
||||
|
||||
@@ -613,21 +611,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mTransientFpErrorClearRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mLockIcon.setTransientFpError(false);
|
||||
mIndicationController.hideTransientIndication();
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mHideTransientIndicationRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mIndicationController.hideTransientIndication();
|
||||
}
|
||||
};
|
||||
|
||||
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
@@ -660,39 +643,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
mLockIcon.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintRunningStateChanged(boolean running) {
|
||||
mLockIcon.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintHelp(int msgId, String helpString) {
|
||||
if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()) {
|
||||
return;
|
||||
}
|
||||
mLockIcon.setTransientFpError(true);
|
||||
mIndicationController.showTransientIndication(helpString,
|
||||
getResources().getColor(R.color.system_warning_color, null));
|
||||
removeCallbacks(mTransientFpErrorClearRunnable);
|
||||
postDelayed(mTransientFpErrorClearRunnable, TRANSIENT_FP_ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintError(int msgId, String errString) {
|
||||
if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()
|
||||
|| msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
|
||||
return;
|
||||
}
|
||||
// TODO: Go to bouncer if this is "too many attempts" (lockout) error.
|
||||
mIndicationController.showTransientIndication(errString,
|
||||
getResources().getColor(R.color.system_warning_color, null));
|
||||
removeCallbacks(mHideTransientIndicationRunnable);
|
||||
postDelayed(mHideTransientIndicationRunnable, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
public void setKeyguardIndicationController(
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Choreographer;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -103,6 +102,10 @@ public class KeyguardBouncer {
|
||||
mKeyguardView.showPromptReason(reason);
|
||||
}
|
||||
|
||||
public void showMessage(String message, int color) {
|
||||
mKeyguardView.showMessage(message, color);
|
||||
}
|
||||
|
||||
private void cancelShowRunnable() {
|
||||
DejankUtils.removeCallbacks(mShowRunnable);
|
||||
mShowingSoon = false;
|
||||
|
||||
@@ -780,7 +780,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mKeyguardBottomArea.setAssistManager(mAssistManager);
|
||||
mKeyguardIndicationController = new KeyguardIndicationController(mContext,
|
||||
(KeyguardIndicationTextView) mStatusBarWindow.findViewById(
|
||||
R.id.keyguard_indication_text));
|
||||
R.id.keyguard_indication_text),
|
||||
mKeyguardBottomArea.getLockIcon());
|
||||
mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
|
||||
|
||||
// set the inital view visibility
|
||||
@@ -1011,6 +1012,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
|
||||
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
|
||||
mStatusBarWindow, mStatusBarWindowManager, mScrimController);
|
||||
mKeyguardIndicationController.setStatusBarKeyguardViewManager(
|
||||
mStatusBarKeyguardViewManager);
|
||||
mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
|
||||
}
|
||||
|
||||
|
||||
@@ -491,4 +491,8 @@ public class StatusBarKeyguardViewManager {
|
||||
mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void showBouncerMessage(String message, int color) {
|
||||
mBouncer.showMessage(message, color);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user