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