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