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