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