From cfafe4ea6ff1610c24d94a9a9ecc7df6b841518c Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Tue, 11 Aug 2015 14:58:44 -0700 Subject: [PATCH] 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 --- .../keyguard/KeyguardAbsKeyInputView.java | 6 ++ .../android/keyguard/KeyguardHostView.java | 4 + .../android/keyguard/KeyguardMessageArea.java | 15 +++ .../android/keyguard/KeyguardPatternView.java | 11 ++- .../keyguard/KeyguardSecurityContainer.java | 7 ++ .../keyguard/KeyguardSecurityView.java | 8 ++ .../keyguard/KeyguardSecurityViewFlipper.java | 8 ++ .../keyguard/SecurityMessageDisplay.java | 11 ++- .../KeyguardIndicationController.java | 92 +++++++++++++++++-- .../phone/KeyguardBottomAreaView.java | 48 +--------- .../statusbar/phone/KeyguardBouncer.java | 5 +- .../statusbar/phone/PhoneStatusBar.java | 5 +- .../phone/StatusBarKeyguardViewManager.java | 4 + 13 files changed, 158 insertions(+), 66 deletions(-) diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java index 8f792de32db92..dfc31ab44aec0 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -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 diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java index ff4e8154d0f5e..32892cf4bc6a2 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java @@ -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. * diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java index 2951af915ff8c..c8adf640f5237 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java @@ -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); } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java index 4bd1a2ed29fcd..a96c79f0dbc3d 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java @@ -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); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java index 85da29837f54b..8fc3cde3cbe7a 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -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(); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java index 5658a7492d93f..7e82c6332e900 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java @@ -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. * diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java index a0ff21b1fd517..6012c45014121 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java @@ -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(); diff --git a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java index b38cfd5f6aeb5..ddb1f6ec48cae 100644 --- a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java +++ b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 31c94f788a6f7..54f91da18220f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -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; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 7b67c6c7ff4d0..4878cd923049e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -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( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index e9b2c611ae344..37f563e63b4fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -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; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index efd72a73371b9..1da62938a9585 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -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(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 44aa780706d96..1bdcf0314d1ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -491,4 +491,8 @@ public class StatusBarKeyguardViewManager { mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true); } } + + public void showBouncerMessage(String message, int color) { + mBouncer.showMessage(message, color); + } }