• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.service.dreams.DreamManagerInternal;
22 import android.util.Log;
23 import android.util.Slog;
24 import android.util.proto.ProtoOutputStream;
25 import android.view.WindowManagerPolicyConstants;
26 
27 import com.android.internal.policy.IKeyguardDismissCallback;
28 import com.android.internal.policy.IKeyguardDrawnCallback;
29 import com.android.internal.policy.IKeyguardExitCallback;
30 import com.android.internal.policy.IKeyguardService;
31 import com.android.server.LocalServices;
32 import com.android.server.UiThread;
33 import com.android.server.policy.WindowManagerPolicy.OnKeyguardExitResult;
34 import com.android.server.wm.EventLogTags;
35 
36 import java.io.PrintWriter;
37 
38 /**
39  * A local class that keeps a cache of keyguard state that can be restored in the event
40  * keyguard crashes. It currently also allows runtime-selectable
41  * local or remote instances of keyguard.
42  */
43 public class KeyguardServiceDelegate {
44     private static final String TAG = "KeyguardServiceDelegate";
45     private static final boolean DEBUG = false;
46 
47     private static final int SCREEN_STATE_OFF = 0;
48     private static final int SCREEN_STATE_TURNING_ON = 1;
49     private static final int SCREEN_STATE_ON = 2;
50     private static final int SCREEN_STATE_TURNING_OFF = 3;
51 
52     private static final int INTERACTIVE_STATE_SLEEP = 0;
53     private static final int INTERACTIVE_STATE_WAKING = 1;
54     private static final int INTERACTIVE_STATE_AWAKE = 2;
55     private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 3;
56 
57     protected KeyguardServiceWrapper mKeyguardService;
58     private final Context mContext;
59     private final Handler mHandler;
60     private final KeyguardState mKeyguardState = new KeyguardState();
61     private final KeyguardStateMonitor.StateCallback mCallback;
62 
63     private DrawnListener mDrawnListenerWhenConnect;
64 
65     private final DreamManagerInternal.DreamManagerStateListener mDreamManagerStateListener =
66             new DreamManagerInternal.DreamManagerStateListener() {
67                 @Override
68                 public void onDreamingStarted() {
69                     KeyguardServiceDelegate.this.onDreamingStarted();
70                 }
71 
72                 @Override
73                 public void onDreamingStopped() {
74                     KeyguardServiceDelegate.this.onDreamingStopped();
75                 }
76             };
77 
78     private static final class KeyguardState {
KeyguardState()79         KeyguardState() {
80             reset();
81         }
82         boolean showing;
83         boolean inputRestricted;
84         volatile boolean occluded;
85         boolean secure;
86         boolean dreaming;
87         boolean systemIsReady;
88         boolean deviceHasKeyguard;
89         public boolean enabled;
90         public int offReason;
91         public int currentUser;
92         public boolean bootCompleted;
93         public int screenState;
94         public int interactiveState;
95         boolean doKeyguardTimeoutRequested;
96         Bundle doKeyguardTimeoutRequestedOptions;
97 
reset()98         private void reset() {
99             // Assume keyguard is showing and secure until we know for sure. This is here in
100             // the event something checks before the service is actually started.
101             // KeyguardService itself should default to this state until the real state is known.
102             showing = true;
103             occluded = false;
104             secure = true;
105             deviceHasKeyguard = true;
106             enabled = true;
107             currentUser = UserHandle.USER_NULL;
108         }
109     };
110 
111     public interface DrawnListener {
onDrawn()112         void onDrawn();
113     }
114 
115     // A delegate class to map a particular invocation with a ShowListener object.
116     private final class KeyguardShowDelegate extends IKeyguardDrawnCallback.Stub {
117         private DrawnListener mDrawnListener;
118 
KeyguardShowDelegate(DrawnListener drawnListener)119         KeyguardShowDelegate(DrawnListener drawnListener) {
120             mDrawnListener = drawnListener;
121         }
122 
123         @Override
onDrawn()124         public void onDrawn() throws RemoteException {
125             if (DEBUG) Log.v(TAG, "**** SHOWN CALLED ****");
126             if (mDrawnListener != null) {
127                 mDrawnListener.onDrawn();
128             }
129         }
130     };
131 
132     // A delegate class to map a particular invocation with an OnKeyguardExitResult object.
133     private final class KeyguardExitDelegate extends IKeyguardExitCallback.Stub {
134         private OnKeyguardExitResult mOnKeyguardExitResult;
135 
KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult)136         KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult) {
137             mOnKeyguardExitResult = onKeyguardExitResult;
138         }
139 
140         @Override
onKeyguardExitResult(boolean success)141         public void onKeyguardExitResult(boolean success) throws RemoteException {
142             if (DEBUG) Log.v(TAG, "**** onKeyguardExitResult(" + success +") CALLED ****");
143             if (mOnKeyguardExitResult != null) {
144                 mOnKeyguardExitResult.onKeyguardExitResult(success);
145             }
146         }
147     };
148 
KeyguardServiceDelegate(Context context, KeyguardStateMonitor.StateCallback callback)149     public KeyguardServiceDelegate(Context context, KeyguardStateMonitor.StateCallback callback) {
150         mContext = context;
151         mHandler = UiThread.getHandler();
152         mCallback = callback;
153     }
154 
bindService(Context context)155     public void bindService(Context context) {
156         Intent intent = new Intent();
157         final Resources resources = context.getApplicationContext().getResources();
158 
159         final ComponentName keyguardComponent = ComponentName.unflattenFromString(
160                 resources.getString(com.android.internal.R.string.config_keyguardComponent));
161         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
162         intent.setComponent(keyguardComponent);
163 
164         if (!context.bindServiceAsUser(intent, mKeyguardConnection,
165                 Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) {
166             Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);
167             mKeyguardState.showing = false;
168             mKeyguardState.secure = false;
169             synchronized (mKeyguardState) {
170                 // TODO: Fix synchronisation model in this class. The other state in this class
171                 // is at least self-healing but a race condition here can lead to the scrim being
172                 // stuck on keyguard-less devices.
173                 mKeyguardState.deviceHasKeyguard = false;
174             }
175         } else {
176             if (DEBUG) Log.v(TAG, "*** Keyguard started");
177         }
178 
179         final DreamManagerInternal dreamManager =
180                 LocalServices.getService(DreamManagerInternal.class);
181         if(dreamManager != null){
182             dreamManager.registerDreamManagerStateListener(mDreamManagerStateListener);
183         }
184     }
185 
186     private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
187         @Override
188         public void onServiceConnected(ComponentName name, IBinder service) {
189             if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
190             mKeyguardService = new KeyguardServiceWrapper(mContext,
191                     IKeyguardService.Stub.asInterface(service), mCallback);
192             if (mKeyguardState.systemIsReady) {
193                 // If the system is ready, it means keyguard crashed and restarted.
194                 mKeyguardService.onSystemReady();
195                 if (mKeyguardState.currentUser != UserHandle.USER_NULL) {
196                     // There has been a user switch earlier
197                     mKeyguardService.setCurrentUser(mKeyguardState.currentUser);
198                 }
199                 // This is used to hide the scrim once keyguard displays.
200                 if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE
201                         || mKeyguardState.interactiveState == INTERACTIVE_STATE_WAKING) {
202                     mKeyguardService.onStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN,
203                             false /* powerButtonLaunchGestureTriggered */);
204                 }
205                 if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
206                     mKeyguardService.onFinishedWakingUp();
207                 }
208                 if (mKeyguardState.screenState == SCREEN_STATE_ON
209                         || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
210                     mKeyguardService.onScreenTurningOn(
211                             new KeyguardShowDelegate(mDrawnListenerWhenConnect));
212                 }
213                 if (mKeyguardState.screenState == SCREEN_STATE_ON) {
214                     mKeyguardService.onScreenTurnedOn();
215                 }
216                 mDrawnListenerWhenConnect = null;
217             }
218             if (mKeyguardState.bootCompleted) {
219                 mKeyguardService.onBootCompleted();
220             }
221             if (mKeyguardState.occluded) {
222                 mKeyguardService.setOccluded(mKeyguardState.occluded, false /* animate */);
223             }
224             if (!mKeyguardState.enabled) {
225                 mKeyguardService.setKeyguardEnabled(mKeyguardState.enabled);
226             }
227             if (mKeyguardState.dreaming) {
228                 mKeyguardService.onDreamingStarted();
229             }
230             if (mKeyguardState.doKeyguardTimeoutRequested) {
231                 mKeyguardService.doKeyguardTimeout(
232                         mKeyguardState.doKeyguardTimeoutRequestedOptions);
233                 mKeyguardState.doKeyguardTimeoutRequested = false;
234                 mKeyguardState.doKeyguardTimeoutRequestedOptions = null;
235             }
236         }
237 
238         @Override
239         public void onServiceDisconnected(ComponentName name) {
240             if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");
241             mKeyguardService = null;
242             mKeyguardState.reset();
243             mHandler.post(() -> {
244                 try {
245                     ActivityTaskManager.getService().setLockScreenShown(true /* keyguardShowing */,
246                             false /* aodShowing */);
247                 } catch (RemoteException e) {
248                     // Local call.
249                 }
250             });
251         }
252     };
253 
isShowing()254     public boolean isShowing() {
255         if (mKeyguardService != null) {
256             mKeyguardState.showing = mKeyguardService.isShowing();
257         }
258         return mKeyguardState.showing;
259     }
260 
isTrusted()261     public boolean isTrusted() {
262         if (mKeyguardService != null) {
263             return mKeyguardService.isTrusted();
264         }
265         return false;
266     }
267 
hasKeyguard()268     public boolean hasKeyguard() {
269         return mKeyguardState.deviceHasKeyguard;
270     }
271 
isInputRestricted()272     public boolean isInputRestricted() {
273         if (mKeyguardService != null) {
274             mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted();
275         }
276         return mKeyguardState.inputRestricted;
277     }
278 
verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult)279     public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) {
280         if (mKeyguardService != null) {
281             mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult));
282         }
283     }
284 
setOccluded(boolean isOccluded, boolean notify)285     public void setOccluded(boolean isOccluded, boolean notify) {
286         if (mKeyguardService != null && notify) {
287             if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ")");
288             EventLogTags.writeWmSetKeyguardOccluded(
289                     isOccluded ? 1 : 0,
290                     0 /* animate */,
291                     0 /* transit */,
292                     "setOccluded");
293             mKeyguardService.setOccluded(isOccluded, false /* animate */);
294         }
295         mKeyguardState.occluded = isOccluded;
296     }
297 
isOccluded()298     public boolean isOccluded() {
299         return mKeyguardState.occluded;
300     }
301 
dismiss(IKeyguardDismissCallback callback, CharSequence message)302     public void dismiss(IKeyguardDismissCallback callback, CharSequence message) {
303         if (mKeyguardService != null) {
304             mKeyguardService.dismiss(callback, message);
305         }
306     }
307 
isSecure(int userId)308     public boolean isSecure(int userId) {
309         if (mKeyguardService != null) {
310             mKeyguardState.secure = mKeyguardService.isSecure(userId);
311         }
312         return mKeyguardState.secure;
313     }
314 
onDreamingStarted()315     public void onDreamingStarted() {
316         if (mKeyguardService != null) {
317             mKeyguardService.onDreamingStarted();
318         }
319         mKeyguardState.dreaming = true;
320     }
321 
onDreamingStopped()322     public void onDreamingStopped() {
323         if (mKeyguardService != null) {
324             mKeyguardService.onDreamingStopped();
325         }
326         mKeyguardState.dreaming = false;
327     }
328 
onStartedWakingUp( @owerManager.WakeReason int pmWakeReason, boolean powerButtonLaunchGestureTriggered)329     public void onStartedWakingUp(
330             @PowerManager.WakeReason int pmWakeReason, boolean powerButtonLaunchGestureTriggered) {
331         if (mKeyguardService != null) {
332             if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
333             mKeyguardService.onStartedWakingUp(pmWakeReason, powerButtonLaunchGestureTriggered);
334         }
335         mKeyguardState.interactiveState = INTERACTIVE_STATE_WAKING;
336     }
337 
onFinishedWakingUp()338     public void onFinishedWakingUp() {
339         if (mKeyguardService != null) {
340             if (DEBUG) Log.v(TAG, "onFinishedWakingUp()");
341             mKeyguardService.onFinishedWakingUp();
342         }
343         mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE;
344     }
345 
onScreenTurningOff()346     public void onScreenTurningOff() {
347         if (mKeyguardService != null) {
348             if (DEBUG) Log.v(TAG, "onScreenTurningOff()");
349             mKeyguardService.onScreenTurningOff();
350         }
351         mKeyguardState.screenState = SCREEN_STATE_TURNING_OFF;
352     }
353 
onScreenTurnedOff()354     public void onScreenTurnedOff() {
355         if (mKeyguardService != null) {
356             if (DEBUG) Log.v(TAG, "onScreenTurnedOff()");
357             mKeyguardService.onScreenTurnedOff();
358         }
359         mKeyguardState.screenState = SCREEN_STATE_OFF;
360     }
361 
onScreenTurningOn(final DrawnListener drawnListener)362     public void onScreenTurningOn(final DrawnListener drawnListener) {
363         if (mKeyguardService != null) {
364             if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + drawnListener + ")");
365             mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener));
366         } else {
367             // try again when we establish a connection
368             Slog.w(TAG, "onScreenTurningOn(): no keyguard service!");
369             // This shouldn't happen, but if it does, show the scrim immediately and
370             // invoke the listener's callback after the service actually connects.
371             mDrawnListenerWhenConnect = drawnListener;
372         }
373         mKeyguardState.screenState = SCREEN_STATE_TURNING_ON;
374     }
375 
onScreenTurnedOn()376     public void onScreenTurnedOn() {
377         if (mKeyguardService != null) {
378             if (DEBUG) Log.v(TAG, "onScreenTurnedOn()");
379             mKeyguardService.onScreenTurnedOn();
380         }
381         mKeyguardState.screenState = SCREEN_STATE_ON;
382     }
383 
onStartedGoingToSleep(@owerManager.GoToSleepReason int pmSleepReason)384     public void onStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
385         if (mKeyguardService != null) {
386             mKeyguardService.onStartedGoingToSleep(pmSleepReason);
387         }
388         mKeyguardState.offReason =
389                 WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason);
390         mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP;
391     }
392 
onFinishedGoingToSleep( @owerManager.GoToSleepReason int pmSleepReason, boolean powerButtonLaunchGestureTriggered)393     public void onFinishedGoingToSleep(
394             @PowerManager.GoToSleepReason int pmSleepReason,
395             boolean powerButtonLaunchGestureTriggered) {
396         if (mKeyguardService != null) {
397             mKeyguardService.onFinishedGoingToSleep(pmSleepReason,
398                     powerButtonLaunchGestureTriggered);
399         }
400         mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP;
401     }
402 
setKeyguardEnabled(boolean enabled)403     public void setKeyguardEnabled(boolean enabled) {
404         if (mKeyguardService != null) {
405             mKeyguardService.setKeyguardEnabled(enabled);
406         }
407         mKeyguardState.enabled = enabled;
408     }
409 
onSystemReady()410     public void onSystemReady() {
411         if (mKeyguardService != null) {
412             mKeyguardService.onSystemReady();
413         } else {
414             mKeyguardState.systemIsReady = true;
415         }
416     }
417 
doKeyguardTimeout(Bundle options)418     public void doKeyguardTimeout(Bundle options) {
419         if (mKeyguardService != null) {
420             mKeyguardService.doKeyguardTimeout(options);
421         } else {
422             mKeyguardState.doKeyguardTimeoutRequested = true;
423             if (options != null) {
424                 mKeyguardState.doKeyguardTimeoutRequestedOptions = options;
425             }
426         }
427     }
428 
429     /**
430      * Request to show the keyguard immediately without immediately locking the device.
431      */
showDismissibleKeyguard()432     public void showDismissibleKeyguard() {
433         if (mKeyguardService != null) {
434             mKeyguardService.showDismissibleKeyguard();
435         }
436     }
437 
setCurrentUser(int newUserId)438     public void setCurrentUser(int newUserId) {
439         if (mKeyguardService != null) {
440             mKeyguardService.setCurrentUser(newUserId);
441         }
442         mKeyguardState.currentUser = newUserId;
443     }
444 
setSwitchingUser(boolean switching)445     public void setSwitchingUser(boolean switching) {
446         if (mKeyguardService != null) {
447             mKeyguardService.setSwitchingUser(switching);
448         }
449     }
450 
startKeyguardExitAnimation(long startTime)451     public void startKeyguardExitAnimation(long startTime) {
452         if (mKeyguardService != null) {
453             mKeyguardService.startKeyguardExitAnimation(startTime, 0);
454         }
455     }
456 
onBootCompleted()457     public void onBootCompleted() {
458         if (mKeyguardService != null) {
459             mKeyguardService.onBootCompleted();
460         }
461         mKeyguardState.bootCompleted = true;
462     }
463 
onShortPowerPressedGoHome()464     public void onShortPowerPressedGoHome() {
465         if (mKeyguardService != null) {
466             mKeyguardService.onShortPowerPressedGoHome();
467         }
468     }
469 
dismissKeyguardToLaunch(Intent intentToLaunch)470     public void dismissKeyguardToLaunch(Intent intentToLaunch) {
471         if (mKeyguardService != null) {
472             mKeyguardService.dismissKeyguardToLaunch(intentToLaunch);
473         }
474     }
onSystemKeyPressed(int keycode)475     public void onSystemKeyPressed(int keycode) {
476         if (mKeyguardService != null) {
477             mKeyguardService.onSystemKeyPressed(keycode);
478         }
479     }
480 
dumpDebug(ProtoOutputStream proto, long fieldId)481     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
482         final long token = proto.start(fieldId);
483         proto.write(SHOWING, mKeyguardState.showing);
484         proto.write(OCCLUDED, mKeyguardState.occluded);
485         proto.write(SECURE, mKeyguardState.secure);
486         proto.write(SCREEN_STATE, mKeyguardState.screenState);
487         proto.write(INTERACTIVE_STATE, mKeyguardState.interactiveState);
488         proto.end(token);
489     }
490 
dump(String prefix, PrintWriter pw)491     public void dump(String prefix, PrintWriter pw) {
492         pw.println(prefix + TAG);
493         prefix += "  ";
494         pw.println(prefix + "showing=" + mKeyguardState.showing);
495         pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted);
496         pw.println(prefix + "occluded=" + mKeyguardState.occluded);
497         pw.println(prefix + "secure=" + mKeyguardState.secure);
498         pw.println(prefix + "dreaming=" + mKeyguardState.dreaming);
499         pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady);
500         pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard);
501         pw.println(prefix + "enabled=" + mKeyguardState.enabled);
502         pw.println(prefix + "offReason=" +
503                 WindowManagerPolicyConstants.offReasonToString(mKeyguardState.offReason));
504         pw.println(prefix + "currentUser=" + mKeyguardState.currentUser);
505         pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted);
506         pw.println(prefix + "screenState=" + screenStateToString(mKeyguardState.screenState));
507         pw.println(prefix + "interactiveState=" +
508                 interactiveStateToString(mKeyguardState.interactiveState));
509         if (mKeyguardService != null) {
510             mKeyguardService.dump(prefix, pw);
511         }
512     }
513 
screenStateToString(int screen)514     private static String screenStateToString(int screen) {
515         switch (screen) {
516             case SCREEN_STATE_OFF:
517                 return "SCREEN_STATE_OFF";
518             case SCREEN_STATE_TURNING_ON:
519                 return "SCREEN_STATE_TURNING_ON";
520             case SCREEN_STATE_ON:
521                 return "SCREEN_STATE_ON";
522             case SCREEN_STATE_TURNING_OFF:
523                 return "SCREEN_STATE_TURNING_OFF";
524             default:
525                 return Integer.toString(screen);
526         }
527     }
528 
interactiveStateToString(int interactive)529     private static String interactiveStateToString(int interactive) {
530         switch (interactive) {
531             case INTERACTIVE_STATE_SLEEP:
532                 return "INTERACTIVE_STATE_SLEEP";
533             case INTERACTIVE_STATE_WAKING:
534                 return "INTERACTIVE_STATE_WAKING";
535             case INTERACTIVE_STATE_AWAKE:
536                 return "INTERACTIVE_STATE_AWAKE";
537             case INTERACTIVE_STATE_GOING_TO_SLEEP:
538                 return "INTERACTIVE_STATE_GOING_TO_SLEEP";
539             default:
540                 return Integer.toString(interactive);
541         }
542     }
543 }
544