blob: 4be93df0e81a6f9c7c843dfb48ee0c3117ff32d4 [file] [log] [blame]
Adrian Roos12c1ef52014-06-04 13:54:08 +02001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar;
18
Beverly8c785892018-01-31 17:25:52 -050019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010021import android.app.admin.DevicePolicyManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020022import android.content.Context;
Jason Chang2386a372018-04-24 16:05:30 +080023import android.content.res.ColorStateList;
Lucas Dupinff6628d2018-10-15 10:12:37 -070024import android.content.res.Resources;
Jorim Jaggi27c9b742015-04-09 10:34:49 -070025import android.graphics.Color;
Lucas Dupinff6628d2018-10-15 10:12:37 -070026import android.hardware.biometrics.BiometricSourceType;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020027import android.hardware.face.FaceManager;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070028import android.hardware.fingerprint.FingerprintManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020029import android.os.BatteryManager;
30import android.os.BatteryStats;
31import android.os.Handler;
32import android.os.Message;
33import android.os.RemoteException;
34import android.os.ServiceManager;
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -060035import android.os.UserManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020036import android.text.TextUtils;
37import android.text.format.Formatter;
38import android.util.Log;
39import android.view.View;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010040import android.view.ViewGroup;
Adrian Roos12c1ef52014-06-04 13:54:08 +020041
Adrian Roosc1b50322017-02-27 21:07:58 +010042import com.android.internal.annotations.VisibleForTesting;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070043import com.android.internal.app.IBatteryStats;
Lucas Dupin2e838ac2019-04-17 16:50:58 -070044import com.android.internal.logging.nano.MetricsProto;
45import com.android.internal.widget.LockPatternUtils;
Lucas Dupineff8ef02019-06-06 11:14:01 -070046import com.android.internal.widget.ViewClippingUtil;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070047import com.android.keyguard.KeyguardUpdateMonitor;
48import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jason Monk58be7a62017-02-01 20:17:51 -050049import com.android.settingslib.Utils;
Jason Monk9c7844c2017-01-18 15:21:53 -050050import com.android.systemui.Dependency;
Beverly8c785892018-01-31 17:25:52 -050051import com.android.systemui.Interpolators;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070052import com.android.systemui.R;
Beverly8fdb5332019-02-04 14:29:49 -050053import com.android.systemui.plugins.statusbar.StatusBarStateController;
54import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070055import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
56import com.android.systemui.statusbar.phone.LockIcon;
Lucas Dupin2e838ac2019-04-17 16:50:58 -070057import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070058import com.android.systemui.statusbar.phone.ShadeController;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070059import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070060import com.android.systemui.statusbar.phone.UnlockMethodCache;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070061import com.android.systemui.statusbar.policy.AccessibilityController;
Zachary Iqbalf50284c2017-01-22 18:54:46 -080062import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roosc1b50322017-02-27 21:07:58 +010063import com.android.systemui.util.wakelock.SettableWakeLock;
64import com.android.systemui.util.wakelock.WakeLock;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070065
Lucas Dupin3fcdd472018-01-19 19:06:45 -080066import java.io.FileDescriptor;
67import java.io.PrintWriter;
Lucas Dupin4272f442018-01-13 22:00:35 -080068import java.text.NumberFormat;
Lucas Dupin8d595d22018-03-08 10:34:58 -080069import java.util.IllegalFormatConversionException;
Lucas Dupin4272f442018-01-13 22:00:35 -080070
Adrian Roos12c1ef52014-06-04 13:54:08 +020071/**
Selim Cinekcfafe4e2015-08-11 14:58:44 -070072 * Controls the indications and error messages shown on the Keyguard
Adrian Roos12c1ef52014-06-04 13:54:08 +020073 */
Lucas Dupin8e2fd012019-04-25 16:40:54 -070074public class KeyguardIndicationController implements StateListener,
75 UnlockMethodCache.OnUnlockMethodChangedListener {
Adrian Roos12c1ef52014-06-04 13:54:08 +020076
Adrian Roos0c859ae2015-11-23 16:47:50 -080077 private static final String TAG = "KeyguardIndication";
78 private static final boolean DEBUG_CHARGING_SPEED = false;
Adrian Roos12c1ef52014-06-04 13:54:08 +020079
80 private static final int MSG_HIDE_TRANSIENT = 1;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020081 private static final int MSG_CLEAR_BIOMETRIC_MSG = 2;
Lucas Dupin51996bb2019-05-16 17:56:43 -070082 private static final int MSG_SWIPE_UP_TO_UNLOCK = 3;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020083 private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
Robert Snoebergerddfb0652019-06-21 16:41:46 -040084 private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
Adrian Roos12c1ef52014-06-04 13:54:08 +020085
86 private final Context mContext;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070087 private final ShadeController mShadeController;
88 private final AccessibilityController mAccessibilityController;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070089 private final UnlockMethodCache mUnlockMethodCache;
90 private final StatusBarStateController mStatusBarStateController;
91 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
Lucas Dupin987f1932017-05-13 21:02:52 -070092 private ViewGroup mIndicationArea;
93 private KeyguardIndicationTextView mTextView;
94 private KeyguardIndicationTextView mDisclosure;
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -060095 private final UserManager mUserManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020096 private final IBatteryStats mBatteryInfo;
Adrian Roosc1b50322017-02-27 21:07:58 +010097 private final SettableWakeLock mWakeLock;
Lucas Dupin2e838ac2019-04-17 16:50:58 -070098 private final LockPatternUtils mLockPatternUtils;
Adrian Roos12c1ef52014-06-04 13:54:08 +020099
Adrian Roos7b043112015-07-10 13:00:33 -0700100 private final int mSlowThreshold;
101 private final int mFastThreshold;
Lucas Dupin05904652019-04-09 16:16:15 -0700102 private final LockIcon mLockIcon;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700103 private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700104 private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
Adrian Roos7b043112015-07-10 13:00:33 -0700105
Adrian Roos12c1ef52014-06-04 13:54:08 +0200106 private String mRestingIndication;
Lucas Dupinef886542018-01-03 16:03:07 -0800107 private CharSequence mTransientIndication;
Jason Chang2386a372018-04-24 16:05:30 +0800108 private ColorStateList mTransientTextColorState;
109 private ColorStateList mInitialTextColorState;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200110 private boolean mVisible;
111
112 private boolean mPowerPluggedIn;
Beverly2034c832018-03-19 11:18:51 -0400113 private boolean mPowerPluggedInWired;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200114 private boolean mPowerCharged;
Adrian Roos7b043112015-07-10 13:00:33 -0700115 private int mChargingSpeed;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800116 private int mChargingWattage;
Lucas Dupin4272f442018-01-13 22:00:35 -0800117 private int mBatteryLevel;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700118 private String mMessageToShowOnScreenOn;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200119
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700120 private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800121
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100122 private final DevicePolicyManager mDevicePolicyManager;
Adrian Roos91ba3072017-02-14 16:50:46 +0100123 private boolean mDozing;
Lucas Dupineff8ef02019-06-06 11:14:01 -0700124 private final ViewClippingUtil.ClippingParameters mClippingParams =
125 new ViewClippingUtil.ClippingParameters() {
126 @Override
127 public boolean shouldFinish(View view) {
128 return view == mIndicationArea;
129 }
130 };
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100131
Adrian Roosaf45b602017-03-14 13:10:25 -0700132 /**
133 * Creates a new KeyguardIndicationController and registers callbacks.
134 */
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100135 public KeyguardIndicationController(Context context, ViewGroup indicationArea,
136 LockIcon lockIcon) {
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700137 this(context, indicationArea, lockIcon, new LockPatternUtils(context),
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700138 WakeLock.createPartial(context, "Doze:KeyguardIndication"),
139 Dependency.get(ShadeController.class),
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700140 Dependency.get(AccessibilityController.class),
141 UnlockMethodCache.getInstance(context),
142 Dependency.get(StatusBarStateController.class),
143 KeyguardUpdateMonitor.getInstance(context));
Adrian Roosc1b50322017-02-27 21:07:58 +0100144 }
145
Adrian Roosaf45b602017-03-14 13:10:25 -0700146 /**
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700147 * Creates a new KeyguardIndicationController for testing.
Adrian Roosaf45b602017-03-14 13:10:25 -0700148 */
Adrian Roosc1b50322017-02-27 21:07:58 +0100149 @VisibleForTesting
150 KeyguardIndicationController(Context context, ViewGroup indicationArea, LockIcon lockIcon,
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700151 LockPatternUtils lockPatternUtils, WakeLock wakeLock, ShadeController shadeController,
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700152 AccessibilityController accessibilityController, UnlockMethodCache unlockMethodCache,
153 StatusBarStateController statusBarStateController,
154 KeyguardUpdateMonitor keyguardUpdateMonitor) {
Adrian Roos12c1ef52014-06-04 13:54:08 +0200155 mContext = context;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700156 mLockIcon = lockIcon;
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700157 mShadeController = shadeController;
158 mAccessibilityController = accessibilityController;
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700159 mUnlockMethodCache = unlockMethodCache;
160 mStatusBarStateController = statusBarStateController;
161 mKeyguardUpdateMonitor = keyguardUpdateMonitor;
Brad Stenning691c2742019-04-19 11:48:00 -0700162 // lock icon is not used on all form factors.
163 if (mLockIcon != null) {
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700164 mLockIcon.setOnLongClickListener(this::handleLockLongClick);
165 mLockIcon.setOnClickListener(this::handleLockClick);
Brad Stenning691c2742019-04-19 11:48:00 -0700166 }
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800167 mWakeLock = new SettableWakeLock(wakeLock, TAG);
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700168 mLockPatternUtils = lockPatternUtils;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200169
Adrian Roos7b043112015-07-10 13:00:33 -0700170 Resources res = context.getResources();
171 mSlowThreshold = res.getInteger(R.integer.config_chargingSlowlyThreshold);
172 mFastThreshold = res.getInteger(R.integer.config_chargingFastThreshold);
173
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600174 mUserManager = context.getSystemService(UserManager.class);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200175 mBatteryInfo = IBatteryStats.Stub.asInterface(
176 ServiceManager.getService(BatteryStats.SERVICE_NAME));
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600177
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100178 mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(
179 Context.DEVICE_POLICY_SERVICE);
Lucas Dupin00ebe132019-04-26 16:17:56 -0700180 setIndicationArea(indicationArea);
Adrian Roosaf45b602017-03-14 13:10:25 -0700181 updateDisclosure();
Adrian Roosaf45b602017-03-14 13:10:25 -0700182
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700183 mKeyguardUpdateMonitor.registerCallback(getKeyguardCallback());
184 mKeyguardUpdateMonitor.registerCallback(mTickReceiver);
185 mStatusBarStateController.addCallback(this);
186 mUnlockMethodCache.addListener(this);
Evan Laird878c8532018-10-15 15:54:29 -0400187 }
188
Lucas Dupin00ebe132019-04-26 16:17:56 -0700189 public void setIndicationArea(ViewGroup indicationArea) {
190 mIndicationArea = indicationArea;
191 mTextView = indicationArea.findViewById(R.id.keyguard_indication_text);
192 mInitialTextColorState = mTextView != null ?
193 mTextView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
194 mDisclosure = indicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure);
195 updateIndication(false /* animate */);
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100196 }
197
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700198 private boolean handleLockLongClick(View view) {
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700199 mLockscreenGestureLogger.write(MetricsProto.MetricsEvent.ACTION_LS_LOCK,
200 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
201 showTransientIndication(R.string.keyguard_indication_trust_disabled);
Lucas Dupinca88e5f2019-05-14 16:11:08 -0700202 mKeyguardUpdateMonitor.onLockIconPressed();
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700203 mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
204
205 return true;
206 }
207
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700208 private void handleLockClick(View view) {
209 if (!mAccessibilityController.isAccessibilityEnabled()) {
210 return;
211 }
Lucas Dupind54f00e2019-05-06 17:44:03 -0700212 mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700213 }
214
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800215 /**
216 * Gets the {@link KeyguardUpdateMonitorCallback} instance associated with this
217 * {@link KeyguardIndicationController}.
218 *
219 * <p>Subclasses may override this method to extend or change the callback behavior by extending
220 * the {@link BaseKeyguardCallback}.
221 *
222 * @return A KeyguardUpdateMonitorCallback. Multiple calls to this method <b>must</b> return the
223 * same instance.
224 */
225 protected KeyguardUpdateMonitorCallback getKeyguardCallback() {
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700226 if (mUpdateMonitorCallback == null) {
227 mUpdateMonitorCallback = new BaseKeyguardCallback();
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800228 }
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700229 return mUpdateMonitorCallback;
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800230 }
231
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100232 private void updateDisclosure() {
233 if (mDevicePolicyManager == null) {
234 return;
235 }
236
Adrian Roos91ba3072017-02-14 16:50:46 +0100237 if (!mDozing && mDevicePolicyManager.isDeviceManaged()) {
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100238 final CharSequence organizationName =
239 mDevicePolicyManager.getDeviceOwnerOrganizationName();
240 if (organizationName != null) {
241 mDisclosure.switchIndication(mContext.getResources().getString(
242 R.string.do_disclosure_with_name, organizationName));
243 } else {
244 mDisclosure.switchIndication(R.string.do_disclosure_generic);
245 }
246 mDisclosure.setVisibility(View.VISIBLE);
247 } else {
248 mDisclosure.setVisibility(View.GONE);
249 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200250 }
251
252 public void setVisible(boolean visible) {
253 mVisible = visible;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100254 mIndicationArea.setVisibility(visible ? View.VISIBLE : View.GONE);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200255 if (visible) {
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700256 // If this is called after an error message was already shown, we should not clear it.
257 // Otherwise the error message won't be shown
258 if (!mHandler.hasMessages(MSG_HIDE_TRANSIENT)) {
259 hideTransientIndication();
260 }
Beverly8c785892018-01-31 17:25:52 -0500261 updateIndication(false);
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700262 } else if (!visible) {
263 // If we unlock and return to keyguard quickly, previous error should not be shown
264 hideTransientIndication();
Adrian Roos12c1ef52014-06-04 13:54:08 +0200265 }
266 }
267
268 /**
269 * Sets the indication that is shown if nothing else is showing.
270 */
271 public void setRestingIndication(String restingIndication) {
272 mRestingIndication = restingIndication;
Beverly8c785892018-01-31 17:25:52 -0500273 updateIndication(false);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200274 }
275
276 /**
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800277 * Sets the active controller managing changes and callbacks to user information.
278 */
279 public void setUserInfoController(UserInfoController userInfoController) {
280 }
281
282 /**
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700283 * Returns the indication text indicating that trust has been granted.
284 *
285 * @return {@code null} or an empty string if a trust indication text should not be shown.
286 */
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700287 @VisibleForTesting
288 String getTrustGrantedIndication() {
Lucas Dupin859f2c82019-04-17 18:30:00 -0700289 return mContext.getString(R.string.keyguard_indication_trust_unlocked);
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700290 }
291
292 /**
293 * Returns the indication text indicating that trust is currently being managed.
294 *
295 * @return {@code null} or an empty string if a trust managed text should not be shown.
296 */
Lucas Dupin859f2c82019-04-17 18:30:00 -0700297 private String getTrustManagedIndication() {
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700298 return null;
299 }
300
301 /**
Adrian Roos12c1ef52014-06-04 13:54:08 +0200302 * Hides transient indication in {@param delayMs}.
303 */
304 public void hideTransientIndicationDelayed(long delayMs) {
305 mHandler.sendMessageDelayed(
306 mHandler.obtainMessage(MSG_HIDE_TRANSIENT), delayMs);
307 }
308
309 /**
310 * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
311 */
312 public void showTransientIndication(int transientIndication) {
313 showTransientIndication(mContext.getResources().getString(transientIndication));
314 }
315
316 /**
317 * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
318 */
Lucas Dupinef886542018-01-03 16:03:07 -0800319 public void showTransientIndication(CharSequence transientIndication) {
Jason Chang2386a372018-04-24 16:05:30 +0800320 showTransientIndication(transientIndication, mInitialTextColorState);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700321 }
322
323 /**
324 * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
325 */
Jason Chang2386a372018-04-24 16:05:30 +0800326 public void showTransientIndication(CharSequence transientIndication,
327 ColorStateList textColorState) {
Adrian Roos12c1ef52014-06-04 13:54:08 +0200328 mTransientIndication = transientIndication;
Jason Chang2386a372018-04-24 16:05:30 +0800329 mTransientTextColorState = textColorState;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200330 mHandler.removeMessages(MSG_HIDE_TRANSIENT);
Lucas Dupin51996bb2019-05-16 17:56:43 -0700331 mHandler.removeMessages(MSG_SWIPE_UP_TO_UNLOCK);
Adrian Roosc1b50322017-02-27 21:07:58 +0100332 if (mDozing && !TextUtils.isEmpty(mTransientIndication)) {
333 // Make sure this doesn't get stuck and burns in. Acquire wakelock until its cleared.
334 mWakeLock.setAcquired(true);
335 hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
336 }
Beverly8c785892018-01-31 17:25:52 -0500337
338 updateIndication(false);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200339 }
340
341 /**
342 * Hides transient indication.
343 */
344 public void hideTransientIndication() {
345 if (mTransientIndication != null) {
346 mTransientIndication = null;
347 mHandler.removeMessages(MSG_HIDE_TRANSIENT);
Beverly8c785892018-01-31 17:25:52 -0500348 updateIndication(false);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200349 }
350 }
351
Beverly8c785892018-01-31 17:25:52 -0500352 protected final void updateIndication(boolean animate) {
Adrian Roosc1b50322017-02-27 21:07:58 +0100353 if (TextUtils.isEmpty(mTransientIndication)) {
354 mWakeLock.setAcquired(false);
355 }
356
Adrian Roos12c1ef52014-06-04 13:54:08 +0200357 if (mVisible) {
Lucas Dupin53d50622017-05-13 15:54:14 -0700358 // Walk down a precedence-ordered list of what indication
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600359 // should be shown based on user or device state
Lucas Dupinff6628d2018-10-15 10:12:37 -0700360 if (mDozing) {
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700361 // When dozing we ignore any text color and use white instead, because
362 // colors can be hard to read in low brightness.
363 mTextView.setTextColor(Color.WHITE);
Lucas Dupinff6628d2018-10-15 10:12:37 -0700364 if (!TextUtils.isEmpty(mTransientIndication)) {
Lucas Dupinff6628d2018-10-15 10:12:37 -0700365 mTextView.switchIndication(mTransientIndication);
Lucas Dupin07ed3df2019-03-26 21:23:59 -0700366 } else if (mPowerPluggedIn) {
367 String indication = computePowerIndication();
368 if (animate) {
369 animateText(mTextView, indication);
370 } else {
371 mTextView.switchIndication(indication);
372 }
373 } else {
374 String percentage = NumberFormat.getPercentInstance()
375 .format(mBatteryLevel / 100f);
376 mTextView.switchIndication(percentage);
Lucas Dupinff6628d2018-10-15 10:12:37 -0700377 }
Lucas Dupinff6628d2018-10-15 10:12:37 -0700378 return;
379 }
380
Jorim Jaggifabc7432017-05-15 02:40:05 +0200381 int userId = KeyguardUpdateMonitor.getCurrentUser();
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700382 String trustGrantedIndication = getTrustGrantedIndication();
383 String trustManagedIndication = getTrustManagedIndication();
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700384 if (!mUserManager.isUserUnlocked(userId)) {
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600385 mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
Jason Chang2386a372018-04-24 16:05:30 +0800386 mTextView.setTextColor(mInitialTextColorState);
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600387 } else if (!TextUtils.isEmpty(mTransientIndication)) {
388 mTextView.switchIndication(mTransientIndication);
Jason Chang2386a372018-04-24 16:05:30 +0800389 mTextView.setTextColor(mTransientTextColorState);
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700390 } else if (!TextUtils.isEmpty(trustGrantedIndication)
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700391 && mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700392 mTextView.switchIndication(trustGrantedIndication);
Jason Chang2386a372018-04-24 16:05:30 +0800393 mTextView.setTextColor(mInitialTextColorState);
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600394 } else if (mPowerPluggedIn) {
395 String indication = computePowerIndication();
396 if (DEBUG_CHARGING_SPEED) {
397 indication += ", " + (mChargingWattage / 1000) + " mW";
398 }
Jason Chang2386a372018-04-24 16:05:30 +0800399 mTextView.setTextColor(mInitialTextColorState);
Beverly85499d92018-02-14 15:55:16 -0500400 if (animate) {
401 animateText(mTextView, indication);
402 } else {
403 mTextView.switchIndication(indication);
404 }
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700405 } else if (!TextUtils.isEmpty(trustManagedIndication)
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700406 && mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
407 && !mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700408 mTextView.switchIndication(trustManagedIndication);
Jason Chang2386a372018-04-24 16:05:30 +0800409 mTextView.setTextColor(mInitialTextColorState);
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600410 } else {
411 mTextView.switchIndication(mRestingIndication);
Jason Chang2386a372018-04-24 16:05:30 +0800412 mTextView.setTextColor(mInitialTextColorState);
Adrian Roos7b043112015-07-10 13:00:33 -0700413 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200414 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200415 }
416
Beverly85499d92018-02-14 15:55:16 -0500417 // animates textView - textView moves up and bounces down
418 private void animateText(KeyguardIndicationTextView textView, String indication) {
419 int yTranslation = mContext.getResources().getInteger(
420 R.integer.wired_charging_keyguard_text_animation_distance);
421 int animateUpDuration = mContext.getResources().getInteger(
422 R.integer.wired_charging_keyguard_text_animation_duration_up);
423 int animateDownDuration = mContext.getResources().getInteger(
424 R.integer.wired_charging_keyguard_text_animation_duration_down);
Lucas Dupindef43692018-07-02 15:22:58 -0700425 textView.animate().cancel();
Lucas Dupineff8ef02019-06-06 11:14:01 -0700426 ViewClippingUtil.setClippingDeactivated(textView, true, mClippingParams);
Beverly85499d92018-02-14 15:55:16 -0500427 textView.animate()
428 .translationYBy(yTranslation)
429 .setInterpolator(Interpolators.LINEAR)
430 .setDuration(animateUpDuration)
431 .setListener(new AnimatorListenerAdapter() {
Lucas Dupindef43692018-07-02 15:22:58 -0700432 private boolean mCancelled;
433
Beverly85499d92018-02-14 15:55:16 -0500434 @Override
435 public void onAnimationStart(Animator animation) {
436 textView.switchIndication(indication);
437 }
Lucas Dupindef43692018-07-02 15:22:58 -0700438
439 @Override
440 public void onAnimationCancel(Animator animation) {
Robert Snoebergerddfb0652019-06-21 16:41:46 -0400441 textView.setTranslationY(BOUNCE_ANIMATION_FINAL_Y);
Lucas Dupindef43692018-07-02 15:22:58 -0700442 mCancelled = true;
443 }
444
Beverly85499d92018-02-14 15:55:16 -0500445 @Override
446 public void onAnimationEnd(Animator animation) {
Lucas Dupindef43692018-07-02 15:22:58 -0700447 if (mCancelled) {
Lucas Dupineff8ef02019-06-06 11:14:01 -0700448 ViewClippingUtil.setClippingDeactivated(textView, false,
449 mClippingParams);
Lucas Dupindef43692018-07-02 15:22:58 -0700450 return;
451 }
Beverly85499d92018-02-14 15:55:16 -0500452 textView.animate()
453 .setDuration(animateDownDuration)
454 .setInterpolator(Interpolators.BOUNCE)
Robert Snoebergerddfb0652019-06-21 16:41:46 -0400455 .translationY(BOUNCE_ANIMATION_FINAL_Y)
Lucas Dupindef43692018-07-02 15:22:58 -0700456 .setListener(new AnimatorListenerAdapter() {
457 @Override
Lucas Dupineff8ef02019-06-06 11:14:01 -0700458 public void onAnimationEnd(Animator animation) {
Robert Snoebergerddfb0652019-06-21 16:41:46 -0400459 textView.setTranslationY(BOUNCE_ANIMATION_FINAL_Y);
Lucas Dupineff8ef02019-06-06 11:14:01 -0700460 ViewClippingUtil.setClippingDeactivated(textView, false,
461 mClippingParams);
462 }
Lucas Dupindef43692018-07-02 15:22:58 -0700463 });
Beverly85499d92018-02-14 15:55:16 -0500464 }
465 });
466 }
467
Adrian Roos12c1ef52014-06-04 13:54:08 +0200468 private String computePowerIndication() {
469 if (mPowerCharged) {
470 return mContext.getResources().getString(R.string.keyguard_charged);
471 }
472
473 // Try fetching charging time from battery stats.
Adrian Roos7e39e592015-09-23 17:03:47 -0700474 long chargingTimeRemaining = 0;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200475 try {
Adrian Roos7e39e592015-09-23 17:03:47 -0700476 chargingTimeRemaining = mBatteryInfo.computeChargeTimeRemaining();
477
Adrian Roos12c1ef52014-06-04 13:54:08 +0200478 } catch (RemoteException e) {
479 Log.e(TAG, "Error calling IBatteryStats: ", e);
480 }
Adrian Roos7e39e592015-09-23 17:03:47 -0700481 final boolean hasChargingTime = chargingTimeRemaining > 0;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200482
Adrian Roos7b043112015-07-10 13:00:33 -0700483 int chargingId;
Beverly7d7f6992019-02-11 13:58:27 -0500484 if (mPowerPluggedInWired) {
485 switch (mChargingSpeed) {
486 case KeyguardUpdateMonitor.BatteryStatus.CHARGING_FAST:
487 chargingId = hasChargingTime
488 ? R.string.keyguard_indication_charging_time_fast
489 : R.string.keyguard_plugged_in_charging_fast;
490 break;
491 case KeyguardUpdateMonitor.BatteryStatus.CHARGING_SLOWLY:
492 chargingId = hasChargingTime
493 ? R.string.keyguard_indication_charging_time_slowly
494 : R.string.keyguard_plugged_in_charging_slowly;
495 break;
496 default:
497 chargingId = hasChargingTime
498 ? R.string.keyguard_indication_charging_time
499 : R.string.keyguard_plugged_in;
500 break;
501 }
502 } else {
503 chargingId = hasChargingTime
504 ? R.string.keyguard_indication_charging_time_wireless
505 : R.string.keyguard_plugged_in_wireless;
Adrian Roos7b043112015-07-10 13:00:33 -0700506 }
Adrian Roos7e39e592015-09-23 17:03:47 -0700507
Lucas Dupin8d595d22018-03-08 10:34:58 -0800508 String percentage = NumberFormat.getPercentInstance()
509 .format(mBatteryLevel / 100f);
Adrian Roos7e39e592015-09-23 17:03:47 -0700510 if (hasChargingTime) {
Lucas Dupin8d595d22018-03-08 10:34:58 -0800511 // We now have battery percentage in these strings and it's expected that all
512 // locales will also have it in the future. For now, we still have to support the old
513 // format until all languages get the new translations.
Adrian Roos7e39e592015-09-23 17:03:47 -0700514 String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
515 mContext, chargingTimeRemaining);
Lucas Dupin8d595d22018-03-08 10:34:58 -0800516 try {
517 return mContext.getResources().getString(chargingId, chargingTimeFormatted,
518 percentage);
519 } catch (IllegalFormatConversionException e) {
520 return mContext.getResources().getString(chargingId, chargingTimeFormatted);
521 }
Adrian Roos7e39e592015-09-23 17:03:47 -0700522 } else {
Lucas Dupin8d595d22018-03-08 10:34:58 -0800523 // Same as above
524 try {
525 return mContext.getResources().getString(chargingId, percentage);
526 } catch (IllegalFormatConversionException e) {
527 return mContext.getResources().getString(chargingId);
528 }
Adrian Roos7e39e592015-09-23 17:03:47 -0700529 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200530 }
531
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800532 public void setStatusBarKeyguardViewManager(
533 StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
534 mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
535 }
536
Lucas Dupin7e171e22018-12-20 11:29:35 -0800537 private final KeyguardUpdateMonitorCallback mTickReceiver =
538 new KeyguardUpdateMonitorCallback() {
539 @Override
540 public void onTimeChanged() {
541 if (mVisible) {
542 updateIndication(false /* animate */);
543 }
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800544 }
Lucas Dupin7e171e22018-12-20 11:29:35 -0800545 };
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800546
547 private final Handler mHandler = new Handler() {
548 @Override
549 public void handleMessage(Message msg) {
Adrian Roosc1b50322017-02-27 21:07:58 +0100550 if (msg.what == MSG_HIDE_TRANSIENT) {
551 hideTransientIndication();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200552 } else if (msg.what == MSG_CLEAR_BIOMETRIC_MSG) {
Lucas Dupinc9e5d762019-01-28 09:34:30 -0800553 mLockIcon.setTransientBiometricsError(false);
Lucas Dupin51996bb2019-05-16 17:56:43 -0700554 } else if (msg.what == MSG_SWIPE_UP_TO_UNLOCK) {
555 showSwipeUpToUnlock();
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800556 }
557 }
558 };
559
Lucas Dupin51996bb2019-05-16 17:56:43 -0700560 private void showSwipeUpToUnlock() {
561 if (mDozing) {
562 return;
563 }
564
565 String message = mContext.getString(R.string.keyguard_unlock);
566 if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
567 mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
568 } else if (mKeyguardUpdateMonitor.isScreenOn()) {
569 showTransientIndication(message);
570 hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
571 }
572 }
573
Adrian Roos91ba3072017-02-14 16:50:46 +0100574 public void setDozing(boolean dozing) {
Jorim Jaggifabc7432017-05-15 02:40:05 +0200575 if (mDozing == dozing) {
576 return;
577 }
Adrian Roos91ba3072017-02-14 16:50:46 +0100578 mDozing = dozing;
Beverly8c785892018-01-31 17:25:52 -0500579 updateIndication(false);
Adrian Roos91ba3072017-02-14 16:50:46 +0100580 updateDisclosure();
581 }
582
Lucas Dupin3fcdd472018-01-19 19:06:45 -0800583 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
584 pw.println("KeyguardIndicationController:");
Jason Chang2386a372018-04-24 16:05:30 +0800585 pw.println(" mTransientTextColorState: " + mTransientTextColorState);
586 pw.println(" mInitialTextColorState: " + mInitialTextColorState);
Beverly2034c832018-03-19 11:18:51 -0400587 pw.println(" mPowerPluggedInWired: " + mPowerPluggedInWired);
Lucas Dupin3fcdd472018-01-19 19:06:45 -0800588 pw.println(" mPowerPluggedIn: " + mPowerPluggedIn);
589 pw.println(" mPowerCharged: " + mPowerCharged);
590 pw.println(" mChargingSpeed: " + mChargingSpeed);
591 pw.println(" mChargingWattage: " + mChargingWattage);
592 pw.println(" mMessageToShowOnScreenOn: " + mMessageToShowOnScreenOn);
593 pw.println(" mDozing: " + mDozing);
594 pw.println(" mBatteryLevel: " + mBatteryLevel);
595 pw.println(" mTextView.getText(): " + (mTextView == null ? null : mTextView.getText()));
596 pw.println(" computePowerIndication(): " + computePowerIndication());
597 }
598
Evan Laird878c8532018-10-15 15:54:29 -0400599 @Override
600 public void onStateChanged(int newState) {
601 // don't care
602 }
603
604 @Override
605 public void onDozingChanged(boolean isDozing) {
606 setDozing(isDozing);
607 }
608
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700609 @Override
610 public void onUnlockMethodStateChanged() {
611 updateIndication(!mDozing);
612 }
613
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800614 protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
Adrian Roos56021892017-02-27 20:25:09 +0100615 public static final int HIDE_DELAY_MS = 5000;
Selim Cinek3e451942016-07-14 18:07:53 -0700616
Adrian Roos12c1ef52014-06-04 13:54:08 +0200617 @Override
618 public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100619 boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
Adrian Roos12c1ef52014-06-04 13:54:08 +0200620 || status.status == BatteryManager.BATTERY_STATUS_FULL;
Adrian Roos56021892017-02-27 20:25:09 +0100621 boolean wasPluggedIn = mPowerPluggedIn;
Beverly2034c832018-03-19 11:18:51 -0400622 mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100623 mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200624 mPowerCharged = status.isCharged();
Adrian Roos0c859ae2015-11-23 16:47:50 -0800625 mChargingWattage = status.maxChargingWattage;
Adrian Roos7b043112015-07-10 13:00:33 -0700626 mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
Lucas Dupin4272f442018-01-13 22:00:35 -0800627 mBatteryLevel = status.level;
Beverly2034c832018-03-19 11:18:51 -0400628 updateIndication(!wasPluggedIn && mPowerPluggedInWired);
Adrian Roosc1b50322017-02-27 21:07:58 +0100629 if (mDozing) {
630 if (!wasPluggedIn && mPowerPluggedIn) {
631 showTransientIndication(computePowerIndication());
632 hideTransientIndicationDelayed(HIDE_DELAY_MS);
633 } else if (wasPluggedIn && !mPowerPluggedIn) {
634 hideTransientIndication();
635 }
Adrian Roos56021892017-02-27 20:25:09 +0100636 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200637 }
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700638
639 @Override
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100640 public void onKeyguardVisibilityChanged(boolean showing) {
641 if (showing) {
642 updateDisclosure();
643 }
644 }
645
646 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200647 public void onBiometricHelp(int msgId, String helpString,
648 BiometricSourceType biometricSourceType) {
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700649 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200650 if (!updateMonitor.isUnlockingWithBiometricAllowed()) {
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700651 return;
652 }
Lucas Dupine54ad1d2019-04-09 17:08:46 -0700653 animatePadlockError();
Lucas Dupin51996bb2019-05-16 17:56:43 -0700654 boolean showSwipeToUnlock =
655 msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700656 if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
Jason Chang2386a372018-04-24 16:05:30 +0800657 mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
Lucas Dupinc2d11b32019-03-06 16:02:18 -0800658 mInitialTextColorState);
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700659 } else if (updateMonitor.isScreenOn()) {
Lucas Dupinc2d11b32019-03-06 16:02:18 -0800660 showTransientIndication(helpString);
Lucas Dupin51996bb2019-05-16 17:56:43 -0700661 if (!showSwipeToUnlock) {
662 hideTransientIndicationDelayed(TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
663 }
664 }
665 if (showSwipeToUnlock) {
666 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SWIPE_UP_TO_UNLOCK),
667 TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700668 }
669 }
670
671 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200672 public void onBiometricError(int msgId, String errString,
673 BiometricSourceType biometricSourceType) {
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700674 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200675 if (shouldSuppressBiometricError(msgId, biometricSourceType, updateMonitor)) {
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700676 return;
677 }
Lucas Dupine54ad1d2019-04-09 17:08:46 -0700678 animatePadlockError();
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700679 if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
Lucas Dupine54ad1d2019-04-09 17:08:46 -0700680 mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700681 } else if (updateMonitor.isScreenOn()) {
Lucas Dupinc2d11b32019-03-06 16:02:18 -0800682 showTransientIndication(errString);
Selim Cinek3e451942016-07-14 18:07:53 -0700683 // We want to keep this message around in case the screen was off
Adrian Roos56021892017-02-27 20:25:09 +0100684 hideTransientIndicationDelayed(HIDE_DELAY_MS);
Selim Cinek3e451942016-07-14 18:07:53 -0700685 } else {
686 mMessageToShowOnScreenOn = errString;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700687 }
Lucas Dupine54ad1d2019-04-09 17:08:46 -0700688 }
689
690 private void animatePadlockError() {
691 mLockIcon.setTransientBiometricsError(true);
692 mHandler.removeMessages(MSG_CLEAR_BIOMETRIC_MSG);
693 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_BIOMETRIC_MSG),
694 TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700695 }
696
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200697 private boolean shouldSuppressBiometricError(int msgId,
698 BiometricSourceType biometricSourceType, KeyguardUpdateMonitor updateMonitor) {
699 if (biometricSourceType == BiometricSourceType.FINGERPRINT)
700 return shouldSuppressFingerprintError(msgId, updateMonitor);
701 if (biometricSourceType == BiometricSourceType.FACE)
702 return shouldSuppressFaceError(msgId, updateMonitor);
703 return false;
704 }
705
706 private boolean shouldSuppressFingerprintError(int msgId,
707 KeyguardUpdateMonitor updateMonitor) {
708 return ((!updateMonitor.isUnlockingWithBiometricAllowed()
709 && msgId != FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT)
710 || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED);
711 }
712
713 private boolean shouldSuppressFaceError(int msgId, KeyguardUpdateMonitor updateMonitor) {
714 return ((!updateMonitor.isUnlockingWithBiometricAllowed()
715 && msgId != FaceManager.FACE_ERROR_LOCKOUT_PERMANENT)
716 || msgId == FaceManager.FACE_ERROR_CANCELED);
717 }
718
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700719 @Override
Lucas Dupinef886542018-01-03 16:03:07 -0800720 public void onTrustAgentErrorMessage(CharSequence message) {
Jason Chang2386a372018-04-24 16:05:30 +0800721 showTransientIndication(message, Utils.getColorError(mContext));
Lucas Dupinef886542018-01-03 16:03:07 -0800722 }
723
724 @Override
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700725 public void onScreenTurnedOn() {
726 if (mMessageToShowOnScreenOn != null) {
Jason Chang2386a372018-04-24 16:05:30 +0800727 showTransientIndication(mMessageToShowOnScreenOn, Utils.getColorError(mContext));
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700728 // We want to keep this message around in case the screen was off
Adrian Roos56021892017-02-27 20:25:09 +0100729 hideTransientIndicationDelayed(HIDE_DELAY_MS);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700730 mMessageToShowOnScreenOn = null;
731 }
732 }
733
734 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200735 public void onBiometricRunningStateChanged(boolean running,
736 BiometricSourceType biometricSourceType) {
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700737 if (running) {
Lucas Dupin8f3faac2019-03-12 15:28:49 -0700738 // Let's hide any previous messages when authentication starts, otherwise
739 // multiple auth attempts would overlap.
740 hideTransientIndication();
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700741 mMessageToShowOnScreenOn = null;
742 }
743 }
Selim Cinek3e451942016-07-14 18:07:53 -0700744
745 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200746 public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType) {
747 super.onBiometricAuthenticated(userId, biometricSourceType);
Kevin Chyn6d793bd2019-03-27 15:36:13 -0700748 mHandler.sendEmptyMessage(MSG_HIDE_TRANSIENT);
Selim Cinek3e451942016-07-14 18:07:53 -0700749 }
750
751 @Override
Jorim Jaggidadafd42016-09-30 07:20:25 -0700752 public void onUserUnlocked() {
753 if (mVisible) {
Beverly8c785892018-01-31 17:25:52 -0500754 updateIndication(false);
Jorim Jaggidadafd42016-09-30 07:20:25 -0700755 }
756 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700757 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200758}