• 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.WindowManagerService;
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         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         }
207 
208         @Override
209         public void onServiceDisconnected(ComponentName name) {
210             if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");
211             mKeyguardService = null;
212             mKeyguardState.reset();
213             mHandler.post(() -> {
214                 try {
215                     ActivityTaskManager.getService().setLockScreenShown(true /* keyguardShowing */,
216                             false /* aodShowing */);
217                 } catch (RemoteException e) {
218                     // Local call.
219                 }
220             });
221         }
222     };
223 
isShowing()224     public boolean isShowing() {
225         if (mKeyguardService != null) {
226             mKeyguardState.showing = mKeyguardService.isShowing();
227         }
228         return mKeyguardState.showing;
229     }
230 
isTrusted()231     public boolean isTrusted() {
232         if (mKeyguardService != null) {
233             return mKeyguardService.isTrusted();
234         }
235         return false;
236     }
237 
hasLockscreenWallpaper()238     public boolean hasLockscreenWallpaper() {
239         if (mKeyguardService != null) {
240             return mKeyguardService.hasLockscreenWallpaper();
241         }
242         return false;
243     }
244 
hasKeyguard()245     public boolean hasKeyguard() {
246         return mKeyguardState.deviceHasKeyguard;
247     }
248 
isInputRestricted()249     public boolean isInputRestricted() {
250         if (mKeyguardService != null) {
251             mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted();
252         }
253         return mKeyguardState.inputRestricted;
254     }
255 
verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult)256     public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) {
257         if (mKeyguardService != null) {
258             mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult));
259         }
260     }
261 
262     /**
263      * @deprecated Notify occlude status change via remote animation.
264      */
265     @Deprecated
setOccluded(boolean isOccluded, boolean animate)266     public void setOccluded(boolean isOccluded, boolean animate) {
267         if (!WindowManagerService.sEnableRemoteKeyguardOccludeAnimation
268                 && mKeyguardService != null) {
269             if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate);
270             mKeyguardService.setOccluded(isOccluded, animate);
271         }
272         mKeyguardState.occluded = isOccluded;
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 (!WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation
410                 && mKeyguardService != null) {
411             mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration);
412         }
413     }
414 
onBootCompleted()415     public void onBootCompleted() {
416         if (mKeyguardService != null) {
417             mKeyguardService.onBootCompleted();
418         }
419         mKeyguardState.bootCompleted = true;
420     }
421 
onShortPowerPressedGoHome()422     public void onShortPowerPressedGoHome() {
423         if (mKeyguardService != null) {
424             mKeyguardService.onShortPowerPressedGoHome();
425         }
426     }
427 
dumpDebug(ProtoOutputStream proto, long fieldId)428     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
429         final long token = proto.start(fieldId);
430         proto.write(SHOWING, mKeyguardState.showing);
431         proto.write(OCCLUDED, mKeyguardState.occluded);
432         proto.write(SECURE, mKeyguardState.secure);
433         proto.write(SCREEN_STATE, mKeyguardState.screenState);
434         proto.write(INTERACTIVE_STATE, mKeyguardState.interactiveState);
435         proto.end(token);
436     }
437 
dump(String prefix, PrintWriter pw)438     public void dump(String prefix, PrintWriter pw) {
439         pw.println(prefix + TAG);
440         prefix += "  ";
441         pw.println(prefix + "showing=" + mKeyguardState.showing);
442         pw.println(prefix + "showingAndNotOccluded=" + mKeyguardState.showingAndNotOccluded);
443         pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted);
444         pw.println(prefix + "occluded=" + mKeyguardState.occluded);
445         pw.println(prefix + "secure=" + mKeyguardState.secure);
446         pw.println(prefix + "dreaming=" + mKeyguardState.dreaming);
447         pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady);
448         pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard);
449         pw.println(prefix + "enabled=" + mKeyguardState.enabled);
450         pw.println(prefix + "offReason=" +
451                 WindowManagerPolicyConstants.offReasonToString(mKeyguardState.offReason));
452         pw.println(prefix + "currentUser=" + mKeyguardState.currentUser);
453         pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted);
454         pw.println(prefix + "screenState=" + screenStateToString(mKeyguardState.screenState));
455         pw.println(prefix + "interactiveState=" +
456                 interactiveStateToString(mKeyguardState.interactiveState));
457         if (mKeyguardService != null) {
458             mKeyguardService.dump(prefix, pw);
459         }
460     }
461 
screenStateToString(int screen)462     private static String screenStateToString(int screen) {
463         switch (screen) {
464             case SCREEN_STATE_OFF:
465                 return "SCREEN_STATE_OFF";
466             case SCREEN_STATE_TURNING_ON:
467                 return "SCREEN_STATE_TURNING_ON";
468             case SCREEN_STATE_ON:
469                 return "SCREEN_STATE_ON";
470             case SCREEN_STATE_TURNING_OFF:
471                 return "SCREEN_STATE_TURNING_OFF";
472             default:
473                 return Integer.toString(screen);
474         }
475     }
476 
interactiveStateToString(int interactive)477     private static String interactiveStateToString(int interactive) {
478         switch (interactive) {
479             case INTERACTIVE_STATE_SLEEP:
480                 return "INTERACTIVE_STATE_SLEEP";
481             case INTERACTIVE_STATE_WAKING:
482                 return "INTERACTIVE_STATE_WAKING";
483             case INTERACTIVE_STATE_AWAKE:
484                 return "INTERACTIVE_STATE_AWAKE";
485             case INTERACTIVE_STATE_GOING_TO_SLEEP:
486                 return "INTERACTIVE_STATE_GOING_TO_SLEEP";
487             default:
488                 return Integer.toString(interactive);
489         }
490     }
491 }
492