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 24 import static com.android.server.wm.ActivityInterceptorCallback.DREAM_MANAGER_ORDERED_ID; 25 26 import android.annotation.IntDef; 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.app.ActivityManager; 30 import android.app.TaskInfo; 31 import android.content.BroadcastReceiver; 32 import android.content.ComponentName; 33 import android.content.ContentResolver; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.IntentFilter; 37 import android.content.pm.ActivityInfo; 38 import android.content.pm.PackageManager; 39 import android.content.pm.PackageManager.NameNotFoundException; 40 import android.content.pm.ServiceInfo; 41 import android.database.ContentObserver; 42 import android.hardware.display.AmbientDisplayConfiguration; 43 import android.hardware.input.InputManagerInternal; 44 import android.net.Uri; 45 import android.os.BatteryManager; 46 import android.os.Binder; 47 import android.os.Build; 48 import android.os.Handler; 49 import android.os.IBinder; 50 import android.os.Looper; 51 import android.os.PowerManager; 52 import android.os.PowerManagerInternal; 53 import android.os.RemoteException; 54 import android.os.ResultReceiver; 55 import android.os.ShellCallback; 56 import android.os.SystemClock; 57 import android.os.SystemProperties; 58 import android.os.UserHandle; 59 import android.os.UserManager; 60 import android.provider.Settings; 61 import android.service.dreams.DreamManagerInternal; 62 import android.service.dreams.DreamService; 63 import android.service.dreams.IDreamManager; 64 import android.util.Slog; 65 import android.view.Display; 66 67 import com.android.internal.R; 68 import com.android.internal.annotations.GuardedBy; 69 import com.android.internal.logging.UiEventLogger; 70 import com.android.internal.logging.UiEventLoggerImpl; 71 import com.android.internal.util.DumpUtils; 72 import com.android.server.FgThread; 73 import com.android.server.LocalServices; 74 import com.android.server.SystemService; 75 import com.android.server.wm.ActivityInterceptorCallback; 76 import com.android.server.wm.ActivityTaskManagerInternal; 77 78 import java.io.FileDescriptor; 79 import java.io.PrintWriter; 80 import java.lang.annotation.Retention; 81 import java.lang.annotation.RetentionPolicy; 82 import java.util.ArrayList; 83 import java.util.List; 84 import java.util.Objects; 85 import java.util.concurrent.CopyOnWriteArrayList; 86 87 /** 88 * Service api for managing dreams. 89 * 90 * @hide 91 */ 92 public final class DreamManagerService extends SystemService { 93 private static final boolean DEBUG = false; 94 private static final String TAG = "DreamManagerService"; 95 96 private static final String DOZE_WAKE_LOCK_TAG = "dream:doze"; 97 private static final String DREAM_WAKE_LOCK_TAG = "dream:dream"; 98 99 /** Constants for the when to activate dreams. */ 100 @Retention(RetentionPolicy.SOURCE) 101 @IntDef({DREAM_ON_DOCK, DREAM_ON_CHARGE, DREAM_ON_DOCK_OR_CHARGE}) 102 public @interface WhenToDream {} 103 private static final int DREAM_DISABLED = 0x0; 104 private static final int DREAM_ON_DOCK = 0x1; 105 private static final int DREAM_ON_CHARGE = 0x2; 106 private static final int DREAM_ON_DOCK_OR_CHARGE = 0x3; 107 108 private final Object mLock = new Object(); 109 110 private final Context mContext; 111 private final DreamHandler mHandler; 112 private final DreamController mController; 113 private final PowerManager mPowerManager; 114 private final PowerManagerInternal mPowerManagerInternal; 115 private final PowerManager.WakeLock mDozeWakeLock; 116 private final ActivityTaskManagerInternal mAtmInternal; 117 private final UserManager mUserManager; 118 private final UiEventLogger mUiEventLogger; 119 private final DreamUiEventLogger mDreamUiEventLogger; 120 private final ComponentName mAmbientDisplayComponent; 121 private final boolean mDismissDreamOnActivityStart; 122 private final boolean mDreamsOnlyEnabledForDockUser; 123 private final boolean mDreamsEnabledByDefaultConfig; 124 private final boolean mDreamsActivatedOnChargeByDefault; 125 private final boolean mDreamsActivatedOnDockByDefault; 126 private final boolean mKeepDreamingWhenUndockedDefault; 127 128 private final CopyOnWriteArrayList<DreamManagerInternal.DreamManagerStateListener> 129 mDreamManagerStateListeners = new CopyOnWriteArrayList<>(); 130 131 @GuardedBy("mLock") 132 private DreamRecord mCurrentDream; 133 134 private boolean mForceAmbientDisplayEnabled; 135 private SettingsObserver mSettingsObserver; 136 private boolean mDreamsEnabledSetting; 137 @WhenToDream private int mWhenToDream; 138 private boolean mIsDocked; 139 private boolean mIsCharging; 140 141 // A temporary dream component that, when present, takes precedence over user configured dream 142 // component. 143 private ComponentName mSystemDreamComponent; 144 145 private ComponentName mDreamOverlayServiceName; 146 147 private final AmbientDisplayConfiguration mDozeConfig; 148 private final ActivityInterceptorCallback mActivityInterceptorCallback = 149 new ActivityInterceptorCallback() { 150 @Nullable 151 @Override 152 public ActivityInterceptResult intercept(ActivityInterceptorInfo info) { 153 return null; 154 } 155 156 @Override 157 public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo, 158 ActivityInterceptorInfo info) { 159 final int activityType = taskInfo.getActivityType(); 160 final boolean activityAllowed = activityType == ACTIVITY_TYPE_HOME 161 || activityType == ACTIVITY_TYPE_DREAM 162 || activityType == ACTIVITY_TYPE_ASSISTANT; 163 164 boolean shouldRequestAwaken; 165 synchronized (mLock) { 166 shouldRequestAwaken = mCurrentDream != null && !mCurrentDream.isWaking 167 && !mCurrentDream.isDozing && !activityAllowed; 168 } 169 170 if (shouldRequestAwaken) { 171 requestAwakenInternal( 172 "stopping dream due to activity start: " + activityInfo.name); 173 } 174 } 175 }; 176 177 private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() { 178 @Override 179 public void onReceive(Context context, Intent intent) { 180 mIsCharging = BatteryManager.ACTION_CHARGING.equals(intent.getAction()); 181 } 182 }; 183 184 private final BroadcastReceiver mDockStateReceiver = new BroadcastReceiver() { 185 @Override 186 public void onReceive(Context context, Intent intent) { 187 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 188 final int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 189 Intent.EXTRA_DOCK_STATE_UNDOCKED); 190 mIsDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED; 191 } 192 } 193 }; 194 195 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)196 SettingsObserver(Handler handler) { 197 super(handler); 198 } 199 200 @Override onChange(boolean selfChange, Uri uri)201 public void onChange(boolean selfChange, Uri uri) { 202 synchronized (mLock) { 203 updateWhenToDreamSettings(); 204 } 205 } 206 } 207 DreamManagerService(Context context)208 public DreamManagerService(Context context) { 209 super(context); 210 mContext = context; 211 mHandler = new DreamHandler(FgThread.get().getLooper()); 212 mController = new DreamController(context, mHandler, mControllerListener); 213 214 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 215 mPowerManagerInternal = getLocalService(PowerManagerInternal.class); 216 mAtmInternal = getLocalService(ActivityTaskManagerInternal.class); 217 mUserManager = context.getSystemService(UserManager.class); 218 mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, DOZE_WAKE_LOCK_TAG); 219 mDozeConfig = new AmbientDisplayConfiguration(mContext); 220 mUiEventLogger = new UiEventLoggerImpl(); 221 mDreamUiEventLogger = new DreamUiEventLoggerImpl( 222 mContext.getResources().getStringArray(R.array.config_loggable_dream_prefixes)); 223 AmbientDisplayConfiguration adc = new AmbientDisplayConfiguration(mContext); 224 mAmbientDisplayComponent = ComponentName.unflattenFromString(adc.ambientDisplayComponent()); 225 mDreamsOnlyEnabledForDockUser = 226 mContext.getResources().getBoolean(R.bool.config_dreamsOnlyEnabledForDockUser); 227 mDismissDreamOnActivityStart = mContext.getResources().getBoolean( 228 R.bool.config_dismissDreamOnActivityStart); 229 230 mDreamsEnabledByDefaultConfig = mContext.getResources().getBoolean( 231 com.android.internal.R.bool.config_dreamsEnabledByDefault); 232 mDreamsActivatedOnChargeByDefault = mContext.getResources().getBoolean( 233 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault); 234 mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean( 235 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); 236 mSettingsObserver = new SettingsObserver(mHandler); 237 mKeepDreamingWhenUndockedDefault = mContext.getResources().getBoolean( 238 com.android.internal.R.bool.config_keepDreamingWhenUndocking); 239 } 240 241 @Override onStart()242 public void onStart() { 243 publishBinderService(DreamService.DREAM_SERVICE, new BinderService()); 244 publishLocalService(DreamManagerInternal.class, new LocalService()); 245 } 246 247 @Override onBootPhase(int phase)248 public void onBootPhase(int phase) { 249 if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { 250 if (Build.IS_DEBUGGABLE) { 251 SystemProperties.addChangeCallback(mSystemPropertiesChanged); 252 } 253 mContext.registerReceiver(new BroadcastReceiver() { 254 @Override 255 public void onReceive(Context context, Intent intent) { 256 writePulseGestureEnabled(); 257 synchronized (mLock) { 258 stopDreamLocked(false /*immediate*/, "user switched"); 259 } 260 } 261 }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); 262 mContext.getContentResolver().registerContentObserver( 263 Settings.Secure.getUriFor(Settings.Secure.DOZE_DOUBLE_TAP_GESTURE), false, 264 mDozeEnabledObserver, UserHandle.USER_ALL); 265 writePulseGestureEnabled(); 266 267 if (mDismissDreamOnActivityStart) { 268 mAtmInternal.registerActivityStartInterceptor( 269 DREAM_MANAGER_ORDERED_ID, 270 mActivityInterceptorCallback); 271 } 272 273 mContext.registerReceiver( 274 mDockStateReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT)); 275 IntentFilter chargingIntentFilter = new IntentFilter(); 276 chargingIntentFilter.addAction(BatteryManager.ACTION_CHARGING); 277 chargingIntentFilter.addAction(BatteryManager.ACTION_DISCHARGING); 278 mContext.registerReceiver(mChargingReceiver, chargingIntentFilter); 279 280 mSettingsObserver = new SettingsObserver(mHandler); 281 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 282 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP), 283 false, mSettingsObserver, UserHandle.USER_ALL); 284 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 285 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK), 286 false, mSettingsObserver, UserHandle.USER_ALL); 287 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( 288 Settings.Secure.SCREENSAVER_ENABLED), 289 false, mSettingsObserver, UserHandle.USER_ALL); 290 291 // We don't get an initial broadcast for the batter state, so we have to initialize 292 // directly from BatteryManager. 293 mIsCharging = mContext.getSystemService(BatteryManager.class).isCharging(); 294 295 updateWhenToDreamSettings(); 296 } 297 } 298 dumpInternal(PrintWriter pw)299 private void dumpInternal(PrintWriter pw) { 300 synchronized (mLock) { 301 pw.println("DREAM MANAGER (dumpsys dreams)"); 302 pw.println(); 303 pw.println("mCurrentDream=" + mCurrentDream); 304 pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled); 305 pw.println("mDreamsOnlyEnabledForDockUser=" + mDreamsOnlyEnabledForDockUser); 306 pw.println("mDreamsEnabledSetting=" + mDreamsEnabledSetting); 307 pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled); 308 pw.println("mDreamsActivatedOnDockByDefault=" + mDreamsActivatedOnDockByDefault); 309 pw.println("mDreamsActivatedOnChargeByDefault=" + mDreamsActivatedOnChargeByDefault); 310 pw.println("mIsDocked=" + mIsDocked); 311 pw.println("mIsCharging=" + mIsCharging); 312 pw.println("mWhenToDream=" + mWhenToDream); 313 pw.println("mKeepDreamingWhenUndockedDefault=" + mKeepDreamingWhenUndockedDefault); 314 pw.println("getDozeComponent()=" + getDozeComponent()); 315 pw.println(); 316 317 DumpUtils.dumpAsync(mHandler, (pw1, prefix) -> mController.dump(pw1), pw, "", 200); 318 } 319 } 320 updateWhenToDreamSettings()321 private void updateWhenToDreamSettings() { 322 synchronized (mLock) { 323 final ContentResolver resolver = mContext.getContentResolver(); 324 325 final int activateWhenCharging = (Settings.Secure.getIntForUser(resolver, 326 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 327 mDreamsActivatedOnChargeByDefault ? 1 : 0, 328 UserHandle.USER_CURRENT) != 0) ? DREAM_ON_CHARGE : DREAM_DISABLED; 329 final int activateWhenDocked = (Settings.Secure.getIntForUser(resolver, 330 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 331 mDreamsActivatedOnDockByDefault ? 1 : 0, 332 UserHandle.USER_CURRENT) != 0) ? DREAM_ON_DOCK : DREAM_DISABLED; 333 mWhenToDream = activateWhenCharging + activateWhenDocked; 334 335 mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver, 336 Settings.Secure.SCREENSAVER_ENABLED, 337 mDreamsEnabledByDefaultConfig ? 1 : 0, 338 UserHandle.USER_CURRENT) != 0); 339 } 340 } 341 reportKeepDreamingWhenUndockedChanged(boolean keepDreaming)342 private void reportKeepDreamingWhenUndockedChanged(boolean keepDreaming) { 343 mHandler.post(() -> { 344 for (DreamManagerInternal.DreamManagerStateListener listener 345 : mDreamManagerStateListeners) { 346 listener.onKeepDreamingWhenUndockedChanged(keepDreaming); 347 } 348 }); 349 } 350 351 /** Whether a real dream is occurring. */ isDreamingInternal()352 private boolean isDreamingInternal() { 353 synchronized (mLock) { 354 return mCurrentDream != null && !mCurrentDream.isPreview 355 && !mCurrentDream.isWaking; 356 } 357 } 358 359 /** Whether a doze is occurring. */ isDozingInternal()360 private boolean isDozingInternal() { 361 synchronized (mLock) { 362 return mCurrentDream != null && mCurrentDream.isDozing; 363 } 364 } 365 366 /** Whether a real dream, or a dream preview is occurring. */ isDreamingOrInPreviewInternal()367 private boolean isDreamingOrInPreviewInternal() { 368 synchronized (mLock) { 369 return mCurrentDream != null && !mCurrentDream.isWaking; 370 } 371 } 372 373 /** Whether dreaming can start given user settings and the current dock/charge state. */ canStartDreamingInternal(boolean isScreenOn)374 private boolean canStartDreamingInternal(boolean isScreenOn) { 375 synchronized (mLock) { 376 // Can't start dreaming if we are already dreaming. 377 if (isScreenOn && isDreamingInternal()) { 378 return false; 379 } 380 381 if (!mDreamsEnabledSetting) { 382 return false; 383 } 384 385 if (!dreamsEnabledForUser(ActivityManager.getCurrentUser())) { 386 return false; 387 } 388 389 if (!mUserManager.isUserUnlocked()) { 390 return false; 391 } 392 393 if ((mWhenToDream & DREAM_ON_CHARGE) == DREAM_ON_CHARGE) { 394 return mIsCharging; 395 } 396 397 if ((mWhenToDream & DREAM_ON_DOCK) == DREAM_ON_DOCK) { 398 return mIsDocked; 399 } 400 401 return false; 402 } 403 } 404 requestStartDreamFromShell()405 protected void requestStartDreamFromShell() { 406 requestDreamInternal(); 407 } 408 requestDreamInternal()409 private void requestDreamInternal() { 410 // Ask the power manager to nap. It will eventually call back into 411 // startDream() if/when it is appropriate to start dreaming. 412 // Because napping could cause the screen to turn off immediately if the dream 413 // cannot be started, we keep one eye open and gently poke user activity. 414 long time = SystemClock.uptimeMillis(); 415 mPowerManager.userActivity(time, /* noChangeLights= */ true); 416 mPowerManagerInternal.nap(time, /* allowWake= */ true); 417 } 418 requestAwakenInternal(String reason)419 private void requestAwakenInternal(String reason) { 420 // Treat an explicit request to awaken as user activity so that the 421 // device doesn't immediately go to sleep if the timeout expired, 422 // for example when being undocked. 423 long time = SystemClock.uptimeMillis(); 424 mPowerManager.userActivity(time, false /*noChangeLights*/); 425 stopDreamInternal(false /*immediate*/, reason); 426 } 427 finishSelfInternal(IBinder token, boolean immediate)428 private void finishSelfInternal(IBinder token, boolean immediate) { 429 if (DEBUG) { 430 Slog.d(TAG, "Dream finished: " + token + ", immediate=" + immediate); 431 } 432 433 // Note that a dream finishing and self-terminating is not 434 // itself considered user activity. If the dream is ending because 435 // the user interacted with the device then user activity will already 436 // have been poked so the device will stay awake a bit longer. 437 // If the dream is ending on its own for other reasons and no wake 438 // locks are held and the user activity timeout has expired then the 439 // device may simply go to sleep. 440 synchronized (mLock) { 441 if (mCurrentDream != null && mCurrentDream.token == token) { 442 stopDreamLocked(immediate, "finished self"); 443 } 444 } 445 } 446 testDreamInternal(ComponentName dream, int userId)447 private void testDreamInternal(ComponentName dream, int userId) { 448 synchronized (mLock) { 449 startDreamLocked(dream, true /*isPreviewMode*/, false /*canDoze*/, userId, 450 "test dream" /*reason*/); 451 } 452 } 453 startDreamInternal(boolean doze, String reason)454 private void startDreamInternal(boolean doze, String reason) { 455 final int userId = ActivityManager.getCurrentUser(); 456 final ComponentName dream = chooseDreamForUser(doze, userId); 457 if (dream != null) { 458 synchronized (mLock) { 459 startDreamLocked(dream, false /*isPreviewMode*/, doze, userId, reason); 460 } 461 } 462 } 463 requestStopDreamFromShell()464 protected void requestStopDreamFromShell() { 465 stopDreamInternal(true, "stopping dream from shell"); 466 } 467 stopDreamInternal(boolean immediate, String reason)468 private void stopDreamInternal(boolean immediate, String reason) { 469 synchronized (mLock) { 470 stopDreamLocked(immediate, reason); 471 } 472 } 473 startDozingInternal(IBinder token, int screenState, int screenBrightness)474 private void startDozingInternal(IBinder token, int screenState, 475 int screenBrightness) { 476 if (DEBUG) { 477 Slog.d(TAG, "Dream requested to start dozing: " + token 478 + ", screenState=" + screenState 479 + ", screenBrightness=" + screenBrightness); 480 } 481 482 synchronized (mLock) { 483 if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.canDoze) { 484 mCurrentDream.dozeScreenState = screenState; 485 mCurrentDream.dozeScreenBrightness = screenBrightness; 486 mPowerManagerInternal.setDozeOverrideFromDreamManager( 487 screenState, screenBrightness); 488 if (!mCurrentDream.isDozing) { 489 mCurrentDream.isDozing = true; 490 mDozeWakeLock.acquire(); 491 } 492 } 493 } 494 } 495 stopDozingInternal(IBinder token)496 private void stopDozingInternal(IBinder token) { 497 if (DEBUG) { 498 Slog.d(TAG, "Dream requested to stop dozing: " + token); 499 } 500 501 synchronized (mLock) { 502 if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.isDozing) { 503 mCurrentDream.isDozing = false; 504 mDozeWakeLock.release(); 505 mPowerManagerInternal.setDozeOverrideFromDreamManager( 506 Display.STATE_UNKNOWN, PowerManager.BRIGHTNESS_DEFAULT); 507 } 508 } 509 } 510 forceAmbientDisplayEnabledInternal(boolean enabled)511 private void forceAmbientDisplayEnabledInternal(boolean enabled) { 512 if (DEBUG) { 513 Slog.d(TAG, "Force ambient display enabled: " + enabled); 514 } 515 516 synchronized (mLock) { 517 mForceAmbientDisplayEnabled = enabled; 518 } 519 } 520 521 /** 522 * If doze is true, returns the doze component for the user. 523 * Otherwise, returns the system dream component, if present. 524 * Otherwise, returns the first valid user configured dream component. 525 */ chooseDreamForUser(boolean doze, int userId)526 private ComponentName chooseDreamForUser(boolean doze, int userId) { 527 if (doze) { 528 ComponentName dozeComponent = getDozeComponent(userId); 529 return validateDream(dozeComponent) ? dozeComponent : null; 530 } 531 532 if (mSystemDreamComponent != null) { 533 return mSystemDreamComponent; 534 } 535 536 ComponentName[] dreams = getDreamComponentsForUser(userId); 537 return dreams != null && dreams.length != 0 ? dreams[0] : null; 538 } 539 validateDream(ComponentName component)540 private boolean validateDream(ComponentName component) { 541 if (component == null) return false; 542 final ServiceInfo serviceInfo = getServiceInfo(component); 543 if (serviceInfo == null) { 544 Slog.w(TAG, "Dream " + component + " does not exist"); 545 return false; 546 } else if (serviceInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP 547 && !BIND_DREAM_SERVICE.equals(serviceInfo.permission)) { 548 Slog.w(TAG, "Dream " + component 549 + " is not available because its manifest is missing the " + BIND_DREAM_SERVICE 550 + " permission on the dream service declaration."); 551 return false; 552 } 553 return true; 554 } 555 getDreamComponentsForUser(int userId)556 private ComponentName[] getDreamComponentsForUser(int userId) { 557 if (!dreamsEnabledForUser(userId)) { 558 // Don't return any dream components if the user is not allowed to dream. 559 return null; 560 } 561 562 String names = Settings.Secure.getStringForUser(mContext.getContentResolver(), 563 Settings.Secure.SCREENSAVER_COMPONENTS, 564 userId); 565 ComponentName[] components = componentsFromString(names); 566 567 // first, ensure components point to valid services 568 List<ComponentName> validComponents = new ArrayList<>(); 569 if (components != null) { 570 for (ComponentName component : components) { 571 if (validateDream(component)) { 572 validComponents.add(component); 573 } 574 } 575 } 576 577 // fallback to the default dream component if necessary 578 if (validComponents.isEmpty()) { 579 ComponentName defaultDream = getDefaultDreamComponentForUser(userId); 580 if (defaultDream != null) { 581 Slog.w(TAG, "Falling back to default dream " + defaultDream); 582 validComponents.add(defaultDream); 583 } 584 } 585 return validComponents.toArray(new ComponentName[validComponents.size()]); 586 } 587 setDreamComponentsForUser(int userId, ComponentName[] componentNames)588 private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) { 589 Settings.Secure.putStringForUser(mContext.getContentResolver(), 590 Settings.Secure.SCREENSAVER_COMPONENTS, 591 componentsToString(componentNames), 592 userId); 593 } 594 setSystemDreamComponentInternal(ComponentName componentName)595 private void setSystemDreamComponentInternal(ComponentName componentName) { 596 synchronized (mLock) { 597 if (Objects.equals(mSystemDreamComponent, componentName)) { 598 return; 599 } 600 601 mSystemDreamComponent = componentName; 602 reportKeepDreamingWhenUndockedChanged( 603 mKeepDreamingWhenUndockedDefault && mSystemDreamComponent == null); 604 605 // Switch dream if currently dreaming and not dozing. 606 if (isDreamingInternal() && !isDozingInternal()) { 607 startDreamInternal(false /*doze*/, (mSystemDreamComponent == null ? "clear" : "set") 608 + " system dream component" /*reason*/); 609 } 610 } 611 } 612 getDefaultDreamComponentForUser(int userId)613 private ComponentName getDefaultDreamComponentForUser(int userId) { 614 String name = Settings.Secure.getStringForUser(mContext.getContentResolver(), 615 Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, 616 userId); 617 return name == null ? null : ComponentName.unflattenFromString(name); 618 } 619 getDozeComponent()620 private ComponentName getDozeComponent() { 621 return getDozeComponent(ActivityManager.getCurrentUser()); 622 } 623 getDozeComponent(int userId)624 private ComponentName getDozeComponent(int userId) { 625 if (mForceAmbientDisplayEnabled || mDozeConfig.enabled(userId)) { 626 return ComponentName.unflattenFromString(mDozeConfig.ambientDisplayComponent()); 627 } else { 628 return null; 629 } 630 631 } 632 dreamsEnabledForUser(int userId)633 private boolean dreamsEnabledForUser(int userId) { 634 // TODO(b/257333623): Support non-system Dock Users in HSUM. 635 return !mDreamsOnlyEnabledForDockUser || (userId == UserHandle.USER_SYSTEM); 636 } 637 getServiceInfo(ComponentName name)638 private ServiceInfo getServiceInfo(ComponentName name) { 639 try { 640 return name != null ? mContext.getPackageManager().getServiceInfo(name, 641 PackageManager.MATCH_DEBUG_TRIAGED_MISSING) : null; 642 } catch (NameNotFoundException e) { 643 return null; 644 } 645 } 646 647 @GuardedBy("mLock") startDreamLocked(final ComponentName name, final boolean isPreviewMode, final boolean canDoze, final int userId, final String reason)648 private void startDreamLocked(final ComponentName name, 649 final boolean isPreviewMode, final boolean canDoze, final int userId, 650 final String reason) { 651 if (mCurrentDream != null 652 && !mCurrentDream.isWaking 653 && Objects.equals(mCurrentDream.name, name) 654 && mCurrentDream.isPreview == isPreviewMode 655 && mCurrentDream.canDoze == canDoze 656 && mCurrentDream.userId == userId) { 657 Slog.i(TAG, "Already in target dream."); 658 return; 659 } 660 661 Slog.i(TAG, "Entering dreamland."); 662 663 if (mCurrentDream != null && mCurrentDream.isDozing) { 664 stopDozingInternal(mCurrentDream.token); 665 } 666 667 mCurrentDream = new DreamRecord(name, userId, isPreviewMode, canDoze); 668 669 if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) { 670 // TODO(b/213906448): Remove when metrics based on new atom are fully rolled out. 671 mUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_START); 672 mDreamUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_START, 673 mCurrentDream.name.flattenToString()); 674 } 675 676 PowerManager.WakeLock wakeLock = mPowerManager 677 .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, DREAM_WAKE_LOCK_TAG); 678 final Binder dreamToken = mCurrentDream.token; 679 mHandler.post(wakeLock.wrap(() -> { 680 mAtmInternal.notifyActiveDreamChanged(name); 681 mController.startDream(dreamToken, name, isPreviewMode, canDoze, userId, wakeLock, 682 mDreamOverlayServiceName, reason); 683 })); 684 } 685 686 @GuardedBy("mLock") stopDreamLocked(final boolean immediate, String reason)687 private void stopDreamLocked(final boolean immediate, String reason) { 688 if (mCurrentDream != null) { 689 if (immediate) { 690 Slog.i(TAG, "Leaving dreamland."); 691 cleanupDreamLocked(); 692 } else if (mCurrentDream.isWaking) { 693 return; // already waking 694 } else { 695 Slog.i(TAG, "Gently waking up from dream."); 696 mCurrentDream.isWaking = true; 697 } 698 699 mHandler.post(() -> mController.stopDream(immediate, reason)); 700 } 701 } 702 703 @GuardedBy("mLock") cleanupDreamLocked()704 private void cleanupDreamLocked() { 705 mHandler.post(() -> mAtmInternal.notifyActiveDreamChanged(null)); 706 707 if (mCurrentDream == null) { 708 return; 709 } 710 711 if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) { 712 // TODO(b/213906448): Remove when metrics based on new atom are fully rolled out. 713 mUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_STOP); 714 mDreamUiEventLogger.log(DreamUiEventLogger.DreamUiEventEnum.DREAM_STOP, 715 mCurrentDream.name.flattenToString()); 716 } 717 if (mCurrentDream.isDozing) { 718 mDozeWakeLock.release(); 719 } 720 mCurrentDream = null; 721 } 722 checkPermission(String permission)723 private void checkPermission(String permission) { 724 if (mContext.checkCallingOrSelfPermission(permission) 725 != PackageManager.PERMISSION_GRANTED) { 726 throw new SecurityException("Access denied to process: " + Binder.getCallingPid() 727 + ", must have permission " + permission); 728 } 729 } 730 writePulseGestureEnabled()731 private void writePulseGestureEnabled() { 732 ComponentName name = getDozeComponent(); 733 boolean dozeEnabled = validateDream(name); 734 LocalServices.getService(InputManagerInternal.class).setPulseGestureEnabled(dozeEnabled); 735 } 736 componentsToString(ComponentName[] componentNames)737 private static String componentsToString(ComponentName[] componentNames) { 738 if (componentNames == null) { 739 return null; 740 } 741 StringBuilder names = new StringBuilder(); 742 for (ComponentName componentName : componentNames) { 743 if (names.length() > 0) { 744 names.append(','); 745 } 746 names.append(componentName.flattenToString()); 747 } 748 return names.toString(); 749 } 750 componentsFromString(String names)751 private static ComponentName[] componentsFromString(String names) { 752 if (names == null) { 753 return null; 754 } 755 String[] namesArray = names.split(","); 756 ComponentName[] componentNames = new ComponentName[namesArray.length]; 757 for (int i = 0; i < namesArray.length; i++) { 758 componentNames[i] = ComponentName.unflattenFromString(namesArray[i]); 759 } 760 return componentNames; 761 } 762 763 private final DreamController.Listener mControllerListener = new DreamController.Listener() { 764 @Override 765 public void onDreamStopped(Binder token) { 766 synchronized (mLock) { 767 if (mCurrentDream != null && mCurrentDream.token == token) { 768 cleanupDreamLocked(); 769 } 770 } 771 } 772 }; 773 774 private final ContentObserver mDozeEnabledObserver = new ContentObserver(null) { 775 @Override 776 public void onChange(boolean selfChange) { 777 writePulseGestureEnabled(); 778 } 779 }; 780 781 /** 782 * Handler for asynchronous operations performed by the dream manager. 783 * Ensures operations to {@link DreamController} are single-threaded. 784 */ 785 private static final class DreamHandler extends Handler { DreamHandler(Looper looper)786 public DreamHandler(Looper looper) { 787 super(looper, null, true /*async*/); 788 } 789 } 790 791 private final class BinderService extends IDreamManager.Stub { 792 @Override // Binder call dump(FileDescriptor fd, PrintWriter pw, String[] args)793 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 794 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 795 final long ident = Binder.clearCallingIdentity(); 796 try { 797 dumpInternal(pw); 798 } finally { 799 Binder.restoreCallingIdentity(ident); 800 } 801 } 802 onShellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)803 public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, 804 @Nullable FileDescriptor err, 805 @NonNull String[] args, @Nullable ShellCallback callback, 806 @NonNull ResultReceiver resultReceiver) throws RemoteException { 807 new DreamShellCommand(DreamManagerService.this) 808 .exec(this, in, out, err, args, callback, resultReceiver); 809 } 810 811 @Override // Binder call getDreamComponents()812 public ComponentName[] getDreamComponents() { 813 return getDreamComponentsForUser(UserHandle.getCallingUserId()); 814 } 815 816 @Override // Binder call getDreamComponentsForUser(int userId)817 public ComponentName[] getDreamComponentsForUser(int userId) { 818 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 819 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 820 Binder.getCallingUid(), userId, false, true, "getDreamComponents", null); 821 822 final long ident = Binder.clearCallingIdentity(); 823 try { 824 return DreamManagerService.this.getDreamComponentsForUser(userId); 825 } finally { 826 Binder.restoreCallingIdentity(ident); 827 } 828 } 829 830 @Override // Binder call setDreamComponents(ComponentName[] componentNames)831 public void setDreamComponents(ComponentName[] componentNames) { 832 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 833 834 final int userId = UserHandle.getCallingUserId(); 835 final long ident = Binder.clearCallingIdentity(); 836 try { 837 setDreamComponentsForUser(userId, componentNames); 838 } finally { 839 Binder.restoreCallingIdentity(ident); 840 } 841 } 842 843 @Override // Binder call setDreamComponentsForUser(int userId, ComponentName[] componentNames)844 public void setDreamComponentsForUser(int userId, ComponentName[] componentNames) { 845 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 846 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 847 Binder.getCallingUid(), userId, false, true, "setDreamComponents", null); 848 849 final long ident = Binder.clearCallingIdentity(); 850 try { 851 DreamManagerService.this.setDreamComponentsForUser(userId, componentNames); 852 } finally { 853 Binder.restoreCallingIdentity(ident); 854 } 855 } 856 857 @Override // Binder call setSystemDreamComponent(ComponentName componentName)858 public void setSystemDreamComponent(ComponentName componentName) { 859 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 860 861 final long ident = Binder.clearCallingIdentity(); 862 try { 863 DreamManagerService.this.setSystemDreamComponentInternal(componentName); 864 } finally { 865 Binder.restoreCallingIdentity(ident); 866 } 867 } 868 869 @Override // Binder call registerDreamOverlayService(ComponentName overlayComponent)870 public void registerDreamOverlayService(ComponentName overlayComponent) { 871 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 872 873 // Store the overlay service component so that it can be passed to the dream when it is 874 // invoked. 875 mDreamOverlayServiceName = overlayComponent; 876 } 877 878 @Override // Binder call getDefaultDreamComponentForUser(int userId)879 public ComponentName getDefaultDreamComponentForUser(int userId) { 880 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 881 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 882 Binder.getCallingUid(), userId, false, true, "getDefaultDreamComponent", null); 883 884 final long ident = Binder.clearCallingIdentity(); 885 try { 886 return DreamManagerService.this.getDefaultDreamComponentForUser(userId); 887 } finally { 888 Binder.restoreCallingIdentity(ident); 889 } 890 } 891 892 @Override // Binder call isDreaming()893 public boolean isDreaming() { 894 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 895 896 final long ident = Binder.clearCallingIdentity(); 897 try { 898 return isDreamingInternal(); 899 } finally { 900 Binder.restoreCallingIdentity(ident); 901 } 902 } 903 904 @Override // Binder call isDreamingOrInPreview()905 public boolean isDreamingOrInPreview() { 906 checkPermission(android.Manifest.permission.READ_DREAM_STATE); 907 908 final long ident = Binder.clearCallingIdentity(); 909 try { 910 return isDreamingOrInPreviewInternal(); 911 } finally { 912 Binder.restoreCallingIdentity(ident); 913 } 914 } 915 916 917 @Override // Binder call dream()918 public void dream() { 919 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 920 921 final long ident = Binder.clearCallingIdentity(); 922 try { 923 requestDreamInternal(); 924 } finally { 925 Binder.restoreCallingIdentity(ident); 926 } 927 } 928 929 @Override // Binder call testDream(int userId, ComponentName dream)930 public void testDream(int userId, ComponentName dream) { 931 if (dream == null) { 932 throw new IllegalArgumentException("dream must not be null"); 933 } 934 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 935 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 936 Binder.getCallingUid(), userId, false, true, "testDream", null); 937 938 final int currentUserId = ActivityManager.getCurrentUser(); 939 if (userId != currentUserId) { 940 // This check is inherently prone to races but at least it's something. 941 Slog.w(TAG, "Aborted attempt to start a test dream while a different " 942 + " user is active: userId=" + userId 943 + ", currentUserId=" + currentUserId); 944 return; 945 } 946 final long ident = Binder.clearCallingIdentity(); 947 try { 948 testDreamInternal(dream, userId); 949 } finally { 950 Binder.restoreCallingIdentity(ident); 951 } 952 } 953 954 @Override // Binder call awaken()955 public void awaken() { 956 checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); 957 958 final long ident = Binder.clearCallingIdentity(); 959 try { 960 requestAwakenInternal("request awaken"); 961 } finally { 962 Binder.restoreCallingIdentity(ident); 963 } 964 } 965 966 @Override // Binder call finishSelf(IBinder token, boolean immediate)967 public void finishSelf(IBinder token, boolean immediate) { 968 // Requires no permission, called by Dream from an arbitrary process. 969 if (token == null) { 970 throw new IllegalArgumentException("token must not be null"); 971 } 972 973 final long ident = Binder.clearCallingIdentity(); 974 try { 975 finishSelfInternal(token, immediate); 976 } finally { 977 Binder.restoreCallingIdentity(ident); 978 } 979 } 980 981 @Override // Binder call startDozing(IBinder token, int screenState, int screenBrightness)982 public void startDozing(IBinder token, int screenState, int screenBrightness) { 983 // Requires no permission, called by Dream from an arbitrary process. 984 if (token == null) { 985 throw new IllegalArgumentException("token must not be null"); 986 } 987 988 final long ident = Binder.clearCallingIdentity(); 989 try { 990 startDozingInternal(token, screenState, screenBrightness); 991 } finally { 992 Binder.restoreCallingIdentity(ident); 993 } 994 } 995 996 @Override // Binder call stopDozing(IBinder token)997 public void stopDozing(IBinder token) { 998 // Requires no permission, called by Dream from an arbitrary process. 999 if (token == null) { 1000 throw new IllegalArgumentException("token must not be null"); 1001 } 1002 1003 final long ident = Binder.clearCallingIdentity(); 1004 try { 1005 stopDozingInternal(token); 1006 } finally { 1007 Binder.restoreCallingIdentity(ident); 1008 } 1009 } 1010 1011 @Override // Binder call forceAmbientDisplayEnabled(boolean enabled)1012 public void forceAmbientDisplayEnabled(boolean enabled) { 1013 checkPermission(android.Manifest.permission.DEVICE_POWER); 1014 1015 final long ident = Binder.clearCallingIdentity(); 1016 try { 1017 forceAmbientDisplayEnabledInternal(enabled); 1018 } finally { 1019 Binder.restoreCallingIdentity(ident); 1020 } 1021 } 1022 } 1023 1024 private final class LocalService extends DreamManagerInternal { 1025 @Override startDream(boolean doze, String reason)1026 public void startDream(boolean doze, String reason) { 1027 startDreamInternal(doze, reason); 1028 } 1029 1030 @Override stopDream(boolean immediate, String reason)1031 public void stopDream(boolean immediate, String reason) { 1032 stopDreamInternal(immediate, reason); 1033 } 1034 1035 @Override isDreaming()1036 public boolean isDreaming() { 1037 return isDreamingInternal(); 1038 } 1039 1040 @Override canStartDreaming(boolean isScreenOn)1041 public boolean canStartDreaming(boolean isScreenOn) { 1042 return canStartDreamingInternal(isScreenOn); 1043 } 1044 1045 @Override requestDream()1046 public void requestDream() { 1047 requestDreamInternal(); 1048 } 1049 1050 @Override keepDreamingWhenUndockedDefault()1051 public boolean keepDreamingWhenUndockedDefault() { 1052 // This value does not change, so a lock should not be needed. 1053 return mKeepDreamingWhenUndockedDefault; 1054 } 1055 1056 @Override registerDreamManagerStateListener(DreamManagerStateListener listener)1057 public void registerDreamManagerStateListener(DreamManagerStateListener listener) { 1058 mDreamManagerStateListeners.add(listener); 1059 } 1060 1061 @Override unregisterDreamManagerStateListener(DreamManagerStateListener listener)1062 public void unregisterDreamManagerStateListener(DreamManagerStateListener listener) { 1063 mDreamManagerStateListeners.remove(listener); 1064 } 1065 } 1066 1067 private static final class DreamRecord { 1068 public final Binder token = new Binder(); 1069 public final ComponentName name; 1070 public final int userId; 1071 public final boolean isPreview; 1072 public final boolean canDoze; 1073 public boolean isDozing = false; 1074 public boolean isWaking = false; 1075 public int dozeScreenState = Display.STATE_UNKNOWN; 1076 public int dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; 1077 DreamRecord(ComponentName name, int userId, boolean isPreview, boolean canDoze)1078 DreamRecord(ComponentName name, int userId, boolean isPreview, boolean canDoze) { 1079 this.name = name; 1080 this.userId = userId; 1081 this.isPreview = isPreview; 1082 this.canDoze = canDoze; 1083 } 1084 1085 @Override toString()1086 public String toString() { 1087 return "DreamRecord{" 1088 + "token=" + token 1089 + ", name=" + name 1090 + ", userId=" + userId 1091 + ", isPreview=" + isPreview 1092 + ", canDoze=" + canDoze 1093 + ", isDozing=" + isDozing 1094 + ", isWaking=" + isWaking 1095 + ", dozeScreenState=" + dozeScreenState 1096 + ", dozeScreenBrightness=" + dozeScreenBrightness 1097 + '}'; 1098 } 1099 } 1100 1101 private final Runnable mSystemPropertiesChanged = new Runnable() { 1102 @Override 1103 public void run() { 1104 if (DEBUG) Slog.d(TAG, "System properties changed"); 1105 synchronized (mLock) { 1106 if (mCurrentDream != null && mCurrentDream.name != null && mCurrentDream.canDoze 1107 && !mCurrentDream.name.equals(getDozeComponent())) { 1108 // May have updated the doze component, wake up 1109 mPowerManager.wakeUp(SystemClock.uptimeMillis(), 1110 "android.server.dreams:SYSPROP"); 1111 } 1112 } 1113 } 1114 }; 1115 } 1116