blob: 85400a15dfc531aa122f27d4171a5c83378d79ca [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
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010019import android.app.admin.DevicePolicyManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020020import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
Adrian Roos7b043112015-07-10 13:00:33 -070024import android.content.res.Resources;
Jorim Jaggi27c9b742015-04-09 10:34:49 -070025import android.graphics.Color;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070026import android.hardware.fingerprint.FingerprintManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020027import android.os.BatteryManager;
28import android.os.BatteryStats;
29import android.os.Handler;
30import android.os.Message;
31import android.os.RemoteException;
32import android.os.ServiceManager;
33import android.os.UserHandle;
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -060034import android.os.UserManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020035import android.text.TextUtils;
36import android.text.format.Formatter;
37import android.util.Log;
38import android.view.View;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010039import android.view.ViewGroup;
Adrian Roos12c1ef52014-06-04 13:54:08 +020040
Adrian Roosc1b50322017-02-27 21:07:58 +010041import com.android.internal.annotations.VisibleForTesting;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070042import com.android.internal.app.IBatteryStats;
43import com.android.keyguard.KeyguardUpdateMonitor;
44import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jason Monk58be7a62017-02-01 20:17:51 -050045import com.android.settingslib.Utils;
Jason Monk9c7844c2017-01-18 15:21:53 -050046import com.android.systemui.Dependency;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070047import com.android.systemui.R;
48import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
49import com.android.systemui.statusbar.phone.LockIcon;
50import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
Zachary Iqbalf50284c2017-01-22 18:54:46 -080051import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roosc1b50322017-02-27 21:07:58 +010052import com.android.systemui.util.wakelock.SettableWakeLock;
53import com.android.systemui.util.wakelock.WakeLock;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070054
Adrian Roos12c1ef52014-06-04 13:54:08 +020055/**
Selim Cinekcfafe4e2015-08-11 14:58:44 -070056 * Controls the indications and error messages shown on the Keyguard
Adrian Roos12c1ef52014-06-04 13:54:08 +020057 */
58public class KeyguardIndicationController {
59
Adrian Roos0c859ae2015-11-23 16:47:50 -080060 private static final String TAG = "KeyguardIndication";
61 private static final boolean DEBUG_CHARGING_SPEED = false;
Adrian Roos12c1ef52014-06-04 13:54:08 +020062
63 private static final int MSG_HIDE_TRANSIENT = 1;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070064 private static final int MSG_CLEAR_FP_MSG = 2;
65 private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
Adrian Roos12c1ef52014-06-04 13:54:08 +020066
67 private final Context mContext;
Lucas Dupin987f1932017-05-13 21:02:52 -070068 private ViewGroup mIndicationArea;
69 private KeyguardIndicationTextView mTextView;
70 private KeyguardIndicationTextView mDisclosure;
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -060071 private final UserManager mUserManager;
Adrian Roos12c1ef52014-06-04 13:54:08 +020072 private final IBatteryStats mBatteryInfo;
Adrian Roosc1b50322017-02-27 21:07:58 +010073 private final SettableWakeLock mWakeLock;
Adrian Roos12c1ef52014-06-04 13:54:08 +020074
Adrian Roos7b043112015-07-10 13:00:33 -070075 private final int mSlowThreshold;
76 private final int mFastThreshold;
Lucas Dupin987f1932017-05-13 21:02:52 -070077 private LockIcon mLockIcon;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070078 private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
Adrian Roos7b043112015-07-10 13:00:33 -070079
Adrian Roos12c1ef52014-06-04 13:54:08 +020080 private String mRestingIndication;
Lucas Dupinef886542018-01-03 16:03:07 -080081 private CharSequence mTransientIndication;
Jorim Jaggi27c9b742015-04-09 10:34:49 -070082 private int mTransientTextColor;
Lucas Dupin53d50622017-05-13 15:54:14 -070083 private int mInitialTextColor;
Adrian Roos12c1ef52014-06-04 13:54:08 +020084 private boolean mVisible;
85
86 private boolean mPowerPluggedIn;
87 private boolean mPowerCharged;
Adrian Roos7b043112015-07-10 13:00:33 -070088 private int mChargingSpeed;
Adrian Roos0c859ae2015-11-23 16:47:50 -080089 private int mChargingWattage;
Selim Cinekcfafe4e2015-08-11 14:58:44 -070090 private String mMessageToShowOnScreenOn;
Adrian Roos12c1ef52014-06-04 13:54:08 +020091
Zachary Iqbal8f4c2422017-04-20 17:56:42 -070092 private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
Zachary Iqbalf50284c2017-01-22 18:54:46 -080093
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010094 private final DevicePolicyManager mDevicePolicyManager;
Adrian Roos91ba3072017-02-14 16:50:46 +010095 private boolean mDozing;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010096
Adrian Roosaf45b602017-03-14 13:10:25 -070097 /**
98 * Creates a new KeyguardIndicationController and registers callbacks.
99 */
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100100 public KeyguardIndicationController(Context context, ViewGroup indicationArea,
101 LockIcon lockIcon) {
Adrian Roosc1b50322017-02-27 21:07:58 +0100102 this(context, indicationArea, lockIcon,
103 WakeLock.createPartial(context, "Doze:KeyguardIndication"));
Adrian Roosaf45b602017-03-14 13:10:25 -0700104
105 registerCallbacks(KeyguardUpdateMonitor.getInstance(context));
Adrian Roosc1b50322017-02-27 21:07:58 +0100106 }
107
Adrian Roosaf45b602017-03-14 13:10:25 -0700108 /**
109 * Creates a new KeyguardIndicationController for testing. Does *not* register callbacks.
110 */
Adrian Roosc1b50322017-02-27 21:07:58 +0100111 @VisibleForTesting
112 KeyguardIndicationController(Context context, ViewGroup indicationArea, LockIcon lockIcon,
113 WakeLock wakeLock) {
Adrian Roos12c1ef52014-06-04 13:54:08 +0200114 mContext = context;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100115 mIndicationArea = indicationArea;
116 mTextView = (KeyguardIndicationTextView) indicationArea.findViewById(
117 R.id.keyguard_indication_text);
Lucas Dupin987f1932017-05-13 21:02:52 -0700118 mInitialTextColor = mTextView != null ? mTextView.getCurrentTextColor() : Color.WHITE;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100119 mDisclosure = (KeyguardIndicationTextView) indicationArea.findViewById(
120 R.id.keyguard_indication_enterprise_disclosure);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700121 mLockIcon = lockIcon;
Adrian Roosc1b50322017-02-27 21:07:58 +0100122 mWakeLock = new SettableWakeLock(wakeLock);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200123
Adrian Roos7b043112015-07-10 13:00:33 -0700124 Resources res = context.getResources();
125 mSlowThreshold = res.getInteger(R.integer.config_chargingSlowlyThreshold);
126 mFastThreshold = res.getInteger(R.integer.config_chargingFastThreshold);
127
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600128 mUserManager = context.getSystemService(UserManager.class);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200129 mBatteryInfo = IBatteryStats.Stub.asInterface(
130 ServiceManager.getService(BatteryStats.SERVICE_NAME));
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600131
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100132 mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(
133 Context.DEVICE_POLICY_SERVICE);
134
Adrian Roosaf45b602017-03-14 13:10:25 -0700135 updateDisclosure();
136 }
137
138 private void registerCallbacks(KeyguardUpdateMonitor monitor) {
139 monitor.registerCallback(getKeyguardCallback());
140
141 mContext.registerReceiverAsUser(mTickReceiver, UserHandle.SYSTEM,
Jason Monkcd26af72017-01-11 14:32:58 -0500142 new IntentFilter(Intent.ACTION_TIME_TICK), null,
Jason Monk9c7844c2017-01-18 15:21:53 -0500143 Dependency.get(Dependency.TIME_TICK_HANDLER));
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100144 }
145
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800146 /**
147 * Gets the {@link KeyguardUpdateMonitorCallback} instance associated with this
148 * {@link KeyguardIndicationController}.
149 *
150 * <p>Subclasses may override this method to extend or change the callback behavior by extending
151 * the {@link BaseKeyguardCallback}.
152 *
153 * @return A KeyguardUpdateMonitorCallback. Multiple calls to this method <b>must</b> return the
154 * same instance.
155 */
156 protected KeyguardUpdateMonitorCallback getKeyguardCallback() {
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700157 if (mUpdateMonitorCallback == null) {
158 mUpdateMonitorCallback = new BaseKeyguardCallback();
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800159 }
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700160 return mUpdateMonitorCallback;
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800161 }
162
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100163 private void updateDisclosure() {
164 if (mDevicePolicyManager == null) {
165 return;
166 }
167
Adrian Roos91ba3072017-02-14 16:50:46 +0100168 if (!mDozing && mDevicePolicyManager.isDeviceManaged()) {
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100169 final CharSequence organizationName =
170 mDevicePolicyManager.getDeviceOwnerOrganizationName();
171 if (organizationName != null) {
172 mDisclosure.switchIndication(mContext.getResources().getString(
173 R.string.do_disclosure_with_name, organizationName));
174 } else {
175 mDisclosure.switchIndication(R.string.do_disclosure_generic);
176 }
177 mDisclosure.setVisibility(View.VISIBLE);
178 } else {
179 mDisclosure.setVisibility(View.GONE);
180 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200181 }
182
183 public void setVisible(boolean visible) {
184 mVisible = visible;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100185 mIndicationArea.setVisibility(visible ? View.VISIBLE : View.GONE);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200186 if (visible) {
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700187 // If this is called after an error message was already shown, we should not clear it.
188 // Otherwise the error message won't be shown
189 if (!mHandler.hasMessages(MSG_HIDE_TRANSIENT)) {
190 hideTransientIndication();
191 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200192 updateIndication();
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700193 } else if (!visible) {
194 // If we unlock and return to keyguard quickly, previous error should not be shown
195 hideTransientIndication();
Adrian Roos12c1ef52014-06-04 13:54:08 +0200196 }
197 }
198
199 /**
200 * Sets the indication that is shown if nothing else is showing.
201 */
202 public void setRestingIndication(String restingIndication) {
203 mRestingIndication = restingIndication;
204 updateIndication();
205 }
206
207 /**
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800208 * Sets the active controller managing changes and callbacks to user information.
209 */
210 public void setUserInfoController(UserInfoController userInfoController) {
211 }
212
213 /**
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700214 * Returns the indication text indicating that trust has been granted.
215 *
216 * @return {@code null} or an empty string if a trust indication text should not be shown.
217 */
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700218 protected String getTrustGrantedIndication() {
219 return null;
220 }
221
222 /**
223 * Returns the indication text indicating that trust is currently being managed.
224 *
225 * @return {@code null} or an empty string if a trust managed text should not be shown.
226 */
227 protected String getTrustManagedIndication() {
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700228 return null;
229 }
230
231 /**
Adrian Roos12c1ef52014-06-04 13:54:08 +0200232 * Hides transient indication in {@param delayMs}.
233 */
234 public void hideTransientIndicationDelayed(long delayMs) {
235 mHandler.sendMessageDelayed(
236 mHandler.obtainMessage(MSG_HIDE_TRANSIENT), delayMs);
237 }
238
239 /**
240 * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
241 */
242 public void showTransientIndication(int transientIndication) {
243 showTransientIndication(mContext.getResources().getString(transientIndication));
244 }
245
246 /**
247 * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
248 */
Lucas Dupinef886542018-01-03 16:03:07 -0800249 public void showTransientIndication(CharSequence transientIndication) {
Lucas Dupin53d50622017-05-13 15:54:14 -0700250 showTransientIndication(transientIndication, mInitialTextColor);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700251 }
252
253 /**
254 * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
255 */
Lucas Dupinef886542018-01-03 16:03:07 -0800256 public void showTransientIndication(CharSequence transientIndication, int textColor) {
Adrian Roos12c1ef52014-06-04 13:54:08 +0200257 mTransientIndication = transientIndication;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700258 mTransientTextColor = textColor;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200259 mHandler.removeMessages(MSG_HIDE_TRANSIENT);
Adrian Roosc1b50322017-02-27 21:07:58 +0100260 if (mDozing && !TextUtils.isEmpty(mTransientIndication)) {
261 // Make sure this doesn't get stuck and burns in. Acquire wakelock until its cleared.
262 mWakeLock.setAcquired(true);
263 hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
264 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200265 updateIndication();
266 }
267
268 /**
269 * Hides transient indication.
270 */
271 public void hideTransientIndication() {
272 if (mTransientIndication != null) {
273 mTransientIndication = null;
274 mHandler.removeMessages(MSG_HIDE_TRANSIENT);
275 updateIndication();
276 }
277 }
278
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700279 protected final void updateIndication() {
Adrian Roosc1b50322017-02-27 21:07:58 +0100280 if (TextUtils.isEmpty(mTransientIndication)) {
281 mWakeLock.setAcquired(false);
282 }
283
Adrian Roos12c1ef52014-06-04 13:54:08 +0200284 if (mVisible) {
Lucas Dupin53d50622017-05-13 15:54:14 -0700285 // Walk down a precedence-ordered list of what indication
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600286 // should be shown based on user or device state
Adrian Roos91ba3072017-02-14 16:50:46 +0100287 if (mDozing) {
288 // If we're dozing, never show a persistent indication.
289 if (!TextUtils.isEmpty(mTransientIndication)) {
Adrian Roos12e112d2017-07-25 16:46:23 +0200290 // When dozing we ignore any text color and use white instead, because
291 // colors can be hard to read in low brightness.
292 mTextView.setTextColor(Color.WHITE);
Adrian Roos91ba3072017-02-14 16:50:46 +0100293 mTextView.switchIndication(mTransientIndication);
Adrian Roos91ba3072017-02-14 16:50:46 +0100294 } else {
295 mTextView.switchIndication(null);
296 }
297 return;
298 }
299
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700300 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
Jorim Jaggifabc7432017-05-15 02:40:05 +0200301 int userId = KeyguardUpdateMonitor.getCurrentUser();
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700302 String trustGrantedIndication = getTrustGrantedIndication();
303 String trustManagedIndication = getTrustManagedIndication();
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700304 if (!mUserManager.isUserUnlocked(userId)) {
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600305 mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
Lucas Dupin53d50622017-05-13 15:54:14 -0700306 mTextView.setTextColor(mInitialTextColor);
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600307 } else if (!TextUtils.isEmpty(mTransientIndication)) {
308 mTextView.switchIndication(mTransientIndication);
309 mTextView.setTextColor(mTransientTextColor);
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700310 } else if (!TextUtils.isEmpty(trustGrantedIndication)
Zachary Iqbal8f4c2422017-04-20 17:56:42 -0700311 && updateMonitor.getUserHasTrust(userId)) {
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700312 mTextView.switchIndication(trustGrantedIndication);
Lucas Dupin53d50622017-05-13 15:54:14 -0700313 mTextView.setTextColor(mInitialTextColor);
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600314 } else if (mPowerPluggedIn) {
315 String indication = computePowerIndication();
316 if (DEBUG_CHARGING_SPEED) {
317 indication += ", " + (mChargingWattage / 1000) + " mW";
318 }
319 mTextView.switchIndication(indication);
Lucas Dupin53d50622017-05-13 15:54:14 -0700320 mTextView.setTextColor(mInitialTextColor);
Zachary Iqbaldc05aa02017-05-17 18:52:49 -0700321 } else if (!TextUtils.isEmpty(trustManagedIndication)
322 && updateMonitor.getUserTrustIsManaged(userId)
323 && !updateMonitor.getUserHasTrust(userId)) {
324 mTextView.switchIndication(trustManagedIndication);
Lucas Dupin53d50622017-05-13 15:54:14 -0700325 mTextView.setTextColor(mInitialTextColor);
Jeff Sharkeyb6edaa92016-07-27 15:51:31 -0600326 } else {
327 mTextView.switchIndication(mRestingIndication);
Lucas Dupin53d50622017-05-13 15:54:14 -0700328 mTextView.setTextColor(mInitialTextColor);
Adrian Roos7b043112015-07-10 13:00:33 -0700329 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200330 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200331 }
332
333 private String computePowerIndication() {
334 if (mPowerCharged) {
335 return mContext.getResources().getString(R.string.keyguard_charged);
336 }
337
338 // Try fetching charging time from battery stats.
Adrian Roos7e39e592015-09-23 17:03:47 -0700339 long chargingTimeRemaining = 0;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200340 try {
Adrian Roos7e39e592015-09-23 17:03:47 -0700341 chargingTimeRemaining = mBatteryInfo.computeChargeTimeRemaining();
342
Adrian Roos12c1ef52014-06-04 13:54:08 +0200343 } catch (RemoteException e) {
344 Log.e(TAG, "Error calling IBatteryStats: ", e);
345 }
Adrian Roos7e39e592015-09-23 17:03:47 -0700346 final boolean hasChargingTime = chargingTimeRemaining > 0;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200347
Adrian Roos7b043112015-07-10 13:00:33 -0700348 int chargingId;
349 switch (mChargingSpeed) {
350 case KeyguardUpdateMonitor.BatteryStatus.CHARGING_FAST:
Adrian Roos7e39e592015-09-23 17:03:47 -0700351 chargingId = hasChargingTime
Adrian Roosf142cac2015-09-25 15:15:17 -0700352 ? R.string.keyguard_indication_charging_time_fast
Adrian Roos7e39e592015-09-23 17:03:47 -0700353 : R.string.keyguard_plugged_in_charging_fast;
Adrian Roos7b043112015-07-10 13:00:33 -0700354 break;
355 case KeyguardUpdateMonitor.BatteryStatus.CHARGING_SLOWLY:
Adrian Roos7e39e592015-09-23 17:03:47 -0700356 chargingId = hasChargingTime
Adrian Roosf142cac2015-09-25 15:15:17 -0700357 ? R.string.keyguard_indication_charging_time_slowly
Adrian Roos7e39e592015-09-23 17:03:47 -0700358 : R.string.keyguard_plugged_in_charging_slowly;
Adrian Roos7b043112015-07-10 13:00:33 -0700359 break;
360 default:
Adrian Roos7e39e592015-09-23 17:03:47 -0700361 chargingId = hasChargingTime
362 ? R.string.keyguard_indication_charging_time
363 : R.string.keyguard_plugged_in;
Adrian Roos7b043112015-07-10 13:00:33 -0700364 break;
365 }
Adrian Roos7e39e592015-09-23 17:03:47 -0700366
367 if (hasChargingTime) {
368 String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
369 mContext, chargingTimeRemaining);
370 return mContext.getResources().getString(chargingId, chargingTimeFormatted);
371 } else {
372 return mContext.getResources().getString(chargingId);
373 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200374 }
375
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800376 public void setStatusBarKeyguardViewManager(
377 StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
378 mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
379 }
380
Adrian Roosaf45b602017-03-14 13:10:25 -0700381 private final BroadcastReceiver mTickReceiver = new BroadcastReceiver() {
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800382 @Override
383 public void onReceive(Context context, Intent intent) {
384 mHandler.post(() -> {
385 if (mVisible) {
386 updateIndication();
387 }
388 });
389 }
390 };
391
392 private final Handler mHandler = new Handler() {
393 @Override
394 public void handleMessage(Message msg) {
Adrian Roosc1b50322017-02-27 21:07:58 +0100395 if (msg.what == MSG_HIDE_TRANSIENT) {
396 hideTransientIndication();
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800397 } else if (msg.what == MSG_CLEAR_FP_MSG) {
398 mLockIcon.setTransientFpError(false);
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800399 }
400 }
401 };
402
Adrian Roos91ba3072017-02-14 16:50:46 +0100403 public void setDozing(boolean dozing) {
Jorim Jaggifabc7432017-05-15 02:40:05 +0200404 if (mDozing == dozing) {
405 return;
406 }
Adrian Roos91ba3072017-02-14 16:50:46 +0100407 mDozing = dozing;
408 updateIndication();
409 updateDisclosure();
410 }
411
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800412 protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
Adrian Roos56021892017-02-27 20:25:09 +0100413 public static final int HIDE_DELAY_MS = 5000;
Zachary Iqbalf50284c2017-01-22 18:54:46 -0800414 private int mLastSuccessiveErrorMessage = -1;
Selim Cinek3e451942016-07-14 18:07:53 -0700415
Adrian Roos12c1ef52014-06-04 13:54:08 +0200416 @Override
417 public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100418 boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
Adrian Roos12c1ef52014-06-04 13:54:08 +0200419 || status.status == BatteryManager.BATTERY_STATUS_FULL;
Adrian Roos56021892017-02-27 20:25:09 +0100420 boolean wasPluggedIn = mPowerPluggedIn;
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100421 mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200422 mPowerCharged = status.isCharged();
Adrian Roos0c859ae2015-11-23 16:47:50 -0800423 mChargingWattage = status.maxChargingWattage;
Adrian Roos7b043112015-07-10 13:00:33 -0700424 mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200425 updateIndication();
Adrian Roosc1b50322017-02-27 21:07:58 +0100426 if (mDozing) {
427 if (!wasPluggedIn && mPowerPluggedIn) {
428 showTransientIndication(computePowerIndication());
429 hideTransientIndicationDelayed(HIDE_DELAY_MS);
430 } else if (wasPluggedIn && !mPowerPluggedIn) {
431 hideTransientIndication();
432 }
Adrian Roos56021892017-02-27 20:25:09 +0100433 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200434 }
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700435
436 @Override
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100437 public void onKeyguardVisibilityChanged(boolean showing) {
438 if (showing) {
439 updateDisclosure();
440 }
441 }
442
443 @Override
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700444 public void onFingerprintHelp(int msgId, String helpString) {
445 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
446 if (!updateMonitor.isUnlockingWithFingerprintAllowed()) {
447 return;
448 }
Jason Monk58be7a62017-02-01 20:17:51 -0500449 int errorColor = Utils.getColorError(mContext);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700450 if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
451 mStatusBarKeyguardViewManager.showBouncerMessage(helpString, errorColor);
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700452 } else if (updateMonitor.isScreenOn()) {
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700453 mLockIcon.setTransientFpError(true);
454 showTransientIndication(helpString, errorColor);
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700455 hideTransientIndicationDelayed(TRANSIENT_FP_ERROR_TIMEOUT);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700456 mHandler.removeMessages(MSG_CLEAR_FP_MSG);
457 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_FP_MSG),
458 TRANSIENT_FP_ERROR_TIMEOUT);
459 }
Selim Cinek3e451942016-07-14 18:07:53 -0700460 // Help messages indicate that there was actually a try since the last error, so those
461 // are not two successive error messages anymore.
462 mLastSuccessiveErrorMessage = -1;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700463 }
464
465 @Override
466 public void onFingerprintError(int msgId, String errString) {
467 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700468 if ((!updateMonitor.isUnlockingWithFingerprintAllowed()
469 && msgId != FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT)
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700470 || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
471 return;
472 }
Jason Monk58be7a62017-02-01 20:17:51 -0500473 int errorColor = Utils.getColorError(mContext);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700474 if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
Selim Cinek3e451942016-07-14 18:07:53 -0700475 // When swiping up right after receiving a fingerprint error, the bouncer calls
476 // authenticate leading to the same message being shown again on the bouncer.
477 // We want to avoid this, as it may confuse the user when the message is too
478 // generic.
479 if (mLastSuccessiveErrorMessage != msgId) {
480 mStatusBarKeyguardViewManager.showBouncerMessage(errString, errorColor);
481 }
Kevin Chyn4c4001c2017-08-25 14:23:36 -0700482 } else if (updateMonitor.isScreenOn()) {
Selim Cinek3e451942016-07-14 18:07:53 -0700483 showTransientIndication(errString, errorColor);
484 // We want to keep this message around in case the screen was off
Adrian Roos56021892017-02-27 20:25:09 +0100485 hideTransientIndicationDelayed(HIDE_DELAY_MS);
Selim Cinek3e451942016-07-14 18:07:53 -0700486 } else {
487 mMessageToShowOnScreenOn = errString;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700488 }
Selim Cinek3e451942016-07-14 18:07:53 -0700489 mLastSuccessiveErrorMessage = msgId;
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700490 }
491
492 @Override
Lucas Dupinef886542018-01-03 16:03:07 -0800493 public void onTrustAgentErrorMessage(CharSequence message) {
494 int errorColor = Utils.getColorError(mContext);
495 showTransientIndication(message, errorColor);
496 }
497
498 @Override
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700499 public void onScreenTurnedOn() {
500 if (mMessageToShowOnScreenOn != null) {
Jason Monk58be7a62017-02-01 20:17:51 -0500501 int errorColor = Utils.getColorError(mContext);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700502 showTransientIndication(mMessageToShowOnScreenOn, errorColor);
503 // We want to keep this message around in case the screen was off
Adrian Roos56021892017-02-27 20:25:09 +0100504 hideTransientIndicationDelayed(HIDE_DELAY_MS);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700505 mMessageToShowOnScreenOn = null;
506 }
507 }
508
509 @Override
510 public void onFingerprintRunningStateChanged(boolean running) {
511 if (running) {
512 mMessageToShowOnScreenOn = null;
513 }
514 }
Selim Cinek3e451942016-07-14 18:07:53 -0700515
516 @Override
517 public void onFingerprintAuthenticated(int userId) {
518 super.onFingerprintAuthenticated(userId);
519 mLastSuccessiveErrorMessage = -1;
520 }
521
522 @Override
523 public void onFingerprintAuthFailed() {
524 super.onFingerprintAuthFailed();
525 mLastSuccessiveErrorMessage = -1;
526 }
Jorim Jaggidadafd42016-09-30 07:20:25 -0700527
528 @Override
529 public void onUserUnlocked() {
530 if (mVisible) {
531 updateIndication();
532 }
533 }
Adrian Roos12c1ef52014-06-04 13:54:08 +0200534 };
Adrian Roos12c1ef52014-06-04 13:54:08 +0200535}