KeyguardServiceDelegate.java revision e69c93181f1f313dcedd07f677af1cea953fdf16
1package com.android.server.policy.keyguard; 2 3import android.app.ActivityManagerNative; 4import android.content.ComponentName; 5import android.content.Context; 6import android.content.Intent; 7import android.content.ServiceConnection; 8import android.content.res.Resources; 9import android.os.Bundle; 10import android.os.Handler; 11import android.os.IBinder; 12import android.os.RemoteException; 13import android.os.UserHandle; 14import android.util.Log; 15import android.util.Slog; 16import android.view.WindowManagerPolicy.OnKeyguardExitResult; 17 18import com.android.internal.policy.IKeyguardDrawnCallback; 19import com.android.internal.policy.IKeyguardExitCallback; 20import com.android.internal.policy.IKeyguardService; 21import com.android.server.UiThread; 22 23import java.io.PrintWriter; 24 25/** 26 * A local class that keeps a cache of keyguard state that can be restored in the event 27 * keyguard crashes. It currently also allows runtime-selectable 28 * local or remote instances of keyguard. 29 */ 30public class KeyguardServiceDelegate { 31 private static final String TAG = "KeyguardServiceDelegate"; 32 private static final boolean DEBUG = true; 33 34 private static final int SCREEN_STATE_OFF = 0; 35 private static final int SCREEN_STATE_TURNING_ON = 1; 36 private static final int SCREEN_STATE_ON = 2; 37 38 private static final int INTERACTIVE_STATE_SLEEP = 0; 39 private static final int INTERACTIVE_STATE_AWAKE = 1; 40 private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 2; 41 42 protected KeyguardServiceWrapper mKeyguardService; 43 private final Context mContext; 44 private final Handler mHandler; 45 private final KeyguardState mKeyguardState = new KeyguardState(); 46 private final KeyguardStateMonitor.StateCallback mCallback; 47 48 private DrawnListener mDrawnListenerWhenConnect; 49 50 private static final class KeyguardState { 51 KeyguardState() { 52 reset(); 53 } 54 boolean showing; 55 boolean showingAndNotOccluded; 56 boolean inputRestricted; 57 boolean occluded; 58 boolean secure; 59 boolean dreaming; 60 boolean systemIsReady; 61 boolean deviceHasKeyguard; 62 public boolean enabled; 63 public int offReason; 64 public int currentUser; 65 public boolean bootCompleted; 66 public int screenState; 67 public int interactiveState; 68 69 private void reset() { 70 // Assume keyguard is showing and secure until we know for sure. This is here in 71 // the event something checks before the service is actually started. 72 // KeyguardService itself should default to this state until the real state is known. 73 showing = true; 74 showingAndNotOccluded = true; 75 secure = true; 76 deviceHasKeyguard = true; 77 enabled = true; 78 currentUser = UserHandle.USER_NULL; 79 } 80 }; 81 82 public interface DrawnListener { 83 void onDrawn(); 84 } 85 86 // A delegate class to map a particular invocation with a ShowListener object. 87 private final class KeyguardShowDelegate extends IKeyguardDrawnCallback.Stub { 88 private DrawnListener mDrawnListener; 89 90 KeyguardShowDelegate(DrawnListener drawnListener) { 91 mDrawnListener = drawnListener; 92 } 93 94 @Override 95 public void onDrawn() throws RemoteException { 96 if (DEBUG) Log.v(TAG, "**** SHOWN CALLED ****"); 97 if (mDrawnListener != null) { 98 mDrawnListener.onDrawn(); 99 } 100 } 101 }; 102 103 // A delegate class to map a particular invocation with an OnKeyguardExitResult object. 104 private final class KeyguardExitDelegate extends IKeyguardExitCallback.Stub { 105 private OnKeyguardExitResult mOnKeyguardExitResult; 106 107 KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult) { 108 mOnKeyguardExitResult = onKeyguardExitResult; 109 } 110 111 @Override 112 public void onKeyguardExitResult(boolean success) throws RemoteException { 113 if (DEBUG) Log.v(TAG, "**** onKeyguardExitResult(" + success +") CALLED ****"); 114 if (mOnKeyguardExitResult != null) { 115 mOnKeyguardExitResult.onKeyguardExitResult(success); 116 } 117 } 118 }; 119 120 public KeyguardServiceDelegate(Context context, KeyguardStateMonitor.StateCallback callback) { 121 mContext = context; 122 mHandler = UiThread.getHandler(); 123 mCallback = callback; 124 } 125 126 public void bindService(Context context) { 127 Intent intent = new Intent(); 128 final Resources resources = context.getApplicationContext().getResources(); 129 130 final ComponentName keyguardComponent = ComponentName.unflattenFromString( 131 resources.getString(com.android.internal.R.string.config_keyguardComponent)); 132 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); 133 intent.setComponent(keyguardComponent); 134 135 if (!context.bindServiceAsUser(intent, mKeyguardConnection, 136 Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) { 137 Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent); 138 mKeyguardState.showing = false; 139 mKeyguardState.showingAndNotOccluded = false; 140 mKeyguardState.secure = false; 141 synchronized (mKeyguardState) { 142 // TODO: Fix synchronisation model in this class. The other state in this class 143 // is at least self-healing but a race condition here can lead to the scrim being 144 // stuck on keyguard-less devices. 145 mKeyguardState.deviceHasKeyguard = false; 146 } 147 } else { 148 if (DEBUG) Log.v(TAG, "*** Keyguard started"); 149 } 150 } 151 152 private final ServiceConnection mKeyguardConnection = new ServiceConnection() { 153 @Override 154 public void onServiceConnected(ComponentName name, IBinder service) { 155 if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)"); 156 mKeyguardService = new KeyguardServiceWrapper(mContext, 157 IKeyguardService.Stub.asInterface(service), mCallback); 158 if (mKeyguardState.systemIsReady) { 159 // If the system is ready, it means keyguard crashed and restarted. 160 mKeyguardService.onSystemReady(); 161 if (mKeyguardState.currentUser != UserHandle.USER_NULL) { 162 // There has been a user switch earlier 163 mKeyguardService.setCurrentUser(mKeyguardState.currentUser); 164 } 165 // This is used to hide the scrim once keyguard displays. 166 if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) { 167 mKeyguardService.onStartedWakingUp(); 168 } 169 if (mKeyguardState.screenState == SCREEN_STATE_ON 170 || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) { 171 mKeyguardService.onScreenTurningOn( 172 new KeyguardShowDelegate(mDrawnListenerWhenConnect)); 173 } 174 if (mKeyguardState.screenState == SCREEN_STATE_ON) { 175 mKeyguardService.onScreenTurnedOn(); 176 } 177 mDrawnListenerWhenConnect = null; 178 } 179 if (mKeyguardState.bootCompleted) { 180 mKeyguardService.onBootCompleted(); 181 } 182 if (mKeyguardState.occluded) { 183 mKeyguardService.setOccluded(mKeyguardState.occluded, false /* animate */); 184 } 185 if (!mKeyguardState.enabled) { 186 mKeyguardService.setKeyguardEnabled(mKeyguardState.enabled); 187 } 188 } 189 190 @Override 191 public void onServiceDisconnected(ComponentName name) { 192 if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)"); 193 mKeyguardService = null; 194 mKeyguardState.reset(); 195 mHandler.post(() -> { 196 try { 197 ActivityManagerNative.getDefault().setLockScreenShown(true); 198 } catch (RemoteException e) { 199 // Local call. 200 } 201 }); 202 } 203 }; 204 205 public boolean isShowing() { 206 if (mKeyguardService != null) { 207 mKeyguardState.showing = mKeyguardService.isShowing(); 208 } 209 return mKeyguardState.showing; 210 } 211 212 public boolean isTrusted() { 213 if (mKeyguardService != null) { 214 return mKeyguardService.isTrusted(); 215 } 216 return false; 217 } 218 219 public boolean hasLockscreenWallpaper() { 220 if (mKeyguardService != null) { 221 return mKeyguardService.hasLockscreenWallpaper(); 222 } 223 return false; 224 } 225 226 public boolean isInputRestricted() { 227 if (mKeyguardService != null) { 228 mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted(); 229 } 230 return mKeyguardState.inputRestricted; 231 } 232 233 public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) { 234 if (mKeyguardService != null) { 235 mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult)); 236 } 237 } 238 239 public void setOccluded(boolean isOccluded, boolean animate) { 240 if (mKeyguardService != null) { 241 if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate); 242 mKeyguardService.setOccluded(isOccluded, animate); 243 } 244 mKeyguardState.occluded = isOccluded; 245 } 246 247 public void dismiss(boolean allowWhileOccluded) { 248 if (mKeyguardService != null) { 249 mKeyguardService.dismiss(allowWhileOccluded); 250 } 251 } 252 253 public boolean isSecure(int userId) { 254 if (mKeyguardService != null) { 255 mKeyguardState.secure = mKeyguardService.isSecure(userId); 256 } 257 return mKeyguardState.secure; 258 } 259 260 public void onDreamingStarted() { 261 if (mKeyguardService != null) { 262 mKeyguardService.onDreamingStarted(); 263 } 264 mKeyguardState.dreaming = true; 265 } 266 267 public void onDreamingStopped() { 268 if (mKeyguardService != null) { 269 mKeyguardService.onDreamingStopped(); 270 } 271 mKeyguardState.dreaming = false; 272 } 273 274 public void onStartedWakingUp() { 275 if (mKeyguardService != null) { 276 if (DEBUG) Log.v(TAG, "onStartedWakingUp()"); 277 mKeyguardService.onStartedWakingUp(); 278 } 279 mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE; 280 } 281 282 public void onScreenTurnedOff() { 283 if (mKeyguardService != null) { 284 if (DEBUG) Log.v(TAG, "onScreenTurnedOff()"); 285 mKeyguardService.onScreenTurnedOff(); 286 } 287 mKeyguardState.screenState = SCREEN_STATE_OFF; 288 } 289 290 public void onScreenTurningOn(final DrawnListener drawnListener) { 291 if (mKeyguardService != null) { 292 if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + drawnListener + ")"); 293 mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener)); 294 } else { 295 // try again when we establish a connection 296 Slog.w(TAG, "onScreenTurningOn(): no keyguard service!"); 297 // This shouldn't happen, but if it does, show the scrim immediately and 298 // invoke the listener's callback after the service actually connects. 299 mDrawnListenerWhenConnect = drawnListener; 300 } 301 mKeyguardState.screenState = SCREEN_STATE_TURNING_ON; 302 } 303 304 public void onScreenTurnedOn() { 305 if (mKeyguardService != null) { 306 if (DEBUG) Log.v(TAG, "onScreenTurnedOn()"); 307 mKeyguardService.onScreenTurnedOn(); 308 } 309 mKeyguardState.screenState = SCREEN_STATE_ON; 310 } 311 312 public void onStartedGoingToSleep(int why) { 313 if (mKeyguardService != null) { 314 mKeyguardService.onStartedGoingToSleep(why); 315 } 316 mKeyguardState.offReason = why; 317 mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP; 318 } 319 320 public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) { 321 if (mKeyguardService != null) { 322 mKeyguardService.onFinishedGoingToSleep(why, cameraGestureTriggered); 323 } 324 mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP; 325 } 326 327 public void setKeyguardEnabled(boolean enabled) { 328 if (mKeyguardService != null) { 329 mKeyguardService.setKeyguardEnabled(enabled); 330 } 331 mKeyguardState.enabled = enabled; 332 } 333 334 public void onSystemReady() { 335 if (mKeyguardService != null) { 336 mKeyguardService.onSystemReady(); 337 } else { 338 mKeyguardState.systemIsReady = true; 339 } 340 } 341 342 public void doKeyguardTimeout(Bundle options) { 343 if (mKeyguardService != null) { 344 mKeyguardService.doKeyguardTimeout(options); 345 } 346 } 347 348 public void setCurrentUser(int newUserId) { 349 if (mKeyguardService != null) { 350 mKeyguardService.setCurrentUser(newUserId); 351 } 352 mKeyguardState.currentUser = newUserId; 353 } 354 355 public void setSwitchingUser(boolean switching) { 356 if (mKeyguardService != null) { 357 mKeyguardService.setSwitchingUser(switching); 358 } 359 } 360 361 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 362 if (mKeyguardService != null) { 363 mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration); 364 } 365 } 366 367 public void onBootCompleted() { 368 if (mKeyguardService != null) { 369 mKeyguardService.onBootCompleted(); 370 } 371 mKeyguardState.bootCompleted = true; 372 } 373 374 public void dump(String prefix, PrintWriter pw) { 375 pw.println(prefix + TAG); 376 prefix += " "; 377 pw.println(prefix + "showing=" + mKeyguardState.showing); 378 pw.println(prefix + "showingAndNotOccluded=" + mKeyguardState.showingAndNotOccluded); 379 pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted); 380 pw.println(prefix + "occluded=" + mKeyguardState.occluded); 381 pw.println(prefix + "secure=" + mKeyguardState.secure); 382 pw.println(prefix + "dreaming=" + mKeyguardState.dreaming); 383 pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady); 384 pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard); 385 pw.println(prefix + "enabled=" + mKeyguardState.enabled); 386 pw.println(prefix + "offReason=" + mKeyguardState.offReason); 387 pw.println(prefix + "currentUser=" + mKeyguardState.currentUser); 388 pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted); 389 pw.println(prefix + "screenState=" + mKeyguardState.screenState); 390 pw.println(prefix + "interactiveState=" + mKeyguardState.interactiveState); 391 if (mKeyguardService != null) { 392 mKeyguardService.dump(prefix, pw); 393 } 394 } 395} 396