1 /* 2 * Copyright (C) 2012 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.server.dreams; 18 19 import static android.Manifest.permission.BIND_DREAM_SERVICE; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; 22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 23 import static android.service.dreams.Flags.allowDreamWhenPostured; 24 import static android.service.dreams.Flags.cleanupDreamSettingsOnUninstall; 25 import static android.service.dreams.Flags.dreamHandlesBeingObscured; 26 27 import static com.android.server.wm.ActivityInterceptorCallback.DREAM_MANAGER_ORDERED_ID; 28 29 import android.annotation.IntDef; 30 import android.annotation.NonNull; 31 import android.annotation.Nullable; 32 import android.app.ActivityManager; 33 import android.app.IAppTask; 34 import android.app.TaskInfo; 35 import android.content.BroadcastReceiver; 36 import android.content.ComponentName; 37 import android.content.ContentResolver; 38 import android.content.Context; 39 import android.content.Intent; 40 import android.content.IntentFilter; 41 import android.content.pm.ActivityInfo; 42 import android.content.pm.PackageManager; 43 import android.content.pm.PackageManager.NameNotFoundException; 44 import android.content.pm.PackageManagerInternal; 45 import android.content.pm.ServiceInfo; 46 import android.database.ContentObserver; 47 import android.hardware.display.AmbientDisplayConfiguration; 48 import android.net.Uri; 49 import android.os.BatteryManager; 50 import android.os.BatteryManagerInternal; 51 import android.os.Binder; 52 import android.os.Build; 53 import android.os.Handler; 54 import android.os.IBinder; 55 import android.os.Looper; 56 import android.os.PowerManager; 57 import android.os.PowerManagerInternal; 58 import android.os.RemoteException; 59 import android.os.ResultReceiver; 60 import android.os.ShellCallback; 61 import android.os.SystemClock; 62 import android.os.SystemProperties; 63 import android.os.UserHandle; 64 import android.os.UserManager; 65 import android.provider.Settings; 66 import android.service.dreams.DreamManagerInternal; 67 import android.service.dreams.DreamService; 68 import android.service.dreams.IDreamManager; 69 import android.text.TextUtils; 70 import android.util.Slog; 71 import android.util.SparseArray; 72 import android.view.Display; 73 74 import com.android.internal.R; 75 import com.android.internal.annotations.GuardedBy; 76 import com.android.internal.annotations.VisibleForTesting; 77 import com.android.internal.content.PackageMonitor; 78 import com.android.internal.logging.UiEventLogger; 79 import com.android.internal.logging.UiEventLoggerImpl; 80 import com.android.internal.util.DumpUtils; 81 import com.android.server.FgThread; 82 import com.android.server.LocalServices; 83 import com.android.server.SystemService; 84 import com.android.server.input.InputManagerInternal; 85 import com.android.server.pm.UserManagerInternal; 86 import com.android.server.wm.ActivityInterceptorCallback; 87 import com.android.server.wm.ActivityTaskManagerInternal; 88 89 import java.io.FileDescriptor; 90 import java.io.PrintWriter; 91 import java.lang.annotation.Retention; 92 import java.lang.annotation.RetentionPolicy; 93 import java.util.ArrayList; 94 import java.util.Arrays; 95 import java.util.List; 96 import java.util.Objects; 97 import java.util.concurrent.CopyOnWriteArrayList; 98 import java.util.function.Consumer; 99 100 /** 101 * Service api for managing dreams. 102 * 103 * @hide 104 */ 105 public final class DreamManagerService extends SystemService { 106 private static final boolean DEBUG = false; 107 private static final String TAG = "DreamManagerService"; 108 109 private static final String DOZE_WAKE_LOCK_TAG = "dream:doze"; 110 private static final String DREAM_WAKE_LOCK_TAG = "dream:dream"; 111 112 /** Constants for the when to activate dreams. */ 113 @Retention(RetentionPolicy.SOURCE) 114 @IntDef({DREAM_DISABLED, DREAM_ON_DOCK, DREAM_ON_CHARGE, DREAM_ON_POSTURED}) 115 public @interface WhenToDream {} 116 117 private static final int DREAM_DISABLED = 0; 118 private static final int DREAM_ON_DOCK = 1 << 0; 119 private static final int DREAM_ON_CHARGE = 1 << 1; 120 private static final int DREAM_ON_POSTURED = 1 << 2; 121 122 private final Object mLock = new Object(); 123 124 private final Context mContext; 125 private final Handler mHandler; 126 private final DreamController mController; 127 private final PowerManager mPowerManager; 128 private final PowerManagerInternal mPowerManagerInternal; 129 private final BatteryManagerInternal mBatteryManagerInternal; 130 private final PowerManager.WakeLock mDozeWakeLock; 131 private final ActivityTaskManagerInternal mAtmInternal; 132 private final PackageManagerInternal mPmInternal; 133 private final UserManager mUserManager; 134 private final UiEventLogger mUiEventLogger; 135 private final DreamUiEventLogger mDreamUiEventLogger; 136 private final ComponentName mAmbientDisplayComponent; 137 private final boolean mDismissDreamOnActivityStart; 138 private final boolean mDreamsOnlyEnabledForDockUser; 139 private final boolean mDreamsEnabledByDefaultConfig; 140 private final boolean mDreamsActivatedOnChargeByDefault; 141 private final boolean mDreamsActivatedOnDockByDefault; 142 private final boolean mDreamsActivatedOnPosturedByDefault; 143 private final boolean mKeepDreamingWhenUnpluggingDefault; 144 private final boolean mDreamsDisabledByAmbientModeSuppressionConfig; 145 146 private final CopyOnWriteArrayList<DreamManagerInternal.DreamManagerStateListener> 147 mDreamManagerStateListeners = new CopyOnWriteArrayList<>(); 148 149 @GuardedBy("mLock") 150 private DreamRecord mCurrentDream; 151 152 private boolean mForceAmbientDisplayEnabled; 153 private SettingsObserver mSettingsObserver; 154 private boolean mDreamsEnabledSetting; 155 @WhenToDream private int mWhenToDream; 156 private boolean mIsDocked; 157 private boolean mIsCharging; 158 private boolean mIsPostured; 159 160 // A temporary dream component that, when present, takes precedence over user configured dream 161 // component. 162 private ComponentName mSystemDreamComponent; 163 164 private ComponentName mDreamOverlayServiceName; 165 166 private final AmbientDisplayConfiguration mDozeConfig; 167 168 /** Stores {@link PerUserPackageMonitor} to monitor dream uninstalls. */ 169 private final SparseArray<PackageMonitor> mPackageMonitors = new SparseArray<>(); 170 171 private final ActivityInterceptorCallback mActivityInterceptorCallback = 172 new ActivityInterceptorCallback() { 173 @Nullable 174 @Override 175 public ActivityInterceptResult onInterceptActivityLaunch(@NonNull 176 ActivityInterceptorInfo info) { 177 return null; 178 } 179 180 @Override 181 public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo, 182 ActivityInterceptorInfo info) { 183 final int activityType = taskInfo.getActivityType(); 184 final boolean activityAllowed = activityType == ACTIVITY_TYPE_HOME 185 || activityType == ACTIVITY_TYPE_DREAM 186 || activityType == ACTIVITY_TYPE_ASSISTANT; 187 188 boolean shouldRequestAwaken; 189 synchronized (mLock) { 190 shouldRequestAwaken = mCurrentDream != null && !mCurrentDream.isWaking 191 && !mCurrentDream.isDozing && !activityAllowed; 192 } 193 194 if (shouldRequestAwaken) { 195 requestAwakenInternal( 196 "stopping dream due to activity start: " + activityInfo.name); 197 } 198 } 199 }; 200 201 private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() { 202 @Override 203 public void onReceive(Context context, Intent intent) { 204 if (Flags.useBatteryChangedBroadcast()) { 205 mIsCharging = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); 206 } else { 207 mIsCharging = (BatteryManager.ACTION_CHARGING.equals(intent.getAction())); 208 } 209 } 210 }; 211 212 private final BroadcastReceiver mDockStateReceiver = new BroadcastReceiver() { 213 @Override 214 public void onReceive(Context context, Intent intent) { 215 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 216 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 217 Intent.EXTRA_DOCK_STATE_UNDOCKED); 218 mIsDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED; 219 } 220 } 221 }; 222 223 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)224 SettingsObserver(Handler handler) { 225 super(handler); 226 } 227 228 @Override onChange(boolean selfChange, Uri uri)229 public void onChange(boolean selfChange, Uri uri) { 230 updateWhenToDreamSettings(); 231 } 232 } 233 234 private final class PerUserPackageMonitor extends PackageMonitor { 235 @Override onPackageRemoved(String packageName, int uid)236 public void onPackageRemoved(String packageName, int uid) { 237 super.onPackageRemoved(packageName, uid); 238 final int userId = getChangingUserId(); 239 updateDreamOnPackageRemoved(packageName, userId); 240 } 241 } 242 DreamManagerService(Context context)243 public DreamManagerService(Context context) { 244 this(context, new DreamHandler(FgThread.get().getLooper())); 245 } 246 247 @VisibleForTesting DreamManagerService(Context context, Handler handler)248 DreamManagerService(Context context, Handler handler) { 249 super(context); 250 mContext = context; 251 mHandler = handler; 252 mController = new DreamController(context, mHandler, mControllerListener); 253 254 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 255 mPowerManagerInternal = getLocalService(PowerManagerInternal.class); 256 mAtmInternal = getLocalService(ActivityTaskManagerInternal.class); 257 mPmInternal = getLocalService(PackageManagerInternal.class); 258 mUserManager = context.getSystemService(UserManager.class); 259 mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, DOZE_WAKE_LOCK_TAG); 260 mDozeConfig = new AmbientDisplayConfiguration(mContext); 261 mUiEventLogger = new UiEventLoggerImpl(); 262 mDreamUiEventLogger = new DreamUiEventLoggerImpl( 263 mContext.getResources().getStringArray(R.array.config_loggable_dream_prefixes)); 264 AmbientDisplayConfiguration adc = new AmbientDisplayConfiguration(mContext); 265 mAmbientDisplayComponent = ComponentName.unflattenFromString(adc.ambientDisplayComponent()); 266 mDreamsOnlyEnabledForDockUser = 267 mContext.getResources().getBoolean(R.bool.config_dreamsOnlyEnabledForDockUser); 268 mDismissDreamOnActivityStart = mContext.getResources().getBoolean( 269 R.bool.config_dismissDreamOnActivityStart); 270 271 mDreamsEnabledByDefaultConfig = mContext.getResources().getBoolean( 272 com.android.internal.R.bool.config_dreamsEnabledByDefault); 273 mDreamsActivatedOnChargeByDefault = mContext.getResources().getBoolean( 274 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault); 275 mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean( 276 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); 277 mDreamsActivatedOnPosturedByDefault = mContext.getResources().getBoolean( 278 com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault); 279 mSettingsObserver = new SettingsObserver(mHandler); 280 mKeepDreamingWhenUnpluggingDefault = mContext.getResources().getBoolean( 281 com.android.internal.R.bool.config_keepDreamingWhenUnplugging); 282 mDreamsDisabledByAmbientModeSuppressionConfig = mContext.getResources().getBoolean( 283 com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig); 284 285 if (Flags.useBatteryChangedBroadcast()) { 286 mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); 287 } else { 288 mBatteryManagerInternal = null; 289 } 290 } 291 292 @Override onStart()293 public void onStart() { 294 publishBinderService(DreamService.DREAM_SERVICE, new BinderService()); 295 publishLocalService(DreamManagerInternal.class, new LocalService()); 296 } 297 298 @Override onBootPhase(int phase)299 public void onBootPhase(int phase) { 300 if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { 301 if (Build.IS_DEBUGGABLE) { 302 SystemProperties.addChangeCallback(mSystemPropertiesChanged); 303 } 304 305 mContext.getContentResolver().registerContentObserver( 306 Settings.Secure.getUriFor(Settings.Secure.DOZE_DOUBLE_TAP_GESTURE), false, 307 mDozeEnabledObserver, UserHandle.USER_ALL); 308 writePulseGestureEnabled(); 309 310 if (mDismissDreamOnActivityStart) { 311 mAtmInternal.registerActivityStartInterceptor( 312 DREAM_MANAGER_ORDERED_ID, 313 mActivityInterceptorCallback); 314 } 315 316 mContext.registerReceiver( 317 mDockStateReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT)); 318 319 IntentFilter chargingIntentFilter = new IntentFilter(); 320 if (Flags.useBatteryChangedBroadcast()) { 321 chargingIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); 322 chargingIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 323 } else { 324 chargingIntentFilter.addAction(BatteryManager.ACTION_CHARGING); 325 chargingIntentFilter.addAction(BatteryManager.ACTION_DISCHARGING); 326 } 327 mContext.registerReceiver(mChargingReceiver, chargingIntentFilter); 328 329 mSettingsObserver = new SettingsObserver(mHandler); 330 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 331 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP), 332 false, mSettingsObserver, UserHandle.USER_ALL); 333 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 334 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK), 335 false, mSettingsObserver, UserHandle.USER_ALL); 336 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 337 Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED), 338 false, mSettingsObserver, UserHandle.USER_ALL); 339 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 340 Settings.Secure.SCREENSAVER_ENABLED), 341 false, mSettingsObserver, UserHandle.USER_ALL); 342 343 // We don't get an initial broadcast for the batter state, so we have to initialize 344 // directly from BatteryManager. 345 mIsCharging = mContext.getSystemService(BatteryManager.class).isCharging(); 346 347 updateWhenToDreamSettings(); 348 } 349 } 350 351 @Override onUserSwitching(@ullable TargetUser from, @NonNull TargetUser to)352 public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { 353 updateWhenToDreamSettings(); 354 355 mHandler.post(() -> { 356 writePulseGestureEnabled(); 357 synchronized (mLock) { 358 stopDreamLocked(false /*immediate*/, "user switched"); 359 } 360 }); 361 } 362 363 @Override onUserStarting(@onNull TargetUser user)364 public void onUserStarting(@NonNull TargetUser user) { 365 super.onUserStarting(user); 366 if (cleanupDreamSettingsOnUninstall()) { 367 mHandler.post(() -> { 368 final int userId = user.getUserIdentifier(); 369 if (!mPackageMonitors.contains(userId)) { 370 final PackageMonitor monitor = new PerUserPackageMonitor(); 371 monitor.register(mContext, UserHandle.of(userId), mHandler); 372 mPackageMonitors.put(userId, monitor); 373 } else { 374 Slog.w(TAG, "Package monitor already registered for " + userId); 375 } 376 }); 377 } 378 } 379 380 @Override onUserStopping(@onNull TargetUser user)381 public void onUserStopping(@NonNull TargetUser user) { 382 super.onUserStopping(user); 383 if (cleanupDreamSettingsOnUninstall()) { 384 mHandler.post(() -> { 385 final PackageMonitor monitor = mPackageMonitors.removeReturnOld( 386 user.getUserIdentifier()); 387 if (monitor != null) { 388 monitor.unregister(); 389 } 390 }); 391 } 392 } 393 dumpInternal(PrintWriter pw)394 private void dumpInternal(PrintWriter pw) { 395 synchronized (mLock) { 396 pw.println("DREAM MANAGER (dumpsys dreams)"); 397 pw.println(); 398 pw.println("mCurrentDream=" + mCurrentDream); 399 pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled); 400 pw.println("mDreamsOnlyEnabledForDockUser=" + mDreamsOnlyEnabledForDockUser); 401 pw.println("mDreamsEnabledSetting=" + mDreamsEnabledSetting); 402 pw.println("mDreamsActivatedOnDockByDefault=" + mDreamsActivatedOnDockByDefault); 403 pw.println("mDreamsActivatedOnChargeByDefault=" + mDreamsActivatedOnChargeByDefault); 404 pw.println("mDreamsActivatedOnPosturedByDefault=" 405 + mDreamsActivatedOnPosturedByDefault); 406 pw.println("mIsDocked=" + mIsDocked); 407 pw.println("mIsCharging=" + mIsCharging); 408 pw.println("mWhenToDream=" + mWhenToDream); 409 pw.println("mKeepDreamingWhenUnpluggingDefault=" + mKeepDreamingWhenUnpluggingDefault); 410 pw.println("getDozeComponent()=" + getDozeComponent()); 411 pw.println("mDreamOverlayServiceName=" 412 + ComponentName.flattenToShortString(mDreamOverlayServiceName)); 413 pw.println(); 414 415 DumpUtils.dumpAsync(mHandler, (pw1, prefix) -> mController.dump(pw1), pw, "", 200); 416 } 417 } 418 updateWhenToDreamSettings()419 private void updateWhenToDreamSettings() { 420 synchronized (mLock) { 421 final ContentResolver resolver = mContext.getContentResolver(); 422 423 mWhenToDream = DREAM_DISABLED; 424 425 if ((Settings.Secure.getIntForUser(resolver, 426 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 427 mDreamsActivatedOnChargeByDefault ? 1 : 0, 428 UserHandle.USER_CURRENT) != 0)) { 429 mWhenToDream |= DREAM_ON_CHARGE; 430 } 431 432 if (Settings.Secure.getIntForUser(resolver, 433 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 434 mDreamsActivatedOnDockByDefault ? 1 : 0, 435 UserHandle.USER_CURRENT) != 0) { 436 mWhenToDream |= DREAM_ON_DOCK; 437 } 438 439 if (Settings.Secure.getIntForUser(resolver, 440 Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, 441 mDreamsActivatedOnPosturedByDefault ? 1 : 0, 442 UserHandle.USER_CURRENT) != 0) { 443 mWhenToDream |= DREAM_ON_POSTURED; 444 } 445 446 mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver, 447 Settings.Secure.SCREENSAVER_ENABLED, 448 mDreamsEnabledByDefaultConfig ? 1 : 0, 449 UserHandle.USER_CURRENT) != 0); 450 } 451 } 452 reportKeepDreamingWhenUnpluggingChanged(boolean keepDreaming)453 private void reportKeepDreamingWhenUnpluggingChanged(boolean keepDreaming) { 454 notifyDreamStateListeners( 455 listener -> listener.onKeepDreamingWhenUnpluggingChanged(keepDreaming)); 456 } 457 reportDreamingStarted()458 private void reportDreamingStarted() { 459 notifyDreamStateListeners(listener -> listener.onDreamingStarted()); 460 } 461 reportDreamingStopped()462 private void reportDreamingStopped() { 463 notifyDreamStateListeners(listener -> listener.onDreamingStopped()); 464 } 465 notifyDreamStateListeners( Consumer<DreamManagerInternal.DreamManagerStateListener> notifier)466 private void notifyDreamStateListeners( 467 Consumer<DreamManagerInternal.DreamManagerStateListener> notifier) { 468 mHandler.post(() -> { 469 for (DreamManagerInternal.DreamManagerStateListener listener 470 : mDreamManagerStateListeners) { 471 notifier.accept(listener); 472 } 473 }); 474 } 475 476 /** Whether a real dream is occurring. */ isDreamingInternal()477 private boolean isDreamingInternal() { 478 synchronized (mLock) { 479 return mCurrentDream != null && !mCurrentDream.isPreview 480 && !mCurrentDream.isWaking; 481 } 482 } 483 484 /** Whether a doze is occurring. */ isDozingInternal()485 private boolean isDozingInternal() { 486 synchronized (mLock) { 487 return mCurrentDream != null && mCurrentDream.isDozing; 488 } 489 } 490 491 /** Whether a real dream, or a dream preview is occurring. */ isDreamingOrInPreviewInternal()492 private boolean isDreamingOrInPreviewInternal() { 493 synchronized (mLock) { 494 return mCurrentDream != null && !mCurrentDream.isWaking; 495 } 496 } 497 498 @VisibleForTesting dreamConditionActiveInternal()499 boolean dreamConditionActiveInternal() { 500 synchronized (mLock) { 501 return dreamConditionActiveInternalLocked(); 502 } 503 } 504 dreamConditionActiveInternalLocked()505 private boolean dreamConditionActiveInternalLocked() { 506 if ((mWhenToDream & DREAM_ON_CHARGE) == DREAM_ON_CHARGE) { 507 return mIsCharging; 508 } 509 510 if ((mWhenToDream & DREAM_ON_DOCK) == DREAM_ON_DOCK) { 511 return mIsDocked; 512 } 513 514 if ((mWhenToDream & DREAM_ON_POSTURED) == DREAM_ON_POSTURED) { 515 return mIsPostured; 516 } 517 518 return false; 519 } 520 521 @VisibleForTesting dreamsEnabled()522 boolean dreamsEnabled() { 523 return mDreamsEnabledSetting; 524 } 525 526 /** Whether dreaming can start given user settings and the current dock/charge state. */ canStartDreamingInternal(boolean isScreenOn)527 private boolean canStartDreamingInternal(boolean isScreenOn) { 528 synchronized (mLock) { 529 // Can't start dreaming if we are already dreaming and the dream has focus. If we are 530 // dreaming but the dream does not have focus, then the dream can be brought to the 531 // front so it does have focus. 532 if (isScreenOn && isDreamingInternal() && dreamIsFrontmost()) { 533 return false; 534 } 535 536 if (!mDreamsEnabledSetting) { 537 return false; 538 } 539 540 if (!dreamsEnabledForUser(ActivityManager.getCurrentUser())) { 541 return false; 542 } 543 544 if (!mUserManager.isUserUnlocked()) { 545 return false; 546 } 547 548 if (mDreamsDisabledByAmbientModeSuppressionConfig 549 && mPowerManagerInternal.isAmbientDisplaySuppressed()) { 550 // Don't dream if Bedtime (or something else) is suppressing ambient. 551 Slog.i(TAG, "Can't start dreaming because ambient is suppressed."); 552 return false; 553 } 554 555 // All dream prerequisites fulfilled, check if device state matches "when to dream" 556 // setting. 557 return dreamConditionActiveInternalLocked(); 558 } 559 } 560 dreamIsFrontmost()561 private boolean dreamIsFrontmost() { 562 // Dreams were always considered frontmost before they began tracking whether they are 563 // obscured. 564 return !dreamHandlesBeingObscured() || mController.dreamIsFrontmost(); 565 } 566 requestStartDreamFromShell()567 protected void requestStartDreamFromShell() { 568 requestDreamInternal(); 569 } 570 requestDreamInternal()571 private void requestDreamInternal() { 572 if (isDreamingInternal() && !dreamIsFrontmost() && mController.bringDreamToFront()) { 573 return; 574 } 575 576 // Ask the power manager to nap. It will eventually call back into 577 // startDream() if/when it is appropriate to start dreaming. 578 // Because napping could cause the screen to turn off immediately if the dream 579 // cannot be started, we keep one eye open and gently poke user activity. 580 long time = SystemClock.uptimeMillis(); 581 mPowerManager.userActivity(time, /* noChangeLights= */ true); 582 mPowerManagerInternal.nap(time, /* allowWake= */ true); 583 } 584 requestAwakenInternal(String reason)585 private void requestAwakenInternal(String reason) { 586 // Treat an explicit request to awaken as user activity so that the 587 // device doesn't immediately go to sleep if the timeout expired, 588 // for example when being undocked. 589 long time = SystemClock.uptimeMillis(); 590 mPowerManager.userActivity(time, false /*noChangeLights*/); 591 stopDreamInternal(false /*immediate*/, reason); 592 } 593 finishSelfInternal(IBinder token, boolean immediate)594 private void finishSelfInternal(IBinder token, boolean immediate) { 595 if (DEBUG) { 596 Slog.d(TAG, "Dream finished: " + token + ", immediate=" + immediate); 597 } 598 599 // Note that a dream finishing and self-terminating is not 600 // itself considered user activity. If the dream is ending because 601 // the user interacted with the device then user activity will already 602 // have been poked so the device will stay awake a bit longer. 603 // If the dream is ending on its own for other reasons and no wake 604 // locks are held and the user activity timeout has expired then the 605 // device may simply go to sleep. 606 synchronized (mLock) { 607 if (mCurrentDream != null && mCurrentDream.token == token) { 608 stopDreamLocked(immediate, "finished self"); 609 } 610 } 611 } 612 testDreamInternal(ComponentName dream, int userId)613 private void testDreamInternal(ComponentName dream, int userId) { 614 synchronized (mLock) { 615 startDreamLocked(dream, true /*isPreviewMode*/, false /*canDoze*/, userId, 616 "test dream" /*reason*/); 617 } 618 } 619 startDreamInternal(boolean doze, String reason)620 private void startDreamInternal(boolean doze, String reason) { 621 final int userId = ActivityManager.getCurrentUser(); 622 final ComponentName dream = chooseDreamForUser(doze, userId); 623 if (dream != null) { 624 synchronized (mLock) { 625 startDreamLocked(dream, false /*isPreviewMode*/, doze, userId, reason); 626 } 627 } 628 } 629 requestStopDreamFromShell()630 protected void requestStopDreamFromShell() { 631 stopDreamInternal(false, "stopping dream from shell"); 632 } 633 stopDreamInternal(boolean immediate, String reason)634 private void stopDreamInternal(boolean immediate, String reason) { 635 synchronized (mLock) { 636 stopDreamLocked(immediate, reason); 637 } 638 } 639 startDozingInternal(IBinder token, int screenState, @Display.StateReason int reason, float screenBrightnessFloat, int screenBrightnessInt, boolean useNormalBrightnessForDoze)640 private void startDozingInternal(IBinder token, int screenState, 641 @Display.StateReason int reason, float screenBrightnessFloat, int screenBrightnessInt, 642 boolean useNormalBrightnessForDoze) { 643 Slog.d(TAG, "Dream requested to start dozing: " + token 644 + ", screenState=" + Display.stateToString(screenState) 645 + ", reason=" + Display.stateReasonToString(reason) 646 + ", screenBrightnessFloat=" + screenBrightnessFloat 647 + ", screenBrightnessInt=" + screenBrightnessInt 648 + ", useNormalBrightnessForDoze=" + useNormalBrightnessForDoze); 649 650 synchronized (mLock) { 651 if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.canDoze) { 652 mCurrentDream.dozeScreenState = screenState; 653 mCurrentDream.dozeScreenBrightness = screenBrightnessInt; 654 mCurrentDream.dozeScreenBrightnessFloat = screenBrightnessFloat; 655 mPowerManagerInternal.setDozeOverrideFromDreamManager( 656 screenState, reason, screenBrightnessFloat, screenBrightnessInt, 657 useNormalBrightnessForDoze); 658 if (!mCurrentDream.isDozing) { 659 mCurrentDream.isDozing = true; 660 mDozeWakeLock.acquire(); 661 } 662 } 663 } 664 } 665 stopDozingInternal(IBinder token)666 private void stopDozingInternal(IBinder token) { 667 if (DEBUG) { 668 Slog.d(TAG, "Dream requested to stop dozing: " + token); 669 } 670 671 synchronized (mLock) { 672 if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.isDozing) { 673 mCurrentDream.isDozing = false; 674 mDozeWakeLock.release(); 675 mPowerManagerInternal.setDozeOverrideFromDreamManager( 676 Display.STATE_UNKNOWN, 677 Display.STATE_REASON_DREAM_MANAGER, 678 PowerManager.BRIGHTNESS_INVALID_FLOAT, 679 PowerManager.BRIGHTNESS_DEFAULT, 680 /* useNormalBrightnessForDoze= */ false); 681 } 682 } 683 } 684 forceAmbientDisplayEnabledInternal(boolean enabled)685 private void forceAmbientDisplayEnabledInternal(boolean enabled) { 686 if (DEBUG) { 687 Slog.d(TAG, "Force ambient display enabled: " + enabled); 688 } 689 690 synchronized (mLock) { 691 mForceAmbientDisplayEnabled = enabled; 692 } 693 } 694 695 @VisibleForTesting setDevicePosturedInternal(boolean isPostured)696 void setDevicePosturedInternal(boolean isPostured) { 697 Slog.d(TAG, "Device postured: " + isPostured); 698 synchronized (mLock) { 699 mIsPostured = isPostured; 700 mHandler.post(() -> mPowerManagerInternal.setDevicePostured(isPostured)); 701 } 702 } 703 704 /** 705 * If doze is true, returns the doze component for the user. 706 * Otherwise, returns the system dream component, if present. 707 * Otherwise, returns the first valid user configured dream component. 708 */ chooseDreamForUser(boolean doze, int userId)709 private ComponentName chooseDreamForUser(boolean doze, int userId) { 710 if (doze) { 711 ComponentName dozeComponent = getDozeComponent(userId); 712 return validateDream(dozeComponent, userId) ? dozeComponent : null; 713 } 714 715 if (mSystemDreamComponent != null) { 716 return mSystemDreamComponent; 717 } 718 719 ComponentName[] dreams = getDreamComponentsForUser(userId); 720 return dreams != null && dreams.length != 0 ? dreams[0] : null; 721 } 722 validateDream(ComponentName component, int userId)723 private boolean validateDream(ComponentName component, int userId) { 724 if (component == null) return false; 725 final ServiceInfo serviceInfo = getServiceInfo(component, userId); 726 if (serviceInfo == null) { 727 Slog.w(TAG, "Dream " + component + " does not exist on user " + userId); 728 return false; 729 } else if (serviceInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP 730 && !BIND_DREAM_SERVICE.equals(serviceInfo.permission)) { 731 Slog.w(TAG, "Dream " + component 732 + " is not available because its manifest is missing the " + BIND_DREAM_SERVICE 733 + " permission on the dream service declaration."); 734 return false; 735 } 736 return true; 737 } 738 getDreamComponentsForUser(int userId)739 private ComponentName[] getDreamComponentsForUser(int userId) { 740 if (!dreamsEnabledForUser(userId)) { 741 // Don't return any dream components if the user is not allowed to dream. 742 return null; 743 } 744 745 String names = Settings.Secure.getStringForUser(mContext.getContentResolver(), 746 Settings.Secure.SCREENSAVER_COMPONENTS, 747 userId); 748 ComponentName[] components = componentsFromString(names); 749 750 // first, ensure components point to valid services 751 List<ComponentName> validComponents = new ArrayList<>(); 752 if (components != null) { 753 for (ComponentName component : components) { 754 if (validateDream(component, userId)) { 755 validComponents.add(component); 756 } 757 } 758 } 759 760 // fallback to the default dream component if necessary 761 if (validComponents.isEmpty()) { 762 ComponentName defaultDream = getDefaultDreamComponentForUser(userId); 763 if (defaultDream != null) { 764 Slog.w(TAG, "Falling back to default dream " + defaultDream); 765 validComponents.add(defaultDream); 766 } 767 } 768 return validComponents.toArray(new ComponentName[validComponents.size()]); 769 } 770 updateDreamOnPackageRemoved(String packageName, int userId)771 private void updateDreamOnPackageRemoved(String packageName, int userId) { 772 final ComponentName[] componentNames = componentsFromString( 773 Settings.Secure.getStringForUser(mContext.getContentResolver(), 774 Settings.Secure.SCREENSAVER_COMPONENTS, 775 userId)); 776 if (componentNames != null) { 777 // Filter out any components in the removed package. 778 final ComponentName[] filteredComponents = 779 Arrays.stream(componentNames) 780 .filter((componentName -> !isSamePackage(packageName, componentName))) 781 .toArray(ComponentName[]::new); 782 if (filteredComponents.length != componentNames.length) { 783 setDreamComponentsForUser(userId, filteredComponents); 784 } 785 } 786 } 787 isSamePackage(String packageName, ComponentName componentName)788 private static boolean isSamePackage(String packageName, ComponentName componentName) { 789 if (packageName == null || componentName == null) { 790 return false; 791 } 792 return TextUtils.equals(componentName.getPackageName(), packageName); 793 } 794 setDreamComponentsForUser(int userId, ComponentName[] componentNames)795 private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) { 796 Settings.Secure.putStringForUser(mContext.getContentResolver(), 797 Settings.Secure.SCREENSAVER_COMPONENTS, 798 componentsToString(componentNames), 799 userId); 800 } 801 setSystemDreamComponentInternal(ComponentName componentName)802 private void setSystemDreamComponentInternal(ComponentName componentName) { 803 synchronized (mLock) { 804 if (Objects.equals(mSystemDreamComponent, componentName)) { 805 return; 806 } 807 808 mSystemDreamComponent = componentName; 809 reportKeepDreamingWhenUnpluggingChanged(shouldKeepDreamingWhenUnplugging()); 810 // Switch dream if currently dreaming and not dozing. 811 if (isDreamingInternal() && !isDozingInternal()) { 812 startDreamInternal(false /*doze*/, (mSystemDreamComponent == null ? "clear" : "set") 813 + " system dream component" /*reason*/); 814 } 815 } 816 } 817 shouldKeepDreamingWhenUnplugging()818 private boolean shouldKeepDreamingWhenUnplugging() { 819 return mKeepDreamingWhenUnpluggingDefault && mSystemDreamComponent == null; 820 } 821 getDefaultDreamComponentForUser(int userId)822 private ComponentName getDefaultDreamComponentForUser(int userId) { 823 String name = Settings.Secure.getStringForUser(mContext.getContentResolver(), 824 Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, 825 userId); 826 return name == null ? null : ComponentName.unflattenFromString(name); 827 } 828 getDozeComponent()829 private ComponentName getDozeComponent() { 830 return getDozeComponent(ActivityManager.getCurrentUser()); 831 } 832 getDozeComponent(int userId)833 private ComponentName getDozeComponent(int userId) { 834 if (mForceAmbientDisplayEnabled || mDozeConfig.enabled(userId)) { 835 return ComponentName.unflattenFromString(mDozeConfig.ambientDisplayComponent()); 836 } else { 837 return null; 838 } 839 840 } 841 dreamsEnabledForUser(int userId)842 private boolean dreamsEnabledForUser(int userId) { 843 if (!mDreamsOnlyEnabledForDockUser) return true; 844 if (userId < 0) return false; 845 final int mainUserId = LocalServices.getService(UserManagerInternal.class).getMainUserId(); 846 return userId == mainUserId; 847 } 848 getServiceInfo(ComponentName name, int userId)849 private ServiceInfo getServiceInfo(ComponentName name, int userId) { 850 final Context userContext = mContext.createContextAsUser(UserHandle.of(userId), 0); 851 try { 852 return name != null ? userContext.getPackageManager().getServiceInfo(name, 853 PackageManager.MATCH_DEBUG_TRIAGED_MISSING) : null; 854 } catch (NameNotFoundException e) { 855 return null; 856 } 857 } 858 859 @GuardedBy("mLock") startDreamLocked(final ComponentName name, final boolean isPreviewMode, final boolean canDoze, final int userId, final String reason)860 private void startDreamLocked(final ComponentName name, 861 final boolean isPreviewMode, final boolean canDoze, final int userId, 862 final String reason) { 863 if (mCurrentDream != null 864 && !mCurrentDream.isWaking 865 && Objects.equals(mCurrentDream.name, name) 866 && mCurrentDream.isPreview == isPreviewMode 867 && mCurrentDream.canDoze == canDoze 868 && mCurrentDream.userId == userId) { 869 Slog.i(TAG, "Already in target dream."); 870 return; 871 } 872 873 Slog.i(TAG, "Entering dreamland."); 874 875 if (mCurrentDream != null && mCurrentDream.isDozing) { 876 stopDozingInternal(mCurrentDream.token); 877 } 878 879 mCurrentDream = new DreamRecord(name, userId, isPreviewMode, canDoze); 880 881 if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) { 882 // TODO(b/213906448): Remove when metrics based on new atom are fully rolled out. 883 mUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_START); 884 mDreamUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_START, 885 mCurrentDream.name.flattenToString()); 886 } 887 888 PowerManager.WakeLock wakeLock = mPowerManager 889 .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, DREAM_WAKE_LOCK_TAG); 890 final Binder dreamToken = mCurrentDream.token; 891 mHandler.post(wakeLock.wrap(() -> { 892 mAtmInternal.notifyActiveDreamChanged(name); 893 mController.startDream(dreamToken, name, isPreviewMode, canDoze, userId, wakeLock, 894 mDreamOverlayServiceName, reason); 895 })); 896 } 897 898 @GuardedBy("mLock") stopDreamLocked(final boolean immediate, String reason)899 private void stopDreamLocked(final boolean immediate, String reason) { 900 if (mCurrentDream != null) { 901 if (immediate) { 902 Slog.i(TAG, "Leaving dreamland."); 903 cleanupDreamLocked(); 904 } else if (mCurrentDream.isWaking) { 905 return; // already waking 906 } else { 907 Slog.i(TAG, "Gently waking up from dream."); 908 mCurrentDream.isWaking = true; 909 } 910 911 mHandler.post(() -> mController.stopDream(immediate, reason)); 912 } 913 } 914 915 @GuardedBy("mLock") cleanupDreamLocked()916 private void cleanupDreamLocked() { 917 mHandler.post(() -> mAtmInternal.notifyActiveDreamChanged(null)); 918 919 if (mCurrentDream == null) { 920 return; 921 } 922 923 if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) { 924 // TODO(b/213906448): Remove when metrics based on new atom are fully rolled out. 925 mUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_STOP); 926 mDreamUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_STOP, 927 mCurrentDream.name.flattenToString()); 928 } 929 if (mCurrentDream.isDozing) { 930 mDozeWakeLock.release(); 931 } 932 mCurrentDream = null; 933 } 934 checkPermission(String permission)935 private void checkPermission(String permission) { 936 if (mContext.checkCallingOrSelfPermission(permission) 937 != PackageManager.PERMISSION_GRANTED) { 938 throw new SecurityException("Access denied to process: " + Binder.getCallingPid() 939 + ", must have permission " + permission); 940 } 941 } 942 writePulseGestureEnabled()943 private void writePulseGestureEnabled() { 944 ComponentName name = getDozeComponent(); 945 boolean dozeEnabled = validateDream(name, ActivityManager.getCurrentUser()); 946 LocalServices.getService(InputManagerInternal.class).setPulseGestureEnabled(dozeEnabled); 947 } 948 componentsToString(ComponentName[] componentNames)949 private static String componentsToString(ComponentName[] componentNames) { 950 if (componentNames == null) { 951 return null; 952 } 953 StringBuilder names = new StringBuilder(); 954 for (ComponentName componentName : componentNames) { 955 if (componentName == null) { 956 continue; 957 } 958 if (!names.isEmpty()) { 959 names.append(','); 960 } 961 names.append(componentName.flattenToString()); 962 } 963 return names.toString(); 964 } 965 componentsFromString(String names)966 private static ComponentName[] componentsFromString(String names) { 967 if (names == null) { 968 return null; 969 } 970 String[] namesArray = names.split(","); 971 ComponentName[] componentNames = new ComponentName[namesArray.length]; 972 for (int i = 0; i < namesArray.length; i++) { 973 componentNames[i] = ComponentName.unflattenFromString(namesArray[i]); 974 } 975 return componentNames; 976 } 977 978 private final DreamController.Listener mControllerListener = new DreamController.Listener() { 979 @Override 980 public void onDreamStarted(Binder token) { 981 // Note that this event is distinct from DreamManagerService#startDreamLocked as it 982 // tracks the DreamService attach point from DreamController, closest to the broadcast 983 // of ACTION_DREAMING_STARTED. 984 985 reportDreamingStarted(); 986 } 987 988 @Override 989 public void onDreamStopped(Binder token) { 990 synchronized (mLock) { 991 if (mCurrentDream != null && mCurrentDream.token == token) { 992 cleanupDreamLocked(); 993 } 994 } 995 996 reportDreamingStopped(); 997 } 998 }; 999 1000 private final ContentObserver mDozeEnabledObserver = new ContentObserver(null) { 1001 @Override 1002 public void onChange(boolean selfChange) { 1003 writePulseGestureEnabled(); 1004 } 1005 }; 1006 1007 /** 1008 * Handler for asynchronous operations performed by the dream manager. 1009 * Ensures operations to {@link DreamController} are single-threaded. 1010 */ 1011 private static final class DreamHandler extends Handler { DreamHandler(Looper looper)1012 public DreamHandler(Looper looper) { 1013 super(looper, null, true /*async*/); 1014 } 1015 } 1016 1017 private final class BinderService extends IDreamManager.Stub { 1018 @Override // Binder call dump(FileDescriptor fd, PrintWriter pw, String[] args)1019 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1020 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 1021 final long ident = Binder.clearCallingIdentity(); 1022 try { 1023 dumpInternal(pw); 1024 } finally { 1025 Binder.restoreCallingIdentity(ident); 1026 } 1027 } 1028 onShellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)1029 public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, 1030 @Nullable FileDescriptor err, 1031 @NonNull String[] args, @Nullable ShellCallback callback, 1032 @NonNull ResultReceiver resultReceiver) throws RemoteException { 1033 new DreamShellCommand(DreamManagerService.this) 1034 .exec(this, in, out, err, args, callback, resultReceiver); 1035 } 1036 1037 @Override // Binder call getDreamComponents()1038 public ComponentName[] getDreamComponents() { 1039 return getDreamComponentsForUser(UserHandle.getCallingUserId()); 1040 } 1041 1042 @Override // Binder call getDreamComponentsForUser(int userId)1043 public ComponentName[] getDreamComponentsForUser(int userId) { 1044 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 1045 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 1046 Binder.getCallingUid(), userId, false, true, "getDreamComponents", null); 1047 1048 final long ident = Binder.clearCallingIdentity(); 1049 try { 1050 return DreamManagerService.this.getDreamComponentsForUser(userId); 1051 } finally { 1052 Binder.restoreCallingIdentity(ident); 1053 } 1054 } 1055 1056 @Override // Binder call setDreamComponents(ComponentName[] componentNames)1057 public void setDreamComponents(ComponentName[] componentNames) { 1058 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1059 1060 final int userId = UserHandle.getCallingUserId(); 1061 final long ident = Binder.clearCallingIdentity(); 1062 try { 1063 setDreamComponentsForUser(userId, componentNames); 1064 } finally { 1065 Binder.restoreCallingIdentity(ident); 1066 } 1067 } 1068 1069 @Override // Binder call setDreamComponentsForUser(int userId, ComponentName[] componentNames)1070 public void setDreamComponentsForUser(int userId, ComponentName[] componentNames) { 1071 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1072 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 1073 Binder.getCallingUid(), userId, false, true, "setDreamComponents", null); 1074 1075 final long ident = Binder.clearCallingIdentity(); 1076 try { 1077 DreamManagerService.this.setDreamComponentsForUser(userId, componentNames); 1078 } finally { 1079 Binder.restoreCallingIdentity(ident); 1080 } 1081 } 1082 1083 @Override // Binder call setSystemDreamComponent(ComponentName componentName)1084 public void setSystemDreamComponent(ComponentName componentName) { 1085 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1086 1087 final long ident = Binder.clearCallingIdentity(); 1088 try { 1089 DreamManagerService.this.setSystemDreamComponentInternal(componentName); 1090 } finally { 1091 Binder.restoreCallingIdentity(ident); 1092 } 1093 } 1094 1095 @Override // Binder call registerDreamOverlayService(ComponentName overlayComponent)1096 public void registerDreamOverlayService(ComponentName overlayComponent) { 1097 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1098 1099 // Store the overlay service component so that it can be passed to the dream when it is 1100 // invoked. 1101 mDreamOverlayServiceName = overlayComponent; 1102 } 1103 1104 @Override // Binder call getDefaultDreamComponentForUser(int userId)1105 public ComponentName getDefaultDreamComponentForUser(int userId) { 1106 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 1107 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 1108 Binder.getCallingUid(), userId, false, true, "getDefaultDreamComponent", null); 1109 1110 final long ident = Binder.clearCallingIdentity(); 1111 try { 1112 return DreamManagerService.this.getDefaultDreamComponentForUser(userId); 1113 } finally { 1114 Binder.restoreCallingIdentity(ident); 1115 } 1116 } 1117 1118 @Override // Binder call isDreaming()1119 public boolean isDreaming() { 1120 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 1121 1122 final long ident = Binder.clearCallingIdentity(); 1123 try { 1124 return isDreamingInternal(); 1125 } finally { 1126 Binder.restoreCallingIdentity(ident); 1127 } 1128 } 1129 1130 @Override // Binder call isDreamingOrInPreview()1131 public boolean isDreamingOrInPreview() { 1132 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 1133 1134 final long ident = Binder.clearCallingIdentity(); 1135 try { 1136 return isDreamingOrInPreviewInternal(); 1137 } finally { 1138 Binder.restoreCallingIdentity(ident); 1139 } 1140 } 1141 1142 1143 @Override // Binder call dream()1144 public void dream() { 1145 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1146 1147 final long ident = Binder.clearCallingIdentity(); 1148 try { 1149 requestDreamInternal(); 1150 } finally { 1151 Binder.restoreCallingIdentity(ident); 1152 } 1153 } 1154 1155 @Override // Binder call canStartDreaming(boolean isScreenOn)1156 public boolean canStartDreaming(boolean isScreenOn) { 1157 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 1158 1159 final long ident = Binder.clearCallingIdentity(); 1160 try { 1161 return canStartDreamingInternal(isScreenOn); 1162 } finally { 1163 Binder.restoreCallingIdentity(ident); 1164 } 1165 } 1166 1167 @Override // Binder call testDream(int userId, ComponentName dream)1168 public void testDream(int userId, ComponentName dream) { 1169 if (dream == null) { 1170 throw new IllegalArgumentException("dream must not be null"); 1171 } 1172 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1173 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 1174 Binder.getCallingUid(), userId, false, true, "testDream", null); 1175 1176 final int currentUserId = ActivityManager.getCurrentUser(); 1177 if (userId != currentUserId) { 1178 // This check is inherently prone to races but at least it's something. 1179 Slog.w(TAG, "Aborted attempt to start a test dream while a different " 1180 + " user is active: userId=" + userId 1181 + ", currentUserId=" + currentUserId); 1182 return; 1183 } 1184 final long ident = Binder.clearCallingIdentity(); 1185 try { 1186 testDreamInternal(dream, userId); 1187 } finally { 1188 Binder.restoreCallingIdentity(ident); 1189 } 1190 } 1191 1192 @Override // Binder call awaken()1193 public void awaken() { 1194 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1195 1196 final long ident = Binder.clearCallingIdentity(); 1197 try { 1198 requestAwakenInternal("request awaken"); 1199 } finally { 1200 Binder.restoreCallingIdentity(ident); 1201 } 1202 } 1203 1204 @Override // Binder call finishSelf(IBinder token, boolean immediate)1205 public void finishSelf(IBinder token, boolean immediate) { 1206 // Requires no permission, called by Dream from an arbitrary process. 1207 if (token == null) { 1208 throw new IllegalArgumentException("token must not be null"); 1209 } 1210 1211 final long ident = Binder.clearCallingIdentity(); 1212 try { 1213 finishSelfInternal(token, immediate); 1214 } finally { 1215 Binder.restoreCallingIdentity(ident); 1216 } 1217 } 1218 1219 @Override // Binder call finishSelfOneway(IBinder token, boolean immediate)1220 public void finishSelfOneway(IBinder token, boolean immediate) { 1221 // Requires no permission, called by Dream from an arbitrary process. 1222 if (token == null) { 1223 throw new IllegalArgumentException("token must not be null"); 1224 } 1225 1226 final long ident = Binder.clearCallingIdentity(); 1227 try { 1228 finishSelfInternal(token, immediate); 1229 } finally { 1230 Binder.restoreCallingIdentity(ident); 1231 } 1232 } 1233 1234 @Override // Binder call startDozing( IBinder token, int screenState, @Display.StateReason int reason, float screenBrightnessFloat, int screeBrightnessInt, boolean useNormalBrightnessForDoze)1235 public void startDozing( 1236 IBinder token, int screenState, @Display.StateReason int reason, 1237 float screenBrightnessFloat, int screeBrightnessInt, 1238 boolean useNormalBrightnessForDoze) { 1239 // Requires no permission, called by Dream from an arbitrary process. 1240 if (token == null) { 1241 throw new IllegalArgumentException("token must not be null"); 1242 } 1243 1244 final long ident = Binder.clearCallingIdentity(); 1245 try { 1246 startDozingInternal(token, screenState, reason, screenBrightnessFloat, 1247 screeBrightnessInt, useNormalBrightnessForDoze); 1248 } finally { 1249 Binder.restoreCallingIdentity(ident); 1250 } 1251 } 1252 1253 @Override // Binder call startDozingOneway( IBinder token, int screenState, @Display.StateReason int reason, float screenBrightnessFloat, int screeBrightnessInt, boolean useNormalBrightnessForDoze)1254 public void startDozingOneway( 1255 IBinder token, int screenState, @Display.StateReason int reason, 1256 float screenBrightnessFloat, int screeBrightnessInt, 1257 boolean useNormalBrightnessForDoze) { 1258 // Requires no permission, called by Dream from an arbitrary process. 1259 if (token == null) { 1260 throw new IllegalArgumentException("token must not be null"); 1261 } 1262 1263 final long ident = Binder.clearCallingIdentity(); 1264 try { 1265 startDozingInternal(token, screenState, reason, screenBrightnessFloat, 1266 screeBrightnessInt, useNormalBrightnessForDoze); 1267 } finally { 1268 Binder.restoreCallingIdentity(ident); 1269 } 1270 } 1271 1272 @Override // Binder call stopDozing(IBinder token)1273 public void stopDozing(IBinder token) { 1274 // Requires no permission, called by Dream from an arbitrary process. 1275 if (token == null) { 1276 throw new IllegalArgumentException("token must not be null"); 1277 } 1278 1279 final long ident = Binder.clearCallingIdentity(); 1280 try { 1281 stopDozingInternal(token); 1282 } finally { 1283 Binder.restoreCallingIdentity(ident); 1284 } 1285 } 1286 1287 @Override // Binder call forceAmbientDisplayEnabled(boolean enabled)1288 public void forceAmbientDisplayEnabled(boolean enabled) { 1289 checkPermission(android.Manifest.permission.DEVICE_POWER); 1290 1291 final long ident = Binder.clearCallingIdentity(); 1292 try { 1293 forceAmbientDisplayEnabledInternal(enabled); 1294 } finally { 1295 Binder.restoreCallingIdentity(ident); 1296 } 1297 } 1298 1299 @Override // Binder call startDreamActivity(@onNull Intent intent)1300 public void startDreamActivity(@NonNull Intent intent) { 1301 final int callingUid = Binder.getCallingUid(); 1302 final int callingPid = Binder.getCallingPid(); 1303 // We post here, because startDreamActivity and setDreamAppTask have to run 1304 // synchronously and DreamController#setDreamAppTask has to run on mHandler. 1305 mHandler.post(() -> { 1306 final Binder dreamToken; 1307 final String dreamPackageName; 1308 synchronized (mLock) { 1309 if (mCurrentDream == null) { 1310 Slog.e(TAG, "Attempt to start DreamActivity, but the device is not " 1311 + "dreaming. Aborting without starting the DreamActivity."); 1312 return; 1313 } 1314 dreamToken = mCurrentDream.token; 1315 dreamPackageName = mCurrentDream.name.getPackageName(); 1316 } 1317 1318 if (!canLaunchDreamActivity(dreamPackageName, intent.getPackage(), 1319 callingUid)) { 1320 Slog.e(TAG, "The dream activity can be started only when the device is dreaming" 1321 + " and only by the active dream package."); 1322 return; 1323 } 1324 1325 final IAppTask appTask = mAtmInternal.startDreamActivity(intent, callingUid, 1326 callingPid); 1327 if (appTask == null) { 1328 Slog.e(TAG, "Could not start dream activity."); 1329 stopDreamInternal(true, "DreamActivity not started"); 1330 return; 1331 } 1332 mController.setDreamAppTask(dreamToken, appTask); 1333 }); 1334 } 1335 1336 @Override setDreamIsObscured(boolean isObscured)1337 public void setDreamIsObscured(boolean isObscured) { 1338 if (!dreamHandlesBeingObscured()) { 1339 return; 1340 } 1341 1342 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1343 1344 final long ident = Binder.clearCallingIdentity(); 1345 try { 1346 mHandler.post(() -> mController.setDreamIsObscured(isObscured)); 1347 } finally { 1348 Binder.restoreCallingIdentity(ident); 1349 } 1350 } 1351 1352 @Override setDevicePostured(boolean isPostured)1353 public void setDevicePostured(boolean isPostured) { 1354 if (!allowDreamWhenPostured()) { 1355 return; 1356 } 1357 1358 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 1359 1360 final long ident = Binder.clearCallingIdentity(); 1361 try { 1362 setDevicePosturedInternal(isPostured); 1363 } finally { 1364 Binder.restoreCallingIdentity(ident); 1365 } 1366 } 1367 1368 @Override setScreensaverEnabled(boolean enabled)1369 public void setScreensaverEnabled(boolean enabled) { 1370 checkPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS); 1371 final UserHandle userHandle = getCallingUserHandle(); 1372 final long ident = Binder.clearCallingIdentity(); 1373 try { 1374 Settings.Secure.putIntForUser(mContext.getContentResolver(), 1375 Settings.Secure.SCREENSAVER_ENABLED, enabled ? 1 : 0, 1376 userHandle.getIdentifier()); 1377 mPowerManagerInternal.updateSettings(); 1378 } finally { 1379 Binder.restoreCallingIdentity(ident); 1380 } 1381 } 1382 canLaunchDreamActivity(String dreamPackageName, String packageName, int callingUid)1383 boolean canLaunchDreamActivity(String dreamPackageName, String packageName, 1384 int callingUid) { 1385 if (dreamPackageName == null || packageName == null) { 1386 Slog.e(TAG, "Cannot launch dream activity due to invalid state. dream component= " 1387 + dreamPackageName + ", packageName=" + packageName); 1388 return false; 1389 } 1390 if (!mPmInternal.isSameApp(packageName, callingUid, UserHandle.getUserId(callingUid))) { 1391 Slog.e(TAG, "Cannot launch dream activity because package=" 1392 + packageName + " does not match callingUid=" + callingUid); 1393 return false; 1394 } 1395 if (packageName.equals(dreamPackageName)) { 1396 return true; 1397 } 1398 Slog.e(TAG, "Dream packageName does not match active dream. Package " + packageName 1399 + " does not match " + dreamPackageName); 1400 return false; 1401 } 1402 1403 } 1404 1405 private final class LocalService extends DreamManagerInternal { 1406 @Override startDream(boolean doze, String reason)1407 public void startDream(boolean doze, String reason) { 1408 startDreamInternal(doze, reason); 1409 } 1410 1411 @Override stopDream(boolean immediate, String reason)1412 public void stopDream(boolean immediate, String reason) { 1413 stopDreamInternal(immediate, reason); 1414 } 1415 1416 @Override isDreaming()1417 public boolean isDreaming() { 1418 return isDreamingInternal(); 1419 } 1420 1421 @Override canStartDreaming(boolean isScreenOn)1422 public boolean canStartDreaming(boolean isScreenOn) { 1423 return canStartDreamingInternal(isScreenOn); 1424 } 1425 1426 @Override dreamConditionActive()1427 public boolean dreamConditionActive() { 1428 return dreamConditionActiveInternal(); 1429 } 1430 1431 @Override requestDream()1432 public void requestDream() { 1433 requestDreamInternal(); 1434 } 1435 1436 @Override registerDreamManagerStateListener(DreamManagerStateListener listener)1437 public void registerDreamManagerStateListener(DreamManagerStateListener listener) { 1438 mDreamManagerStateListeners.add(listener); 1439 // Initialize the listener's state. 1440 listener.onKeepDreamingWhenUnpluggingChanged(shouldKeepDreamingWhenUnplugging()); 1441 } 1442 1443 @Override unregisterDreamManagerStateListener(DreamManagerStateListener listener)1444 public void unregisterDreamManagerStateListener(DreamManagerStateListener listener) { 1445 mDreamManagerStateListeners.remove(listener); 1446 } 1447 } 1448 1449 private static final class DreamRecord { 1450 public final Binder token = new Binder(); 1451 public final ComponentName name; 1452 public final int userId; 1453 public final boolean isPreview; 1454 public final boolean canDoze; 1455 public boolean isDozing = false; 1456 public boolean isWaking = false; 1457 public int dozeScreenState = Display.STATE_UNKNOWN; 1458 public int dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; 1459 public float dozeScreenBrightnessFloat = PowerManager.BRIGHTNESS_INVALID_FLOAT; 1460 DreamRecord(ComponentName name, int userId, boolean isPreview, boolean canDoze)1461 DreamRecord(ComponentName name, int userId, boolean isPreview, boolean canDoze) { 1462 this.name = name; 1463 this.userId = userId; 1464 this.isPreview = isPreview; 1465 this.canDoze = canDoze; 1466 } 1467 1468 @Override toString()1469 public String toString() { 1470 return "DreamRecord{" 1471 + "token=" + token 1472 + ", name=" + name 1473 + ", userId=" + userId 1474 + ", isPreview=" + isPreview 1475 + ", canDoze=" + canDoze 1476 + ", isDozing=" + isDozing 1477 + ", isWaking=" + isWaking 1478 + ", dozeScreenState=" + dozeScreenState 1479 + ", dozeScreenBrightness=" + dozeScreenBrightness 1480 + ", dozeScreenBrightnessFloat=" + dozeScreenBrightnessFloat 1481 + '}'; 1482 } 1483 } 1484 1485 private final Runnable mSystemPropertiesChanged = new Runnable() { 1486 @Override 1487 public void run() { 1488 if (DEBUG) Slog.d(TAG, "System properties changed"); 1489 synchronized (mLock) { 1490 if (mCurrentDream != null && mCurrentDream.name != null && mCurrentDream.canDoze 1491 && !mCurrentDream.name.equals(getDozeComponent())) { 1492 // May have updated the doze component, wake up 1493 mPowerManager.wakeUp(SystemClock.uptimeMillis(), 1494 "android.server.dreams:SYSPROP"); 1495 } 1496 } 1497 } 1498 }; 1499 } 1500