• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.systemui.keyguard;
18 
19 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20 import static android.view.Display.DEFAULT_DISPLAY;
21 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
22 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
23 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE;
24 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
25 
26 import android.app.ActivityTaskManager;
27 import android.app.Service;
28 import android.content.Intent;
29 import android.os.Binder;
30 import android.os.Bundle;
31 import android.os.Debug;
32 import android.os.IBinder;
33 import android.os.PowerManager;
34 import android.os.Process;
35 import android.os.RemoteException;
36 import android.os.SystemProperties;
37 import android.os.Trace;
38 import android.util.Log;
39 import android.util.Slog;
40 import android.view.IRemoteAnimationFinishedCallback;
41 import android.view.IRemoteAnimationRunner;
42 import android.view.RemoteAnimationAdapter;
43 import android.view.RemoteAnimationDefinition;
44 import android.view.RemoteAnimationTarget;
45 import android.view.WindowManager;
46 import android.view.WindowManagerPolicyConstants;
47 
48 import com.android.internal.policy.IKeyguardDismissCallback;
49 import com.android.internal.policy.IKeyguardDrawnCallback;
50 import com.android.internal.policy.IKeyguardExitCallback;
51 import com.android.internal.policy.IKeyguardService;
52 import com.android.internal.policy.IKeyguardStateCallback;
53 import com.android.systemui.SystemUIApplication;
54 import com.android.wm.shell.transition.Transitions;
55 
56 import javax.inject.Inject;
57 
58 public class KeyguardService extends Service {
59     static final String TAG = "KeyguardService";
60     static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
61 
62     /**
63      * Run Keyguard animation as remote animation in System UI instead of local animation in
64      * the server process.
65      *
66      * 0: Runs all keyguard animation as local animation
67      * 1: Only runs keyguard going away animation as remote animation
68      * 2: Runs all keyguard animation as remote animation
69      *
70      * Note: Must be consistent with WindowManagerService.
71      */
72     private static final String ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY =
73             "persist.wm.enable_remote_keyguard_animation";
74 
75     private static final int sEnableRemoteKeyguardAnimation =
76             SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 0);
77 
78     /**
79      * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY
80      */
81     public static boolean sEnableRemoteKeyguardGoingAwayAnimation =
82             !Transitions.ENABLE_SHELL_TRANSITIONS && sEnableRemoteKeyguardAnimation >= 1;
83 
84     /**
85      * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY
86      */
87     public static boolean sEnableRemoteKeyguardOccludeAnimation =
88             !Transitions.ENABLE_SHELL_TRANSITIONS && sEnableRemoteKeyguardAnimation >= 2;
89 
90     private final KeyguardViewMediator mKeyguardViewMediator;
91     private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
92 
93     @Inject
KeyguardService(KeyguardViewMediator keyguardViewMediator, KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher)94     public KeyguardService(KeyguardViewMediator keyguardViewMediator,
95                            KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher) {
96         super();
97         mKeyguardViewMediator = keyguardViewMediator;
98         mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
99 
100         RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
101         if (sEnableRemoteKeyguardGoingAwayAnimation) {
102             final RemoteAnimationAdapter exitAnimationAdapter =
103                     new RemoteAnimationAdapter(mExitAnimationRunner, 0, 0);
104             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, exitAnimationAdapter);
105             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
106                     exitAnimationAdapter);
107         }
108         if (sEnableRemoteKeyguardOccludeAnimation) {
109             final RemoteAnimationAdapter occludeAnimationAdapter =
110                     new RemoteAnimationAdapter(mOccludeAnimationRunner, 0, 0);
111             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE, occludeAnimationAdapter);
112             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE, occludeAnimationAdapter);
113         }
114         ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay(
115                 DEFAULT_DISPLAY, definition);
116     }
117 
118     @Override
onCreate()119     public void onCreate() {
120         ((SystemUIApplication) getApplication()).startServicesIfNeeded();
121     }
122 
123     @Override
onBind(Intent intent)124     public IBinder onBind(Intent intent) {
125         return mBinder;
126     }
127 
checkPermission()128     void checkPermission() {
129         // Avoid deadlock by avoiding calling back into the system process.
130         if (Binder.getCallingUid() == Process.SYSTEM_UID) return;
131 
132         // Otherwise,explicitly check for caller permission ...
133         if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
134             Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
135             throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
136                     + ", must have permission " + PERMISSION);
137         }
138     }
139 
140     private final IRemoteAnimationRunner.Stub mExitAnimationRunner =
141             new IRemoteAnimationRunner.Stub() {
142         @Override // Binder interface
143         public void onAnimationStart(@WindowManager.TransitionOldType int transit,
144                 RemoteAnimationTarget[] apps,
145                 RemoteAnimationTarget[] wallpapers,
146                 RemoteAnimationTarget[] nonApps,
147                 IRemoteAnimationFinishedCallback finishedCallback) {
148             Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation");
149             checkPermission();
150             mKeyguardViewMediator.startKeyguardExitAnimation(transit, apps, wallpapers,
151                     null /* nonApps */, finishedCallback);
152             Trace.endSection();
153         }
154 
155         @Override // Binder interface
156         public void onAnimationCancelled() {
157             mKeyguardViewMediator.cancelKeyguardExitAnimation();
158         }
159     };
160 
161     private final IRemoteAnimationRunner.Stub mOccludeAnimationRunner =
162             new IRemoteAnimationRunner.Stub() {
163         @Override // Binder interface
164         public void onAnimationStart(@WindowManager.TransitionOldType int transit,
165                        RemoteAnimationTarget[] apps,
166                        RemoteAnimationTarget[] wallpapers,
167                         RemoteAnimationTarget[] nonApps,
168                         IRemoteAnimationFinishedCallback finishedCallback) {
169             try {
170                 if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE) {
171                     mBinder.setOccluded(true /* isOccluded */, true /* animate */);
172                 } else if (transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE) {
173                     mBinder.setOccluded(false /* isOccluded */, true /* animate */);
174                 }
175                 // TODO(bc-unlock): Implement occlude/unocclude animation applied on apps,
176                 //  wallpapers and nonApps.
177                 finishedCallback.onAnimationFinished();
178             } catch (RemoteException e) {
179                 Slog.e(TAG, "RemoteException");
180             }
181         }
182 
183         @Override // Binder interface
184         public void onAnimationCancelled() {
185         }
186     };
187 
188     private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
189 
190         @Override // Binder interface
191         public void addStateMonitorCallback(IKeyguardStateCallback callback) {
192             checkPermission();
193             mKeyguardViewMediator.addStateMonitorCallback(callback);
194         }
195 
196         @Override // Binder interface
197         public void verifyUnlock(IKeyguardExitCallback callback) {
198             Trace.beginSection("KeyguardService.mBinder#verifyUnlock");
199             checkPermission();
200             mKeyguardViewMediator.verifyUnlock(callback);
201             Trace.endSection();
202         }
203 
204         @Override // Binder interface
205         public void setOccluded(boolean isOccluded, boolean animate) {
206             Trace.beginSection("KeyguardService.mBinder#setOccluded");
207             checkPermission();
208             mKeyguardViewMediator.setOccluded(isOccluded, animate);
209             Trace.endSection();
210         }
211 
212         @Override // Binder interface
213         public void dismiss(IKeyguardDismissCallback callback, CharSequence message) {
214             checkPermission();
215             mKeyguardViewMediator.dismiss(callback, message);
216         }
217 
218         @Override // Binder interface
219         public void onDreamingStarted() {
220             checkPermission();
221             mKeyguardViewMediator.onDreamingStarted();
222         }
223 
224         @Override // Binder interface
225         public void onDreamingStopped() {
226             checkPermission();
227             mKeyguardViewMediator.onDreamingStopped();
228         }
229 
230         @Override // Binder interface
231         public void onStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
232             checkPermission();
233             mKeyguardViewMediator.onStartedGoingToSleep(
234                     WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason));
235             mKeyguardLifecyclesDispatcher.dispatch(
236                     KeyguardLifecyclesDispatcher.STARTED_GOING_TO_SLEEP, pmSleepReason);
237         }
238 
239         @Override // Binder interface
240         public void onFinishedGoingToSleep(
241                 @PowerManager.GoToSleepReason int pmSleepReason, boolean cameraGestureTriggered) {
242             checkPermission();
243             mKeyguardViewMediator.onFinishedGoingToSleep(
244                     WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason),
245                     cameraGestureTriggered);
246             mKeyguardLifecyclesDispatcher.dispatch(
247                     KeyguardLifecyclesDispatcher.FINISHED_GOING_TO_SLEEP);
248         }
249 
250         @Override // Binder interface
251         public void onStartedWakingUp(
252                 @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) {
253             Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
254             checkPermission();
255             mKeyguardViewMediator.onStartedWakingUp(cameraGestureTriggered);
256             mKeyguardLifecyclesDispatcher.dispatch(
257                     KeyguardLifecyclesDispatcher.STARTED_WAKING_UP, pmWakeReason);
258             Trace.endSection();
259         }
260 
261         @Override // Binder interface
262         public void onFinishedWakingUp() {
263             Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp");
264             checkPermission();
265             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP);
266             Trace.endSection();
267         }
268 
269         @Override // Binder interface
270         public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
271             Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
272             checkPermission();
273             mKeyguardViewMediator.onScreenTurningOn(callback);
274             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON);
275             Trace.endSection();
276         }
277 
278         @Override // Binder interface
279         public void onScreenTurnedOn() {
280             Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
281             checkPermission();
282             mKeyguardViewMediator.onScreenTurnedOn();
283             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
284             Trace.endSection();
285         }
286 
287         @Override // Binder interface
288         public void onScreenTurningOff() {
289             checkPermission();
290             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_OFF);
291         }
292 
293         @Override // Binder interface
294         public void onScreenTurnedOff() {
295             checkPermission();
296             mKeyguardViewMediator.onScreenTurnedOff();
297             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF);
298         }
299 
300         @Override // Binder interface
301         public void setKeyguardEnabled(boolean enabled) {
302             checkPermission();
303             mKeyguardViewMediator.setKeyguardEnabled(enabled);
304         }
305 
306         @Override // Binder interface
307         public void onSystemReady() {
308             Trace.beginSection("KeyguardService.mBinder#onSystemReady");
309             checkPermission();
310             mKeyguardViewMediator.onSystemReady();
311             Trace.endSection();
312         }
313 
314         @Override // Binder interface
315         public void doKeyguardTimeout(Bundle options) {
316             checkPermission();
317             mKeyguardViewMediator.doKeyguardTimeout(options);
318         }
319 
320         @Override // Binder interface
321         public void setSwitchingUser(boolean switching) {
322             checkPermission();
323             mKeyguardViewMediator.setSwitchingUser(switching);
324         }
325 
326         @Override // Binder interface
327         public void setCurrentUser(int userId) {
328             checkPermission();
329             mKeyguardViewMediator.setCurrentUser(userId);
330         }
331 
332         @Override
333         public void onBootCompleted() {
334             checkPermission();
335             mKeyguardViewMediator.onBootCompleted();
336         }
337 
338         /**
339          * @deprecated When remote animation is enabled, this won't be called anymore. Use
340          * {@code IRemoteAnimationRunner#onAnimationStart} instead.
341          */
342         @Deprecated
343         @Override
344         public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
345             Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation");
346             checkPermission();
347             mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
348             Trace.endSection();
349         }
350 
351         @Override
352         public void onShortPowerPressedGoHome() {
353             checkPermission();
354             mKeyguardViewMediator.onShortPowerPressedGoHome();
355         }
356     };
357 }
358 
359