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