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