1 /* 2 * Copyright (C) 2021 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.power; 18 19 import static android.os.PowerManager.SCREEN_TIMEOUT_KEEP_DISPLAY_ON; 20 import static android.os.PowerManager.SCREEN_TIMEOUT_ACTIVE; 21 import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; 22 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; 23 import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; 24 import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; 25 import static android.os.PowerManagerInternal.isInteractive; 26 27 import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN; 28 import static com.android.server.power.PowerManagerService.TRACE_SCREEN_ON; 29 import static com.android.server.power.PowerManagerService.USER_ACTIVITY_SCREEN_BRIGHT; 30 import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE; 31 import static com.android.server.power.PowerManagerService.WAKE_LOCK_DRAW; 32 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT; 33 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM; 34 import static com.android.server.power.PowerManagerService.WAKE_LOCK_STAY_AWAKE; 35 36 import android.hardware.display.DisplayManagerInternal; 37 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; 38 import android.os.PowerManager; 39 import android.os.PowerManager.ScreenTimeoutPolicy; 40 import android.os.PowerManagerInternal; 41 import android.os.PowerSaveState; 42 import android.os.Trace; 43 import android.util.Slog; 44 import android.view.Display; 45 46 import com.android.internal.annotations.VisibleForTesting; 47 import com.android.internal.util.LatencyTracker; 48 import com.android.server.LocalServices; 49 import com.android.server.companion.virtual.VirtualDeviceManagerInternal; 50 import com.android.server.power.feature.PowerManagerFlags; 51 52 /** 53 * Used to store power related requests to every display in a 54 * {@link com.android.server.display.DisplayGroup}. 55 * For each {@link com.android.server.display.DisplayGroup} there exists a {@link PowerGroup}. 56 * The mapping is tracked in {@link PowerManagerService}. 57 * <p><b>Note:</b> Methods with the {@code *Locked} suffix require the 58 * {@code PowerManagerService#mLock} to be held by the caller. 59 */ 60 public class PowerGroup { 61 private static final String TAG = PowerGroup.class.getSimpleName(); 62 private static final boolean DEBUG = false; 63 64 /** 65 * Indicates that the default dim/sleep timeouts should be used. 66 */ 67 private static final long INVALID_TIMEOUT = -1; 68 69 @VisibleForTesting 70 final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest(); 71 private final PowerGroupListener mWakefulnessListener; 72 private final Notifier mNotifier; 73 private final DisplayManagerInternal mDisplayManagerInternal; 74 private final boolean mSupportsSandman; 75 private final int mGroupId; 76 private final PowerManagerFlags mFeatureFlags; 77 78 /** True if DisplayManagerService has applied all the latest display states that were requested 79 * for this group. */ 80 private boolean mReady; 81 /** True if this group is in the process of powering on */ 82 private boolean mPoweringOn; 83 /** True if this group is about to dream */ 84 private boolean mIsSandmanSummoned; 85 private int mUserActivitySummary; 86 /** The current wakefulness of this group */ 87 private int mWakefulness; 88 private int mWakeLockSummary; 89 private long mLastPowerOnTime; 90 private long mLastUserActivityTime; 91 private long mLastUserActivityTimeNoChangeLights; 92 @PowerManager.UserActivityEvent 93 private int mLastUserActivityEvent; 94 /** Timestamp (milliseconds since boot) of the last time the power group was awoken.*/ 95 private long mLastWakeTime; 96 /** Timestamp (milliseconds since boot) of the last time the power group was put to sleep. */ 97 private long mLastSleepTime; 98 /** The last reason that woke the power group. */ 99 private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN; 100 /** The last reason that put the power group to sleep. */ 101 private @PowerManager.GoToSleepReason int mLastSleepReason = 102 PowerManager.GO_TO_SLEEP_REASON_UNKNOWN; 103 104 private final long mDimDuration; 105 private final long mScreenOffTimeout; 106 PowerGroup(int groupId, PowerGroupListener wakefulnessListener, Notifier notifier, DisplayManagerInternal displayManagerInternal, int wakefulness, boolean ready, boolean supportsSandman, long eventTime, PowerManagerFlags featureFlags)107 PowerGroup(int groupId, PowerGroupListener wakefulnessListener, Notifier notifier, 108 DisplayManagerInternal displayManagerInternal, int wakefulness, boolean ready, 109 boolean supportsSandman, long eventTime, PowerManagerFlags featureFlags) { 110 mGroupId = groupId; 111 mWakefulnessListener = wakefulnessListener; 112 mNotifier = notifier; 113 mDisplayManagerInternal = displayManagerInternal; 114 mWakefulness = wakefulness; 115 mReady = ready; 116 mSupportsSandman = supportsSandman; 117 mLastWakeTime = eventTime; 118 mLastSleepTime = eventTime; 119 mFeatureFlags = featureFlags; 120 121 long dimDuration = INVALID_TIMEOUT; 122 long screenOffTimeout = INVALID_TIMEOUT; 123 if (android.companion.virtualdevice.flags.Flags.deviceAwareDisplayPower() 124 && mGroupId != Display.DEFAULT_DISPLAY_GROUP) { 125 VirtualDeviceManagerInternal vdm = 126 LocalServices.getService(VirtualDeviceManagerInternal.class); 127 if (vdm != null) { 128 int[] displayIds = mDisplayManagerInternal.getDisplayIdsForGroup(mGroupId); 129 if (displayIds != null && displayIds.length > 0) { 130 int deviceId = vdm.getDeviceIdForDisplayId(displayIds[0]); 131 if (vdm.isValidVirtualDeviceId(deviceId)) { 132 dimDuration = vdm.getDimDurationMillisForDeviceId(deviceId); 133 screenOffTimeout = vdm.getScreenOffTimeoutMillisForDeviceId(deviceId); 134 if (dimDuration > 0 && dimDuration > screenOffTimeout) { 135 // If the dim duration is set, cap it to the screen off timeout. 136 dimDuration = screenOffTimeout; 137 } 138 } 139 } 140 } 141 } 142 mDimDuration = dimDuration; 143 mScreenOffTimeout = screenOffTimeout; 144 } 145 PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, Notifier notifier, DisplayManagerInternal displayManagerInternal, long eventTime, PowerManagerFlags featureFlags)146 PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, Notifier notifier, 147 DisplayManagerInternal displayManagerInternal, long eventTime, 148 PowerManagerFlags featureFlags) { 149 mGroupId = Display.DEFAULT_DISPLAY_GROUP; 150 mWakefulnessListener = wakefulnessListener; 151 mNotifier = notifier; 152 mDisplayManagerInternal = displayManagerInternal; 153 mWakefulness = wakefulness; 154 mReady = false; 155 mSupportsSandman = true; 156 mLastWakeTime = eventTime; 157 mLastSleepTime = eventTime; 158 mFeatureFlags = featureFlags; 159 mDimDuration = INVALID_TIMEOUT; 160 mScreenOffTimeout = INVALID_TIMEOUT; 161 } 162 getScreenOffTimeoutOverrideLocked(long defaultScreenOffTimeout)163 long getScreenOffTimeoutOverrideLocked(long defaultScreenOffTimeout) { 164 return mScreenOffTimeout == INVALID_TIMEOUT ? defaultScreenOffTimeout : mScreenOffTimeout; 165 } 166 getScreenDimDurationOverrideLocked(long defaultScreenDimDuration)167 long getScreenDimDurationOverrideLocked(long defaultScreenDimDuration) { 168 return mDimDuration == INVALID_TIMEOUT ? defaultScreenDimDuration : mDimDuration; 169 } 170 getLastWakeTimeLocked()171 long getLastWakeTimeLocked() { 172 return mLastWakeTime; 173 } 174 getLastSleepTimeLocked()175 long getLastSleepTimeLocked() { 176 return mLastSleepTime; 177 } 178 getWakefulnessLocked()179 int getWakefulnessLocked() { 180 return mWakefulness; 181 } 182 getGroupId()183 int getGroupId() { 184 return mGroupId; 185 } 186 187 /** 188 * Sets the {@code wakefulness} value for this {@link PowerGroup}. 189 * 190 * @return {@code true} if the wakefulness value was changed; {@code false} otherwise. 191 */ setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid, String opPackageName, String details)192 boolean setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid, 193 String opPackageName, String details) { 194 if (mWakefulness != newWakefulness) { 195 if (newWakefulness == WAKEFULNESS_AWAKE) { 196 setLastPowerOnTimeLocked(eventTime); 197 setIsPoweringOnLocked(true); 198 mLastWakeTime = eventTime; 199 if (mFeatureFlags.isPolicyReasonInDisplayPowerRequestEnabled()) { 200 mLastWakeReason = reason; 201 } 202 } else if (isInteractive(mWakefulness) && !isInteractive(newWakefulness)) { 203 mLastSleepTime = eventTime; 204 if (mFeatureFlags.isPolicyReasonInDisplayPowerRequestEnabled()) { 205 mLastSleepReason = reason; 206 } 207 } 208 mWakefulness = newWakefulness; 209 mWakefulnessListener.onWakefulnessChangedLocked(mGroupId, mWakefulness, eventTime, 210 reason, uid, opUid, opPackageName, details); 211 return true; 212 } 213 return false; 214 } 215 216 /** 217 * Returns {@code true} if every display in this group has its requested state matching 218 * its actual state. 219 */ isReadyLocked()220 boolean isReadyLocked() { 221 return mReady; 222 } 223 224 /** 225 * Sets whether the displays of this group are all ready. 226 * 227 * <p>A display is ready if its reported 228 * {@link android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged() 229 * actual state} matches its 230 * {@link android.hardware.display.DisplayManagerInternal#requestPowerState requested state}. 231 * 232 * @param isReady {@code true} if every display in the group is ready; otherwise {@code false}. 233 * @return {@code true} if the ready state changed; otherwise {@code false}. 234 */ setReadyLocked(boolean isReady)235 boolean setReadyLocked(boolean isReady) { 236 if (mReady != isReady) { 237 mReady = isReady; 238 return true; 239 } 240 return false; 241 } 242 getLastPowerOnTimeLocked()243 long getLastPowerOnTimeLocked() { 244 return mLastPowerOnTime; 245 } 246 setLastPowerOnTimeLocked(long time)247 void setLastPowerOnTimeLocked(long time) { 248 mLastPowerOnTime = time; 249 } 250 isPoweringOnLocked()251 boolean isPoweringOnLocked() { 252 return mPoweringOn; 253 } 254 setIsPoweringOnLocked(boolean isPoweringOnNew)255 void setIsPoweringOnLocked(boolean isPoweringOnNew) { 256 mPoweringOn = isPoweringOnNew; 257 } 258 isSandmanSummonedLocked()259 boolean isSandmanSummonedLocked() { 260 return mIsSandmanSummoned; 261 } 262 263 /** 264 * Sets whether or not the sandman is summoned for this {@link PowerGroup}. 265 * 266 * @param isSandmanSummoned {@code true} to summon the sandman; {@code false} to unsummon. 267 */ setSandmanSummonedLocked(boolean isSandmanSummoned)268 void setSandmanSummonedLocked(boolean isSandmanSummoned) { 269 mIsSandmanSummoned = isSandmanSummoned; 270 } 271 wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid, String opPackageName, int opUid, LatencyTracker latencyTracker)272 void wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid, 273 String opPackageName, int opUid, LatencyTracker latencyTracker) { 274 if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE) { 275 return; 276 } 277 278 Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakePowerGroup" + mGroupId); 279 try { 280 Slog.i(TAG, "Waking up power group from " 281 + PowerManagerInternal.wakefulnessToString(mWakefulness) 282 + " (groupId=" + mGroupId 283 + ", uid=" + uid 284 + ", reason=" + PowerManager.wakeReasonToString(reason) 285 + ", details=" + details 286 + ")..."); 287 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, mGroupId); 288 // The instrument will be timed out automatically after 2 seconds. 289 latencyTracker.onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(mGroupId)); 290 291 setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid, 292 opPackageName, details); 293 } finally { 294 Trace.traceEnd(Trace.TRACE_TAG_POWER); 295 } 296 } 297 dreamLocked(long eventTime, int uid, boolean allowWake)298 boolean dreamLocked(long eventTime, int uid, boolean allowWake) { 299 if (eventTime < mLastWakeTime || (!allowWake && mWakefulness != WAKEFULNESS_AWAKE)) { 300 return false; 301 } 302 303 Trace.traceBegin(Trace.TRACE_TAG_POWER, "dreamPowerGroup" + getGroupId()); 304 try { 305 Slog.i(TAG, "Napping power group (groupId=" + getGroupId() + ", uid=" + uid + ")..."); 306 setSandmanSummonedLocked(true); 307 setWakefulnessLocked(WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */0, 308 /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null); 309 } finally { 310 Trace.traceEnd(Trace.TRACE_TAG_POWER); 311 } 312 return true; 313 } 314 dozeLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason)315 boolean dozeLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason) { 316 if (eventTime < getLastWakeTimeLocked() || !isInteractive(mWakefulness)) { 317 return false; 318 } 319 320 Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay"); 321 try { 322 reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX, 323 Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN)); 324 long millisSinceLastUserActivity = eventTime - Math.max( 325 mLastUserActivityTimeNoChangeLights, mLastUserActivityTime); 326 Slog.i(TAG, "Powering off display group due to " 327 + PowerManager.sleepReasonToString(reason) 328 + " (groupId= " + getGroupId() + ", uid= " + uid 329 + ", millisSinceLastUserActivity=" + millisSinceLastUserActivity 330 + ", lastUserActivityEvent=" + PowerManager.userActivityEventToString( 331 mLastUserActivityEvent) + ")..."); 332 333 setSandmanSummonedLocked(/* isSandmanSummoned= */ true); 334 setWakefulnessLocked(WAKEFULNESS_DOZING, eventTime, uid, reason, /* opUid= */ 0, 335 /* opPackageName= */ null, /* details= */ null); 336 } finally { 337 Trace.traceEnd(Trace.TRACE_TAG_POWER); 338 } 339 return true; 340 } 341 sleepLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason)342 boolean sleepLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason) { 343 if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) { 344 return false; 345 } 346 347 Trace.traceBegin(Trace.TRACE_TAG_POWER, "sleepPowerGroup"); 348 try { 349 Slog.i(TAG, 350 "Sleeping power group (groupId=" + getGroupId() + ", uid=" + uid + ", reason=" 351 + PowerManager.sleepReasonToString(reason) + ")..."); 352 setSandmanSummonedLocked(/* isSandmanSummoned= */ true); 353 setWakefulnessLocked(WAKEFULNESS_ASLEEP, eventTime, uid, reason, /* opUid= */0, 354 /* opPackageName= */ null, /* details= */ null); 355 } finally { 356 Trace.traceEnd(Trace.TRACE_TAG_POWER); 357 } 358 return true; 359 } 360 getLastUserActivityTimeLocked()361 long getLastUserActivityTimeLocked() { 362 return mLastUserActivityTime; 363 } 364 setLastUserActivityTimeLocked(long lastUserActivityTime, @PowerManager.UserActivityEvent int event)365 void setLastUserActivityTimeLocked(long lastUserActivityTime, 366 @PowerManager.UserActivityEvent int event) { 367 mLastUserActivityTime = lastUserActivityTime; 368 mLastUserActivityEvent = event; 369 } 370 getLastUserActivityTimeNoChangeLightsLocked()371 public long getLastUserActivityTimeNoChangeLightsLocked() { 372 return mLastUserActivityTimeNoChangeLights; 373 } 374 setLastUserActivityTimeNoChangeLightsLocked(long time, @PowerManager.UserActivityEvent int event)375 public void setLastUserActivityTimeNoChangeLightsLocked(long time, 376 @PowerManager.UserActivityEvent int event) { 377 mLastUserActivityTimeNoChangeLights = time; 378 mLastUserActivityEvent = event; 379 } 380 getUserActivitySummaryLocked()381 public int getUserActivitySummaryLocked() { 382 return mUserActivitySummary; 383 } 384 isPolicyBrightLocked()385 public boolean isPolicyBrightLocked() { 386 return mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT; 387 } 388 isPolicyDimLocked()389 public boolean isPolicyDimLocked() { 390 return mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM; 391 } 392 isBrightOrDimLocked()393 public boolean isBrightOrDimLocked() { 394 return mDisplayPowerRequest.isBrightOrDim(); 395 } 396 setUserActivitySummaryLocked(int summary)397 public void setUserActivitySummaryLocked(int summary) { 398 mUserActivitySummary = summary; 399 } 400 getWakeLockSummaryLocked()401 public int getWakeLockSummaryLocked() { 402 return mWakeLockSummary; 403 } 404 405 /** 406 * Query whether a wake lock is at least partially responsible for keeping the device awake. 407 * 408 * This does not necessarily mean the wake lock is the sole reason the device is awake; there 409 * could also be user activity keeping the device awake, for example. It just means a wake lock 410 * is being held that would keep the device awake even if nothing else was. 411 * 412 * @return whether the PowerGroup is being kept awake at least in part because a wake lock is 413 * being held. 414 */ hasWakeLockKeepingScreenOnLocked()415 public boolean hasWakeLockKeepingScreenOnLocked() { 416 final int screenOnWakeLockMask = 417 WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM | WAKE_LOCK_STAY_AWAKE; 418 return (mWakeLockSummary & (screenOnWakeLockMask)) != 0; 419 } 420 421 @ScreenTimeoutPolicy getScreenTimeoutPolicy()422 public int getScreenTimeoutPolicy() { 423 return hasWakeLockKeepingScreenOnLocked() ? SCREEN_TIMEOUT_KEEP_DISPLAY_ON 424 : SCREEN_TIMEOUT_ACTIVE; 425 } 426 setWakeLockSummaryLocked(int summary)427 public void setWakeLockSummaryLocked(int summary) { 428 mWakeLockSummary = summary; 429 } 430 431 /** 432 * Whether or not this DisplayGroup supports dreaming. 433 * @return {@code true} if this DisplayGroup supports dreaming; otherwise {@code false}. 434 */ supportsSandmanLocked()435 public boolean supportsSandmanLocked() { 436 return mSupportsSandman; 437 } 438 439 /** 440 * Return true if we must keep a suspend blocker active on behalf of a power group. 441 * We do so if the screen is on or is in transition between states. 442 */ needSuspendBlockerLocked(boolean proximityPositive, boolean suspendWhenScreenOffDueToProximityConfig)443 boolean needSuspendBlockerLocked(boolean proximityPositive, 444 boolean suspendWhenScreenOffDueToProximityConfig) { 445 if (isBrightOrDimLocked()) { 446 // If we asked for the screen to be on but it is off due to the proximity 447 // sensor then we may suspend but only if the configuration allows it. 448 // On some hardware it may not be safe to suspend because the proximity 449 // sensor may not be correctly configured as a wake-up source. 450 if (!mDisplayPowerRequest.useProximitySensor || !proximityPositive 451 || !suspendWhenScreenOffDueToProximityConfig) { 452 return true; 453 } 454 } 455 456 if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE 457 && mDisplayPowerRequest.dozeScreenState == Display.STATE_ON) { 458 // Although we are in DOZE and would normally allow the device to suspend, 459 // the doze service has explicitly requested the display to remain in the ON 460 // state which means we should hold the display suspend blocker. 461 return true; 462 } 463 return false; 464 } 465 466 // TODO: create and use more specific policy reasons, beyond the ones that correlate to 467 // interactivity state updateScreenPolicyLocked(boolean quiescent, boolean dozeAfterScreenOff, boolean bootCompleted, boolean screenBrightnessBoostInProgress, boolean brightWhenDozing)468 private void updateScreenPolicyLocked(boolean quiescent, boolean dozeAfterScreenOff, 469 boolean bootCompleted, boolean screenBrightnessBoostInProgress, 470 boolean brightWhenDozing) { 471 final int wakefulness = getWakefulnessLocked(); 472 final int wakeLockSummary = getWakeLockSummaryLocked(); 473 int policyReason = Display.STATE_REASON_DEFAULT_POLICY; 474 int policy = Integer.MAX_VALUE; // do not set to real policy to start with. 475 if (quiescent) { 476 policy = DisplayPowerRequest.POLICY_OFF; 477 } else if (wakefulness == WAKEFULNESS_ASLEEP) { 478 policy = DisplayPowerRequest.POLICY_OFF; 479 policyReason = sleepReasonToDisplayStateReason(mLastSleepReason); 480 } else if (wakefulness == WAKEFULNESS_DOZING) { 481 if ((wakeLockSummary & WAKE_LOCK_DOZE) != 0) { 482 policy = DisplayPowerRequest.POLICY_DOZE; 483 } else if (dozeAfterScreenOff) { 484 policy = DisplayPowerRequest.POLICY_OFF; 485 } else if (brightWhenDozing) { 486 policy = DisplayPowerRequest.POLICY_BRIGHT; 487 } 488 // Fall through and preserve the current screen policy if not configured to 489 // bright when dozing or doze after screen off. This causes the screen off transition 490 // to be skipped. 491 } 492 493 if (policy == Integer.MAX_VALUE) { // policy is not set yet. 494 if (isInteractive(wakefulness)) { 495 policyReason = wakeReasonToDisplayStateReason(mLastWakeReason); 496 } 497 if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0 498 || !bootCompleted 499 || (getUserActivitySummaryLocked() & USER_ACTIVITY_SCREEN_BRIGHT) != 0 500 || screenBrightnessBoostInProgress) { 501 policy = DisplayPowerRequest.POLICY_BRIGHT; 502 } else { 503 policy = DisplayPowerRequest.POLICY_DIM; 504 } 505 } 506 507 if (mFeatureFlags.isPolicyReasonInDisplayPowerRequestEnabled()) { 508 mDisplayPowerRequest.policyReason = policyReason; 509 } 510 mDisplayPowerRequest.policy = policy; 511 } 512 getPolicyLocked()513 int getPolicyLocked() { 514 return mDisplayPowerRequest.policy; 515 } 516 updateLocked(float screenBrightnessOverride, CharSequence overrideTag, boolean useProximitySensor, boolean boostScreenBrightness, int dozeScreenState, @Display.StateReason int dozeScreenStateReason, float dozeScreenBrightness, boolean useNormalBrightnessForDoze, boolean overrideDrawWakeLock, PowerSaveState powerSaverState, boolean quiescent, boolean dozeAfterScreenOff, boolean bootCompleted, boolean screenBrightnessBoostInProgress, boolean waitForNegativeProximity, boolean brightWhenDozing)517 boolean updateLocked(float screenBrightnessOverride, CharSequence overrideTag, 518 boolean useProximitySensor, boolean boostScreenBrightness, int dozeScreenState, 519 @Display.StateReason int dozeScreenStateReason, 520 float dozeScreenBrightness, boolean useNormalBrightnessForDoze, 521 boolean overrideDrawWakeLock, 522 PowerSaveState powerSaverState, boolean quiescent, 523 boolean dozeAfterScreenOff, boolean bootCompleted, 524 boolean screenBrightnessBoostInProgress, boolean waitForNegativeProximity, 525 boolean brightWhenDozing) { 526 updateScreenPolicyLocked(quiescent, dozeAfterScreenOff, 527 bootCompleted, screenBrightnessBoostInProgress, brightWhenDozing); 528 mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride; 529 mDisplayPowerRequest.screenBrightnessOverrideTag = overrideTag; 530 mDisplayPowerRequest.useProximitySensor = useProximitySensor; 531 mDisplayPowerRequest.boostScreenBrightness = boostScreenBrightness; 532 533 if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { 534 mDisplayPowerRequest.dozeScreenState = dozeScreenState; 535 mDisplayPowerRequest.dozeScreenStateReason = dozeScreenStateReason; 536 if ((getWakeLockSummaryLocked() & WAKE_LOCK_DRAW) != 0 && !overrideDrawWakeLock) { 537 if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) { 538 mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE; 539 mDisplayPowerRequest.dozeScreenStateReason = 540 Display.STATE_REASON_DRAW_WAKE_LOCK; 541 } 542 if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) { 543 mDisplayPowerRequest.dozeScreenState = Display.STATE_ON; 544 mDisplayPowerRequest.dozeScreenStateReason = 545 Display.STATE_REASON_DRAW_WAKE_LOCK; 546 } 547 } 548 mDisplayPowerRequest.dozeScreenBrightness = dozeScreenBrightness; 549 mDisplayPowerRequest.useNormalBrightnessForDoze = useNormalBrightnessForDoze; 550 } else { 551 mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN; 552 mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; 553 mDisplayPowerRequest.dozeScreenStateReason = 554 Display.STATE_REASON_DEFAULT_POLICY; 555 mDisplayPowerRequest.useNormalBrightnessForDoze = false; 556 } 557 mDisplayPowerRequest.lowPowerMode = powerSaverState.batterySaverEnabled; 558 mDisplayPowerRequest.screenLowPowerBrightnessFactor = powerSaverState.brightnessFactor; 559 boolean ready = mDisplayManagerInternal.requestPowerState(mGroupId, mDisplayPowerRequest, 560 waitForNegativeProximity); 561 mNotifier.onScreenPolicyUpdate(mGroupId, mDisplayPowerRequest.policy); 562 return ready; 563 } 564 565 /** Determines the respective display state reason for a given PowerManager WakeReason. */ wakeReasonToDisplayStateReason(@owerManager.WakeReason int wakeReason)566 private static int wakeReasonToDisplayStateReason(@PowerManager.WakeReason int wakeReason) { 567 switch (wakeReason) { 568 case PowerManager.WAKE_REASON_POWER_BUTTON: 569 case PowerManager.WAKE_REASON_WAKE_KEY: 570 return Display.STATE_REASON_KEY; 571 case PowerManager.WAKE_REASON_WAKE_MOTION: 572 return Display.STATE_REASON_MOTION; 573 case PowerManager.WAKE_REASON_TILT: 574 return Display.STATE_REASON_TILT; 575 default: 576 return Display.STATE_REASON_DEFAULT_POLICY; 577 } 578 } 579 580 /** Determines the respective display state reason for a given PowerManager GoToSleepReason. */ sleepReasonToDisplayStateReason( @owerManager.GoToSleepReason int sleepReason)581 private static int sleepReasonToDisplayStateReason( 582 @PowerManager.GoToSleepReason int sleepReason) { 583 switch (sleepReason) { 584 case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON: 585 case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON: 586 return Display.STATE_REASON_KEY; 587 default: 588 return Display.STATE_REASON_DEFAULT_POLICY; 589 } 590 } 591 592 protected interface PowerGroupListener { 593 /** 594 * Informs the recipient about a wakefulness change of a {@link PowerGroup}. 595 * 596 * @param groupId The PowerGroup's id for which the wakefulness has changed. 597 * @param wakefulness The new wakefulness. 598 * @param eventTime The time of the event. 599 * @param reason The reason, any of {@link android.os.PowerManager.WakeReason} or 600 * {@link android.os.PowerManager.GoToSleepReason}. 601 * @param uid The uid which caused the wakefulness change. 602 * @param opUid The uid used for AppOps. 603 * @param opPackageName The Package name used for AppOps. 604 * @param details Details about the event. 605 */ onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, int reason, int uid, int opUid, String opPackageName, String details)606 void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, int reason, 607 int uid, int opUid, String opPackageName, String details); 608 } 609 } 610