11f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/*
21f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
31f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
41f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
51f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * you may not use this file except in compliance with the License.
61f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * You may obtain a copy of the License at
71f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
81f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
91f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * See the License for the specific language governing permissions and
141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * limitations under the License.
151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
175ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
19dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggiimport static android.content.Intent.ACTION_USER_UNLOCKED;
20e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
21e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.BATTERY_STATUS_FULL;
22e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
23e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.EXTRA_HEALTH;
24e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.EXTRA_LEVEL;
25e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
26e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
27e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.EXTRA_PLUGGED;
28e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport static android.os.BatteryManager.EXTRA_STATUS;
29e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi
30ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggiimport android.app.ActivityManager;
31c7dea6ee9b06369b0c0c3773dc2e40409ce86a8eJorim Jaggiimport android.app.AlarmManager;
328f09fd2e3123c7713d50886dc3745d330a1879c5Jim Millerimport android.app.PendingIntent;
332c4522cc1bf3a3d0178688427a33b860ddfe4bbaSudheer Shankaimport android.app.UserSwitchObserver;
34b030476d193a423f6c1baf3053f66fc768c925e0Jim Millerimport android.app.admin.DevicePolicyManager;
3546842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roosimport android.app.trust.TrustManager;
361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.BroadcastReceiver;
37031f79560f65499281bbb500c36e57724d7b514aJorim Jaggiimport android.content.ComponentName;
381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.IntentFilter;
41031f79560f65499281bbb500c36e57724d7b514aJorim Jaggiimport android.content.pm.PackageManager;
42031f79560f65499281bbb500c36e57724d7b514aJorim Jaggiimport android.content.pm.ResolveInfo;
431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.database.ContentObserver;
448f09fd2e3123c7713d50886dc3745d330a1879c5Jim Millerimport android.graphics.Bitmap;
4586bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggiimport android.hardware.fingerprint.FingerprintManager;
4686bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggiimport android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
4786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggiimport android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
4847088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Millerimport android.media.AudioManager;
4979a444a0cd78bc6528e19336a0d49ef4a17b263cJim Millerimport android.os.BatteryManager;
509f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport android.os.CancellationSignal;
511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Handler;
525dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackbornimport android.os.IRemoteCallback;
531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Message;
545dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackbornimport android.os.RemoteException;
554cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggiimport android.os.SystemClock;
561d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniersimport android.os.Trace;
57e8e93a143eaec158450c146e96e8fe05fd2401e7Amith Yamasaniimport android.os.UserHandle;
58e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport android.os.UserManager;
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.provider.Settings;
6047051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohenimport android.telephony.ServiceState;
6152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Millerimport android.telephony.SubscriptionInfo;
6252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Millerimport android.telephony.SubscriptionManager;
63d09c4cad65c708f2c4810d24295456708a2000d2Wink Savilleimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
64c23024d32779b170dde32a50fbdd945ce521b874Jim Millerimport android.telephony.TelephonyManager;
6525b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggiimport android.util.ArraySet;
661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
6746842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roosimport android.util.SparseBooleanArray;
689f74303eb8432aa64a7030f58ab0c3279a20c53eJorim Jaggiimport android.util.SparseIntArray;
6946842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos
701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.google.android.collect.Lists;
711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7286bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggiimport com.android.internal.telephony.IccCardConstants;
7386bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggiimport com.android.internal.telephony.IccCardConstants.State;
7486bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggiimport com.android.internal.telephony.PhoneConstants;
7586bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggiimport com.android.internal.telephony.TelephonyIntents;
76b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport com.android.internal.widget.LockPatternUtils;
7786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi
78ab5252726211069daf558d40da75e544c341c63bJason Monkimport java.io.FileDescriptor;
79ab5252726211069daf558d40da75e544c341c63bJason Monkimport java.io.PrintWriter;
80dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport java.lang.ref.WeakReference;
811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.ArrayList;
8252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Millerimport java.util.HashMap;
8352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Millerimport java.util.List;
8452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Millerimport java.util.Map.Entry;
851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Watches for updates that may be interesting to the keyguard, and provides
881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * the up to date information as well as a registration for callbacks that care
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * to be updated.
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Note: under time crunch, this has been extended to include some stuff that
921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * doesn't really belong here.  see {@link #handleBatteryUpdate} where it shutdowns
93258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
94258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller * and {@link #clearFailedUnlockAttempts()}.  Maybe we should rename this 'KeyguardContext'...
951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
9646842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roospublic class KeyguardUpdateMonitor implements TrustManager.TrustListener {
971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
98bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final String TAG = "KeyguardUpdateMonitor";
995cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi    private static final boolean DEBUG = KeyguardConstants.DEBUG;
10052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
101bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int LOW_BATTERY_THRESHOLD = 20;
1021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
103e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi    private static final String ACTION_FACE_UNLOCK_STARTED
104e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi            = "com.android.facelock.FACE_UNLOCK_STARTED";
105e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi    private static final String ACTION_FACE_UNLOCK_STOPPED
106e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi            = "com.android.facelock.FACE_UNLOCK_STOPPED";
107e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi
108bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    // Callback messages
109bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_TIME_UPDATE = 301;
110bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_BATTERY_UPDATE = 302;
111bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_SIM_STATE_CHANGE = 304;
112bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_RINGER_MODE_CHANGED = 305;
113bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_PHONE_STATE_CHANGED = 306;
114bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private static final int MSG_DEVICE_PROVISIONED = 308;
1155737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private static final int MSG_DPM_STATE_CHANGED = 309;
116f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    private static final int MSG_USER_SWITCHING = 310;
1171fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    private static final int MSG_KEYGUARD_RESET = 312;
118f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    private static final int MSG_BOOT_COMPLETED = 313;
119f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    private static final int MSG_USER_SWITCH_COMPLETE = 314;
120f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    private static final int MSG_USER_INFO_CHANGED = 317;
121f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
1220d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    private static final int MSG_STARTED_WAKING_UP = 319;
1230d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
12495e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
125b601162a60663329355720083bfa199909dbf6efAdrian Roos    private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
126ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
127ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
128052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk    private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
12947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen    private static final int MSG_SERVICE_STATE_CHANGE = 330;
130f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private static final int MSG_SCREEN_TURNED_ON = 331;
131f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private static final int MSG_SCREEN_TURNED_OFF = 332;
132994153944e6d76d1b1a060afb131129172a915d1Selim Cinek    private static final int MSG_DREAMING_STATE_CHANGED = 333;
133dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi    private static final int MSG_USER_UNLOCKED = 334;
1341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
13586bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    /** Fingerprint state: Not listening to fingerprint. */
13686bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    private static final int FINGERPRINT_STATE_STOPPED = 0;
13786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi
13886bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    /** Fingerprint state: Listening. */
13986bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    private static final int FINGERPRINT_STATE_RUNNING = 1;
14086bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi
14186bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    /**
14286bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi     * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
14386bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi     * send us the confirmation that cancellation has happened.
14486bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi     */
14586bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    private static final int FINGERPRINT_STATE_CANCELLING = 2;
14686bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi
14786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    /**
14886bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi     * Fingerprint state: During cancelling we got another request to start listening, so when we
14986bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi     * receive the cancellation done signal, we should start listening again.
15086bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi     */
15186bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
15286bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi
1530c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos    private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
1540c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos
155031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi    private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
156031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi            "com.android.settings", "com.android.settings.FallbackHome");
157031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi
158dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private static KeyguardUpdateMonitor sInstance;
159dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final Context mContext;
16152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
16247051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen    HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
1631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
164bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private int mRingMode;
165bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private int mPhoneState;
1665d2404da57926736317c1a08d989cd55784ef8a1Danielle Millett    private boolean mKeyguardIsVisible;
1676db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn    private boolean mKeyguardGoingAway;
16895e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    private boolean mGoingToSleep;
169b601162a60663329355720083bfa199909dbf6efAdrian Roos    private boolean mBouncer;
1704eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    private boolean mBootCompleted;
171031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi    private boolean mNeedsSlowUnlockTransition;
172d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi    private boolean mHasLockscreenWallpaper;
1731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
174dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Device provisioning state
1751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mDeviceProvisioned;
17647088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
177dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Battery status
17816464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller    private BatteryStatus mBatteryStatus;
17979a444a0cd78bc6528e19336a0d49ef4a17b263cJim Miller
180dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Password attempts
1819f74303eb8432aa64a7030f58ab0c3279a20c53eJorim Jaggi    private SparseIntArray mFailedAttempts = new SparseIntArray();
182cc4104fd71225ed092f16b11882d9a10084e34acBrian Colonna
183a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer    private final StrongAuthTracker mStrongAuthTracker;
184054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
1856212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
186dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mCallbacks = Lists.newArrayList();
187fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private ContentObserver mDeviceProvisionedObserver;
1881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
189a5239891dc324db21beb87535f90ea76fba803b9Brian Colonna    private boolean mSwitchingUser;
190a5239891dc324db21beb87535f90ea76fba803b9Brian Colonna
1910d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    private boolean mDeviceInteractive;
19220daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    private boolean mScreenOn;
193d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville    private SubscriptionManager mSubscriptionManager;
194d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville    private List<SubscriptionInfo> mSubscriptionInfo;
195237b061182d36fd3bf2238092ccf3d529ec8877bJorim Jaggi    private TrustManager mTrustManager;
196e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi    private UserManager mUserManager;
19786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
198c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski    private LockPatternUtils mLockPatternUtils;
19920daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
2000c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn    // If FP daemon dies, keyguard should retry after a short delay
2010c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn    private int mHardwareUnavailableRetryCount = 0;
2020c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn    private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
2030c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn    private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
2040c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn
205bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private final Handler mHandler = new Handler() {
206bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        @Override
207bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public void handleMessage(Message msg) {
208bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            switch (msg.what) {
209bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_TIME_UPDATE:
210bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleTimeUpdate();
211bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
212bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_BATTERY_UPDATE:
213bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleBatteryUpdate((BatteryStatus) msg.obj);
214bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
215bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_SIM_STATE_CHANGE:
21652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                    handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
217bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
218bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_RINGER_MODE_CHANGED:
219bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleRingerModeChange(msg.arg1);
220bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
221bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_PHONE_STATE_CHANGED:
222b601162a60663329355720083bfa199909dbf6efAdrian Roos                    handlePhoneStateChanged((String) msg.obj);
223bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
224bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_DEVICE_PROVISIONED:
225bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleDeviceProvisioned();
226bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
227bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                case MSG_DPM_STATE_CHANGED:
228bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    handleDevicePolicyManagerStateChanged();
229bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
230f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                case MSG_USER_SWITCHING:
231b601162a60663329355720083bfa199909dbf6efAdrian Roos                    handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
232f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                    break;
233f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                case MSG_USER_SWITCH_COMPLETE:
234f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                    handleUserSwitchComplete(msg.arg1);
235bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    break;
2361fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek                case MSG_KEYGUARD_RESET:
2371fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek                    handleKeyguardReset();
2381fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek                    break;
239b601162a60663329355720083bfa199909dbf6efAdrian Roos                case MSG_KEYGUARD_BOUNCER_CHANGED:
240b601162a60663329355720083bfa199909dbf6efAdrian Roos                    handleKeyguardBouncerChanged(msg.arg1);
241b601162a60663329355720083bfa199909dbf6efAdrian Roos                    break;
242efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                case MSG_BOOT_COMPLETED:
243efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                    handleBootCompleted();
244efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                    break;
2456fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani                case MSG_USER_INFO_CHANGED:
2466fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani                    handleUserInfoChanged(msg.arg1);
2476fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani                    break;
2487fce38021694925295f5d14bfba71f28cba19404Brian Colonna                case MSG_REPORT_EMERGENCY_CALL_ACTION:
2497fce38021694925295f5d14bfba71f28cba19404Brian Colonna                    handleReportEmergencyCallAction();
2507fce38021694925295f5d14bfba71f28cba19404Brian Colonna                    break;
25195e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi                case MSG_STARTED_GOING_TO_SLEEP:
25295e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi                    handleStartedGoingToSleep(msg.arg1);
25395e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi                    break;
2540d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi                case MSG_FINISHED_GOING_TO_SLEEP:
2550d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi                    handleFinishedGoingToSleep(msg.arg1);
25620daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller                    break;
2570d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi                case MSG_STARTED_WAKING_UP:
2581d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                    Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
2590d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi                    handleStartedWakingUp();
2601d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                    Trace.endSection();
26120daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller                    break;
262e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi                case MSG_FACE_UNLOCK_STATE_CHANGED:
2631d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                    Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
2644a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos                    handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
2651d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                    Trace.endSection();
266e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi                    break;
26752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
26852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                    handleSimSubscriptionInfoChanged();
26952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                    break;
270052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk                case MSG_AIRPLANE_MODE_CHANGED:
271052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk                    handleAirplaneModeChanged();
272052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk                    break;
27347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                case MSG_SERVICE_STATE_CHANGE:
27447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
27547051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    break;
276f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                case MSG_SCREEN_TURNED_ON:
277f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                    handleScreenTurnedOn();
278f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                    break;
279f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                case MSG_SCREEN_TURNED_OFF:
2801d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                    Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
281f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                    handleScreenTurnedOff();
2821d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                    Trace.endSection();
283f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                    break;
284994153944e6d76d1b1a060afb131129172a915d1Selim Cinek                case MSG_DREAMING_STATE_CHANGED:
285994153944e6d76d1b1a060afb131129172a915d1Selim Cinek                    handleDreamingStateChanged(msg.arg1);
286994153944e6d76d1b1a060afb131129172a915d1Selim Cinek                    break;
287dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi                case MSG_USER_UNLOCKED:
288dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi                    handleUserUnlocked();
289dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi                    break;
290bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            }
291bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
292bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    };
293bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
294d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville    private OnSubscriptionsChangedListener mSubscriptionListener =
295d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            new OnSubscriptionsChangedListener() {
29652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        @Override
297d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        public void onSubscriptionsChanged() {
29852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
29952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
30052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    };
30152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
30246842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos    private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
3037861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
3049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
3054a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
30646842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos
307d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos    private static int sCurrentUser;
308d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos
309d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos    public synchronized static void setCurrentUser(int currentUser) {
310d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos        sCurrentUser = currentUser;
311d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos    }
312d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos
313d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos    public synchronized static int getCurrentUser() {
314d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos        return sCurrentUser;
315d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos    }
316d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos
31746842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos    @Override
31894e15a59b757678949cccb5d783bee1638e84697Adrian Roos    public void onTrustChanged(boolean enabled, int userId, int flags) {
31946842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos        mUserHasTrust.put(userId, enabled);
3202fe592d49b20826f998e26cbc63ed0c0deff46c1Adrian Roos        for (int i = 0; i < mCallbacks.size(); i++) {
3212fe592d49b20826f998e26cbc63ed0c0deff46c1Adrian Roos            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
3222fe592d49b20826f998e26cbc63ed0c0deff46c1Adrian Roos            if (cb != null) {
3232fe592d49b20826f998e26cbc63ed0c0deff46c1Adrian Roos                cb.onTrustChanged(userId);
32494e15a59b757678949cccb5d783bee1638e84697Adrian Roos                if (enabled && flags != 0) {
32594e15a59b757678949cccb5d783bee1638e84697Adrian Roos                    cb.onTrustGrantedWithFlags(flags, userId);
3263c9a3501651aa8ad4f289e89119a6c0b4bdaf78aAdrian Roos                }
3272fe592d49b20826f998e26cbc63ed0c0deff46c1Adrian Roos            }
3282fe592d49b20826f998e26cbc63ed0c0deff46c1Adrian Roos        }
32946842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos    }
33046842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos
33152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    protected void handleSimSubscriptionInfoChanged() {
33252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        if (DEBUG_SIM_STATES) {
33352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            Log.v(TAG, "onSubscriptionInfoChanged()");
334d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
335d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            if (sil != null) {
336d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville                for (SubscriptionInfo subInfo : sil) {
337d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville                    Log.v(TAG, "SubInfo:" + subInfo);
338d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville                }
339d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            } else {
340d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville                Log.v(TAG, "onSubscriptionInfoChanged: list is null");
34152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            }
34252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
34352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
34452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
34552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // Hack level over 9000: Because the subscription id is not yet valid when we see the
34652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // first update in handleSimStateChange, we need to force refresh all all SIM states
34752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // so the subscription id for them is consistent.
34801ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
34952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        for (int i = 0; i < subscriptionInfos.size(); i++) {
35052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            SubscriptionInfo info = subscriptionInfos.get(i);
35101ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
35201ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            if (changed) {
35301ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi                changedSubscriptions.add(info);
35401ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            }
35552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
35601ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        for (int i = 0; i < changedSubscriptions.size(); i++) {
35701ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
35852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            for (int j = 0; j < mCallbacks.size(); j++) {
35952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
36052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                if (cb != null) {
36152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                    cb.onSimStateChanged(data.subId, data.slotId, data.simState);
36252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                }
36352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            }
36452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
3656c985dcc2d6276c3d4f7598ee066bd8e1fd82710Jason Monk        for (int j = 0; j < mCallbacks.size(); j++) {
3666c985dcc2d6276c3d4f7598ee066bd8e1fd82710Jason Monk            KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
3676c985dcc2d6276c3d4f7598ee066bd8e1fd82710Jason Monk            if (cb != null) {
3686c985dcc2d6276c3d4f7598ee066bd8e1fd82710Jason Monk                cb.onRefreshCarrierInfo();
3696c985dcc2d6276c3d4f7598ee066bd8e1fd82710Jason Monk            }
3706c985dcc2d6276c3d4f7598ee066bd8e1fd82710Jason Monk        }
37152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    }
37252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
373052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk    private void handleAirplaneModeChanged() {
374052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk        for (int j = 0; j < mCallbacks.size(); j++) {
375052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk            KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
376052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk            if (cb != null) {
377052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk                cb.onRefreshCarrierInfo();
378052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk            }
379052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk        }
380052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk    }
381052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk
382d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville    /** @return List of SubscriptionInfo records, maybe empty but never null */
383316bf544843ae581336fa157355c76774e0e0cbcAdrian Roos    public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
384d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        List<SubscriptionInfo> sil = mSubscriptionInfo;
385d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        if (sil == null || forceReload) {
386d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            sil = mSubscriptionManager.getActiveSubscriptionInfoList();
387d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        }
388d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        if (sil == null) {
389d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            // getActiveSubscriptionInfoList was null callers expect an empty list.
390d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
391d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        } else {
392d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville            mSubscriptionInfo = sil;
39352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
39452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        return mSubscriptionInfo;
39552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    }
39652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
3977861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    @Override
3987861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    public void onTrustManagedChanged(boolean managed, int userId) {
3997861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        mUserTrustIsManaged.put(userId, managed);
4007861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
4017861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        for (int i = 0; i < mCallbacks.size(); i++) {
4027861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
4037861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            if (cb != null) {
4047861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                cb.onTrustManagedChanged(userId);
4057861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            }
4067861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        }
4077861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    }
4087861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
4096db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn    /**
4106db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn     * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
4116db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn     * @param goingAway
4126db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn     */
4136db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn    public void setKeyguardGoingAway(boolean goingAway) {
4146db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn        mKeyguardGoingAway = goingAway;
4156db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn    }
4166db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn
41783eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi    private void onFingerprintAuthenticated(int userId) {
4181d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
4199f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mUserFingerprintAuthenticated.put(userId, true);
420625a014006d63ddb59c4b3b7520f0b14afbc18a3Kevin Chyn        // Don't send cancel if authentication succeeds
421625a014006d63ddb59c4b3b7520f0b14afbc18a3Kevin Chyn        mFingerprintCancelSignal = null;
422f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
423f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
424f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller            if (cb != null) {
42583eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi                cb.onFingerprintAuthenticated(userId);
426f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller            }
427f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        }
4281d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.endSection();
429f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    }
430f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
431ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void handleFingerprintAuthFailed() {
43283eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi        for (int i = 0; i < mCallbacks.size(); i++) {
43383eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
43483eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi            if (cb != null) {
43583eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi                cb.onFingerprintAuthFailed();
43683eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi            }
437007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi        }
438ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
439ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
44027c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi
4414cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi    private void handleFingerprintAcquired(int acquireInfo) {
4424cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi        if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
4434cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            return;
4444cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi        }
445007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi        for (int i = 0; i < mCallbacks.size(); i++) {
446007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
447007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi            if (cb != null) {
44883eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi                cb.onFingerprintAcquired();
449007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi            }
450007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi        }
451007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi    }
452007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi
453837fa7e56dc4e91feaf104bd09ef5e03065b1b86Jim Miller    private void handleFingerprintAuthenticated(int authUserId) {
4541d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
45527c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi        try {
45627c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            final int userId;
45727c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            try {
458dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka                userId = ActivityManager.getService().getCurrentUser().id;
45927c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            } catch (RemoteException e) {
46027c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi                Log.e(TAG, "Failed to get current user id: ", e);
46127c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi                return;
46227c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            }
463837fa7e56dc4e91feaf104bd09ef5e03065b1b86Jim Miller            if (userId != authUserId) {
464837fa7e56dc4e91feaf104bd09ef5e03065b1b86Jim Miller                Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
465837fa7e56dc4e91feaf104bd09ef5e03065b1b86Jim Miller                return;
466837fa7e56dc4e91feaf104bd09ef5e03065b1b86Jim Miller            }
46727c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            if (isFingerprintDisabled(userId)) {
46827c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi                Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
46927c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi                return;
470f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller            }
47183eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi            onFingerprintAuthenticated(userId);
47227c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi        } finally {
47386bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
474f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        }
4751d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.endSection();
476f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    }
477f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
4789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private void handleFingerprintHelp(int msgId, String helpString) {
479f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
480f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
481f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller            if (cb != null) {
4829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                cb.onFingerprintHelp(msgId, helpString);
4839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
4849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
4859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    }
4869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
4870c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn    private Runnable mRetryFingerprintAuthentication = new Runnable() {
4880c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn        @Override
4890c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn        public void run() {
4900c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn            Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
4910c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn                    mHardwareUnavailableRetryCount);
4920c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn            updateFingerprintListeningState();
4930c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn        }
4940c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn    };
4950c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn
4969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private void handleFingerprintError(int msgId, String errString) {
49786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
49886bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi                && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
49986bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
50086bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            startListeningForFingerprint();
50186bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        } else {
50286bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
50386bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        }
5040c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn
5050c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn        if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
5060c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn            if (mHardwareUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
5070c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn                mHardwareUnavailableRetryCount++;
5080c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn                mHandler.removeCallbacks(mRetryFingerprintAuthentication);
5090c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn                mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
5100c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn            }
5110c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn        }
5120c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn
513df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn        if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
514df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn            mLockPatternUtils.requireStrongAuth(
515df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn                    LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
516df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn                    getCurrentUser());
517df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn        }
518df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn
5199f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
5209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
5219f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (cb != null) {
5229f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                cb.onFingerprintError(msgId, errString);
523f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller            }
524f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        }
525f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    }
526f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
5273a464785088e7fd206666f640912729533948ce8Jorim Jaggi    private void handleFingerprintLockoutReset() {
5283a464785088e7fd206666f640912729533948ce8Jorim Jaggi        updateFingerprintListeningState();
5293a464785088e7fd206666f640912729533948ce8Jorim Jaggi    }
5303a464785088e7fd206666f640912729533948ce8Jorim Jaggi
53186bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi    private void setFingerprintRunningState(int fingerprintRunningState) {
53286bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
53386bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
53486bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        mFingerprintRunningState = fingerprintRunningState;
53586bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi
53686bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        // Clients of KeyguardUpdateMonitor don't care about the internal state about the
53786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        // asynchronousness of the cancel cycle. So only notify them if the actualy running state
53886bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        // has changed.
53986bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        if (wasRunning != isRunning) {
54027c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            notifyFingerprintRunningStateChanged();
54127c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi        }
54227c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi    }
54327c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi
54427c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi    private void notifyFingerprintRunningStateChanged() {
54527c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi        for (int i = 0; i < mCallbacks.size(); i++) {
54627c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
54727c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            if (cb != null) {
54886bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi                cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
54927c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi            }
55027c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi        }
55127c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi    }
5524a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    private void handleFaceUnlockStateChanged(boolean running, int userId) {
5534a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        mUserFaceUnlockRunning.put(userId, running);
554e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi        for (int i = 0; i < mCallbacks.size(); i++) {
555e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
556e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi            if (cb != null) {
5574a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos                cb.onFaceUnlockStateChanged(running, userId);
558e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi            }
559e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi        }
560e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi    }
561e7b1252e244eee31a0e4ae29135667ed26f1e4b2Jorim Jaggi
5624a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    public boolean isFaceUnlockRunning(int userId) {
5634a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        return mUserFaceUnlockRunning.get(userId);
5644a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    }
5654a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos
56627c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi    public boolean isFingerprintDetectionRunning() {
56786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
56827c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi    }
56927c9b7435083c5620bddefa0cce6a056863b4801Jorim Jaggi
57050e62183d4aed2fb8e189196c1809e333e71dd89Jim Miller    private boolean isTrustDisabled(int userId) {
571a4da9f6b99c7452475e1b85a1feed60b22a950fdAdrian Roos        // Don't allow trust agent if device is secured with a SIM PIN. This is here
572a4da9f6b99c7452475e1b85a1feed60b22a950fdAdrian Roos        // mainly because there's no other way to prompt the user to enter their SIM PIN
573a4da9f6b99c7452475e1b85a1feed60b22a950fdAdrian Roos        // once they get past the keyguard screen.
574a4da9f6b99c7452475e1b85a1feed60b22a950fdAdrian Roos        final boolean disabledBySimPin = isSimPinSecure();
575a4da9f6b99c7452475e1b85a1feed60b22a950fdAdrian Roos        return disabledBySimPin;
57650e62183d4aed2fb8e189196c1809e333e71dd89Jim Miller    }
57750e62183d4aed2fb8e189196c1809e333e71dd89Jim Miller
57806e345089a0425c6cd5a5596835113fb229b7d41Jim Miller    private boolean isFingerprintDisabled(int userId) {
57906e345089a0425c6cd5a5596835113fb229b7d41Jim Miller        final DevicePolicyManager dpm =
58006e345089a0425c6cd5a5596835113fb229b7d41Jim Miller                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
58106e345089a0425c6cd5a5596835113fb229b7d41Jim Miller        return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
582733b663cc22648d38abf70bfbf8ae0eb43ff396eAdrian Roos                    & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
583733b663cc22648d38abf70bfbf8ae0eb43ff396eAdrian Roos                || isSimPinSecure();
58406e345089a0425c6cd5a5596835113fb229b7d41Jim Miller    }
58506e345089a0425c6cd5a5596835113fb229b7d41Jim Miller
586e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek    public boolean getUserCanSkipBouncer(int userId) {
5871fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
5881fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek                && isUnlockingWithFingerprintAllowed());
589e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek    }
590e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek
59146842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos    public boolean getUserHasTrust(int userId) {
592e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek        return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
59346842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos    }
59446842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos
5957861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    public boolean getUserTrustIsManaged(int userId) {
5967861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
5977861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    }
5987861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
5991fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    public boolean isUnlockingWithFingerprintAllowed() {
600c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski        return mStrongAuthTracker.isUnlockingWithFingerprintAllowed();
601b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos    }
602b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos
603031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi    public boolean needsSlowUnlockTransition() {
604031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        return mNeedsSlowUnlockTransition;
605e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi    }
606e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi
607b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos    public StrongAuthTracker getStrongAuthTracker() {
608b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        return mStrongAuthTracker;
60925b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi    }
61025b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi
61125b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi    public void reportSuccessfulStrongAuthUnlockAttempt() {
612e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        if (mFpm != null) {
613e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
614e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            mFpm.resetTimeout(token);
615e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        }
61625b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi    }
61725b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi
6181de8bcb1e51917a301cab2ef7d276b4f9423d95fAdrian Roos    private void notifyStrongAuthStateChanged(int userId) {
61925b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi        for (int i = 0; i < mCallbacks.size(); i++) {
62025b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
62125b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi            if (cb != null) {
6221de8bcb1e51917a301cab2ef7d276b4f9423d95fAdrian Roos                cb.onStrongAuthStateChanged(userId);
62325b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi            }
62425b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi        }
6251fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    }
6261fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek
62791ba307d9bbd1b9c62feb1bea1d8035d11572d72Adrian Roos    public boolean isScreenOn() {
62891ba307d9bbd1b9c62feb1bea1d8035d11572d72Adrian Roos        return mScreenOn;
62991ba307d9bbd1b9c62feb1bea1d8035d11572d72Adrian Roos    }
63091ba307d9bbd1b9c62feb1bea1d8035d11572d72Adrian Roos
6318f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    static class DisplayClientState {
6328f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        public int clientGeneration;
6338f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        public boolean clearing;
6348f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        public PendingIntent intent;
6358f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        public int playbackState;
6368f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        public long playbackEventTime;
6378f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
6388f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
6398f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private DisplayClientState mDisplayClientState = new DisplayClientState();
6408f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
641bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
642bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
643d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller        @Override
644bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public void onReceive(Context context, Intent intent) {
645bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            final String action = intent.getAction();
646bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            if (DEBUG) Log.d(TAG, "received broadcast " + action);
647bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
648bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            if (Intent.ACTION_TIME_TICK.equals(action)
649bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                    || Intent.ACTION_TIME_CHANGED.equals(action)
65048c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                    || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
65190873d53fba63afcd15b11008eead07b4c88bba0Jim Miller                mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
652bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
653bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
654bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
655bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
656bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
6570c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos
6580c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
6590c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
6600c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                final int maxChargingMicroWatt;
6610c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos
6620c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                if (maxChargingMicroVolt <= 0) {
6630c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                    maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
6640c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                }
6650c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                if (maxChargingMicroAmp > 0) {
6660c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                    // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
6670c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                    // to maintain precision equally on both factors.
6680c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                    maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
6690c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                            * (maxChargingMicroVolt / 1000);
6700c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                } else {
6710c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                    maxChargingMicroWatt = -1;
6720c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                }
673bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                final Message msg = mHandler.obtainMessage(
6747b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos                        MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
6750c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                                maxChargingMicroWatt));
676bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(msg);
677bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
67852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                SimData args = SimData.fromIntent(intent);
679bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                if (DEBUG_SIM_STATES) {
68052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                    Log.v(TAG, "action " + action
68152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                        + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
68252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                        + " slotId: " + args.slotId + " subid: " + args.subId);
683bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                }
68452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
68552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                        .sendToTarget();
686bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
687bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
688bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                        intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
689bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
690bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
691bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
692052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk            } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
693052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk                mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
694efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
69590873d53fba63afcd15b11008eead07b4c88bba0Jim Miller                dispatchBootCompleted();
69647051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
69747051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
69847051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
69947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
70047051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                if (DEBUG) {
70147051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
70247051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                            + subId);
70347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                }
70447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                mHandler.sendMessage(
70547051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                        mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
706bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            }
707bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
708bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    };
7092de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller
7106fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani    private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
7116fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani
712d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller        @Override
7136fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani        public void onReceive(Context context, Intent intent) {
7146fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani            final String action = intent.getAction();
71548c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos            if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
71648c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
71748c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos            } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
7186fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani                mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
7196fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani                        intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
72048c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos            } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
7211d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
72248c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
72348c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                        getSendingUserId()));
7241d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                Trace.endSection();
72548c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos            } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
72648c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
72748c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                        getSendingUserId()));
72848c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos            } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
72948c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                    .equals(action)) {
73048c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos                mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
731dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi            } else if (ACTION_USER_UNLOCKED.equals(action)) {
732dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi                mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
7336fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani            }
7346fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani        }
7356fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani    };
7369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7373a464785088e7fd206666f640912729533948ce8Jorim Jaggi    private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
7383a464785088e7fd206666f640912729533948ce8Jorim Jaggi            = new FingerprintManager.LockoutResetCallback() {
7393a464785088e7fd206666f640912729533948ce8Jorim Jaggi        @Override
7403a464785088e7fd206666f640912729533948ce8Jorim Jaggi        public void onLockoutReset() {
7413a464785088e7fd206666f640912729533948ce8Jorim Jaggi            handleFingerprintLockoutReset();
7423a464785088e7fd206666f640912729533948ce8Jorim Jaggi        }
7433a464785088e7fd206666f640912729533948ce8Jorim Jaggi    };
7443a464785088e7fd206666f640912729533948ce8Jorim Jaggi
7459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private FingerprintManager.AuthenticationCallback mAuthenticationCallback
7469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            = new AuthenticationCallback() {
7479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
748f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        @Override
749ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationFailed() {
7504cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            handleFingerprintAuthFailed();
751ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        };
752ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
753ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        @Override
7549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onAuthenticationSucceeded(AuthenticationResult result) {
7551d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers            Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
756837fa7e56dc4e91feaf104bd09ef5e03065b1b86Jim Miller            handleFingerprintAuthenticated(result.getUserId());
7571d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers            Trace.endSection();
7589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
759f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
760f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        @Override
7619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
7624cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            handleFingerprintHelp(helpMsgId, helpString.toString());
763f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        }
764f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
765f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        @Override
7669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onAuthenticationError(int errMsgId, CharSequence errString) {
7674cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            handleFingerprintError(errMsgId, errString.toString());
7684cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi        }
7694cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi
7704cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi        @Override
7714cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi        public void onAuthenticationAcquired(int acquireInfo) {
7724cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            handleFingerprintAcquired(acquireInfo);
773f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        }
774f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    };
7759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private CancellationSignal mFingerprintCancelSignal;
7769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private FingerprintManager mFpm;
7776fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani
7781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
77947088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller     * When we receive a
78047088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller     * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
78137c124c3fa3078af98c0ebd3e52c9a4ca477a767Wink Saville     * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
7821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * we need a single object to pass to the handler.  This class helps decode
78347088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller     * the intent and provide a {@link SimCard.State} result.
7841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
78552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    private static class SimData {
78652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        public State simState;
78752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        public int slotId;
78852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        public int subId;
7891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
79052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        SimData(State state, int slot, int id) {
79190d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller            simState = state;
79252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            slotId = slot;
79352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            subId = id;
79490d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller        }
79590d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller
79652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        static SimData fromIntent(Intent intent) {
79752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            State state;
7981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
7991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
8001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
801a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
80252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
80352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
804d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
805a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
806b0b24b3df50988d23f571b83d829fecc986ec497John Wang                final String absentReason = intent
807a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
808b0b24b3df50988d23f571b83d829fecc986ec497John Wang
809a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
810b0b24b3df50988d23f571b83d829fecc986ec497John Wang                        absentReason)) {
811a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.PERM_DISABLED;
812b0b24b3df50988d23f571b83d829fecc986ec497John Wang                } else {
813a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.ABSENT;
814b0b24b3df50988d23f571b83d829fecc986ec497John Wang                }
815a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
816a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                state = IccCardConstants.State.READY;
817a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
8181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final String lockedReason = intent
819a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                        .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
820a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
821a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.PIN_REQUIRED;
822a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
823a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.PUK_REQUIRED;
8241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                } else {
825a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    state = IccCardConstants.State.UNKNOWN;
8261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
827a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
828a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                state = IccCardConstants.State.NETWORK_LOCKED;
829109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller            } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
830109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                        || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
831109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                // This is required because telephony doesn't return to "READY" after
832109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                // these state transitions. See bug 7197471.
833109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                state = IccCardConstants.State.READY;
8341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            } else {
835a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                state = IccCardConstants.State.UNKNOWN;
8361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
83752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            return new SimData(state, slotId, subId);
8381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
840d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller        @Override
8411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public String toString() {
84252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
8431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
8451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
84612c1ef57d0758b4fc3514c164897390d83edc463Adrian Roos    public static class BatteryStatus {
8477b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos        public static final int CHARGING_UNKNOWN = -1;
8487b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos        public static final int CHARGING_SLOWLY = 0;
8497b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos        public static final int CHARGING_REGULAR = 1;
8507b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos        public static final int CHARGING_FAST = 2;
8517b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos
85216464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int status;
85316464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int level;
85416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int plugged;
85516464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        public final int health;
8560c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos        public final int maxChargingWattage;
8570c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos        public BatteryStatus(int status, int level, int plugged, int health,
8580c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                int maxChargingWattage) {
85916464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.status = status;
86016464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.level = level;
86116464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.plugged = plugged;
86216464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            this.health = health;
8630c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos            this.maxChargingWattage = maxChargingWattage;
86416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        }
86516464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller
866bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        /**
867a92a01bb0bb458401af90bed5a46d932278160d7Brian Muramatsu         * Determine whether the device is plugged in (USB, power, or wireless).
868bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * @return true if the device is plugged in.
869bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         */
870ad3bc7f878ace1a0eb6f73466d55d9d7b060e48cAdrian Roos        public boolean isPluggedIn() {
871bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            return plugged == BatteryManager.BATTERY_PLUGGED_AC
872a92a01bb0bb458401af90bed5a46d932278160d7Brian Muramatsu                    || plugged == BatteryManager.BATTERY_PLUGGED_USB
873a92a01bb0bb458401af90bed5a46d932278160d7Brian Muramatsu                    || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
874bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
875bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
876bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        /**
877bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * Whether or not the device is charged. Note that some devices never return 100% for
878bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * battery level, so this allows either battery level or status to determine if the
879bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * battery is charged.
880bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * @return true if the device is charged
881bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         */
882bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public boolean isCharged() {
883bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            return status == BATTERY_STATUS_FULL || level >= 100;
884bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
885bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
886bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        /**
887bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * Whether battery is low and needs to be charged.
888bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         * @return true if battery is low
889bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller         */
890bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        public boolean isBatteryLow() {
891bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            return level < LOW_BATTERY_THRESHOLD;
892bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
893bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
8947b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos        public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
8950c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos            return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
8960c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                    maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
8970c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos                    maxChargingWattage > fastThreshold ? CHARGING_FAST :
8987b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos                    CHARGING_REGULAR;
8997b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos        }
90016464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller    }
90116464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller
902b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos    public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
903a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer        public StrongAuthTracker(Context context) {
904a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer            super(context);
905a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer        }
906b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos
907b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        public boolean isUnlockingWithFingerprintAllowed() {
908b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos            int userId = getCurrentUser();
909b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos            return isFingerprintAllowedForUser(userId);
910b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        }
911b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos
912b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        public boolean hasUserAuthenticatedSinceBoot() {
913b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos            int userId = getCurrentUser();
914b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos            return (getStrongAuthForUser(userId)
915b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos                    & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
916b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        }
917b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos
918b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        @Override
919b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        public void onStrongAuthRequiredChanged(int userId) {
9201de8bcb1e51917a301cab2ef7d276b4f9423d95fAdrian Roos            notifyStrongAuthStateChanged(userId);
921b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos        }
922b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos    }
923b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos
924dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public static KeyguardUpdateMonitor getInstance(Context context) {
925dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (sInstance == null) {
926dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            sInstance = new KeyguardUpdateMonitor(context);
927dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
928dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return sInstance;
929dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
930dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
9310d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    protected void handleStartedWakingUp() {
9321d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
933864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi        updateFingerprintListeningState();
93420daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        final int count = mCallbacks.size();
93520daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        for (int i = 0; i < count; i++) {
93620daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
93720daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            if (cb != null) {
9380d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi                cb.onStartedWakingUp();
93920daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            }
94020daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        }
9411d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.endSection();
94220daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    }
94320daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
94495e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    protected void handleStartedGoingToSleep(int arg1) {
945f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        clearFingerprintRecognized();
94620daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        final int count = mCallbacks.size();
94720daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        for (int i = 0; i < count; i++) {
94820daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
94920daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            if (cb != null) {
95095e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi                cb.onStartedGoingToSleep(arg1);
95120daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            }
95220daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        }
95395e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        mGoingToSleep = true;
954ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi        updateFingerprintListeningState();
95520daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    }
95620daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
95795e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    protected void handleFinishedGoingToSleep(int arg1) {
95895e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        mGoingToSleep = false;
95995e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        final int count = mCallbacks.size();
96095e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        for (int i = 0; i < count; i++) {
96195e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
96295e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi            if (cb != null) {
96395e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi                cb.onFinishedGoingToSleep(arg1);
96495e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi            }
96595e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        }
96695e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        updateFingerprintListeningState();
96795e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    }
96895e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi
969f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private void handleScreenTurnedOn() {
970f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        final int count = mCallbacks.size();
971f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        for (int i = 0; i < count; i++) {
972f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
973f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            if (cb != null) {
974f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                cb.onScreenTurnedOn();
975f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            }
976f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        }
977f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    }
978f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi
979f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private void handleScreenTurnedOff() {
9800c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn        mHardwareUnavailableRetryCount = 0;
981f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        final int count = mCallbacks.size();
982f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        for (int i = 0; i < count; i++) {
983f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
984f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            if (cb != null) {
985f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                cb.onScreenTurnedOff();
986f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            }
987f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        }
988f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    }
989f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi
990994153944e6d76d1b1a060afb131129172a915d1Selim Cinek    private void handleDreamingStateChanged(int dreamStart) {
991994153944e6d76d1b1a060afb131129172a915d1Selim Cinek        final int count = mCallbacks.size();
992994153944e6d76d1b1a060afb131129172a915d1Selim Cinek        boolean showingDream = dreamStart == 1;
993994153944e6d76d1b1a060afb131129172a915d1Selim Cinek        for (int i = 0; i < count; i++) {
994994153944e6d76d1b1a060afb131129172a915d1Selim Cinek            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
995994153944e6d76d1b1a060afb131129172a915d1Selim Cinek            if (cb != null) {
996994153944e6d76d1b1a060afb131129172a915d1Selim Cinek                cb.onDreamingStateChanged(showingDream);
997994153944e6d76d1b1a060afb131129172a915d1Selim Cinek            }
998994153944e6d76d1b1a060afb131129172a915d1Selim Cinek        }
999994153944e6d76d1b1a060afb131129172a915d1Selim Cinek    }
1000994153944e6d76d1b1a060afb131129172a915d1Selim Cinek
100143a372f38ad642f86047e8112e3d43edb7300439Adam Powell    /**
100243a372f38ad642f86047e8112e3d43edb7300439Adam Powell     * IMPORTANT: Must be called from UI thread.
100343a372f38ad642f86047e8112e3d43edb7300439Adam Powell     */
100443a372f38ad642f86047e8112e3d43edb7300439Adam Powell    public void dispatchSetBackground(Bitmap bmp) {
100543a372f38ad642f86047e8112e3d43edb7300439Adam Powell        if (DEBUG) Log.d(TAG, "dispatchSetBackground");
100643a372f38ad642f86047e8112e3d43edb7300439Adam Powell        final int count = mCallbacks.size();
100743a372f38ad642f86047e8112e3d43edb7300439Adam Powell        for (int i = 0; i < count; i++) {
100843a372f38ad642f86047e8112e3d43edb7300439Adam Powell            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
100943a372f38ad642f86047e8112e3d43edb7300439Adam Powell            if (cb != null) {
101043a372f38ad642f86047e8112e3d43edb7300439Adam Powell                cb.onSetBackground(bmp);
101143a372f38ad642f86047e8112e3d43edb7300439Adam Powell            }
101243a372f38ad642f86047e8112e3d43edb7300439Adam Powell        }
101343a372f38ad642f86047e8112e3d43edb7300439Adam Powell    }
101443a372f38ad642f86047e8112e3d43edb7300439Adam Powell
10156fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani    private void handleUserInfoChanged(int userId) {
10166fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani        for (int i = 0; i < mCallbacks.size(); i++) {
10176fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
10186fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani            if (cb != null) {
10196fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani                cb.onUserInfoChanged(userId);
10206fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani            }
10216fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani        }
10226fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani    }
10236fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani
1024dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi    private void handleUserUnlocked() {
1025dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi        mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1026dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi        for (int i = 0; i < mCallbacks.size(); i++) {
1027dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1028dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi            if (cb != null) {
1029dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi                cb.onUserUnlocked();
1030dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi            }
1031dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi        }
1032dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi    }
1033dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi
1034dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardUpdateMonitor(Context context) {
10351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mContext = context;
1036d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        mSubscriptionManager = SubscriptionManager.from(context);
1037fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
1038a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer        mStrongAuthTracker = new StrongAuthTracker(context);
103925b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi
10401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // Since device can't be un-provisioned, we only need to register a content observer
10411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // to update mDeviceProvisioned when we are...
10421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (!mDeviceProvisioned) {
1043bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            watchForDeviceProvisioning();
10441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
104547088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
1046bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // Take a guess at initial SIM state, battery status and PLMN until we get an update
10477b04311d88e377c67b4c663091b6b1c63c932c52Adrian Roos        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
10481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1049bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // Watch for interesting updates
10501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final IntentFilter filter = new IntentFilter();
10511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_TIME_TICK);
10521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_TIME_CHANGED);
10531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
10541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
1055052082c529f2a5ee1a16608b284ca261f720dd0eJason Monk        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
10561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
105747051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
1058c23024d32779b170dde32a50fbdd945ce521b874Jim Miller        filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
105947088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
1060bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        context.registerReceiver(mBroadcastReceiver, filter);
10615dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn
1062c276e82dd070e75017192507df33958a10cadb87Adam Cohen        final IntentFilter bootCompleteFilter = new IntentFilter();
1063c276e82dd070e75017192507df33958a10cadb87Adam Cohen        bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1064c276e82dd070e75017192507df33958a10cadb87Adam Cohen        bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
1065c276e82dd070e75017192507df33958a10cadb87Adam Cohen        context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
1066c276e82dd070e75017192507df33958a10cadb87Adam Cohen
106748c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos        final IntentFilter allUserFilter = new IntentFilter();
106848c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos        allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
106948c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos        allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
107048c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos        allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
107148c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos        allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
107248c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos        allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1073dadafd4109c69f088893e72551d50a3cc04d085eJorim Jaggi        allUserFilter.addAction(ACTION_USER_UNLOCKED);
107448c796cad62b5dcd488a6018cb0289baa0e442dbAdrian Roos        context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
10756fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani                null, null);
10766fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38Amith Yamasani
1077071743f0cbbfab36150db6ec945452579d02e8ddWink Saville        mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
10785dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        try {
1079dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka            ActivityManager.getService().registerUserSwitchObserver(
10802c4522cc1bf3a3d0178688427a33b860ddfe4bbaSudheer Shanka                    new UserSwitchObserver() {
10815dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        @Override
10825dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        public void onUserSwitching(int newUserId, IRemoteCallback reply) {
1083f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
10845dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                                    newUserId, 0, reply));
10855dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        }
10865dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        @Override
10875dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        public void onUserSwitchComplete(int newUserId) throws RemoteException {
1088f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
1089be47b07bef0596dd9bf7137ea08cc1112328c6e8Adrian Roos                                    newUserId, 0));
10905dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn                        }
10910b77ef9f5199b7cd0956f2bfe049cbd699ca03b4Fyodor Kupolov                    }, TAG);
10925dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        } catch (RemoteException e) {
10930b77ef9f5199b7cd0956f2bfe049cbd699ca03b4Fyodor Kupolov            e.rethrowAsRuntimeException();
10945dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        }
109546842d946d1777c22f05e6bb96933c1b5cbd00d4Adrian Roos
1096237b061182d36fd3bf2238092ccf3d529ec8877bJorim Jaggi        mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1097237b061182d36fd3bf2238092ccf3d529ec8877bJorim Jaggi        mTrustManager.registerTrustListener(this);
1098c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski        mLockPatternUtils = new LockPatternUtils(context);
1099c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski        mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
1100f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
11013f12426d006bc1bd51b59601de1ccc558227687bJorim Jaggi        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
11023f12426d006bc1bd51b59601de1ccc558227687bJorim Jaggi            mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
11033f12426d006bc1bd51b59601de1ccc558227687bJorim Jaggi        }
1104ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi        updateFingerprintListeningState();
11053a464785088e7fd206666f640912729533948ce8Jorim Jaggi        if (mFpm != null) {
11063a464785088e7fd206666f640912729533948ce8Jorim Jaggi            mFpm.addLockoutResetCallback(mLockoutResetCallback);
11073a464785088e7fd206666f640912729533948ce8Jorim Jaggi        }
1108e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi
1109e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi        mUserManager = context.getSystemService(UserManager.class);
1110ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi    }
1111ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi
1112ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi    private void updateFingerprintListeningState() {
11130c45b07fe238b3e88f30c67219440669818aa1eeKevin Chyn        mHandler.removeCallbacks(mRetryFingerprintAuthentication);
1114ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi        boolean shouldListenForFingerprint = shouldListenForFingerprint();
111586bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
1116ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi            stopListeningForFingerprint();
111786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
111886bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi                && shouldListenForFingerprint) {
1119ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi            startListeningForFingerprint();
1120ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi        }
1121ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi    }
1122ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi
1123ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi    private boolean shouldListenForFingerprint() {
11246db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn        return (mKeyguardIsVisible || !mDeviceInteractive ||
11256db7d5fc84ae67cc0d11b0cd376b5cf21a1fafd3Kevin Chyn                    (mBouncer && !mKeyguardGoingAway) || mGoingToSleep)
1126625a014006d63ddb59c4b3b7520f0b14afbc18a3Kevin Chyn                && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser());
11279f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    }
11289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
1129ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void startListeningForFingerprint() {
113086bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
113186bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
113286bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            return;
113386bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        }
1134ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
11352aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        int userId = ActivityManager.getCurrentUser();
113671448a70036e8f95a4f7f3b0f6252bd3344976bbJorim Jaggi        if (isUnlockWithFingerprintPossible(userId)) {
1137ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (mFingerprintCancelSignal != null) {
11389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mFingerprintCancelSignal.cancel();
11399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
1140ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mFingerprintCancelSignal = new CancellationSignal();
1141f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
114286bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
11439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
11449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    }
11459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
114625b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi    public boolean isUnlockWithFingerprintPossible(int userId) {
11473122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek        return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
11483122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek                && mFpm.getEnrolledFingerprints(userId).size() > 0;
11493122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek    }
11503122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek
1151ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi    private void stopListeningForFingerprint() {
1152ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
115386bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
11549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mFingerprintCancelSignal.cancel();
1155ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mFingerprintCancelSignal = null;
115686bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
115786bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        }
115886bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi        if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
115986bed40605e407459496ee2bfdf6b8af1ae1a581Jorim Jaggi            setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
11609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
1161bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    }
1162bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
1163fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private boolean isDeviceProvisionedInSettingsDb() {
1164fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        return Settings.Global.getInt(mContext.getContentResolver(),
1165fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1166fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    }
1167fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka
1168bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private void watchForDeviceProvisioning() {
1169fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        mDeviceProvisionedObserver = new ContentObserver(mHandler) {
1170bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            @Override
1171bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            public void onChange(boolean selfChange) {
1172bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                super.onChange(selfChange);
1173fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka                mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
1174bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                if (mDeviceProvisioned) {
117590873d53fba63afcd15b11008eead07b4c88bba0Jim Miller                    mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
11761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
1177bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller                if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
1178bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            }
1179bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        };
1180bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
1181bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        mContext.getContentResolver().registerContentObserver(
1182bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
1183fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka                false, mDeviceProvisionedObserver);
1184bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller
1185bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // prevent a race condition between where we check the flag and where we register the
1186bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        // observer by grabbing the value once again...
1187fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        boolean provisioned = isDeviceProvisionedInSettingsDb();
1188bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        if (provisioned != mDeviceProvisioned) {
1189bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            mDeviceProvisioned = provisioned;
1190bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            if (mDeviceProvisioned) {
119190873d53fba63afcd15b11008eead07b4c88bba0Jim Miller                mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
11921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1193bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        }
11941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
11951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1196bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
1197d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi     * Update the state whether Keyguard currently has a lockscreen wallpaper.
1198d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi     *
1199d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi     * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1200d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi     */
1201d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi    public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
1202d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi        if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1203d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi            mHasLockscreenWallpaper = hasLockscreenWallpaper;
1204d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1205d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1206d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi                if (cb != null) {
1207d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi                    cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1208d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi                }
1209d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi            }
1210d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi        }
1211d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi    }
1212d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi
1213d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi    /**
1214d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi     * @return Whether Keyguard has a lockscreen wallpaper.
1215d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi     */
1216d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi    public boolean hasLockscreenWallpaper() {
1217d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi        return mHasLockscreenWallpaper;
1218d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi    }
1219d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi
1220d11d1a9486d44b98e28b70c25711ebfc283b746eJorim Jaggi    /**
1221bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_DPM_STATE_CHANGED}
1222bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
1223b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    protected void handleDevicePolicyManagerStateChanged() {
1224733b663cc22648d38abf70bfbf8ae0eb43ff396eAdrian Roos        updateFingerprintListeningState();
1225dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1226dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1227dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
1228dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onDevicePolicyManagerStateChanged();
1229dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1230b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
1231b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    }
1232b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
1233bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
1234f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren     * Handle {@link #MSG_USER_SWITCHING}
1235bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
1236f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    protected void handleUserSwitching(int userId, IRemoteCallback reply) {
1237bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
1238dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1239dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
1240f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                cb.onUserSwitching(userId);
1241dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
124252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        }
12435dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        try {
12445dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn            reply.sendResult(null);
12455dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        } catch (RemoteException e) {
12465dc5a00e7ebadc085ded7e29feacd17e53698486Dianne Hackborn        }
124752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
124852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
1249bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
1250f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren     * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1251f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren     */
1252f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    protected void handleUserSwitchComplete(int userId) {
1253f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        for (int i = 0; i < mCallbacks.size(); i++) {
1254f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1255f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            if (cb != null) {
1256f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                cb.onUserSwitchComplete(userId);
1257f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            }
1258f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
1259f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    }
1260f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
1261f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    /**
126290873d53fba63afcd15b11008eead07b4c88bba0Jim Miller     * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
126390873d53fba63afcd15b11008eead07b4c88bba0Jim Miller     * keyguard crashes sometime after boot, then it will never receive this
126490873d53fba63afcd15b11008eead07b4c88bba0Jim Miller     * broadcast and hence not handle the event. This method is ultimately called by
126590873d53fba63afcd15b11008eead07b4c88bba0Jim Miller     * PhoneWindowManager in this case.
126690873d53fba63afcd15b11008eead07b4c88bba0Jim Miller     */
12675cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi    public void dispatchBootCompleted() {
1268e5f910a667088ab63e017d5851f0956c77b823daJim Miller        mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
126990873d53fba63afcd15b11008eead07b4c88bba0Jim Miller    }
127090873d53fba63afcd15b11008eead07b4c88bba0Jim Miller
127190873d53fba63afcd15b11008eead07b4c88bba0Jim Miller    /**
1272efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen     * Handle {@link #MSG_BOOT_COMPLETED}
1273efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen     */
1274efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    protected void handleBootCompleted() {
1275e5f910a667088ab63e017d5851f0956c77b823daJim Miller        if (mBootCompleted) return;
12764eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen        mBootCompleted = true;
1277efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        for (int i = 0; i < mCallbacks.size(); i++) {
1278efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1279efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            if (cb != null) {
1280efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                cb.onBootCompleted();
1281efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            }
1282efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        }
1283efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    }
1284efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen
1285efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    /**
12865ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller     * We need to store this state in the KeyguardUpdateMonitor since this class will not be
12874eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen     * destroyed.
12884eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen     */
12894eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    public boolean hasBootCompleted() {
12904eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen        return mBootCompleted;
12914eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    }
12924eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen
12934eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen    /**
1294bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_DEVICE_PROVISIONED}
1295bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
129624d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly    protected void handleDeviceProvisioned() {
1297bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
1298dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1299dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
1300dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onDeviceProvisioned();
1301dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
130224d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly        }
1303fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        if (mDeviceProvisionedObserver != null) {
130424d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly            // We don't need the observer anymore...
1305fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1306fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            mDeviceProvisionedObserver = null;
130724d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly        }
130824d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly    }
130924d7b5f22ac98392f8b2d2c94560173e44d1ca6cNick Pelly
1310bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
1311bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_PHONE_STATE_CHANGED}
1312bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
1313c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    protected void handlePhoneStateChanged(String newState) {
1314c23024d32779b170dde32a50fbdd945ce521b874Jim Miller        if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
13153f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
13163f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller            mPhoneState = TelephonyManager.CALL_STATE_IDLE;
13173f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
13183f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller            mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
13193f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
13203f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller            mPhoneState = TelephonyManager.CALL_STATE_RINGING;
13213f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        }
1322bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
1323dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1324dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
1325dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onPhoneStateChanged(mPhoneState);
1326dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1327c23024d32779b170dde32a50fbdd945ce521b874Jim Miller        }
1328c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    }
1329c23024d32779b170dde32a50fbdd945ce521b874Jim Miller
1330bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
1331bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Handle {@link #MSG_RINGER_MODE_CHANGED}
1332bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     */
133347088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller    protected void handleRingerModeChange(int mode) {
133447088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller        if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
13353f5f83b54fad4c797f5dbd75f050e4980e839122Jim Miller        mRingMode = mode;
1336bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
1337dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1338dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
1339dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onRingerModeChanged(mode);
1340dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
134147088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller        }
134247088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller    }
134347088bbbef61e3bd8d2930f4a2b72884129b5bd5Jim Miller
13441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
13451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Handle {@link #MSG_TIME_UPDATE}
13461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
13471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void handleTimeUpdate() {
13481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) Log.d(TAG, "handleTimeUpdate");
1349bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
1350dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1351dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (cb != null) {
1352dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                cb.onTimeChanged();
1353dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
13541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
13551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
13561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
13571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
13581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Handle {@link #MSG_BATTERY_UPDATE}
13591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1360bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    private void handleBatteryUpdate(BatteryStatus status) {
13611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
1362bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1363bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        mBatteryStatus = status;
136416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        if (batteryUpdateInteresting) {
1365bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            for (int i = 0; i < mCallbacks.size(); i++) {
1366dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1367dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                if (cb != null) {
1368dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    cb.onRefreshBatteryInfo(status);
1369dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                }
13701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
13711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
13721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
13731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
13741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
13751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Handle {@link #MSG_SIM_STATE_CHANGE}
13761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
137752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    private void handleSimStateChange(int subId, int slotId, State state) {
13781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
137952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        if (DEBUG_SIM_STATES) {
138052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
138152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                    + slotId + ", state=" + state +")");
13821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
13831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1384a54bf6583380cf328b9858d942b4c387c6163f0fWink Saville        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
138552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            Log.w(TAG, "invalid subId in handleSimStateChange()");
138652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            return;
138752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
138852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
138952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        SimData data = mSimDatas.get(subId);
139052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        final boolean changed;
139152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        if (data == null) {
139252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            data = new SimData(state, slotId, subId);
139352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            mSimDatas.put(subId, data);
139452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            changed = true; // no data yet; force update
139552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        } else {
139652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
139752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            data.simState = state;
139852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            data.subId = subId;
139952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            data.slotId = slotId;
140052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
140152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        if (changed && state != State.UNKNOWN) {
1402bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller            for (int i = 0; i < mCallbacks.size(); i++) {
1403dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1404dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                if (cb != null) {
140552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                    cb.onSimStateChanged(subId, slotId, state);
1406dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                }
14071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
14081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
14091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
14101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1411bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    /**
141247051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen     * Handle {@link #MSG_SERVICE_STATE_CHANGE}
141347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen     */
141447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen    private void handleServiceStateChange(int subId, ServiceState serviceState) {
141547051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        if (DEBUG) {
141647051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            Log.d(TAG,
141747051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
141847051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        }
141947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen
142047051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
142147051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            Log.w(TAG, "invalid subId in handleServiceStateChange()");
142247051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            return;
142347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        }
142447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen
142547051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        mServiceStates.put(subId, serviceState);
142647051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen
142747051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        for (int j = 0; j < mCallbacks.size(); j++) {
142847051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
142947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            if (cb != null) {
143047051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                cb.onRefreshCarrierInfo();
143147051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            }
143247051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        }
143347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen    }
143447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen
143547051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen    /**
14366a15d528c0a4501389008ef945dec38b5ca6919aJorim Jaggi     * Notifies that the visibility state of Keyguard has changed.
14376a15d528c0a4501389008ef945dec38b5ca6919aJorim Jaggi     *
14386a15d528c0a4501389008ef945dec38b5ca6919aJorim Jaggi     * <p>Needs to be called from the main thread.
1439f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett     */
14406a15d528c0a4501389008ef945dec38b5ca6919aJorim Jaggi    public void onKeyguardVisibilityChanged(boolean showing) {
14416a15d528c0a4501389008ef945dec38b5ca6919aJorim Jaggi        if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
14426a15d528c0a4501389008ef945dec38b5ca6919aJorim Jaggi        mKeyguardIsVisible = showing;
1443f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        for (int i = 0; i < mCallbacks.size(); i++) {
1444f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1445f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett            if (cb != null) {
14466a15d528c0a4501389008ef945dec38b5ca6919aJorim Jaggi                cb.onKeyguardVisibilityChangedRaw(showing);
1447f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett            }
1448f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett        }
1449ea65706d89dc1ab3f295eb53dca548ea39fcb456Jorim Jaggi        updateFingerprintListeningState();
1450f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett    }
1451f6d0fc190c4b257ee4f2f1ae8a59519d3a21ce6dDanielle Millett
14527fce38021694925295f5d14bfba71f28cba19404Brian Colonna    /**
14531fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek     * Handle {@link #MSG_KEYGUARD_RESET}
14541fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek     */
14551fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    private void handleKeyguardReset() {
14561fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        if (DEBUG) Log.d(TAG, "handleKeyguardReset");
1457f6d51acec69366b6ea34f5e0c9aa8cc840f04a4dAdrian Roos        updateFingerprintListeningState();
1458031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1459031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi    }
1460031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi
1461031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi    private boolean resolveNeedsSlowUnlockTransition() {
1462031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        if (mUserManager.isUserUnlocked(getCurrentUser())) {
1463031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi            return false;
1464031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        }
1465031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        Intent homeIntent = new Intent(Intent.ACTION_MAIN)
1466031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi                .addCategory(Intent.CATEGORY_HOME);
1467031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
1468031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi                0 /* flags */);
1469031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
14701fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    }
14711fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek
14721fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    /**
1473b601162a60663329355720083bfa199909dbf6efAdrian Roos     * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1474b601162a60663329355720083bfa199909dbf6efAdrian Roos     * @see #sendKeyguardBouncerChanged(boolean)
1475b601162a60663329355720083bfa199909dbf6efAdrian Roos     */
1476b601162a60663329355720083bfa199909dbf6efAdrian Roos    private void handleKeyguardBouncerChanged(int bouncer) {
1477b601162a60663329355720083bfa199909dbf6efAdrian Roos        if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1478b601162a60663329355720083bfa199909dbf6efAdrian Roos        boolean isBouncer = (bouncer == 1);
1479b601162a60663329355720083bfa199909dbf6efAdrian Roos        mBouncer = isBouncer;
1480b601162a60663329355720083bfa199909dbf6efAdrian Roos        for (int i = 0; i < mCallbacks.size(); i++) {
1481b601162a60663329355720083bfa199909dbf6efAdrian Roos            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1482b601162a60663329355720083bfa199909dbf6efAdrian Roos            if (cb != null) {
1483b601162a60663329355720083bfa199909dbf6efAdrian Roos                cb.onKeyguardBouncerChanged(isBouncer);
1484b601162a60663329355720083bfa199909dbf6efAdrian Roos            }
1485b601162a60663329355720083bfa199909dbf6efAdrian Roos        }
14863cf7eef1b1890131902447465a343484e23e2115Jorim Jaggi        updateFingerprintListeningState();
1487b601162a60663329355720083bfa199909dbf6efAdrian Roos    }
1488b601162a60663329355720083bfa199909dbf6efAdrian Roos
1489b601162a60663329355720083bfa199909dbf6efAdrian Roos    /**
14907fce38021694925295f5d14bfba71f28cba19404Brian Colonna     * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
14917fce38021694925295f5d14bfba71f28cba19404Brian Colonna     */
14927fce38021694925295f5d14bfba71f28cba19404Brian Colonna    private void handleReportEmergencyCallAction() {
14937fce38021694925295f5d14bfba71f28cba19404Brian Colonna        for (int i = 0; i < mCallbacks.size(); i++) {
14947fce38021694925295f5d14bfba71f28cba19404Brian Colonna            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
14957fce38021694925295f5d14bfba71f28cba19404Brian Colonna            if (cb != null) {
14967fce38021694925295f5d14bfba71f28cba19404Brian Colonna                cb.onEmergencyCallAction();
14977fce38021694925295f5d14bfba71f28cba19404Brian Colonna            }
14987fce38021694925295f5d14bfba71f28cba19404Brian Colonna        }
14997fce38021694925295f5d14bfba71f28cba19404Brian Colonna    }
15007fce38021694925295f5d14bfba71f28cba19404Brian Colonna
150116464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller    private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
1502bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        final boolean nowPluggedIn = current.isPluggedIn();
1503bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        final boolean wasPluggedIn = old.isPluggedIn();
150479a444a0cd78bc6528e19336a0d49ef4a17b263cJim Miller        final boolean stateChangedWhilePluggedIn =
150516464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            wasPluggedIn == true && nowPluggedIn == true
150616464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            && (old.status != current.status);
150716464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller
150816464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        // change in plug state is always interesting
150916464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
15101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
15111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
15121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
15131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // change in battery level while plugged in
151416464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        if (nowPluggedIn && old.level != current.level) {
15151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
15161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
15171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
151816464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller        // change where battery needs charging
1519bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller        if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
152016464b8e55020a4d77a8e5e4673db974e749dc82Jim Miller            return true;
15211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
152276dc5a51cde1db0e8e193f22bc8a7ace9edef53dAdrian Roos
152376dc5a51cde1db0e8e193f22bc8a7ace9edef53dAdrian Roos        // change in charging current while plugged in
15240c859ae9c76db756ba898508a8dc2d92d86e9096Adrian Roos        if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
152576dc5a51cde1db0e8e193f22bc8a7ace9edef53dAdrian Roos            return true;
152676dc5a51cde1db0e8e193f22bc8a7ace9edef53dAdrian Roos        }
152776dc5a51cde1db0e8e193f22bc8a7ace9edef53dAdrian Roos
15281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return false;
15291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
15301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
15311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1532bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     * Remove the given observer's callback.
1533bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller     *
15346212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller     * @param callback The callback to remove
15351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
15366212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    public void removeCallback(KeyguardUpdateMonitorCallback callback) {
15376212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
15386212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
15396212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller            if (mCallbacks.get(i).get() == callback) {
15406212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                mCallbacks.remove(i);
15416212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller            }
15426212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        }
15431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
15441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
15451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
15461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Register to receive notifications about general keyguard information
15471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * (see {@link InfoCallback}.
15486212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller     * @param callback The callback to register
15491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1550bbf1a743186e8e62c3918971344e8bff3dfaa737Jim Miller    public void registerCallback(KeyguardUpdateMonitorCallback callback) {
15516212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
15526212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        // Prevent adding duplicate callbacks
15536212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        for (int i = 0; i < mCallbacks.size(); i++) {
15546212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller            if (mCallbacks.get(i).get() == callback) {
15556212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                if (DEBUG) Log.e(TAG, "Object tried to add another callback",
15566212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                        new Exception("Called by"));
15576212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller                return;
1558dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1559dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
15606212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
15616212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        removeCallback(null); // remove unused references
15626212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        sendUpdates(callback);
15636212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    }
15646212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller
15651839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky    public boolean isSwitchingUser() {
15661839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky        return mSwitchingUser;
15671839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky    }
15681839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky
15691839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky    public void setSwitchingUser(boolean switching) {
15701839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky        mSwitchingUser = switching;
15711839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky        updateFingerprintListeningState();
15721839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky    }
15731839645126c8e7e0909e8ed8f0686c2122ba6078Evan Rosky
15746212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller    private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
15756212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        // Notify listener of the current state
15766212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onRefreshBatteryInfo(mBatteryStatus);
15776212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onTimeChanged();
15786212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onRingerModeChanged(mRingMode);
15796212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onPhoneStateChanged(mPhoneState);
15809ff69bd8f115e70a16c72c798449908536a173eaJason Monk        callback.onRefreshCarrierInfo();
15816212cc0d3f59139421ceeaf630f6494239d81cd1Jim Miller        callback.onClockVisibilityChanged();
158252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
158352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            final SimData state = data.getValue();
158452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            callback.onSimStateChanged(state.subId, state.slotId, state.simState);
158552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
15861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
15871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
15881fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    public void sendKeyguardReset() {
15891fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
15901fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek    }
15911fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek
1592b601162a60663329355720083bfa199909dbf6efAdrian Roos    /**
1593b601162a60663329355720083bfa199909dbf6efAdrian Roos     * @see #handleKeyguardBouncerChanged(int)
1594b601162a60663329355720083bfa199909dbf6efAdrian Roos     */
1595b601162a60663329355720083bfa199909dbf6efAdrian Roos    public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1596b601162a60663329355720083bfa199909dbf6efAdrian Roos        if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1597b601162a60663329355720083bfa199909dbf6efAdrian Roos        Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1598b601162a60663329355720083bfa199909dbf6efAdrian Roos        message.arg1 = showingBouncer ? 1 : 0;
1599b601162a60663329355720083bfa199909dbf6efAdrian Roos        message.sendToTarget();
1600b601162a60663329355720083bfa199909dbf6efAdrian Roos    }
1601b601162a60663329355720083bfa199909dbf6efAdrian Roos
16021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
160390d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
16041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * have the information earlier than waiting for the intent
16051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * broadcast from the telephony code.
160690d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     *
160790d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
160890d5d46b9e1bfc2df1a4a16b411eafb43c80eba5Jim Miller     * through mHandler, this *must* be called from the UI thread.
16091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
161052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    public void reportSimUnlocked(int subId) {
161152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
16127e4602519977b6bb9c41afc91a44ca782e716e40Sanket Padawe        int slotId = SubscriptionManager.getSlotIndex(subId);
161352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        handleSimStateChange(subId, slotId, State.READY);
16141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
16151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
16167fce38021694925295f5d14bfba71f28cba19404Brian Colonna    /**
16177fce38021694925295f5d14bfba71f28cba19404Brian Colonna     * Report that the emergency call button has been pressed and the emergency dialer is
16187fce38021694925295f5d14bfba71f28cba19404Brian Colonna     * about to be displayed.
16197fce38021694925295f5d14bfba71f28cba19404Brian Colonna     *
16207fce38021694925295f5d14bfba71f28cba19404Brian Colonna     * @param bypassHandler runs immediately.
16217fce38021694925295f5d14bfba71f28cba19404Brian Colonna     *
16227fce38021694925295f5d14bfba71f28cba19404Brian Colonna     * NOTE: Must be called from UI thread if bypassHandler == true.
16237fce38021694925295f5d14bfba71f28cba19404Brian Colonna     */
16247fce38021694925295f5d14bfba71f28cba19404Brian Colonna    public void reportEmergencyCallAction(boolean bypassHandler) {
16257fce38021694925295f5d14bfba71f28cba19404Brian Colonna        if (!bypassHandler) {
16267fce38021694925295f5d14bfba71f28cba19404Brian Colonna            mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
16277fce38021694925295f5d14bfba71f28cba19404Brian Colonna        } else {
16287fce38021694925295f5d14bfba71f28cba19404Brian Colonna            handleReportEmergencyCallAction();
16297fce38021694925295f5d14bfba71f28cba19404Brian Colonna        }
16307fce38021694925295f5d14bfba71f28cba19404Brian Colonna    }
16317fce38021694925295f5d14bfba71f28cba19404Brian Colonna
16321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
16331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return Whether the device is provisioned (whether they have gone through
16341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   the setup wizard)
16351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
16361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public boolean isDeviceProvisioned() {
16371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mDeviceProvisioned;
16381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
16391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1640258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    public void clearFailedUnlockAttempts() {
16419f74303eb8432aa64a7030f58ab0c3279a20c53eJorim Jaggi        mFailedAttempts.delete(sCurrentUser);
16421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
16431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1644ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia    public int getFailedUnlockAttempts(int userId) {
1645ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia        return mFailedAttempts.get(userId, 0);
1646f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller    }
1647f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
1648ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia    public void reportFailedStrongAuthUnlockAttempt(int userId) {
1649ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia        mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
1650054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey    }
1651054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
16529f74303eb8432aa64a7030f58ab0c3279a20c53eJorim Jaggi    public void clearFingerprintRecognized() {
16539f74303eb8432aa64a7030f58ab0c3279a20c53eJorim Jaggi        mUserFingerprintAuthenticated.clear();
1654267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna    }
1655b9430d2a1c8dbf7b9998d349544c9ae133dab18fSteven Ross
165652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    public boolean isSimPinVoiceSecure() {
165752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // TODO: only count SIMs that handle voice
165852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        return isSimPinSecure();
1659dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1660dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
166152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    public boolean isSimPinSecure() {
166252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // True if any SIM is pin secure
166352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
166452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
166552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
166652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        return false;
1667dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1668dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
16699ff69bd8f115e70a16c72c798449908536a173eaJason Monk    public State getSimState(int subId) {
167052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        if (mSimDatas.containsKey(subId)) {
167152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            return mSimDatas.get(subId).simState;
167252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        } else {
167352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            return State.UNKNOWN;
167452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
167552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    }
167652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
167701ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi    /**
167801ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi     * @return true if and only if the state has changed for the specified {@code slotId}
167901ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi     */
168001ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi    private boolean refreshSimState(int subId, int slotId) {
168152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
168252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // This is awful. It exists because there are two APIs for getting the SIM status
168352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // that don't return the complete set of values and have different types. In Keyguard we
168452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // need IccCardConstants, but TelephonyManager would only give us
168552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        // TelephonyManager.SIM_STATE*, so we retrieve it manually.
168618b9c3cb506ae99bed1e9e95757a22b234cf366bxinhe        final TelephonyManager tele = TelephonyManager.from(mContext);
168718b9c3cb506ae99bed1e9e95757a22b234cf366bxinhe        int simState =  tele.getSimState(slotId);
168852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        State state;
168952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        try {
169018b9c3cb506ae99bed1e9e95757a22b234cf366bxinhe            state = State.intToState(simState);
169152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        } catch(IllegalArgumentException ex) {
169218b9c3cb506ae99bed1e9e95757a22b234cf366bxinhe            Log.w(TAG, "Unknown sim state: " + simState);
169352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            state = State.UNKNOWN;
16945b13e9227155e74310710bda4be1731aef43d1c2John Spurlock        }
169501ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        SimData data = mSimDatas.get(subId);
169601ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        final boolean changed;
169701ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        if (data == null) {
169801ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            data = new SimData(state, slotId, subId);
169901ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            mSimDatas.put(subId, data);
170001ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            changed = true; // no data yet; force update
170101ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        } else {
170201ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            changed = data.simState != state;
170301ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi            data.simState = state;
170401ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        }
170501ba98b856a018c735a911d7b2c1604ea2ff2f95Jorim Jaggi        return changed;
1706dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1707dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1708dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public static boolean isSimPinSecure(IccCardConstants.State state) {
1709dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        final IccCardConstants.State simState = state;
1710dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return (simState == IccCardConstants.State.PIN_REQUIRED
1711dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                || simState == IccCardConstants.State.PUK_REQUIRED
1712dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                || simState == IccCardConstants.State.PERM_DISABLED);
1713b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    }
17148f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
17158f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    public DisplayClientState getCachedDisplayClientState() {
17168f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        return mDisplayClientState;
17178f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
171820daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
171920daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
172020daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    // (KeyguardViewMediator, KeyguardHostView)
17210d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    public void dispatchStartedWakingUp() {
17220d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        synchronized (this) {
17230d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi            mDeviceInteractive = true;
17240d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        }
17250d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
17260d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    }
17270d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi
172895e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    public void dispatchStartedGoingToSleep(int why) {
172995e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
173095e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    }
173195e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi
17320d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    public void dispatchFinishedGoingToSleep(int why) {
17330d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        synchronized(this) {
17340d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi            mDeviceInteractive = false;
17350d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        }
17360d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
17370d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    }
17380d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi
173920daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    public void dispatchScreenTurnedOn() {
174020daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        synchronized (this) {
174120daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            mScreenOn = true;
174220daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        }
1743f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
174420daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    }
174520daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
17460d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    public void dispatchScreenTurnedOff() {
174720daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        synchronized(this) {
174820daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            mScreenOn = false;
174920daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        }
1750f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
175120daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    }
175220daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
1753994153944e6d76d1b1a060afb131129172a915d1Selim Cinek    public void dispatchDreamingStarted() {
1754994153944e6d76d1b1a060afb131129172a915d1Selim Cinek        mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
1755994153944e6d76d1b1a060afb131129172a915d1Selim Cinek    }
1756994153944e6d76d1b1a060afb131129172a915d1Selim Cinek
1757994153944e6d76d1b1a060afb131129172a915d1Selim Cinek    public void dispatchDreamingStopped() {
1758994153944e6d76d1b1a060afb131129172a915d1Selim Cinek        mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
1759994153944e6d76d1b1a060afb131129172a915d1Selim Cinek    }
1760994153944e6d76d1b1a060afb131129172a915d1Selim Cinek
17610d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    public boolean isDeviceInteractive() {
17620d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        return mDeviceInteractive;
176320daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller    }
176452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
176595e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    public boolean isGoingToSleep() {
176695e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi        return mGoingToSleep;
176795e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi    }
176895e4038bb127fdd41bd3b11373a6d2328facb850Jorim Jaggi
176952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    /**
177052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller     * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
177152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller     * @param state
1772d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville     * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
177352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller     */
177452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    public int getNextSubIdForState(State state) {
177552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1776d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
177752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
177852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        for (int i = 0; i < list.size(); i++) {
177952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            final SubscriptionInfo info = list.get(i);
178052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            final int id = info.getSubscriptionId();
17817e4602519977b6bb9c41afc91a44ca782e716e40Sanket Padawe            int slotId = SubscriptionManager.getSlotIndex(id);
178252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            if (state == getSimState(id) && bestSlotId > slotId ) {
178352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                resultId = id;
178452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller                bestSlotId = slotId;
178552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            }
178652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
178752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        return resultId;
178852a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    }
178952a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller
179052a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
179152a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
179252a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        for (int i = 0; i < list.size(); i++) {
179352a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            SubscriptionInfo info = list.get(i);
179452a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller            if (subId == info.getSubscriptionId()) return info;
179552a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        }
179652a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller        return null; // not found
179752a6133f4ba8b1d08f5158d802790d6a1b16568dJim Miller    }
1798ab5252726211069daf558d40da75e544c341c63bJason Monk
1799ab5252726211069daf558d40da75e544c341c63bJason Monk    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1800ab5252726211069daf558d40da75e544c341c63bJason Monk        pw.println("KeyguardUpdateMonitor state:");
1801ab5252726211069daf558d40da75e544c341c63bJason Monk        pw.println("  SIM States:");
1802ab5252726211069daf558d40da75e544c341c63bJason Monk        for (SimData data : mSimDatas.values()) {
1803ab5252726211069daf558d40da75e544c341c63bJason Monk            pw.println("    " + data.toString());
1804ab5252726211069daf558d40da75e544c341c63bJason Monk        }
1805ab5252726211069daf558d40da75e544c341c63bJason Monk        pw.println("  Subs:");
1806ab5252726211069daf558d40da75e544c341c63bJason Monk        if (mSubscriptionInfo != null) {
1807ab5252726211069daf558d40da75e544c341c63bJason Monk            for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1808ab5252726211069daf558d40da75e544c341c63bJason Monk                pw.println("    " + mSubscriptionInfo.get(i));
1809ab5252726211069daf558d40da75e544c341c63bJason Monk            }
1810ab5252726211069daf558d40da75e544c341c63bJason Monk        }
1811ab5252726211069daf558d40da75e544c341c63bJason Monk        pw.println("  Service states:");
1812ab5252726211069daf558d40da75e544c341c63bJason Monk        for (int subId : mServiceStates.keySet()) {
1813ab5252726211069daf558d40da75e544c341c63bJason Monk            pw.println("    " + subId + "=" + mServiceStates.get(subId));
1814ab5252726211069daf558d40da75e544c341c63bJason Monk        }
1815d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller        if (mFpm != null && mFpm.isHardwareDetected()) {
1816d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            final int userId = ActivityManager.getCurrentUser();
1817d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
1818d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("  Fingerprint state (user=" + userId + ")");
1819d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("    allowed=" + isUnlockingWithFingerprintAllowed());
1820d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("    auth'd=" + mUserFingerprintAuthenticated.get(userId));
1821d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("    authSinceBoot="
1822d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller                    + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
1823d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("    disabled(DPM)=" + isFingerprintDisabled(userId));
1824d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("    possible=" + isUnlockWithFingerprintPossible(userId));
1825d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
1826d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller            pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
1827d72d5ac5981050bb36ef7d4e36aa93cc419f33b2Jim Miller        }
1828ab5252726211069daf558d40da75e544c341c63bJason Monk    }
18291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
1830