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