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.WindowManagerService; 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 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 } 207 208 @Override 209 public void onServiceDisconnected(ComponentName name) { 210 if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)"); 211 mKeyguardService = null; 212 mKeyguardState.reset(); 213 mHandler.post(() -> { 214 try { 215 ActivityTaskManager.getService().setLockScreenShown(true /* keyguardShowing */, 216 false /* aodShowing */); 217 } catch (RemoteException e) { 218 // Local call. 219 } 220 }); 221 } 222 }; 223 isShowing()224 public boolean isShowing() { 225 if (mKeyguardService != null) { 226 mKeyguardState.showing = mKeyguardService.isShowing(); 227 } 228 return mKeyguardState.showing; 229 } 230 isTrusted()231 public boolean isTrusted() { 232 if (mKeyguardService != null) { 233 return mKeyguardService.isTrusted(); 234 } 235 return false; 236 } 237 hasLockscreenWallpaper()238 public boolean hasLockscreenWallpaper() { 239 if (mKeyguardService != null) { 240 return mKeyguardService.hasLockscreenWallpaper(); 241 } 242 return false; 243 } 244 hasKeyguard()245 public boolean hasKeyguard() { 246 return mKeyguardState.deviceHasKeyguard; 247 } 248 isInputRestricted()249 public boolean isInputRestricted() { 250 if (mKeyguardService != null) { 251 mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted(); 252 } 253 return mKeyguardState.inputRestricted; 254 } 255 verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult)256 public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) { 257 if (mKeyguardService != null) { 258 mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult)); 259 } 260 } 261 262 /** 263 * @deprecated Notify occlude status change via remote animation. 264 */ 265 @Deprecated setOccluded(boolean isOccluded, boolean animate)266 public void setOccluded(boolean isOccluded, boolean animate) { 267 if (!WindowManagerService.sEnableRemoteKeyguardOccludeAnimation 268 && mKeyguardService != null) { 269 if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate); 270 mKeyguardService.setOccluded(isOccluded, animate); 271 } 272 mKeyguardState.occluded = isOccluded; 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 (!WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation 410 && mKeyguardService != null) { 411 mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration); 412 } 413 } 414 onBootCompleted()415 public void onBootCompleted() { 416 if (mKeyguardService != null) { 417 mKeyguardService.onBootCompleted(); 418 } 419 mKeyguardState.bootCompleted = true; 420 } 421 onShortPowerPressedGoHome()422 public void onShortPowerPressedGoHome() { 423 if (mKeyguardService != null) { 424 mKeyguardService.onShortPowerPressedGoHome(); 425 } 426 } 427 dumpDebug(ProtoOutputStream proto, long fieldId)428 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 429 final long token = proto.start(fieldId); 430 proto.write(SHOWING, mKeyguardState.showing); 431 proto.write(OCCLUDED, mKeyguardState.occluded); 432 proto.write(SECURE, mKeyguardState.secure); 433 proto.write(SCREEN_STATE, mKeyguardState.screenState); 434 proto.write(INTERACTIVE_STATE, mKeyguardState.interactiveState); 435 proto.end(token); 436 } 437 dump(String prefix, PrintWriter pw)438 public void dump(String prefix, PrintWriter pw) { 439 pw.println(prefix + TAG); 440 prefix += " "; 441 pw.println(prefix + "showing=" + mKeyguardState.showing); 442 pw.println(prefix + "showingAndNotOccluded=" + mKeyguardState.showingAndNotOccluded); 443 pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted); 444 pw.println(prefix + "occluded=" + mKeyguardState.occluded); 445 pw.println(prefix + "secure=" + mKeyguardState.secure); 446 pw.println(prefix + "dreaming=" + mKeyguardState.dreaming); 447 pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady); 448 pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard); 449 pw.println(prefix + "enabled=" + mKeyguardState.enabled); 450 pw.println(prefix + "offReason=" + 451 WindowManagerPolicyConstants.offReasonToString(mKeyguardState.offReason)); 452 pw.println(prefix + "currentUser=" + mKeyguardState.currentUser); 453 pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted); 454 pw.println(prefix + "screenState=" + screenStateToString(mKeyguardState.screenState)); 455 pw.println(prefix + "interactiveState=" + 456 interactiveStateToString(mKeyguardState.interactiveState)); 457 if (mKeyguardService != null) { 458 mKeyguardService.dump(prefix, pw); 459 } 460 } 461 screenStateToString(int screen)462 private static String screenStateToString(int screen) { 463 switch (screen) { 464 case SCREEN_STATE_OFF: 465 return "SCREEN_STATE_OFF"; 466 case SCREEN_STATE_TURNING_ON: 467 return "SCREEN_STATE_TURNING_ON"; 468 case SCREEN_STATE_ON: 469 return "SCREEN_STATE_ON"; 470 case SCREEN_STATE_TURNING_OFF: 471 return "SCREEN_STATE_TURNING_OFF"; 472 default: 473 return Integer.toString(screen); 474 } 475 } 476 interactiveStateToString(int interactive)477 private static String interactiveStateToString(int interactive) { 478 switch (interactive) { 479 case INTERACTIVE_STATE_SLEEP: 480 return "INTERACTIVE_STATE_SLEEP"; 481 case INTERACTIVE_STATE_WAKING: 482 return "INTERACTIVE_STATE_WAKING"; 483 case INTERACTIVE_STATE_AWAKE: 484 return "INTERACTIVE_STATE_AWAKE"; 485 case INTERACTIVE_STATE_GOING_TO_SLEEP: 486 return "INTERACTIVE_STATE_GOING_TO_SLEEP"; 487 default: 488 return Integer.toString(interactive); 489 } 490 } 491 } 492