KeyguardViewMediator.java revision a6310293c5a861cdb54f2c894e90a8d9da87f8d7
15073402289471575a1bab5d43c9f3709a12148f3Jason Sams/* 25073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Copyright (C) 2014 The Android Open Source Project 35073402289471575a1bab5d43c9f3709a12148f3Jason Sams * 45073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 55073402289471575a1bab5d43c9f3709a12148f3Jason Sams * you may not use this file except in compliance with the License. 65073402289471575a1bab5d43c9f3709a12148f3Jason Sams * You may obtain a copy of the License at 75073402289471575a1bab5d43c9f3709a12148f3Jason Sams * 85073402289471575a1bab5d43c9f3709a12148f3Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 95073402289471575a1bab5d43c9f3709a12148f3Jason Sams * 105073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Unless required by applicable law or agreed to in writing, software 115073402289471575a1bab5d43c9f3709a12148f3Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 125073402289471575a1bab5d43c9f3709a12148f3Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135073402289471575a1bab5d43c9f3709a12148f3Jason Sams * See the License for the specific language governing permissions and 145073402289471575a1bab5d43c9f3709a12148f3Jason Sams * limitations under the License 155073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 165073402289471575a1bab5d43c9f3709a12148f3Jason Sams 175073402289471575a1bab5d43c9f3709a12148f3Jason Samspackage com.android.systemui.keyguard; 185073402289471575a1bab5d43c9f3709a12148f3Jason Sams 195073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.app.Activity; 205073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.app.ActivityManagerNative; 215073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.app.AlarmManager; 225073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.app.PendingIntent; 235073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.app.SearchManager; 245073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.app.StatusBarManager; 255073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.content.BroadcastReceiver; 265073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.content.ContentResolver; 2731f4588d26e258c61543e90e796c4c9a8c2a1482Jason Samsimport android.content.Context; 2831f4588d26e258c61543e90e796c4c9a8c2a1482Jason Samsimport android.content.Intent; 2931f4588d26e258c61543e90e796c4c9a8c2a1482Jason Samsimport android.content.IntentFilter; 3031f4588d26e258c61543e90e796c4c9a8c2a1482Jason Samsimport android.media.AudioManager; 315073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.media.SoundPool; 325073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.os.Build; 335073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.os.Bundle; 345073402289471575a1bab5d43c9f3709a12148f3Jason Samsimport android.os.Handler; 35fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.os.Looper; 36fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.os.Message; 37fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.os.PowerManager; 38fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.os.RemoteException; 39fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.os.SystemClock; 40b4a8c2d0c147e8f7929ec048adceb340da26be22Pirama Arumuga Nainarimport android.os.SystemProperties; 41fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.os.UserHandle; 42fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.os.UserManager; 43fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.provider.Settings; 44fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.telephony.TelephonyManager; 45fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.util.EventLog; 46fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.util.Log; 47fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.util.Slog; 48fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.view.ViewGroup; 49fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.view.WindowManager; 50fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport android.view.WindowManagerPolicy; 51fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams 52fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.internal.policy.IKeyguardExitCallback; 53fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.internal.policy.IKeyguardShowCallback; 54fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.internal.telephony.IccCardConstants; 55fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.internal.widget.LockPatternUtils; 56fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.keyguard.KeyguardDisplayManager; 57fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.keyguard.KeyguardUpdateMonitor; 58fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.keyguard.KeyguardUpdateMonitorCallback; 59fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.keyguard.MultiUserAvatarCache; 60fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.keyguard.ViewMediatorCallback; 61fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.keyguard.analytics.KeyguardAnalytics; 62fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.keyguard.analytics.Session; 63fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.systemui.SystemUI; 64fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.systemui.statusbar.phone.PhoneStatusBar; 65fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; 66fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport com.android.systemui.statusbar.phone.StatusBarWindowManager; 67fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams 68fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport java.io.File; 69fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams 70fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 71fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Samsimport static com.android.keyguard.analytics.KeyguardAnalytics.SessionTypeAdapter; 72fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams 73fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams 74fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams/** 75fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams * Mediates requests related to the keyguard. This includes queries about the 76fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams * state of the keyguard, power management events that effect whether the keyguard 77fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams * should be shown or reset, callbacks to the phone window manager to notify 78fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams * it of when the keyguard is showing, and events from the keyguard view itself 796b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams * stating that the keyguard was succesfully unlocked. 806b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams * 816b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams * Note that the keyguard view is shown when the screen is off (as appropriate) 825073402289471575a1bab5d43c9f3709a12148f3Jason Sams * so that once the screen comes on, it will be ready immediately. 835073402289471575a1bab5d43c9f3709a12148f3Jason Sams * 845073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Example queries about the keyguard: 85dbad8eb5a8bb16488351c5236974812d282b7b82Jason Sams * - is {movement, key} one that should wake the keygaurd? 86b7ead98b51e77d1f07934c8bd49ed6fc232360b3Jason Sams * - is the keyguard showing? 875073402289471575a1bab5d43c9f3709a12148f3Jason Sams * - are input events restricted due to the state of the keyguard? 88b7ead98b51e77d1f07934c8bd49ed6fc232360b3Jason Sams * 89b7ead98b51e77d1f07934c8bd49ed6fc232360b3Jason Sams * Callbacks to the phone window manager: 90b7ead98b51e77d1f07934c8bd49ed6fc232360b3Jason Sams * - the keyguard is showing 91b7ead98b51e77d1f07934c8bd49ed6fc232360b3Jason Sams * 92b7ead98b51e77d1f07934c8bd49ed6fc232360b3Jason Sams * Example external events that translate to keyguard view changes: 93dbad8eb5a8bb16488351c5236974812d282b7b82Jason Sams * - screen turned off -> reset the keyguard, and show it so it will be ready 945073402289471575a1bab5d43c9f3709a12148f3Jason Sams * next time the screen turns on 95dbad8eb5a8bb16488351c5236974812d282b7b82Jason Sams * - keyboard is slid open -> if the keyguard is not secure, hide it 96b7ead98b51e77d1f07934c8bd49ed6fc232360b3Jason Sams * 975073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Events from the keyguard view: 985073402289471575a1bab5d43c9f3709a12148f3Jason Sams * - user succesfully unlocked keyguard -> hide keyguard view, and no longer 995073402289471575a1bab5d43c9f3709a12148f3Jason Sams * restrict input events. 1005073402289471575a1bab5d43c9f3709a12148f3Jason Sams * 1015073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Note: in addition to normal power managment events that effect the state of 1025073402289471575a1bab5d43c9f3709a12148f3Jason Sams * whether the keyguard should be showing, external apps and services may request 1035073402289471575a1bab5d43c9f3709a12148f3Jason Sams * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}. When 1045073402289471575a1bab5d43c9f3709a12148f3Jason Sams * false, this will override all other conditions for turning on the keyguard. 1055073402289471575a1bab5d43c9f3709a12148f3Jason Sams * 1065073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Threading and synchronization: 1075073402289471575a1bab5d43c9f3709a12148f3Jason Sams * This class is created by the initialization routine of the {@link android.view.WindowManagerPolicy}, 1085073402289471575a1bab5d43c9f3709a12148f3Jason Sams * and runs on its thread. The keyguard UI is created from that thread in the 1095073402289471575a1bab5d43c9f3709a12148f3Jason Sams * constructor of this class. The apis may be called from other threads, including the 1105073402289471575a1bab5d43c9f3709a12148f3Jason Sams * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s. 1115073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Therefore, methods on this class are synchronized, and any action that is pointed 1125073402289471575a1bab5d43c9f3709a12148f3Jason Sams * directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI 1135073402289471575a1bab5d43c9f3709a12148f3Jason Sams * thread of the keyguard. 1145073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 1155073402289471575a1bab5d43c9f3709a12148f3Jason Samspublic class KeyguardViewMediator extends SystemUI { 116b4a8c2d0c147e8f7929ec048adceb340da26be22Pirama Arumuga Nainar private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000; 117b4a8c2d0c147e8f7929ec048adceb340da26be22Pirama Arumuga Nainar final static boolean DEBUG = false; 118b4a8c2d0c147e8f7929ec048adceb340da26be22Pirama Arumuga Nainar private static final boolean ENABLE_ANALYTICS = Build.IS_DEBUGGABLE; 11969138aaab26753ae55404375f22043ec4e2b59cfJason Sams private final static boolean DBG_WAKE = false; 120b4a8c2d0c147e8f7929ec048adceb340da26be22Pirama Arumuga Nainar 1215073402289471575a1bab5d43c9f3709a12148f3Jason Sams private final static String TAG = "KeyguardViewMediator"; 1225073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1235073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final String DELAYED_KEYGUARD_ACTION = 1245073402289471575a1bab5d43c9f3709a12148f3Jason Sams "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"; 1255073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1265073402289471575a1bab5d43c9f3709a12148f3Jason Sams // used for handler messages 1275073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int SHOW = 2; 1285073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int HIDE = 3; 1295073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int RESET = 4; 1305073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int VERIFY_UNLOCK = 5; 1315073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int NOTIFY_SCREEN_OFF = 6; 1325073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int NOTIFY_SCREEN_ON = 7; 1335073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int KEYGUARD_DONE = 9; 1345073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int KEYGUARD_DONE_DRAWING = 10; 1355073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int KEYGUARD_DONE_AUTHENTICATING = 11; 1365073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int SET_OCCLUDED = 12; 1375073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int KEYGUARD_TIMEOUT = 13; 1385073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int DISMISS = 17; 1395073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1405073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** 1415073402289471575a1bab5d43c9f3709a12148f3Jason Sams * The default amount of time we stay awake (used for all key input) 1425073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 1435073402289471575a1bab5d43c9f3709a12148f3Jason Sams public static final int AWAKE_INTERVAL_DEFAULT_MS = 10000; 1445073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1455073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** 1465073402289471575a1bab5d43c9f3709a12148f3Jason Sams * How long to wait after the screen turns off due to timeout before 1475073402289471575a1bab5d43c9f3709a12148f3Jason Sams * turning on the keyguard (i.e, the user has this much time to turn 1485073402289471575a1bab5d43c9f3709a12148f3Jason Sams * the screen back on without having to face the keyguard). 1495073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 1505073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000; 1515073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1525073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** 1535073402289471575a1bab5d43c9f3709a12148f3Jason Sams * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()} 1545073402289471575a1bab5d43c9f3709a12148f3Jason Sams * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)} 1555073402289471575a1bab5d43c9f3709a12148f3Jason Sams * that is reenabling the keyguard. 1565073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 1575073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000; 1585073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1595073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** 1605073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Allow the user to expand the status bar when the keyguard is engaged 1615073402289471575a1bab5d43c9f3709a12148f3Jason Sams * (without a pattern or password). 1625073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 163859c4817355fcb86ea3aa103d1d1c5fa12ce81faJason Sams private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true; 164859c4817355fcb86ea3aa103d1d1c5fa12ce81faJason Sams 165859c4817355fcb86ea3aa103d1d1c5fa12ce81faJason Sams /** 166859c4817355fcb86ea3aa103d1d1c5fa12ce81faJason Sams * Allow the user to expand the status bar when a SECURE keyguard is engaged 1675073402289471575a1bab5d43c9f3709a12148f3Jason Sams * and {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS} is set 1685073402289471575a1bab5d43c9f3709a12148f3Jason Sams * (private notifications will be masked). 16969138aaab26753ae55404375f22043ec4e2b59cfJason Sams */ 17069138aaab26753ae55404375f22043ec4e2b59cfJason Sams private static final boolean ENABLE_SECURE_STATUS_BAR_EXPAND = true; 1715073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1725073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** 1735073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Default value of {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}. 1745073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 1755073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false; 1765073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1775073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** 1785073402289471575a1bab5d43c9f3709a12148f3Jason Sams * Secure setting whether analytics are collected on the keyguard. 1795073402289471575a1bab5d43c9f3709a12148f3Jason Sams */ 1805073402289471575a1bab5d43c9f3709a12148f3Jason Sams private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics"; 1815073402289471575a1bab5d43c9f3709a12148f3Jason Sams 1825073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** The stream type that the lock sounds are tied to. */ 18369138aaab26753ae55404375f22043ec4e2b59cfJason Sams private int mMasterStreamType; 18469138aaab26753ae55404375f22043ec4e2b59cfJason Sams 18569138aaab26753ae55404375f22043ec4e2b59cfJason Sams private AlarmManager mAlarmManager; 18669138aaab26753ae55404375f22043ec4e2b59cfJason Sams private AudioManager mAudioManager; 187859c4817355fcb86ea3aa103d1d1c5fa12ce81faJason Sams private StatusBarManager mStatusBarManager; 188859c4817355fcb86ea3aa103d1d1c5fa12ce81faJason Sams private boolean mSwitchingUser; 1890ef64c5373a119eb73cbf7b1f7cf7d1da12d97d3Jason Sams 1900ef64c5373a119eb73cbf7b1f7cf7d1da12d97d3Jason Sams private boolean mSystemReady; 1910ef64c5373a119eb73cbf7b1f7cf7d1da12d97d3Jason Sams 1920ef64c5373a119eb73cbf7b1f7cf7d1da12d97d3Jason Sams // Whether the next call to playSounds() should be skipped. Defaults to 193fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams // true because the first lock (on boot) should be silent. 194fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams private boolean mSuppressNextLockSound = true; 195fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams 196fe801921741c8bbec2b28eb49690ff88d149f1b4Jason Sams 1976b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams /** High level access to the power manager for WakeLocks */ 1986b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams private PowerManager mPM; 1996b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams 2006b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams /** UserManager for querying number of users */ 2015073402289471575a1bab5d43c9f3709a12148f3Jason Sams private UserManager mUserManager; 2025073402289471575a1bab5d43c9f3709a12148f3Jason Sams 2035073402289471575a1bab5d43c9f3709a12148f3Jason Sams /** SearchManager for determining whether or not search assistant is available */ 2045073402289471575a1bab5d43c9f3709a12148f3Jason Sams private SearchManager mSearchManager; 2055073402289471575a1bab5d43c9f3709a12148f3Jason Sams 206 /** 207 * Used to keep the device awake while to ensure the keyguard finishes opening before 208 * we sleep. 209 */ 210 private PowerManager.WakeLock mShowKeyguardWakeLock; 211 212 private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; 213 214 private KeyguardAnalytics mKeyguardAnalytics; 215 216 // these are protected by synchronized (this) 217 218 /** 219 * External apps (like the phone app) can tell us to disable the keygaurd. 220 */ 221 private boolean mExternallyEnabled = true; 222 223 /** 224 * Remember if an external call to {@link #setKeyguardEnabled} with value 225 * false caused us to hide the keyguard, so that we need to reshow it once 226 * the keygaurd is reenabled with another call with value true. 227 */ 228 private boolean mNeedToReshowWhenReenabled = false; 229 230 // cached value of whether we are showing (need to know this to quickly 231 // answer whether the input should be restricted) 232 private boolean mShowing; 233 234 // true if the keyguard is hidden by another window 235 private boolean mOccluded = false; 236 237 /** 238 * Helps remember whether the screen has turned on since the last time 239 * it turned off due to timeout. see {@link #onScreenTurnedOff(int)} 240 */ 241 private int mDelayedShowingSequence; 242 243 /** 244 * If the user has disabled the keyguard, then requests to exit, this is 245 * how we'll ultimately let them know whether it was successful. We use this 246 * var being non-null as an indicator that there is an in progress request. 247 */ 248 private IKeyguardExitCallback mExitSecureCallback; 249 250 // the properties of the keyguard 251 252 private KeyguardUpdateMonitor mUpdateMonitor; 253 254 private boolean mScreenOn; 255 256 // last known state of the cellular connection 257 private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE; 258 259 /** 260 * we send this intent when the keyguard is dismissed. 261 */ 262 private static final Intent USER_PRESENT_INTENT = new Intent(Intent.ACTION_USER_PRESENT) 263 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 264 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 265 266 /** 267 * {@link #setKeyguardEnabled} waits on this condition when it reenables 268 * the keyguard. 269 */ 270 private boolean mWaitingUntilKeyguardVisible = false; 271 private LockPatternUtils mLockPatternUtils; 272 private boolean mKeyguardDonePending = false; 273 274 private SoundPool mLockSounds; 275 private int mLockSoundId; 276 private int mUnlockSoundId; 277 private int mLockSoundStreamId; 278 279 /** 280 * Tracks value of {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}. 281 */ 282 private boolean mAllowNotificationsWhenSecure; 283 284 /** 285 * The volume applied to the lock/unlock sounds. 286 */ 287 private float mLockSoundVolume; 288 289 /** 290 * For managing external displays 291 */ 292 private KeyguardDisplayManager mKeyguardDisplayManager; 293 294 KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { 295 296 @Override 297 public void onUserSwitching(int userId) { 298 // Note that the mLockPatternUtils user has already been updated from setCurrentUser. 299 // We need to force a reset of the views, since lockNow (called by 300 // ActivityManagerService) will not reconstruct the keyguard if it is already showing. 301 synchronized (KeyguardViewMediator.this) { 302 mSwitchingUser = true; 303 resetStateLocked(); 304 adjustStatusBarLocked(); 305 // When we switch users we want to bring the new user to the biometric unlock even 306 // if the current user has gone to the backup. 307 KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); 308 } 309 } 310 311 @Override 312 public void onUserSwitchComplete(int userId) { 313 mSwitchingUser = false; 314 } 315 316 @Override 317 public void onUserRemoved(int userId) { 318 mLockPatternUtils.removeUser(userId); 319 MultiUserAvatarCache.getInstance().clear(userId); 320 } 321 322 @Override 323 public void onUserInfoChanged(int userId) { 324 MultiUserAvatarCache.getInstance().clear(userId); 325 } 326 327 @Override 328 public void onPhoneStateChanged(int phoneState) { 329 synchronized (KeyguardViewMediator.this) { 330 if (TelephonyManager.CALL_STATE_IDLE == phoneState // call ending 331 && !mScreenOn // screen off 332 && mExternallyEnabled) { // not disabled by any app 333 334 // note: this is a way to gracefully reenable the keyguard when the call 335 // ends and the screen is off without always reenabling the keyguard 336 // each time the screen turns off while in call (and having an occasional ugly 337 // flicker while turning back on the screen and disabling the keyguard again). 338 if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the " 339 + "keyguard is showing"); 340 doKeyguardLocked(null); 341 } 342 } 343 } 344 345 @Override 346 public void onClockVisibilityChanged() { 347 adjustStatusBarLocked(); 348 } 349 350 @Override 351 public void onDeviceProvisioned() { 352 sendUserPresentBroadcast(); 353 } 354 355 @Override 356 public void onSimStateChanged(IccCardConstants.State simState) { 357 if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState); 358 359 switch (simState) { 360 case NOT_READY: 361 case ABSENT: 362 // only force lock screen in case of missing sim if user hasn't 363 // gone through setup wizard 364 synchronized (this) { 365 if (!mUpdateMonitor.isDeviceProvisioned()) { 366 if (!isShowing()) { 367 if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing," 368 + " we need to show the keyguard since the " 369 + "device isn't provisioned yet."); 370 doKeyguardLocked(null); 371 } else { 372 resetStateLocked(); 373 } 374 } 375 } 376 break; 377 case PIN_REQUIRED: 378 case PUK_REQUIRED: 379 synchronized (this) { 380 if (!isShowing()) { 381 if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't " 382 + "showing; need to show keyguard so user can enter sim pin"); 383 doKeyguardLocked(null); 384 } else { 385 resetStateLocked(); 386 } 387 } 388 break; 389 case PERM_DISABLED: 390 synchronized (this) { 391 if (!isShowing()) { 392 if (DEBUG) Log.d(TAG, "PERM_DISABLED and " 393 + "keygaurd isn't showing."); 394 doKeyguardLocked(null); 395 } else { 396 if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to" 397 + "show permanently disabled message in lockscreen."); 398 resetStateLocked(); 399 } 400 } 401 break; 402 case READY: 403 synchronized (this) { 404 if (isShowing()) { 405 resetStateLocked(); 406 } 407 } 408 break; 409 } 410 } 411 412 }; 413 414 ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { 415 416 public void userActivity() { 417 KeyguardViewMediator.this.userActivity(); 418 } 419 420 public void userActivity(long holdMs) { 421 KeyguardViewMediator.this.userActivity(holdMs); 422 } 423 424 public void keyguardDone(boolean authenticated) { 425 KeyguardViewMediator.this.keyguardDone(authenticated, true); 426 } 427 428 public void keyguardDoneDrawing() { 429 mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING); 430 } 431 432 @Override 433 public void setNeedsInput(boolean needsInput) { 434 mStatusBarKeyguardViewManager.setNeedsInput(needsInput); 435 } 436 437 @Override 438 public void onUserActivityTimeoutChanged() { 439 mStatusBarKeyguardViewManager.updateUserActivityTimeout(); 440 } 441 442 @Override 443 public void keyguardDonePending() { 444 mKeyguardDonePending = true; 445 } 446 447 @Override 448 public void keyguardGone() { 449 mKeyguardDisplayManager.hide(); 450 } 451 }; 452 453 private void userActivity() { 454 userActivity(AWAKE_INTERVAL_DEFAULT_MS); 455 } 456 457 public void userActivity(long holdMs) { 458 // We ignore the hold time. Eventually we should remove it. 459 // Instead, the keyguard window has an explicit user activity timeout set on it. 460 mPM.userActivity(SystemClock.uptimeMillis(), false); 461 } 462 463 private void setup() { 464 mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 465 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 466 mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard"); 467 mShowKeyguardWakeLock.setReferenceCounted(false); 468 469 mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION)); 470 471 mKeyguardDisplayManager = new KeyguardDisplayManager(mContext); 472 473 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 474 475 mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); 476 477 mLockPatternUtils = new LockPatternUtils(mContext); 478 mLockPatternUtils.setCurrentUser(UserHandle.USER_OWNER); 479 480 // Assume keyguard is showing (unless it's disabled) until we know for sure... 481 mShowing = (mUpdateMonitor.isDeviceProvisioned() || mLockPatternUtils.isSecure()) 482 && !mLockPatternUtils.isLockScreenDisabled(); 483 484 mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext, 485 mViewMediatorCallback, mLockPatternUtils); 486 final ContentResolver cr = mContext.getContentResolver(); 487 488 if (ENABLE_ANALYTICS && !LockPatternUtils.isSafeModeEnabled() && 489 Settings.Secure.getInt(cr, KEYGUARD_ANALYTICS_SETTING, 0) == 1) { 490 mKeyguardAnalytics = new KeyguardAnalytics(mContext, new SessionTypeAdapter() { 491 492 @Override 493 public int getSessionType() { 494 return mLockPatternUtils.isSecure() && !mUpdateMonitor.getUserHasTrust( 495 mLockPatternUtils.getCurrentUser()) 496 ? Session.TYPE_KEYGUARD_SECURE 497 : Session.TYPE_KEYGUARD_INSECURE; 498 } 499 }, new File(mContext.getCacheDir(), "keyguard_analytics.bin")); 500 } else { 501 mKeyguardAnalytics = null; 502 } 503 504 mScreenOn = mPM.isScreenOn(); 505 506 mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0); 507 String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND); 508 if (soundPath != null) { 509 mLockSoundId = mLockSounds.load(soundPath, 1); 510 } 511 if (soundPath == null || mLockSoundId == 0) { 512 Log.w(TAG, "failed to load lock sound from " + soundPath); 513 } 514 soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND); 515 if (soundPath != null) { 516 mUnlockSoundId = mLockSounds.load(soundPath, 1); 517 } 518 if (soundPath == null || mUnlockSoundId == 0) { 519 Log.w(TAG, "failed to load unlock sound from " + soundPath); 520 } 521 int lockSoundDefaultAttenuation = mContext.getResources().getInteger( 522 com.android.internal.R.integer.config_lockSoundVolumeDb); 523 mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20); 524 } 525 526 @Override 527 public void start() { 528 setup(); 529 putComponent(KeyguardViewMediator.class, this); 530 } 531 532 /** 533 * Let us know that the system is ready after startup. 534 */ 535 public void onSystemReady() { 536 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 537 synchronized (this) { 538 if (DEBUG) Log.d(TAG, "onSystemReady"); 539 mSystemReady = true; 540 mUpdateMonitor.registerCallback(mUpdateCallback); 541 542 // Suppress biometric unlock right after boot until things have settled if it is the 543 // selected security method, otherwise unsuppress it. It must be unsuppressed if it is 544 // not the selected security method for the following reason: if the user starts 545 // without a screen lock selected, the biometric unlock would be suppressed the first 546 // time they try to use it. 547 // 548 // Note that the biometric unlock will still not show if it is not the selected method. 549 // Calling setAlternateUnlockEnabled(true) simply says don't suppress it if it is the 550 // selected method. 551 if (mLockPatternUtils.usingBiometricWeak() 552 && mLockPatternUtils.isBiometricWeakInstalled()) { 553 if (DEBUG) Log.d(TAG, "suppressing biometric unlock during boot"); 554 mUpdateMonitor.setAlternateUnlockEnabled(false); 555 } else { 556 mUpdateMonitor.setAlternateUnlockEnabled(true); 557 } 558 559 doKeyguardLocked(null); 560 } 561 // Most services aren't available until the system reaches the ready state, so we 562 // send it here when the device first boots. 563 maybeSendUserPresentBroadcast(); 564 } 565 566 /** 567 * Called to let us know the screen was turned off. 568 * @param why either {@link android.view.WindowManagerPolicy#OFF_BECAUSE_OF_USER}, 569 * {@link android.view.WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or 570 * {@link android.view.WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}. 571 */ 572 public void onScreenTurnedOff(int why) { 573 synchronized (this) { 574 mScreenOn = false; 575 if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")"); 576 577 mKeyguardDonePending = false; 578 579 // Lock immediately based on setting if secure (user has a pin/pattern/password). 580 // This also "locks" the device when not secure to provide easy access to the 581 // camera while preventing unwanted input. 582 final boolean lockImmediately = 583 mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure(); 584 585 if (mExitSecureCallback != null) { 586 if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled"); 587 try { 588 mExitSecureCallback.onKeyguardExitResult(false); 589 } catch (RemoteException e) { 590 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 591 } 592 mExitSecureCallback = null; 593 if (!mExternallyEnabled) { 594 hideLocked(); 595 } 596 } else if (mShowing) { 597 notifyScreenOffLocked(); 598 resetStateLocked(); 599 } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT 600 || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) { 601 doKeyguardLaterLocked(); 602 } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) { 603 // Do not enable the keyguard if the prox sensor forced the screen off. 604 } else { 605 doKeyguardLocked(null); 606 } 607 if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) { 608 mKeyguardAnalytics.getCallback().onScreenOff(); 609 } 610 } 611 KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurndOff(why); 612 } 613 614 private void doKeyguardLaterLocked() { 615 // if the screen turned off because of timeout or the user hit the power button 616 // and we don't need to lock immediately, set an alarm 617 // to enable it a little bit later (i.e, give the user a chance 618 // to turn the screen back on within a certain window without 619 // having to unlock the screen) 620 final ContentResolver cr = mContext.getContentResolver(); 621 622 // From DisplaySettings 623 long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT, 624 KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT); 625 626 // From SecuritySettings 627 final long lockAfterTimeout = Settings.Secure.getInt(cr, 628 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 629 KEYGUARD_LOCK_AFTER_DELAY_DEFAULT); 630 631 // From DevicePolicyAdmin 632 final long policyTimeout = mLockPatternUtils.getDevicePolicyManager() 633 .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser()); 634 635 long timeout; 636 if (policyTimeout > 0) { 637 // policy in effect. Make sure we don't go beyond policy limit. 638 displayTimeout = Math.max(displayTimeout, 0); // ignore negative values 639 timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout); 640 } else { 641 timeout = lockAfterTimeout; 642 } 643 644 if (timeout <= 0) { 645 // Lock now 646 mSuppressNextLockSound = true; 647 doKeyguardLocked(null); 648 } else { 649 // Lock in the future 650 long when = SystemClock.elapsedRealtime() + timeout; 651 Intent intent = new Intent(DELAYED_KEYGUARD_ACTION); 652 intent.putExtra("seq", mDelayedShowingSequence); 653 PendingIntent sender = PendingIntent.getBroadcast(mContext, 654 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); 655 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender); 656 if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = " 657 + mDelayedShowingSequence); 658 } 659 } 660 661 private void cancelDoKeyguardLaterLocked() { 662 mDelayedShowingSequence++; 663 } 664 665 /** 666 * Let's us know the screen was turned on. 667 */ 668 public void onScreenTurnedOn(IKeyguardShowCallback callback) { 669 synchronized (this) { 670 mScreenOn = true; 671 cancelDoKeyguardLaterLocked(); 672 if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence); 673 if (callback != null) { 674 notifyScreenOnLocked(callback); 675 } 676 } 677 KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurnedOn(); 678 maybeSendUserPresentBroadcast(); 679 } 680 681 private void maybeSendUserPresentBroadcast() { 682 if (mSystemReady && mLockPatternUtils.isLockScreenDisabled() 683 && !mUserManager.isUserSwitcherEnabled()) { 684 // Lock screen is disabled because the user has set the preference to "None". 685 // In this case, send out ACTION_USER_PRESENT here instead of in 686 // handleKeyguardDone() 687 sendUserPresentBroadcast(); 688 } 689 } 690 691 /** 692 * A dream started. We should lock after the usual screen-off lock timeout but only 693 * if there is a secure lock pattern. 694 */ 695 public void onDreamingStarted() { 696 synchronized (this) { 697 if (mScreenOn && mLockPatternUtils.isSecure()) { 698 doKeyguardLaterLocked(); 699 } 700 } 701 } 702 703 /** 704 * A dream stopped. 705 */ 706 public void onDreamingStopped() { 707 synchronized (this) { 708 if (mScreenOn) { 709 cancelDoKeyguardLaterLocked(); 710 } 711 } 712 } 713 714 /** 715 * Same semantics as {@link android.view.WindowManagerPolicy#enableKeyguard}; provide 716 * a way for external stuff to override normal keyguard behavior. For instance 717 * the phone app disables the keyguard when it receives incoming calls. 718 */ 719 public void setKeyguardEnabled(boolean enabled) { 720 synchronized (this) { 721 if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")"); 722 723 mExternallyEnabled = enabled; 724 725 if (!enabled && mShowing) { 726 if (mExitSecureCallback != null) { 727 if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring"); 728 // we're in the process of handling a request to verify the user 729 // can get past the keyguard. ignore extraneous requests to disable / reenable 730 return; 731 } 732 733 // hiding keyguard that is showing, remember to reshow later 734 if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, " 735 + "disabling status bar expansion"); 736 mNeedToReshowWhenReenabled = true; 737 hideLocked(); 738 } else if (enabled && mNeedToReshowWhenReenabled) { 739 // reenabled after previously hidden, reshow 740 if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling " 741 + "status bar expansion"); 742 mNeedToReshowWhenReenabled = false; 743 744 if (mExitSecureCallback != null) { 745 if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting"); 746 try { 747 mExitSecureCallback.onKeyguardExitResult(false); 748 } catch (RemoteException e) { 749 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 750 } 751 mExitSecureCallback = null; 752 resetStateLocked(); 753 } else { 754 showLocked(null); 755 756 // block until we know the keygaurd is done drawing (and post a message 757 // to unblock us after a timeout so we don't risk blocking too long 758 // and causing an ANR). 759 mWaitingUntilKeyguardVisible = true; 760 mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS); 761 if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false"); 762 while (mWaitingUntilKeyguardVisible) { 763 try { 764 wait(); 765 } catch (InterruptedException e) { 766 Thread.currentThread().interrupt(); 767 } 768 } 769 if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible"); 770 } 771 } 772 } 773 } 774 775 /** 776 * @see android.app.KeyguardManager#exitKeyguardSecurely 777 */ 778 public void verifyUnlock(IKeyguardExitCallback callback) { 779 synchronized (this) { 780 if (DEBUG) Log.d(TAG, "verifyUnlock"); 781 if (!mUpdateMonitor.isDeviceProvisioned()) { 782 // don't allow this api when the device isn't provisioned 783 if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned"); 784 try { 785 callback.onKeyguardExitResult(false); 786 } catch (RemoteException e) { 787 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 788 } 789 } else if (mExternallyEnabled) { 790 // this only applies when the user has externally disabled the 791 // keyguard. this is unexpected and means the user is not 792 // using the api properly. 793 Log.w(TAG, "verifyUnlock called when not externally disabled"); 794 try { 795 callback.onKeyguardExitResult(false); 796 } catch (RemoteException e) { 797 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 798 } 799 } else if (mExitSecureCallback != null) { 800 // already in progress with someone else 801 try { 802 callback.onKeyguardExitResult(false); 803 } catch (RemoteException e) { 804 Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); 805 } 806 } else { 807 mExitSecureCallback = callback; 808 verifyUnlockLocked(); 809 } 810 } 811 } 812 813 /** 814 * Is the keyguard currently showing? 815 */ 816 public boolean isShowing() { 817 return mShowing; 818 } 819 820 public boolean isOccluded() { 821 return mOccluded; 822 } 823 824 /** 825 * Is the keyguard currently showing and not being force hidden? 826 */ 827 public boolean isShowingAndNotOccluded() { 828 return mShowing && !mOccluded; 829 } 830 831 /** 832 * Notify us when the keyguard is occluded by another window 833 */ 834 public void setOccluded(boolean isOccluded) { 835 if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded); 836 mUpdateMonitor.sendKeyguardVisibilityChanged(!isOccluded); 837 mHandler.removeMessages(SET_OCCLUDED); 838 Message msg = mHandler.obtainMessage(SET_OCCLUDED, (isOccluded ? 1 : 0), 0); 839 mHandler.sendMessage(msg); 840 } 841 842 /** 843 * Handles SET_OCCLUDED message sent by setOccluded() 844 */ 845 private void handleSetOccluded(boolean isOccluded) { 846 synchronized (KeyguardViewMediator.this) { 847 if (mOccluded != isOccluded) { 848 mOccluded = isOccluded; 849 mStatusBarKeyguardViewManager.setOccluded(isOccluded); 850 updateActivityLockScreenState(); 851 adjustStatusBarLocked(); 852 } 853 if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) { 854 mKeyguardAnalytics.getCallback().onSetOccluded(isOccluded); 855 } 856 } 857 } 858 859 /** 860 * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout. 861 * This must be safe to call from any thread and with any window manager locks held. 862 */ 863 public void doKeyguardTimeout(Bundle options) { 864 mHandler.removeMessages(KEYGUARD_TIMEOUT); 865 Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options); 866 mHandler.sendMessage(msg); 867 } 868 869 /** 870 * Given the state of the keyguard, is the input restricted? 871 * Input is restricted when the keyguard is showing, or when the keyguard 872 * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet. 873 */ 874 public boolean isInputRestricted() { 875 return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned(); 876 } 877 878 /** 879 * Enable the keyguard if the settings are appropriate. 880 */ 881 private void doKeyguardLocked(Bundle options) { 882 // if another app is disabling us, don't show 883 if (!mExternallyEnabled) { 884 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); 885 886 // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes 887 // for an occasional ugly flicker in this situation: 888 // 1) receive a call with the screen on (no keyguard) or make a call 889 // 2) screen times out 890 // 3) user hits key to turn screen back on 891 // instead, we reenable the keyguard when we know the screen is off and the call 892 // ends (see the broadcast receiver below) 893 // TODO: clean this up when we have better support at the window manager level 894 // for apps that wish to be on top of the keyguard 895 return; 896 } 897 898 // note whether notification access should be allowed 899 mAllowNotificationsWhenSecure = ENABLE_SECURE_STATUS_BAR_EXPAND 900 && 0 != Settings.Global.getInt( 901 mContext.getContentResolver(), 902 Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 903 ALLOW_NOTIFICATIONS_DEFAULT ? 1 : 0); 904 905 // if the keyguard is already showing, don't bother 906 if (mStatusBarKeyguardViewManager.isShowing()) { 907 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing"); 908 return; 909 } 910 911 // if the setup wizard hasn't run yet, don't show 912 final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", 913 false); 914 final boolean provisioned = mUpdateMonitor.isDeviceProvisioned(); 915 final IccCardConstants.State state = mUpdateMonitor.getSimState(); 916 final boolean lockedOrMissing = state.isPinLocked() 917 || ((state == IccCardConstants.State.ABSENT 918 || state == IccCardConstants.State.PERM_DISABLED) 919 && requireSim); 920 921 if (!lockedOrMissing && !provisioned) { 922 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned" 923 + " and the sim is not locked or missing"); 924 return; 925 } 926 927 if (!mUserManager.isUserSwitcherEnabled() 928 && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) { 929 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off"); 930 return; 931 } 932 933 if (mLockPatternUtils.checkVoldPassword()) { 934 if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted"); 935 // Without this, settings is not enabled until the lock screen first appears 936 hideLocked(); 937 return; 938 } 939 940 if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen"); 941 showLocked(options); 942 } 943 944 /** 945 * Dismiss the keyguard through the security layers. 946 */ 947 public void handleDismiss() { 948 if (mShowing && !mOccluded) { 949 mStatusBarKeyguardViewManager.dismiss(); 950 } 951 } 952 953 public void dismiss() { 954 mHandler.sendEmptyMessage(DISMISS); 955 } 956 957 /** 958 * Send message to keyguard telling it to reset its state. 959 * @see #handleReset 960 */ 961 private void resetStateLocked() { 962 if (DEBUG) Log.e(TAG, "resetStateLocked"); 963 Message msg = mHandler.obtainMessage(RESET); 964 mHandler.sendMessage(msg); 965 } 966 967 /** 968 * Send message to keyguard telling it to verify unlock 969 * @see #handleVerifyUnlock() 970 */ 971 private void verifyUnlockLocked() { 972 if (DEBUG) Log.d(TAG, "verifyUnlockLocked"); 973 mHandler.sendEmptyMessage(VERIFY_UNLOCK); 974 } 975 976 977 /** 978 * Send a message to keyguard telling it the screen just turned on. 979 * @see #onScreenTurnedOff(int) 980 * @see #handleNotifyScreenOff 981 */ 982 private void notifyScreenOffLocked() { 983 if (DEBUG) Log.d(TAG, "notifyScreenOffLocked"); 984 mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF); 985 } 986 987 /** 988 * Send a message to keyguard telling it the screen just turned on. 989 * @see #onScreenTurnedOn 990 * @see #handleNotifyScreenOn 991 */ 992 private void notifyScreenOnLocked(IKeyguardShowCallback result) { 993 if (DEBUG) Log.d(TAG, "notifyScreenOnLocked"); 994 Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, result); 995 mHandler.sendMessage(msg); 996 } 997 998 /** 999 * Send message to keyguard telling it to show itself 1000 * @see #handleShow 1001 */ 1002 private void showLocked(Bundle options) { 1003 if (DEBUG) Log.d(TAG, "showLocked"); 1004 // ensure we stay awake until we are finished displaying the keyguard 1005 mShowKeyguardWakeLock.acquire(); 1006 Message msg = mHandler.obtainMessage(SHOW, options); 1007 mHandler.sendMessage(msg); 1008 } 1009 1010 /** 1011 * Send message to keyguard telling it to hide itself 1012 * @see #handleHide() 1013 */ 1014 private void hideLocked() { 1015 if (DEBUG) Log.d(TAG, "hideLocked"); 1016 Message msg = mHandler.obtainMessage(HIDE); 1017 mHandler.sendMessage(msg); 1018 } 1019 1020 public boolean isSecure() { 1021 return mLockPatternUtils.isSecure() 1022 || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure(); 1023 } 1024 1025 /** 1026 * Update the newUserId. Call while holding WindowManagerService lock. 1027 * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing. 1028 * 1029 * @param newUserId The id of the incoming user. 1030 */ 1031 public void setCurrentUser(int newUserId) { 1032 mLockPatternUtils.setCurrentUser(newUserId); 1033 } 1034 1035 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 1036 @Override 1037 public void onReceive(Context context, Intent intent) { 1038 if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) { 1039 final int sequence = intent.getIntExtra("seq", 0); 1040 if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = " 1041 + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence); 1042 synchronized (KeyguardViewMediator.this) { 1043 if (mDelayedShowingSequence == sequence) { 1044 // Don't play lockscreen SFX if the screen went off due to timeout. 1045 mSuppressNextLockSound = true; 1046 doKeyguardLocked(null); 1047 } 1048 } 1049 } 1050 } 1051 }; 1052 1053 public void keyguardDone(boolean authenticated, boolean wakeup) { 1054 if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")"); 1055 EventLog.writeEvent(70000, 2); 1056 synchronized (this) { 1057 mKeyguardDonePending = false; 1058 } 1059 Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0, wakeup ? 1 : 0); 1060 mHandler.sendMessage(msg); 1061 } 1062 1063 /** 1064 * This handler will be associated with the policy thread, which will also 1065 * be the UI thread of the keyguard. Since the apis of the policy, and therefore 1066 * this class, can be called by other threads, any action that directly 1067 * interacts with the keyguard ui should be posted to this handler, rather 1068 * than called directly. 1069 */ 1070 private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) { 1071 @Override 1072 public void handleMessage(Message msg) { 1073 switch (msg.what) { 1074 case SHOW: 1075 handleShow((Bundle) msg.obj); 1076 break; 1077 case HIDE: 1078 handleHide(); 1079 break; 1080 case RESET: 1081 handleReset(); 1082 break; 1083 case VERIFY_UNLOCK: 1084 handleVerifyUnlock(); 1085 break; 1086 case NOTIFY_SCREEN_OFF: 1087 handleNotifyScreenOff(); 1088 break; 1089 case NOTIFY_SCREEN_ON: 1090 handleNotifyScreenOn((IKeyguardShowCallback) msg.obj); 1091 break; 1092 case KEYGUARD_DONE: 1093 handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0); 1094 break; 1095 case KEYGUARD_DONE_DRAWING: 1096 handleKeyguardDoneDrawing(); 1097 break; 1098 case KEYGUARD_DONE_AUTHENTICATING: 1099 keyguardDone(true, true); 1100 break; 1101 case SET_OCCLUDED: 1102 handleSetOccluded(msg.arg1 != 0); 1103 break; 1104 case KEYGUARD_TIMEOUT: 1105 synchronized (KeyguardViewMediator.this) { 1106 doKeyguardLocked((Bundle) msg.obj); 1107 } 1108 break; 1109 case DISMISS: 1110 handleDismiss(); 1111 break; 1112 } 1113 } 1114 }; 1115 1116 /** 1117 * @see #keyguardDone 1118 * @see #KEYGUARD_DONE 1119 */ 1120 private void handleKeyguardDone(boolean authenticated, boolean wakeup) { 1121 if (DEBUG) Log.d(TAG, "handleKeyguardDone"); 1122 1123 if (authenticated) { 1124 mUpdateMonitor.clearFailedUnlockAttempts(); 1125 } 1126 1127 if (mExitSecureCallback != null) { 1128 try { 1129 mExitSecureCallback.onKeyguardExitResult(authenticated); 1130 } catch (RemoteException e) { 1131 Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e); 1132 } 1133 1134 mExitSecureCallback = null; 1135 1136 if (authenticated) { 1137 // after succesfully exiting securely, no need to reshow 1138 // the keyguard when they've released the lock 1139 mExternallyEnabled = true; 1140 mNeedToReshowWhenReenabled = false; 1141 } 1142 } 1143 1144 handleHide(); 1145 sendUserPresentBroadcast(); 1146 } 1147 1148 private void sendUserPresentBroadcast() { 1149 final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser()); 1150 mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser); 1151 } 1152 1153 /** 1154 * @see #keyguardDone 1155 * @see #KEYGUARD_DONE_DRAWING 1156 */ 1157 private void handleKeyguardDoneDrawing() { 1158 synchronized(this) { 1159 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing"); 1160 if (mWaitingUntilKeyguardVisible) { 1161 if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible"); 1162 mWaitingUntilKeyguardVisible = false; 1163 notifyAll(); 1164 1165 // there will usually be two of these sent, one as a timeout, and one 1166 // as a result of the callback, so remove any remaining messages from 1167 // the queue 1168 mHandler.removeMessages(KEYGUARD_DONE_DRAWING); 1169 } 1170 } 1171 } 1172 1173 private void playSounds(boolean locked) { 1174 // User feedback for keyguard. 1175 1176 if (mSuppressNextLockSound) { 1177 mSuppressNextLockSound = false; 1178 return; 1179 } 1180 1181 final ContentResolver cr = mContext.getContentResolver(); 1182 if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) { 1183 final int whichSound = locked 1184 ? mLockSoundId 1185 : mUnlockSoundId; 1186 mLockSounds.stop(mLockSoundStreamId); 1187 // Init mAudioManager 1188 if (mAudioManager == null) { 1189 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 1190 if (mAudioManager == null) return; 1191 mMasterStreamType = mAudioManager.getMasterStreamType(); 1192 } 1193 // If the stream is muted, don't play the sound 1194 if (mAudioManager.isStreamMute(mMasterStreamType)) return; 1195 1196 mLockSoundStreamId = mLockSounds.play(whichSound, 1197 mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/); 1198 } 1199 } 1200 1201 private void updateActivityLockScreenState() { 1202 try { 1203 ActivityManagerNative.getDefault().setLockScreenShown(mShowing && !mOccluded); 1204 } catch (RemoteException e) { 1205 } 1206 } 1207 1208 /** 1209 * Handle message sent by {@link #showLocked}. 1210 * @see #SHOW 1211 */ 1212 private void handleShow(Bundle options) { 1213 synchronized (KeyguardViewMediator.this) { 1214 if (!mSystemReady) { 1215 if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready."); 1216 return; 1217 } else { 1218 if (DEBUG) Log.d(TAG, "handleShow"); 1219 } 1220 1221 mStatusBarKeyguardViewManager.show(options); 1222 mShowing = true; 1223 mKeyguardDonePending = false; 1224 updateActivityLockScreenState(); 1225 adjustStatusBarLocked(); 1226 userActivity(); 1227 1228 // Do this at the end to not slow down display of the keyguard. 1229 playSounds(true); 1230 1231 mShowKeyguardWakeLock.release(); 1232 } 1233 mKeyguardDisplayManager.show(); 1234 } 1235 1236 /** 1237 * Handle message sent by {@link #hideLocked()} 1238 * @see #HIDE 1239 */ 1240 private void handleHide() { 1241 synchronized (KeyguardViewMediator.this) { 1242 if (DEBUG) Log.d(TAG, "handleHide"); 1243 1244 // only play "unlock" noises if not on a call (since the incall UI 1245 // disables the keyguard) 1246 if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { 1247 playSounds(false); 1248 } 1249 1250 mStatusBarKeyguardViewManager.hide(); 1251 mShowing = false; 1252 mKeyguardDonePending = false; 1253 updateActivityLockScreenState(); 1254 adjustStatusBarLocked(); 1255 } 1256 } 1257 1258 private void adjustStatusBarLocked() { 1259 if (mStatusBarManager == null) { 1260 mStatusBarManager = (StatusBarManager) 1261 mContext.getSystemService(Context.STATUS_BAR_SERVICE); 1262 } 1263 if (mStatusBarManager == null) { 1264 Log.w(TAG, "Could not get status bar manager"); 1265 } else { 1266 // Disable aspects of the system/status/navigation bars that must not be re-enabled by 1267 // windows that appear on top, ever 1268 int flags = StatusBarManager.DISABLE_NONE; 1269 if (mShowing) { 1270 // Permanently disable components not available when keyguard is enabled 1271 // (like recents). Temporary enable/disable (e.g. the "back" button) are 1272 // done in KeyguardHostView. 1273 flags |= StatusBarManager.DISABLE_RECENT; 1274 if (isSecure()) { 1275 // showing secure lockscreen; disable ticker and switch private notifications 1276 // to show their public versions, if available. 1277 flags |= StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS; 1278 } 1279 if (!isAssistantAvailable()) { 1280 flags |= StatusBarManager.DISABLE_SEARCH; 1281 } 1282 } 1283 if (isShowingAndNotOccluded()) { 1284 flags |= StatusBarManager.DISABLE_HOME; 1285 } 1286 1287 if (DEBUG) { 1288 Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mOccluded=" + mOccluded 1289 + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags)); 1290 } 1291 1292 if (!(mContext instanceof Activity)) { 1293 mStatusBarManager.disable(flags); 1294 } 1295 } 1296 } 1297 1298 /** 1299 * Handle message sent by {@link #resetStateLocked} 1300 * @see #RESET 1301 */ 1302 private void handleReset() { 1303 synchronized (KeyguardViewMediator.this) { 1304 if (DEBUG) Log.d(TAG, "handleReset"); 1305 mStatusBarKeyguardViewManager.reset(); 1306 } 1307 } 1308 1309 /** 1310 * Handle message sent by {@link #verifyUnlock} 1311 * @see #VERIFY_UNLOCK 1312 */ 1313 private void handleVerifyUnlock() { 1314 synchronized (KeyguardViewMediator.this) { 1315 if (DEBUG) Log.d(TAG, "handleVerifyUnlock"); 1316 mStatusBarKeyguardViewManager.verifyUnlock(); 1317 mShowing = true; 1318 updateActivityLockScreenState(); 1319 } 1320 } 1321 1322 /** 1323 * Handle message sent by {@link #notifyScreenOffLocked()} 1324 * @see #NOTIFY_SCREEN_OFF 1325 */ 1326 private void handleNotifyScreenOff() { 1327 synchronized (KeyguardViewMediator.this) { 1328 if (DEBUG) Log.d(TAG, "handleNotifyScreenOff"); 1329 mStatusBarKeyguardViewManager.onScreenTurnedOff(); 1330 } 1331 } 1332 1333 /** 1334 * Handle message sent by {@link #notifyScreenOnLocked} 1335 * @see #NOTIFY_SCREEN_ON 1336 */ 1337 private void handleNotifyScreenOn(IKeyguardShowCallback callback) { 1338 synchronized (KeyguardViewMediator.this) { 1339 if (DEBUG) Log.d(TAG, "handleNotifyScreenOn"); 1340 mStatusBarKeyguardViewManager.onScreenTurnedOn(callback); 1341 } 1342 } 1343 1344 public boolean isDismissable() { 1345 return mKeyguardDonePending || !isSecure(); 1346 } 1347 1348 private boolean isAssistantAvailable() { 1349 return mSearchManager != null 1350 && mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null; 1351 } 1352 1353 public void onBootCompleted() { 1354 mUpdateMonitor.dispatchBootCompleted(); 1355 } 1356 1357 public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar, 1358 ViewGroup container, StatusBarWindowManager statusBarWindowManager) { 1359 mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container, 1360 statusBarWindowManager); 1361 return mStatusBarKeyguardViewManager; 1362 } 1363 1364 public ViewMediatorCallback getViewMediatorCallback() { 1365 return mViewMediatorCallback; 1366 } 1367} 1368