1 package com.android.server.policy.keyguard; 2 3 import static com.android.server.wm.KeyguardServiceDelegateProto.INTERACTIVE_STATE; 4 import static com.android.server.wm.KeyguardServiceDelegateProto.OCCLUDED; 5 import static com.android.server.wm.KeyguardServiceDelegateProto.SCREEN_STATE; 6 import static com.android.server.wm.KeyguardServiceDelegateProto.SECURE; 7 import static com.android.server.wm.KeyguardServiceDelegateProto.SHOWING; 8 9 import android.app.ActivityTaskManager; 10 import android.content.ComponentName; 11 import android.content.Context; 12 import android.content.Intent; 13 import android.content.ServiceConnection; 14 import android.content.res.Resources; 15 import android.os.Bundle; 16 import android.os.Handler; 17 import android.os.IBinder; 18 import android.os.PowerManager; 19 import android.os.RemoteException; 20 import android.os.UserHandle; 21 import android.util.Log; 22 import android.util.Slog; 23 import android.util.proto.ProtoOutputStream; 24 import android.view.WindowManagerPolicyConstants; 25 26 import com.android.internal.policy.IKeyguardDismissCallback; 27 import com.android.internal.policy.IKeyguardDrawnCallback; 28 import com.android.internal.policy.IKeyguardExitCallback; 29 import com.android.internal.policy.IKeyguardService; 30 import com.android.server.UiThread; 31 import com.android.server.policy.WindowManagerPolicy.OnKeyguardExitResult; 32 33 import java.io.PrintWriter; 34 35 /** 36 * A local class that keeps a cache of keyguard state that can be restored in the event 37 * keyguard crashes. It currently also allows runtime-selectable 38 * local or remote instances of keyguard. 39 */ 40 public class KeyguardServiceDelegate { 41 private static final String TAG = "KeyguardServiceDelegate"; 42 private static final boolean DEBUG = false; 43 44 private static final int SCREEN_STATE_OFF = 0; 45 private static final int SCREEN_STATE_TURNING_ON = 1; 46 private static final int SCREEN_STATE_ON = 2; 47 private static final int SCREEN_STATE_TURNING_OFF = 3; 48 49 private static final int INTERACTIVE_STATE_SLEEP = 0; 50 private static final int INTERACTIVE_STATE_WAKING = 1; 51 private static final int INTERACTIVE_STATE_AWAKE = 2; 52 private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 3; 53 54 protected KeyguardServiceWrapper mKeyguardService; 55 private final Context mContext; 56 private final Handler mHandler; 57 private final KeyguardState mKeyguardState = new KeyguardState(); 58 private final KeyguardStateMonitor.StateCallback mCallback; 59 60 private DrawnListener mDrawnListenerWhenConnect; 61 62 private static final class KeyguardState { KeyguardState()63 KeyguardState() { 64 reset(); 65 } 66 boolean showing; 67 boolean showingAndNotOccluded; 68 boolean inputRestricted; 69 volatile boolean occluded; 70 boolean secure; 71 boolean dreaming; 72 boolean systemIsReady; 73 boolean deviceHasKeyguard; 74 public boolean enabled; 75 public int offReason; 76 public int currentUser; 77 public boolean bootCompleted; 78 public int screenState; 79 public int interactiveState; 80 reset()81 private void reset() { 82 // Assume keyguard is showing and secure until we know for sure. This is here in 83 // the event something checks before the service is actually started. 84 // KeyguardService itself should default to this state until the real state is known. 85 showing = true; 86 showingAndNotOccluded = true; 87 secure = true; 88 deviceHasKeyguard = true; 89 enabled = true; 90 currentUser = UserHandle.USER_NULL; 91 } 92 }; 93 94 public interface DrawnListener { onDrawn()95 void onDrawn(); 96 } 97 98 // A delegate class to map a particular invocation with a ShowListener object. 99 private final class KeyguardShowDelegate extends IKeyguardDrawnCallback.Stub { 100 private DrawnListener mDrawnListener; 101 KeyguardShowDelegate(DrawnListener drawnListener)102 KeyguardShowDelegate(DrawnListener drawnListener) { 103 mDrawnListener = drawnListener; 104 } 105 106 @Override onDrawn()107 public void onDrawn() throws RemoteException { 108 if (DEBUG) Log.v(TAG, "**** SHOWN CALLED ****"); 109 if (mDrawnListener != null) { 110 mDrawnListener.onDrawn(); 111 } 112 } 113 }; 114 115 // A delegate class to map a particular invocation with an OnKeyguardExitResult object. 116 private final class KeyguardExitDelegate extends IKeyguardExitCallback.Stub { 117 private OnKeyguardExitResult mOnKeyguardExitResult; 118 KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult)119 KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult) { 120 mOnKeyguardExitResult = onKeyguardExitResult; 121 } 122 123 @Override onKeyguardExitResult(boolean success)124 public void onKeyguardExitResult(boolean success) throws RemoteException { 125 if (DEBUG) Log.v(TAG, "**** onKeyguardExitResult(" + success +") CALLED ****"); 126 if (mOnKeyguardExitResult != null) { 127 mOnKeyguardExitResult.onKeyguardExitResult(success); 128 } 129 } 130 }; 131 KeyguardServiceDelegate(Context context, KeyguardStateMonitor.StateCallback callback)132 public KeyguardServiceDelegate(Context context, KeyguardStateMonitor.StateCallback callback) { 133 mContext = context; 134 mHandler = UiThread.getHandler(); 135 mCallback = callback; 136 } 137 bindService(Context context)138 public void bindService(Context context) { 139 Intent intent = new Intent(); 140 final Resources resources = context.getApplicationContext().getResources(); 141 142 final ComponentName keyguardComponent = ComponentName.unflattenFromString( 143 resources.getString(com.android.internal.R.string.config_keyguardComponent)); 144 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); 145 intent.setComponent(keyguardComponent); 146 147 if (!context.bindServiceAsUser(intent, mKeyguardConnection, 148 Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) { 149 Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent); 150 mKeyguardState.showing = false; 151 mKeyguardState.showingAndNotOccluded = false; 152 mKeyguardState.secure = false; 153 synchronized (mKeyguardState) { 154 // TODO: Fix synchronisation model in this class. The other state in this class 155 // is at least self-healing but a race condition here can lead to the scrim being 156 // stuck on keyguard-less devices. 157 mKeyguardState.deviceHasKeyguard = false; 158 } 159 } else { 160 if (DEBUG) Log.v(TAG, "*** Keyguard started"); 161 } 162 } 163 164 private final ServiceConnection mKeyguardConnection = new ServiceConnection() { 165 @Override 166 public void onServiceConnected(ComponentName name, IBinder service) { 167 if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)"); 168 mKeyguardService = new KeyguardServiceWrapper(mContext, 169 IKeyguardService.Stub.asInterface(service), mCallback); 170 if (mKeyguardState.systemIsReady) { 171 // If the system is ready, it means keyguard crashed and restarted. 172 mKeyguardService.onSystemReady(); 173 if (mKeyguardState.currentUser != UserHandle.USER_NULL) { 174 // There has been a user switch earlier 175 mKeyguardService.setCurrentUser(mKeyguardState.currentUser); 176 } 177 // This is used to hide the scrim once keyguard displays. 178 if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE 179 || mKeyguardState.interactiveState == INTERACTIVE_STATE_WAKING) { 180 mKeyguardService.onStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN, 181 false /* cameraGestureTriggered */); 182 } 183 if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) { 184 mKeyguardService.onFinishedWakingUp(); 185 } 186 if (mKeyguardState.screenState == SCREEN_STATE_ON 187 || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) { 188 mKeyguardService.onScreenTurningOn( 189 new KeyguardShowDelegate(mDrawnListenerWhenConnect)); 190 } 191 if (mKeyguardState.screenState == SCREEN_STATE_ON) { 192 mKeyguardService.onScreenTurnedOn(); 193 } 194 mDrawnListenerWhenConnect = null; 195 } 196 if (mKeyguardState.bootCompleted) { 197 mKeyguardService.onBootCompleted(); 198 } 199 if (mKeyguardState.occluded) { 200 mKeyguardService.setOccluded(mKeyguardState.occluded, false /* animate */); 201 } 202 if (!mKeyguardState.enabled) { 203 mKeyguardService.setKeyguardEnabled(mKeyguardState.enabled); 204 } 205 } 206 207 @Override 208 public void onServiceDisconnected(ComponentName name) { 209 if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)"); 210 mKeyguardService = null; 211 mKeyguardState.reset(); 212 mHandler.post(() -> { 213 try { 214 ActivityTaskManager.getService().setLockScreenShown(true /* keyguardShowing */, 215 false /* aodShowing */); 216 } catch (RemoteException e) { 217 // Local call. 218 } 219 }); 220 } 221 }; 222 isShowing()223 public boolean isShowing() { 224 if (mKeyguardService != null) { 225 mKeyguardState.showing = mKeyguardService.isShowing(); 226 } 227 return mKeyguardState.showing; 228 } 229 isTrusted()230 public boolean isTrusted() { 231 if (mKeyguardService != null) { 232 return mKeyguardService.isTrusted(); 233 } 234 return false; 235 } 236 hasKeyguard()237 public boolean hasKeyguard() { 238 return mKeyguardState.deviceHasKeyguard; 239 } 240 isInputRestricted()241 public boolean isInputRestricted() { 242 if (mKeyguardService != null) { 243 mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted(); 244 } 245 return mKeyguardState.inputRestricted; 246 } 247 verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult)248 public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) { 249 if (mKeyguardService != null) { 250 mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult)); 251 } 252 } 253 setOccluded(boolean isOccluded, boolean animate, boolean notify)254 public void setOccluded(boolean isOccluded, boolean animate, boolean notify) { 255 if (mKeyguardService != null && notify) { 256 if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate); 257 mKeyguardService.setOccluded(isOccluded, animate); 258 } 259 mKeyguardState.occluded = isOccluded; 260 } 261 isOccluded()262 public boolean isOccluded() { 263 return mKeyguardState.occluded; 264 } 265 dismiss(IKeyguardDismissCallback callback, CharSequence message)266 public void dismiss(IKeyguardDismissCallback callback, CharSequence message) { 267 if (mKeyguardService != null) { 268 mKeyguardService.dismiss(callback, message); 269 } 270 } 271 isSecure(int userId)272 public boolean isSecure(int userId) { 273 if (mKeyguardService != null) { 274 mKeyguardState.secure = mKeyguardService.isSecure(userId); 275 } 276 return mKeyguardState.secure; 277 } 278 onDreamingStarted()279 public void onDreamingStarted() { 280 if (mKeyguardService != null) { 281 mKeyguardService.onDreamingStarted(); 282 } 283 mKeyguardState.dreaming = true; 284 } 285 onDreamingStopped()286 public void onDreamingStopped() { 287 if (mKeyguardService != null) { 288 mKeyguardService.onDreamingStopped(); 289 } 290 mKeyguardState.dreaming = false; 291 } 292 onStartedWakingUp( @owerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered)293 public void onStartedWakingUp( 294 @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) { 295 if (mKeyguardService != null) { 296 if (DEBUG) Log.v(TAG, "onStartedWakingUp()"); 297 mKeyguardService.onStartedWakingUp(pmWakeReason, cameraGestureTriggered); 298 } 299 mKeyguardState.interactiveState = INTERACTIVE_STATE_WAKING; 300 } 301 onFinishedWakingUp()302 public void onFinishedWakingUp() { 303 if (mKeyguardService != null) { 304 if (DEBUG) Log.v(TAG, "onFinishedWakingUp()"); 305 mKeyguardService.onFinishedWakingUp(); 306 } 307 mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE; 308 } 309 onScreenTurningOff()310 public void onScreenTurningOff() { 311 if (mKeyguardService != null) { 312 if (DEBUG) Log.v(TAG, "onScreenTurningOff()"); 313 mKeyguardService.onScreenTurningOff(); 314 } 315 mKeyguardState.screenState = SCREEN_STATE_TURNING_OFF; 316 } 317 onScreenTurnedOff()318 public void onScreenTurnedOff() { 319 if (mKeyguardService != null) { 320 if (DEBUG) Log.v(TAG, "onScreenTurnedOff()"); 321 mKeyguardService.onScreenTurnedOff(); 322 } 323 mKeyguardState.screenState = SCREEN_STATE_OFF; 324 } 325 onScreenTurningOn(final DrawnListener drawnListener)326 public void onScreenTurningOn(final DrawnListener drawnListener) { 327 if (mKeyguardService != null) { 328 if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + drawnListener + ")"); 329 mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener)); 330 } else { 331 // try again when we establish a connection 332 Slog.w(TAG, "onScreenTurningOn(): no keyguard service!"); 333 // This shouldn't happen, but if it does, show the scrim immediately and 334 // invoke the listener's callback after the service actually connects. 335 mDrawnListenerWhenConnect = drawnListener; 336 } 337 mKeyguardState.screenState = SCREEN_STATE_TURNING_ON; 338 } 339 onScreenTurnedOn()340 public void onScreenTurnedOn() { 341 if (mKeyguardService != null) { 342 if (DEBUG) Log.v(TAG, "onScreenTurnedOn()"); 343 mKeyguardService.onScreenTurnedOn(); 344 } 345 mKeyguardState.screenState = SCREEN_STATE_ON; 346 } 347 onStartedGoingToSleep(@owerManager.GoToSleepReason int pmSleepReason)348 public void onStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) { 349 if (mKeyguardService != null) { 350 mKeyguardService.onStartedGoingToSleep(pmSleepReason); 351 } 352 mKeyguardState.offReason = 353 WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason); 354 mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP; 355 } 356 onFinishedGoingToSleep( @owerManager.GoToSleepReason int pmSleepReason, boolean cameraGestureTriggered)357 public void onFinishedGoingToSleep( 358 @PowerManager.GoToSleepReason int pmSleepReason, boolean cameraGestureTriggered) { 359 if (mKeyguardService != null) { 360 mKeyguardService.onFinishedGoingToSleep(pmSleepReason, cameraGestureTriggered); 361 } 362 mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP; 363 } 364 setKeyguardEnabled(boolean enabled)365 public void setKeyguardEnabled(boolean enabled) { 366 if (mKeyguardService != null) { 367 mKeyguardService.setKeyguardEnabled(enabled); 368 } 369 mKeyguardState.enabled = enabled; 370 } 371 onSystemReady()372 public void onSystemReady() { 373 if (mKeyguardService != null) { 374 mKeyguardService.onSystemReady(); 375 } else { 376 mKeyguardState.systemIsReady = true; 377 } 378 } 379 doKeyguardTimeout(Bundle options)380 public void doKeyguardTimeout(Bundle options) { 381 if (mKeyguardService != null) { 382 mKeyguardService.doKeyguardTimeout(options); 383 } 384 } 385 setCurrentUser(int newUserId)386 public void setCurrentUser(int newUserId) { 387 if (mKeyguardService != null) { 388 mKeyguardService.setCurrentUser(newUserId); 389 } 390 mKeyguardState.currentUser = newUserId; 391 } 392 setSwitchingUser(boolean switching)393 public void setSwitchingUser(boolean switching) { 394 if (mKeyguardService != null) { 395 mKeyguardService.setSwitchingUser(switching); 396 } 397 } 398 startKeyguardExitAnimation(long startTime, long fadeoutDuration)399 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 400 if (mKeyguardService != null) { 401 mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration); 402 } 403 } 404 onBootCompleted()405 public void onBootCompleted() { 406 if (mKeyguardService != null) { 407 mKeyguardService.onBootCompleted(); 408 } 409 mKeyguardState.bootCompleted = true; 410 } 411 onShortPowerPressedGoHome()412 public void onShortPowerPressedGoHome() { 413 if (mKeyguardService != null) { 414 mKeyguardService.onShortPowerPressedGoHome(); 415 } 416 } 417 dumpDebug(ProtoOutputStream proto, long fieldId)418 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 419 final long token = proto.start(fieldId); 420 proto.write(SHOWING, mKeyguardState.showing); 421 proto.write(OCCLUDED, mKeyguardState.occluded); 422 proto.write(SECURE, mKeyguardState.secure); 423 proto.write(SCREEN_STATE, mKeyguardState.screenState); 424 proto.write(INTERACTIVE_STATE, mKeyguardState.interactiveState); 425 proto.end(token); 426 } 427 dump(String prefix, PrintWriter pw)428 public void dump(String prefix, PrintWriter pw) { 429 pw.println(prefix + TAG); 430 prefix += " "; 431 pw.println(prefix + "showing=" + mKeyguardState.showing); 432 pw.println(prefix + "showingAndNotOccluded=" + mKeyguardState.showingAndNotOccluded); 433 pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted); 434 pw.println(prefix + "occluded=" + mKeyguardState.occluded); 435 pw.println(prefix + "secure=" + mKeyguardState.secure); 436 pw.println(prefix + "dreaming=" + mKeyguardState.dreaming); 437 pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady); 438 pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard); 439 pw.println(prefix + "enabled=" + mKeyguardState.enabled); 440 pw.println(prefix + "offReason=" + 441 WindowManagerPolicyConstants.offReasonToString(mKeyguardState.offReason)); 442 pw.println(prefix + "currentUser=" + mKeyguardState.currentUser); 443 pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted); 444 pw.println(prefix + "screenState=" + screenStateToString(mKeyguardState.screenState)); 445 pw.println(prefix + "interactiveState=" + 446 interactiveStateToString(mKeyguardState.interactiveState)); 447 if (mKeyguardService != null) { 448 mKeyguardService.dump(prefix, pw); 449 } 450 } 451 screenStateToString(int screen)452 private static String screenStateToString(int screen) { 453 switch (screen) { 454 case SCREEN_STATE_OFF: 455 return "SCREEN_STATE_OFF"; 456 case SCREEN_STATE_TURNING_ON: 457 return "SCREEN_STATE_TURNING_ON"; 458 case SCREEN_STATE_ON: 459 return "SCREEN_STATE_ON"; 460 case SCREEN_STATE_TURNING_OFF: 461 return "SCREEN_STATE_TURNING_OFF"; 462 default: 463 return Integer.toString(screen); 464 } 465 } 466 interactiveStateToString(int interactive)467 private static String interactiveStateToString(int interactive) { 468 switch (interactive) { 469 case INTERACTIVE_STATE_SLEEP: 470 return "INTERACTIVE_STATE_SLEEP"; 471 case INTERACTIVE_STATE_WAKING: 472 return "INTERACTIVE_STATE_WAKING"; 473 case INTERACTIVE_STATE_AWAKE: 474 return "INTERACTIVE_STATE_AWAKE"; 475 case INTERACTIVE_STATE_GOING_TO_SLEEP: 476 return "INTERACTIVE_STATE_GOING_TO_SLEEP"; 477 default: 478 return Integer.toString(interactive); 479 } 480 } 481 } 482