1 package com.android.server.policy.keyguard; 2 3 import static android.view.Display.INVALID_DISPLAY; 4 import static com.android.server.wm.KeyguardServiceDelegateProto.INTERACTIVE_STATE; 5 import static com.android.server.wm.KeyguardServiceDelegateProto.OCCLUDED; 6 import static com.android.server.wm.KeyguardServiceDelegateProto.SCREEN_STATE; 7 import static com.android.server.wm.KeyguardServiceDelegateProto.SECURE; 8 import static com.android.server.wm.KeyguardServiceDelegateProto.SHOWING; 9 10 import android.app.ActivityManager; 11 import android.content.ComponentName; 12 import android.content.Context; 13 import android.content.Intent; 14 import android.content.ServiceConnection; 15 import android.content.res.Resources; 16 import android.os.Bundle; 17 import android.os.Handler; 18 import android.os.IBinder; 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 { 63 KeyguardState() { 64 reset(); 65 } 66 boolean showing; 67 boolean showingAndNotOccluded; 68 boolean inputRestricted; 69 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 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 { 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 102 KeyguardShowDelegate(DrawnListener drawnListener) { 103 mDrawnListener = drawnListener; 104 } 105 106 @Override 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 119 KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult) { 120 mOnKeyguardExitResult = onKeyguardExitResult; 121 } 122 123 @Override 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 132 public KeyguardServiceDelegate(Context context, KeyguardStateMonitor.StateCallback callback) { 133 mContext = context; 134 mHandler = UiThread.getHandler(); 135 mCallback = callback; 136 } 137 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(); 181 } 182 if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) { 183 mKeyguardService.onFinishedWakingUp(); 184 } 185 if (mKeyguardState.screenState == SCREEN_STATE_ON 186 || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) { 187 mKeyguardService.onScreenTurningOn( 188 new KeyguardShowDelegate(mDrawnListenerWhenConnect)); 189 } 190 if (mKeyguardState.screenState == SCREEN_STATE_ON) { 191 mKeyguardService.onScreenTurnedOn(); 192 } 193 mDrawnListenerWhenConnect = null; 194 } 195 if (mKeyguardState.bootCompleted) { 196 mKeyguardService.onBootCompleted(); 197 } 198 if (mKeyguardState.occluded) { 199 mKeyguardService.setOccluded(mKeyguardState.occluded, false /* animate */); 200 } 201 if (!mKeyguardState.enabled) { 202 mKeyguardService.setKeyguardEnabled(mKeyguardState.enabled); 203 } 204 } 205 206 @Override 207 public void onServiceDisconnected(ComponentName name) { 208 if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)"); 209 mKeyguardService = null; 210 mKeyguardState.reset(); 211 mHandler.post(() -> { 212 try { 213 // There are no longer any keyguard windows on secondary displays, so pass 214 // INVALID_DISPLAY. All that means is that showWhenLocked activities on 215 // secondary displays now get to show. 216 ActivityManager.getService().setLockScreenShown(true /* keyguardShowing */, 217 false /* aodShowing */, INVALID_DISPLAY); 218 } catch (RemoteException e) { 219 // Local call. 220 } 221 }); 222 } 223 }; 224 225 public boolean isShowing() { 226 if (mKeyguardService != null) { 227 mKeyguardState.showing = mKeyguardService.isShowing(); 228 } 229 return mKeyguardState.showing; 230 } 231 232 public boolean isTrusted() { 233 if (mKeyguardService != null) { 234 return mKeyguardService.isTrusted(); 235 } 236 return false; 237 } 238 239 public boolean hasLockscreenWallpaper() { 240 if (mKeyguardService != null) { 241 return mKeyguardService.hasLockscreenWallpaper(); 242 } 243 return false; 244 } 245 246 public boolean hasKeyguard() { 247 return mKeyguardState.deviceHasKeyguard; 248 } 249 250 public boolean isInputRestricted() { 251 if (mKeyguardService != null) { 252 mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted(); 253 } 254 return mKeyguardState.inputRestricted; 255 } 256 257 public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) { 258 if (mKeyguardService != null) { 259 mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult)); 260 } 261 } 262 263 public void setOccluded(boolean isOccluded, boolean animate) { 264 if (mKeyguardService != null) { 265 if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate); 266 mKeyguardService.setOccluded(isOccluded, animate); 267 } 268 mKeyguardState.occluded = isOccluded; 269 } 270 271 public void dismiss(IKeyguardDismissCallback callback, CharSequence message) { 272 if (mKeyguardService != null) { 273 mKeyguardService.dismiss(callback, message); 274 } 275 } 276 277 public boolean isSecure(int userId) { 278 if (mKeyguardService != null) { 279 mKeyguardState.secure = mKeyguardService.isSecure(userId); 280 } 281 return mKeyguardState.secure; 282 } 283 284 public void onDreamingStarted() { 285 if (mKeyguardService != null) { 286 mKeyguardService.onDreamingStarted(); 287 } 288 mKeyguardState.dreaming = true; 289 } 290 291 public void onDreamingStopped() { 292 if (mKeyguardService != null) { 293 mKeyguardService.onDreamingStopped(); 294 } 295 mKeyguardState.dreaming = false; 296 } 297 298 public void onStartedWakingUp() { 299 if (mKeyguardService != null) { 300 if (DEBUG) Log.v(TAG, "onStartedWakingUp()"); 301 mKeyguardService.onStartedWakingUp(); 302 } 303 mKeyguardState.interactiveState = INTERACTIVE_STATE_WAKING; 304 } 305 306 public void onFinishedWakingUp() { 307 if (mKeyguardService != null) { 308 if (DEBUG) Log.v(TAG, "onFinishedWakingUp()"); 309 mKeyguardService.onFinishedWakingUp(); 310 } 311 mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE; 312 } 313 314 public void onScreenTurningOff() { 315 if (mKeyguardService != null) { 316 if (DEBUG) Log.v(TAG, "onScreenTurningOff()"); 317 mKeyguardService.onScreenTurningOff(); 318 } 319 mKeyguardState.screenState = SCREEN_STATE_TURNING_OFF; 320 } 321 322 public void onScreenTurnedOff() { 323 if (mKeyguardService != null) { 324 if (DEBUG) Log.v(TAG, "onScreenTurnedOff()"); 325 mKeyguardService.onScreenTurnedOff(); 326 } 327 mKeyguardState.screenState = SCREEN_STATE_OFF; 328 } 329 330 public void onScreenTurningOn(final DrawnListener drawnListener) { 331 if (mKeyguardService != null) { 332 if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + drawnListener + ")"); 333 mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener)); 334 } else { 335 // try again when we establish a connection 336 Slog.w(TAG, "onScreenTurningOn(): no keyguard service!"); 337 // This shouldn't happen, but if it does, show the scrim immediately and 338 // invoke the listener's callback after the service actually connects. 339 mDrawnListenerWhenConnect = drawnListener; 340 } 341 mKeyguardState.screenState = SCREEN_STATE_TURNING_ON; 342 } 343 344 public void onScreenTurnedOn() { 345 if (mKeyguardService != null) { 346 if (DEBUG) Log.v(TAG, "onScreenTurnedOn()"); 347 mKeyguardService.onScreenTurnedOn(); 348 } 349 mKeyguardState.screenState = SCREEN_STATE_ON; 350 } 351 352 public void onStartedGoingToSleep(int why) { 353 if (mKeyguardService != null) { 354 mKeyguardService.onStartedGoingToSleep(why); 355 } 356 mKeyguardState.offReason = why; 357 mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP; 358 } 359 360 public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) { 361 if (mKeyguardService != null) { 362 mKeyguardService.onFinishedGoingToSleep(why, cameraGestureTriggered); 363 } 364 mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP; 365 } 366 367 public void setKeyguardEnabled(boolean enabled) { 368 if (mKeyguardService != null) { 369 mKeyguardService.setKeyguardEnabled(enabled); 370 } 371 mKeyguardState.enabled = enabled; 372 } 373 374 public void onSystemReady() { 375 if (mKeyguardService != null) { 376 mKeyguardService.onSystemReady(); 377 } else { 378 mKeyguardState.systemIsReady = true; 379 } 380 } 381 382 public void doKeyguardTimeout(Bundle options) { 383 if (mKeyguardService != null) { 384 mKeyguardService.doKeyguardTimeout(options); 385 } 386 } 387 388 public void setCurrentUser(int newUserId) { 389 if (mKeyguardService != null) { 390 mKeyguardService.setCurrentUser(newUserId); 391 } 392 mKeyguardState.currentUser = newUserId; 393 } 394 395 public void setSwitchingUser(boolean switching) { 396 if (mKeyguardService != null) { 397 mKeyguardService.setSwitchingUser(switching); 398 } 399 } 400 401 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 402 if (mKeyguardService != null) { 403 mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration); 404 } 405 } 406 407 public void onBootCompleted() { 408 if (mKeyguardService != null) { 409 mKeyguardService.onBootCompleted(); 410 } 411 mKeyguardState.bootCompleted = true; 412 } 413 414 public void onShortPowerPressedGoHome() { 415 if (mKeyguardService != null) { 416 mKeyguardService.onShortPowerPressedGoHome(); 417 } 418 } 419 420 public void writeToProto(ProtoOutputStream proto, long fieldId) { 421 final long token = proto.start(fieldId); 422 proto.write(SHOWING, mKeyguardState.showing); 423 proto.write(OCCLUDED, mKeyguardState.occluded); 424 proto.write(SECURE, mKeyguardState.secure); 425 proto.write(SCREEN_STATE, mKeyguardState.screenState); 426 proto.write(INTERACTIVE_STATE, mKeyguardState.interactiveState); 427 proto.end(token); 428 } 429 430 public void dump(String prefix, PrintWriter pw) { 431 pw.println(prefix + TAG); 432 prefix += " "; 433 pw.println(prefix + "showing=" + mKeyguardState.showing); 434 pw.println(prefix + "showingAndNotOccluded=" + mKeyguardState.showingAndNotOccluded); 435 pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted); 436 pw.println(prefix + "occluded=" + mKeyguardState.occluded); 437 pw.println(prefix + "secure=" + mKeyguardState.secure); 438 pw.println(prefix + "dreaming=" + mKeyguardState.dreaming); 439 pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady); 440 pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard); 441 pw.println(prefix + "enabled=" + mKeyguardState.enabled); 442 pw.println(prefix + "offReason=" + 443 WindowManagerPolicyConstants.offReasonToString(mKeyguardState.offReason)); 444 pw.println(prefix + "currentUser=" + mKeyguardState.currentUser); 445 pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted); 446 pw.println(prefix + "screenState=" + screenStateToString(mKeyguardState.screenState)); 447 pw.println(prefix + "interactiveState=" + 448 interactiveStateToString(mKeyguardState.interactiveState)); 449 if (mKeyguardService != null) { 450 mKeyguardService.dump(prefix, pw); 451 } 452 } 453 454 private static String screenStateToString(int screen) { 455 switch (screen) { 456 case SCREEN_STATE_OFF: 457 return "SCREEN_STATE_OFF"; 458 case SCREEN_STATE_TURNING_ON: 459 return "SCREEN_STATE_TURNING_ON"; 460 case SCREEN_STATE_ON: 461 return "SCREEN_STATE_ON"; 462 case SCREEN_STATE_TURNING_OFF: 463 return "SCREEN_STATE_TURNING_OFF"; 464 default: 465 return Integer.toString(screen); 466 } 467 } 468 469 private static String interactiveStateToString(int interactive) { 470 switch (interactive) { 471 case INTERACTIVE_STATE_SLEEP: 472 return "INTERACTIVE_STATE_SLEEP"; 473 case INTERACTIVE_STATE_WAKING: 474 return "INTERACTIVE_STATE_WAKING"; 475 case INTERACTIVE_STATE_AWAKE: 476 return "INTERACTIVE_STATE_AWAKE"; 477 case INTERACTIVE_STATE_GOING_TO_SLEEP: 478 return "INTERACTIVE_STATE_GOING_TO_SLEEP"; 479 default: 480 return Integer.toString(interactive); 481 } 482 } 483 } 484