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