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