1 /* 2 * Copyright (C) 2022 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.display; 18 19 import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE; 20 21 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT; 22 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE; 23 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; 24 import static com.android.server.display.config.DisplayBrightnessMappingConfig.autoBrightnessPresetToString; 25 26 import android.animation.Animator; 27 import android.animation.ObjectAnimator; 28 import android.annotation.Nullable; 29 import android.annotation.SuppressLint; 30 import android.annotation.UserIdInt; 31 import android.app.ActivityManager; 32 import android.content.Context; 33 import android.content.pm.ParceledListSlice; 34 import android.content.res.Resources; 35 import android.database.ContentObserver; 36 import android.hardware.Sensor; 37 import android.hardware.SensorManager; 38 import android.hardware.display.AmbientBrightnessDayStats; 39 import android.hardware.display.BrightnessChangeEvent; 40 import android.hardware.display.BrightnessConfiguration; 41 import android.hardware.display.BrightnessInfo; 42 import android.hardware.display.DisplayManagerInternal.DisplayOffloadSession; 43 import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; 44 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; 45 import android.metrics.LogMaker; 46 import android.net.Uri; 47 import android.os.Handler; 48 import android.os.HandlerExecutor; 49 import android.os.IBinder; 50 import android.os.Looper; 51 import android.os.Message; 52 import android.os.PowerManager; 53 import android.os.RemoteException; 54 import android.os.SystemClock; 55 import android.os.SystemProperties; 56 import android.os.Trace; 57 import android.os.UserHandle; 58 import android.provider.Settings; 59 import android.util.FloatProperty; 60 import android.util.IndentingPrintWriter; 61 import android.util.MathUtils; 62 import android.util.MutableFloat; 63 import android.util.MutableInt; 64 import android.util.Pair; 65 import android.util.Slog; 66 import android.util.SparseArray; 67 import android.view.Display; 68 69 import com.android.internal.R; 70 import com.android.internal.annotations.GuardedBy; 71 import com.android.internal.annotations.VisibleForTesting; 72 import com.android.internal.app.IBatteryStats; 73 import com.android.internal.display.BrightnessSynchronizer; 74 import com.android.internal.logging.MetricsLogger; 75 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 76 import com.android.internal.util.FrameworkStatsLog; 77 import com.android.internal.util.RingBuffer; 78 import com.android.server.LocalServices; 79 import com.android.server.am.BatteryStatsService; 80 import com.android.server.display.RampAnimator.DualRampAnimator; 81 import com.android.server.display.brightness.BrightnessEvent; 82 import com.android.server.display.brightness.BrightnessReason; 83 import com.android.server.display.brightness.BrightnessUtils; 84 import com.android.server.display.brightness.DisplayBrightnessController; 85 import com.android.server.display.brightness.clamper.BrightnessClamperController; 86 import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2; 87 import com.android.server.display.brightness.strategy.DisplayBrightnessStrategyConstants; 88 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal; 89 import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener; 90 import com.android.server.display.config.HysteresisLevels; 91 import com.android.server.display.feature.DisplayManagerFlags; 92 import com.android.server.display.layout.Layout; 93 import com.android.server.display.state.DisplayStateController; 94 import com.android.server.display.utils.DebugUtils; 95 import com.android.server.display.utils.SensorUtils; 96 import com.android.server.display.whitebalance.DisplayWhiteBalanceController; 97 import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory; 98 import com.android.server.display.whitebalance.DisplayWhiteBalanceSettings; 99 import com.android.server.policy.WindowManagerPolicy; 100 101 import java.io.PrintWriter; 102 import java.util.Objects; 103 104 /** 105 * Controls the power state of the display. 106 * 107 * Handles the proximity sensor, light sensor, and animations between states 108 * including the screen off animation. 109 * 110 * This component acts independently of the rest of the power manager service. 111 * In particular, it does not share any state and it only communicates 112 * via asynchronous callbacks to inform the power manager that something has 113 * changed. 114 * 115 * Everything this class does internally is serialized on its handler although 116 * it may be accessed by other threads from the outside. 117 * 118 * Note that the power manager service guarantees that it will hold a suspend 119 * blocker as long as the display is not ready. So most of the work done here 120 * does not need to worry about holding a suspend blocker unless it happens 121 * independently of the display ready signal. 122 * 123 * For debugging, you can make the color fade and brightness animations run 124 * slower by changing the "animator duration scale" option in Development Settings. 125 */ 126 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks, 127 DisplayWhiteBalanceController.Callbacks, DisplayPowerControllerInterface { 128 private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked"; 129 private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked"; 130 131 private static final String TAG = "DisplayPowerController2"; 132 // To enable these logs, run: 133 // 'adb shell setprop persist.log.tag.DisplayPowerController2 DEBUG && adb reboot' 134 private static final boolean DEBUG = DebugUtils.isDebuggable(TAG); 135 private static final String SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME = 136 "Screen on blocked by displayoffload"; 137 138 // If true, uses the color fade on animation. 139 // We might want to turn this off if we cannot get a guarantee that the screen 140 // actually turns on and starts showing new content after the call to set the 141 // screen state returns. Playing the animation can also be somewhat slow. 142 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false; 143 144 private static final float SCREEN_ANIMATION_RATE_MINIMUM = 0.0f; 145 146 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250; 147 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400; 148 149 private static final int MSG_UPDATE_POWER_STATE = 1; 150 private static final int MSG_SCREEN_ON_UNBLOCKED = 2; 151 private static final int MSG_SCREEN_OFF_UNBLOCKED = 3; 152 private static final int MSG_CONFIGURE_BRIGHTNESS = 4; 153 private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 5; 154 private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 6; 155 private static final int MSG_STOP = 7; 156 private static final int MSG_UPDATE_BRIGHTNESS = 8; 157 private static final int MSG_UPDATE_RBC = 9; 158 private static final int MSG_BRIGHTNESS_RAMP_DONE = 10; 159 private static final int MSG_STATSD_HBM_BRIGHTNESS = 11; 160 private static final int MSG_SWITCH_USER = 12; 161 private static final int MSG_BOOT_COMPLETED = 13; 162 private static final int MSG_SWITCH_AUTOBRIGHTNESS_MODE = 14; 163 private static final int MSG_SET_DWBC_COLOR_OVERRIDE = 15; 164 private static final int MSG_SET_DWBC_LOGGING_ENABLED = 16; 165 private static final int MSG_SET_BRIGHTNESS_FROM_OFFLOAD = 17; 166 private static final int MSG_OFFLOADING_SCREEN_ON_UNBLOCKED = 18; 167 168 169 170 private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500; 171 172 173 // State machine constants for tracking initial brightness ramp skipping when enabled. 174 private static final int RAMP_STATE_SKIP_NONE = 0; 175 private static final int RAMP_STATE_SKIP_INITIAL = 1; 176 private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2; 177 178 private static final int REPORTED_TO_POLICY_UNREPORTED = -1; 179 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0; 180 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1; 181 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2; 182 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3; 183 184 private static final int RINGBUFFER_MAX = 100; 185 private static final int RINGBUFFER_RBC_MAX = 20; 186 187 private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = { 188 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 189 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 190 1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000}; 191 private static final int[] BRIGHTNESS_RANGE_INDEX = { 192 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN, 193 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1, 194 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1_2, 195 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2_3, 196 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3_4, 197 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_4_5, 198 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_5_6, 199 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_6_7, 200 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_7_8, 201 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_8_9, 202 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_9_10, 203 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_10_20, 204 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_20_30, 205 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_30_40, 206 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_40_50, 207 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_50_60, 208 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_60_70, 209 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_70_80, 210 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_80_90, 211 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_90_100, 212 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_100_200, 213 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_200_300, 214 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_300_400, 215 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_400_500, 216 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_500_600, 217 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_600_700, 218 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_700_800, 219 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_800_900, 220 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_900_1000, 221 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1000_1200, 222 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1200_1400, 223 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1400_1600, 224 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1600_1800, 225 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1800_2000, 226 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2000_2250, 227 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2250_2500, 228 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2500_2750, 229 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2750_3000, 230 }; 231 232 private final String mTag; 233 234 private final Object mLock = new Object(); 235 236 private final Context mContext; 237 238 // Our handler. 239 private final DisplayControllerHandler mHandler; 240 241 // Battery stats. 242 @Nullable 243 private final IBatteryStats mBatteryStats; 244 245 // The sensor manager. 246 private final SensorManager mSensorManager; 247 248 // The window manager policy. 249 private final WindowManagerPolicy mWindowManagerPolicy; 250 251 // The display blanker. 252 private final DisplayBlanker mBlanker; 253 254 // The LogicalDisplay tied to this DisplayPowerController2. 255 private final LogicalDisplay mLogicalDisplay; 256 257 // The ID of the LogicalDisplay tied to this DisplayPowerController2. 258 private final int mDisplayId; 259 260 // The ID of the display which this display follows for brightness purposes. 261 private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY; 262 263 // The unique ID of the primary display device currently tied to this logical display 264 private String mUniqueDisplayId; 265 266 // Tracker for brightness changes. 267 @Nullable 268 private final BrightnessTracker mBrightnessTracker; 269 270 // Tracker for brightness settings changes. 271 private final SettingsObserver mSettingsObserver; 272 273 // The doze screen brightness. 274 private final float mScreenBrightnessDozeConfig; 275 276 // True if auto-brightness should be used. 277 private boolean mUseSoftwareAutoBrightnessConfig; 278 279 // Whether or not the color fade on screen on / off is enabled. 280 private final boolean mColorFadeEnabled; 281 282 @GuardedBy("mCachedBrightnessInfo") 283 private final CachedBrightnessInfo mCachedBrightnessInfo = new CachedBrightnessInfo(); 284 285 private DisplayDevice mDisplayDevice; 286 287 // True if we should fade the screen while turning it off, false if we should play 288 // a stylish color fade animation instead. 289 private final boolean mColorFadeFadesConfig; 290 291 // True if we need to fake a transition to off when coming out of a doze state. 292 // Some display hardware will blank itself when coming out of doze in order to hide 293 // artifacts. For these displays we fake a transition into OFF so that policy can appropriately 294 // blank itself and begin an appropriate power on animation. 295 private final boolean mDisplayBlanksAfterDozeConfig; 296 297 // True if there are only buckets of brightness values when the display is in the doze state, 298 // rather than a full range of values. If this is true, then we'll avoid animating the screen 299 // brightness since it'd likely be multiple jarring brightness transitions instead of just one 300 // to reach the final state. 301 private final boolean mBrightnessBucketsInDozeConfig; 302 303 private final Clock mClock; 304 private final Injector mInjector; 305 306 // Maximum time a ramp animation can take. 307 private long mBrightnessRampIncreaseMaxTimeMillis; 308 private long mBrightnessRampDecreaseMaxTimeMillis; 309 310 // Maximum time a ramp animation can take in idle mode. 311 private long mBrightnessRampIncreaseMaxTimeIdleMillis; 312 private long mBrightnessRampDecreaseMaxTimeIdleMillis; 313 314 // The pending power request. 315 // Initially null until the first call to requestPowerState. 316 @GuardedBy("mLock") 317 private DisplayPowerRequest mPendingRequestLocked; 318 319 // True if the pending power request or wait for negative proximity flag 320 // has been changed since the last update occurred. 321 @GuardedBy("mLock") 322 private boolean mPendingRequestChangedLocked; 323 324 // Set to true when the important parts of the pending power request have been applied. 325 // The important parts are mainly the screen state. Brightness changes may occur 326 // concurrently. 327 @GuardedBy("mLock") 328 private boolean mDisplayReadyLocked; 329 330 // Set to true if a power state update is required. 331 @GuardedBy("mLock") 332 private boolean mPendingUpdatePowerStateLocked; 333 334 /* The following state must only be accessed by the handler thread. */ 335 336 // The currently requested power state. 337 // The power controller will progressively update its internal state to match 338 // the requested power state. Initially null until the first update. 339 private DisplayPowerRequest mPowerRequest; 340 341 // The current power state. 342 // Must only be accessed on the handler thread. 343 private DisplayPowerState mPowerState; 344 345 346 347 // The currently active screen on unblocker. This field is non-null whenever 348 // we are waiting for a callback to release it and unblock the screen. 349 private ScreenOnUnblocker mPendingScreenOnUnblocker; 350 private ScreenOffUnblocker mPendingScreenOffUnblocker; 351 private Runnable mPendingScreenOnUnblockerByDisplayOffload; 352 353 // True if we were in the process of turning off the screen. 354 // This allows us to recover more gracefully from situations where we abort 355 // turning off the screen. 356 private boolean mPendingScreenOff; 357 358 // The elapsed real time when the screen on was blocked. 359 private long mScreenOnBlockStartRealTime; 360 private long mScreenOffBlockStartRealTime; 361 private long mScreenOnBlockByDisplayOffloadStartRealTime; 362 363 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields. 364 private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED; 365 366 // Used to deduplicate the displayoffload blocking screen on logic. One block per turning on. 367 // This value is reset when screen on is reported or the blocking is cancelled. 368 private boolean mScreenTurningOnWasBlockedByDisplayOffload; 369 370 // If the last recorded screen state was dozing or not. 371 private boolean mDozing; 372 373 private boolean mAppliedDimming; 374 375 private boolean mAppliedThrottling; 376 377 // Reason for which the brightness was last changed. See {@link BrightnessReason} for more 378 // information. 379 // At the time of this writing, this value is changed within updatePowerState() only, which is 380 // limited to the thread used by DisplayControllerHandler. 381 @VisibleForTesting 382 final BrightnessReason mBrightnessReason = new BrightnessReason(); 383 private final BrightnessReason mBrightnessReasonTemp = new BrightnessReason(); 384 385 // Brightness animation ramp rates in brightness units per second 386 private float mBrightnessRampRateFastDecrease; 387 private float mBrightnessRampRateFastIncrease; 388 private float mBrightnessRampRateSlowDecrease; 389 private float mBrightnessRampRateSlowIncrease; 390 private float mBrightnessRampRateSlowDecreaseIdle; 391 private float mBrightnessRampRateSlowIncreaseIdle; 392 393 // Report HBM brightness change to StatsD 394 private int mDisplayStatsId; 395 private float mLastStatsBrightness = PowerManager.BRIGHTNESS_MIN; 396 397 // Whether or not to skip the initial brightness ramps into STATE_ON. 398 private final boolean mSkipScreenOnBrightnessRamp; 399 400 // Display white balance components. 401 // Critical methods must be called on DPC2 handler thread. 402 @Nullable 403 private final DisplayWhiteBalanceSettings mDisplayWhiteBalanceSettings; 404 @Nullable 405 private final DisplayWhiteBalanceController mDisplayWhiteBalanceController; 406 407 @Nullable 408 private final ColorDisplayServiceInternal mCdsi; 409 private float[] mNitsRange; 410 411 private final BrightnessRangeController mBrightnessRangeController; 412 413 private final BrightnessThrottler mBrightnessThrottler; 414 415 private final BrightnessClamperController mBrightnessClamperController; 416 417 private final Runnable mOnBrightnessChangeRunnable; 418 419 private final BrightnessEvent mLastBrightnessEvent; 420 private final BrightnessEvent mTempBrightnessEvent; 421 422 private final DisplayBrightnessController mDisplayBrightnessController; 423 424 // Keeps a record of brightness changes for dumpsys. 425 private RingBuffer<BrightnessEvent> mBrightnessEventRingBuffer; 426 427 // Keeps a record of rbc changes for dumpsys. 428 private final RingBuffer<BrightnessEvent> mRbcEventRingBuffer = 429 new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_RBC_MAX); 430 431 // Controls and tracks all the wakelocks that are acquired/released by the system. Also acts as 432 // a medium of communication between this class and the PowerManagerService. 433 private final WakelockController mWakelockController; 434 435 // Tracks and manages the proximity state of the associated display. 436 private final DisplayPowerProximityStateController mDisplayPowerProximityStateController; 437 438 // Tracks and manages the display state of the associated display. 439 private final DisplayStateController mDisplayStateController; 440 441 442 // Responsible for evaluating and tracking the automatic brightness relevant states. 443 // Todo: This is a temporary workaround. Ideally DPC2 should never talk to the strategies 444 private final AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy; 445 446 // A record of state for skipping brightness ramps. 447 private int mSkipRampState = RAMP_STATE_SKIP_NONE; 448 449 // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL. 450 private float mInitialAutoBrightness; 451 452 // The controller for the automatic brightness level. 453 @Nullable 454 private AutomaticBrightnessController mAutomaticBrightnessController; 455 456 // The controller for the sensor used to estimate ambient lux while the display is off. 457 @Nullable 458 private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController; 459 460 private Sensor mLightSensor; 461 private Sensor mScreenOffBrightnessSensor; 462 463 private boolean mIsRbcActive; 464 465 // Animators. 466 private ObjectAnimator mColorFadeOnAnimator; 467 private ObjectAnimator mColorFadeOffAnimator; 468 private DualRampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; 469 470 // True if this DisplayPowerController2 has been stopped and should no longer be running. 471 private boolean mStopped; 472 473 private DisplayDeviceConfig mDisplayDeviceConfig; 474 475 private boolean mIsEnabled; 476 private boolean mIsInTransition; 477 private boolean mIsDisplayInternal; 478 479 // The id of the thermal brightness throttling policy that should be used. 480 private String mThermalBrightnessThrottlingDataId; 481 482 // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there 483 // is one lead display, the additional displays follow the brightness value of the lead display. 484 @GuardedBy("mLock") 485 private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers = 486 new SparseArray(); 487 488 private boolean mBootCompleted; 489 private final DisplayManagerFlags mFlags; 490 491 private DisplayOffloadSession mDisplayOffloadSession; 492 493 // Used to scale the brightness in doze mode 494 private float mDozeScaleFactor; 495 496 /** 497 * Creates the display power controller. 498 */ DisplayPowerController(Context context, Injector injector, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata, boolean bootCompleted, DisplayManagerFlags flags)499 DisplayPowerController(Context context, Injector injector, 500 DisplayPowerCallbacks callbacks, Handler handler, 501 SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, 502 BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, 503 Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata, 504 boolean bootCompleted, DisplayManagerFlags flags) { 505 mFlags = flags; 506 mInjector = injector != null ? injector : new Injector(); 507 mClock = mInjector.getClock(); 508 mLogicalDisplay = logicalDisplay; 509 mDisplayId = mLogicalDisplay.getDisplayIdLocked(); 510 mSensorManager = sensorManager; 511 mHandler = new DisplayControllerHandler(handler.getLooper()); 512 mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked() 513 .getDisplayDeviceConfig(); 514 mIsEnabled = logicalDisplay.isEnabledLocked(); 515 mIsInTransition = logicalDisplay.isInTransitionLocked(); 516 mIsDisplayInternal = logicalDisplay.getPrimaryDisplayDeviceLocked() 517 .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL; 518 mWakelockController = mInjector.getWakelockController(mDisplayId, callbacks); 519 mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController( 520 mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(), 521 () -> updatePowerState(), mDisplayId, mSensorManager); 522 mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController); 523 mTag = TAG + "[" + mDisplayId + "]"; 524 mThermalBrightnessThrottlingDataId = 525 logicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId; 526 mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); 527 mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); 528 mDisplayStatsId = mUniqueDisplayId.hashCode(); 529 530 mLastBrightnessEvent = new BrightnessEvent(mDisplayId); 531 mTempBrightnessEvent = new BrightnessEvent(mDisplayId); 532 533 if (mDisplayId == Display.DEFAULT_DISPLAY) { 534 mBatteryStats = BatteryStatsService.getService(); 535 } else { 536 mBatteryStats = null; 537 } 538 539 mSettingsObserver = new SettingsObserver(mHandler); 540 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class); 541 mBlanker = blanker; 542 mContext = context; 543 mBrightnessTracker = brightnessTracker; 544 mOnBrightnessChangeRunnable = onBrightnessChangeRunnable; 545 546 PowerManager pm = context.getSystemService(PowerManager.class); 547 548 final Resources resources = context.getResources(); 549 550 // DOZE AND DIM SETTINGS 551 mScreenBrightnessDozeConfig = BrightnessUtils.clampAbsoluteBrightness( 552 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)); 553 loadBrightnessRampRates(); 554 mSkipScreenOnBrightnessRamp = resources.getBoolean( 555 R.bool.config_skipScreenOnBrightnessRamp); 556 mDozeScaleFactor = context.getResources().getFraction( 557 R.fraction.config_screenAutoBrightnessDozeScaleFactor, 558 1, 1); 559 560 Runnable modeChangeCallback = () -> { 561 sendUpdatePowerState(); 562 postBrightnessChangeRunnable(); 563 // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern. 564 if (mAutomaticBrightnessController != null) { 565 mAutomaticBrightnessController.update(); 566 } 567 }; 568 569 HighBrightnessModeController hbmController = createHbmControllerLocked(hbmMetadata, 570 modeChangeCallback); 571 mBrightnessThrottler = createBrightnessThrottlerLocked(); 572 573 mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController, 574 modeChangeCallback, mDisplayDeviceConfig, mHandler, flags, 575 mDisplayDevice.getDisplayTokenLocked(), 576 mDisplayDevice.getDisplayDeviceInfoLocked()); 577 578 mDisplayBrightnessController = 579 new DisplayBrightnessController(context, null, 580 mDisplayId, mLogicalDisplay.getDisplayInfoLocked().brightnessDefault, 581 brightnessSetting, () -> postBrightnessChangeRunnable(), 582 new HandlerExecutor(mHandler), flags); 583 584 mBrightnessClamperController = mInjector.getBrightnessClamperController( 585 mHandler, modeChangeCallback::run, 586 new BrightnessClamperController.DisplayDeviceData( 587 mUniqueDisplayId, 588 mThermalBrightnessThrottlingDataId, 589 logicalDisplay.getPowerThrottlingDataIdLocked(), 590 mDisplayDeviceConfig), mContext, flags, mSensorManager); 591 // Seed the cached brightness 592 saveBrightnessInfo(getScreenBrightnessSetting()); 593 mAutomaticBrightnessStrategy = 594 mDisplayBrightnessController.getAutomaticBrightnessStrategy(); 595 596 DisplayWhiteBalanceSettings displayWhiteBalanceSettings = null; 597 DisplayWhiteBalanceController displayWhiteBalanceController = null; 598 if (mDisplayId == Display.DEFAULT_DISPLAY) { 599 try { 600 displayWhiteBalanceController = mInjector.getDisplayWhiteBalanceController( 601 mHandler, mSensorManager, resources); 602 displayWhiteBalanceSettings = new DisplayWhiteBalanceSettings(mContext, mHandler); 603 displayWhiteBalanceSettings.setCallbacks(this); 604 displayWhiteBalanceController.setCallbacks(this); 605 } catch (Exception e) { 606 Slog.e(mTag, "failed to set up display white-balance: " + e); 607 } 608 } 609 mDisplayWhiteBalanceSettings = displayWhiteBalanceSettings; 610 mDisplayWhiteBalanceController = displayWhiteBalanceController; 611 612 loadNitsRange(resources); 613 614 if (mDisplayId == Display.DEFAULT_DISPLAY) { 615 mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class); 616 if (mCdsi != null) { 617 boolean active = mCdsi.setReduceBrightColorsListener( 618 new ReduceBrightColorsListener() { 619 @Override 620 public void onReduceBrightColorsActivationChanged(boolean activated, 621 boolean userInitiated) { 622 applyReduceBrightColorsSplineAdjustment(); 623 624 } 625 626 @Override 627 public void onReduceBrightColorsStrengthChanged(int strength) { 628 applyReduceBrightColorsSplineAdjustment(); 629 } 630 }); 631 if (active) { 632 applyReduceBrightColorsSplineAdjustment(); 633 } 634 } 635 } else { 636 mCdsi = null; 637 } 638 639 setUpAutoBrightness(context, handler); 640 641 mColorFadeEnabled = mInjector.isColorFadeEnabled() 642 && !resources.getBoolean( 643 com.android.internal.R.bool.config_displayColorFadeDisabled); 644 mColorFadeFadesConfig = resources.getBoolean( 645 R.bool.config_animateScreenLights); 646 647 mDisplayBlanksAfterDozeConfig = resources.getBoolean( 648 R.bool.config_displayBlanksAfterDoze); 649 650 mBrightnessBucketsInDozeConfig = resources.getBoolean( 651 R.bool.config_displayBrightnessBucketsInDoze); 652 653 mBootCompleted = bootCompleted; 654 } 655 applyReduceBrightColorsSplineAdjustment()656 private void applyReduceBrightColorsSplineAdjustment() { 657 mHandler.obtainMessage(MSG_UPDATE_RBC).sendToTarget(); 658 sendUpdatePowerState(); 659 } 660 handleRbcChanged()661 private void handleRbcChanged() { 662 if (mAutomaticBrightnessController == null) { 663 return; 664 } 665 666 float[] adjustedNits = new float[mNitsRange.length]; 667 for (int i = 0; i < mNitsRange.length; i++) { 668 adjustedNits[i] = mCdsi.getReduceBrightColorsAdjustedBrightnessNits(mNitsRange[i]); 669 } 670 mIsRbcActive = mCdsi.isReduceBrightColorsActivated(); 671 mAutomaticBrightnessController.recalculateSplines(mIsRbcActive, adjustedNits); 672 } 673 674 /** 675 * Returns true if the proximity sensor screen-off function is available. 676 */ 677 @Override isProximitySensorAvailable()678 public boolean isProximitySensorAvailable() { 679 return mDisplayPowerProximityStateController.isProximitySensorAvailable(); 680 } 681 682 /** 683 * Get the {@link BrightnessChangeEvent}s for the specified user. 684 * 685 * @param userId userId to fetch data for 686 * @param includePackage if false will null out the package name in events 687 */ 688 @Nullable 689 @Override getBrightnessEvents( @serIdInt int userId, boolean includePackage)690 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents( 691 @UserIdInt int userId, boolean includePackage) { 692 if (mBrightnessTracker == null) { 693 return null; 694 } 695 return mBrightnessTracker.getEvents(userId, includePackage); 696 } 697 698 @Override onSwitchUser(@serIdInt int newUserId, int userSerial, float newBrightness)699 public void onSwitchUser(@UserIdInt int newUserId, int userSerial, float newBrightness) { 700 Message msg = mHandler.obtainMessage(MSG_SWITCH_USER, newUserId, userSerial, newBrightness); 701 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 702 } 703 handleOnSwitchUser(@serIdInt int newUserId, int userSerial, float newBrightness)704 private void handleOnSwitchUser(@UserIdInt int newUserId, int userSerial, float newBrightness) { 705 Slog.i(mTag, "Switching user newUserId=" + newUserId + " userSerial=" + userSerial 706 + " newBrightness=" + newBrightness); 707 handleBrightnessModeChange(); 708 if (mBrightnessTracker != null) { 709 mBrightnessTracker.onSwitchUser(newUserId); 710 } 711 setBrightness(newBrightness, userSerial); 712 713 // Don't treat user switches as user initiated change. 714 mDisplayBrightnessController.setAndNotifyCurrentScreenBrightness(newBrightness); 715 716 if (mAutomaticBrightnessController != null) { 717 mAutomaticBrightnessController.resetShortTermModel(); 718 } 719 sendUpdatePowerState(); 720 } 721 722 @Nullable 723 @Override getAmbientBrightnessStats( @serIdInt int userId)724 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats( 725 @UserIdInt int userId) { 726 if (mBrightnessTracker == null) { 727 return null; 728 } 729 return mBrightnessTracker.getAmbientBrightnessStats(userId); 730 } 731 732 /** 733 * Persist the brightness slider events and ambient brightness stats to disk. 734 */ 735 @Override persistBrightnessTrackerState()736 public void persistBrightnessTrackerState() { 737 if (mBrightnessTracker != null) { 738 mBrightnessTracker.persistBrightnessTrackerState(); 739 } 740 } 741 742 /** 743 * Requests a new power state. 744 * The controller makes a copy of the provided object and then 745 * begins adjusting the power state to match what was requested. 746 * 747 * @param request The requested power state. 748 * @param waitForNegativeProximity If true, issues a request to wait for 749 * negative proximity before turning the screen back on, 750 * assuming the screen 751 * was turned off by the proximity sensor. 752 * @return True if display is ready, false if there are important changes that must 753 * be made asynchronously (such as turning the screen on), in which case the caller 754 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()} 755 * then try the request again later until the state converges. 756 */ requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)757 public boolean requestPowerState(DisplayPowerRequest request, 758 boolean waitForNegativeProximity) { 759 if (DEBUG) { 760 Slog.d(mTag, "requestPowerState: " 761 + request + ", waitForNegativeProximity=" + waitForNegativeProximity); 762 } 763 764 synchronized (mLock) { 765 if (mStopped) { 766 return true; 767 } 768 769 boolean changed = mDisplayPowerProximityStateController 770 .setPendingWaitForNegativeProximityLocked(waitForNegativeProximity); 771 772 if (mPendingRequestLocked == null) { 773 mPendingRequestLocked = new DisplayPowerRequest(request); 774 changed = true; 775 } else if (!mPendingRequestLocked.equals(request)) { 776 mPendingRequestLocked.copyFrom(request); 777 changed = true; 778 } 779 780 if (changed) { 781 mDisplayReadyLocked = false; 782 if (!mPendingRequestChangedLocked) { 783 mPendingRequestChangedLocked = true; 784 sendUpdatePowerStateLocked(); 785 } 786 } 787 788 return mDisplayReadyLocked; 789 } 790 } 791 792 @Override overrideDozeScreenState(int displayState, @Display.StateReason int reason)793 public void overrideDozeScreenState(int displayState, @Display.StateReason int reason) { 794 Slog.i(TAG, "New offload doze override: " + Display.stateToString(displayState)); 795 mHandler.postAtTime(() -> { 796 if (mDisplayOffloadSession == null 797 || !(DisplayOffloadSession.isSupportedOffloadState(displayState) 798 || displayState == Display.STATE_UNKNOWN)) { 799 return; 800 } 801 mDisplayStateController.overrideDozeScreenState(displayState, reason); 802 updatePowerState(); 803 }, mClock.uptimeMillis()); 804 } 805 806 @Override setDisplayOffloadSession(DisplayOffloadSession session)807 public void setDisplayOffloadSession(DisplayOffloadSession session) { 808 if (session == mDisplayOffloadSession) { 809 return; 810 } 811 unblockScreenOnByDisplayOffload(); 812 mDisplayOffloadSession = session; 813 } 814 815 @Override getDefaultBrightnessConfiguration()816 public BrightnessConfiguration getDefaultBrightnessConfiguration() { 817 if (mAutomaticBrightnessController == null) { 818 return null; 819 } 820 return mAutomaticBrightnessController.getDefaultConfig(); 821 } 822 823 /** 824 * Notified when the display is changed. We use this to apply any changes that might be needed 825 * when displays get swapped on foldable devices. For example, different brightness properties 826 * of each display need to be properly reflected in AutomaticBrightnessController. 827 * 828 * Make sure DisplayManagerService.mSyncRoot lock is held when this is called 829 */ 830 @Override onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId)831 public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) { 832 mLeadDisplayId = leadDisplayId; 833 final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); 834 if (device == null) { 835 Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: " 836 + mLogicalDisplay.getDisplayIdLocked()); 837 return; 838 } 839 840 final String uniqueId = device.getUniqueId(); 841 final DisplayDeviceConfig config = device.getDisplayDeviceConfig(); 842 final IBinder token = device.getDisplayTokenLocked(); 843 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 844 final boolean isEnabled = mLogicalDisplay.isEnabledLocked(); 845 final boolean isInTransition = mLogicalDisplay.isInTransitionLocked(); 846 final boolean isDisplayInternal = mLogicalDisplay.getPrimaryDisplayDeviceLocked() != null 847 && mLogicalDisplay.getPrimaryDisplayDeviceLocked() 848 .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL; 849 final String thermalBrightnessThrottlingDataId = 850 mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId; 851 final String powerThrottlingDataId = 852 mLogicalDisplay.getPowerThrottlingDataIdLocked(); 853 854 mHandler.postAtTime(() -> { 855 boolean changed = false; 856 857 if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) { 858 changed = true; 859 mIsEnabled = isEnabled; 860 mIsInTransition = isInTransition; 861 } 862 863 if (mDisplayDevice != device) { 864 changed = true; 865 mDisplayDevice = device; 866 mUniqueDisplayId = uniqueId; 867 mDisplayStatsId = mUniqueDisplayId.hashCode(); 868 mDisplayDeviceConfig = config; 869 mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId; 870 loadFromDisplayDeviceConfig(token, info, hbmMetadata); 871 mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config); 872 873 // Since the underlying display-device changed, we really don't know the 874 // last command that was sent to change it's state. Let's assume it is unknown so 875 // that we trigger a change immediately. 876 mPowerState.resetScreenState(); 877 } else if (!Objects.equals(mThermalBrightnessThrottlingDataId, 878 thermalBrightnessThrottlingDataId)) { 879 changed = true; 880 mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId; 881 mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( 882 config.getThermalBrightnessThrottlingDataMapByThrottlingId(), 883 config.getTempSensor(), 884 mThermalBrightnessThrottlingDataId, 885 mUniqueDisplayId); 886 } 887 888 mIsDisplayInternal = isDisplayInternal; 889 // using local variables here, when mBrightnessThrottler is removed, 890 // mThermalBrightnessThrottlingDataId could be removed as well 891 // changed = true will be not needed - clampers are maintaining their state and 892 // will call updatePowerState if needed. 893 mBrightnessClamperController.onDisplayChanged( 894 new BrightnessClamperController.DisplayDeviceData(uniqueId, 895 thermalBrightnessThrottlingDataId, powerThrottlingDataId, config)); 896 897 if (changed) { 898 updatePowerState(); 899 } 900 }, mClock.uptimeMillis()); 901 } 902 903 /** 904 * Unregisters all listeners and interrupts all running threads; halting future work. 905 * 906 * This method should be called when the DisplayPowerController2 is no longer in use; i.e. when 907 * the {@link #mDisplayId display} has been removed. 908 */ 909 @Override stop()910 public void stop() { 911 synchronized (mLock) { 912 clearDisplayBrightnessFollowersLocked(); 913 914 mStopped = true; 915 Message msg = mHandler.obtainMessage(MSG_STOP); 916 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 917 918 if (mAutomaticBrightnessController != null) { 919 mAutomaticBrightnessController.stop(); 920 } 921 922 mDisplayBrightnessController.stop(); 923 924 mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); 925 } 926 } 927 loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info, HighBrightnessModeMetadata hbmMetadata)928 private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info, 929 HighBrightnessModeMetadata hbmMetadata) { 930 // All properties that depend on the associated DisplayDevice and the DDC must be 931 // updated here. 932 loadBrightnessRampRates(); 933 loadNitsRange(mContext.getResources()); 934 setUpAutoBrightness(mContext, mHandler); 935 reloadReduceBrightColours(); 936 setAnimatorRampSpeeds(/* isIdleMode= */ false); 937 938 mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig); 939 mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( 940 mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(), 941 mDisplayDeviceConfig.getTempSensor(), 942 mThermalBrightnessThrottlingDataId, mUniqueDisplayId); 943 } 944 sendUpdatePowerState()945 private void sendUpdatePowerState() { 946 synchronized (mLock) { 947 sendUpdatePowerStateLocked(); 948 } 949 } 950 951 @GuardedBy("mLock") sendUpdatePowerStateLocked()952 private void sendUpdatePowerStateLocked() { 953 if (!mStopped && !mPendingUpdatePowerStateLocked) { 954 mPendingUpdatePowerStateLocked = true; 955 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); 956 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 957 } 958 } 959 initialize(int displayState)960 private void initialize(int displayState) { 961 mPowerState = mInjector.getDisplayPowerState(mBlanker, 962 mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId, displayState); 963 964 if (mColorFadeEnabled) { 965 mColorFadeOnAnimator = ObjectAnimator.ofFloat( 966 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f); 967 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS); 968 mColorFadeOnAnimator.addListener(mAnimatorListener); 969 970 mColorFadeOffAnimator = ObjectAnimator.ofFloat( 971 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f); 972 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS); 973 mColorFadeOffAnimator.addListener(mAnimatorListener); 974 } 975 976 mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState, 977 DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT, 978 DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT); 979 setAnimatorRampSpeeds(mAutomaticBrightnessController != null 980 && mAutomaticBrightnessController.isInIdleMode()); 981 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); 982 983 noteScreenState(mPowerState.getScreenState(), Display.STATE_REASON_DEFAULT_POLICY); 984 noteScreenBrightness(mPowerState.getScreenBrightness()); 985 986 // Initialize all of the brightness tracking state 987 final float brightness = mDisplayBrightnessController.convertToAdjustedNits( 988 mPowerState.getScreenBrightness()); 989 if (mBrightnessTracker != null && brightness >= PowerManager.BRIGHTNESS_MIN) { 990 mBrightnessTracker.start(brightness); 991 } 992 993 BrightnessSetting.BrightnessSettingListener brightnessSettingListener = brightnessValue -> { 994 Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue); 995 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 996 }; 997 mDisplayBrightnessController 998 .registerBrightnessSettingChangeListener(brightnessSettingListener); 999 1000 mContext.getContentResolver().registerContentObserver( 1001 Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ), 1002 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); 1003 mContext.getContentResolver().registerContentObserver( 1004 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE), 1005 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); 1006 if (mFlags.areAutoBrightnessModesEnabled()) { 1007 mContext.getContentResolver().registerContentObserver( 1008 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_ALS), 1009 /* notifyForDescendants= */ false, mSettingsObserver, UserHandle.USER_CURRENT); 1010 } 1011 handleBrightnessModeChange(); 1012 } 1013 setUpAutoBrightness(Context context, Handler handler)1014 private void setUpAutoBrightness(Context context, Handler handler) { 1015 mUseSoftwareAutoBrightnessConfig = mDisplayDeviceConfig.isAutoBrightnessAvailable(); 1016 1017 if (!mUseSoftwareAutoBrightnessConfig) { 1018 return; 1019 } 1020 1021 SparseArray<BrightnessMappingStrategy> brightnessMappers = new SparseArray<>(); 1022 1023 BrightnessMappingStrategy defaultModeBrightnessMapper = 1024 mInjector.getDefaultModeBrightnessMapper(context, mDisplayDeviceConfig, 1025 mDisplayWhiteBalanceController); 1026 brightnessMappers.append(AUTO_BRIGHTNESS_MODE_DEFAULT, 1027 defaultModeBrightnessMapper); 1028 1029 final boolean isIdleScreenBrightnessEnabled = context.getResources().getBoolean( 1030 R.bool.config_enableIdleScreenBrightnessMode); 1031 if (isIdleScreenBrightnessEnabled) { 1032 BrightnessMappingStrategy idleModeBrightnessMapper = 1033 BrightnessMappingStrategy.create(context, mDisplayDeviceConfig, 1034 AUTO_BRIGHTNESS_MODE_IDLE, 1035 mDisplayWhiteBalanceController); 1036 if (idleModeBrightnessMapper != null) { 1037 brightnessMappers.append(AUTO_BRIGHTNESS_MODE_IDLE, 1038 idleModeBrightnessMapper); 1039 } 1040 } 1041 1042 BrightnessMappingStrategy dozeModeBrightnessMapper = 1043 BrightnessMappingStrategy.create(context, mDisplayDeviceConfig, 1044 AUTO_BRIGHTNESS_MODE_DOZE, mDisplayWhiteBalanceController); 1045 if (mFlags.areAutoBrightnessModesEnabled() && dozeModeBrightnessMapper != null) { 1046 brightnessMappers.put(AUTO_BRIGHTNESS_MODE_DOZE, dozeModeBrightnessMapper); 1047 } 1048 1049 float userLux = BrightnessMappingStrategy.INVALID_LUX; 1050 float userNits = BrightnessMappingStrategy.INVALID_NITS; 1051 if (mAutomaticBrightnessController != null) { 1052 userLux = mAutomaticBrightnessController.getUserLux(); 1053 userNits = mAutomaticBrightnessController.getUserNits(); 1054 } 1055 1056 if (defaultModeBrightnessMapper != null) { 1057 // Ambient Lux - Active Mode Brightness Thresholds 1058 HysteresisLevels ambientBrightnessThresholds = 1059 mDisplayDeviceConfig.getAmbientBrightnessHysteresis(); 1060 1061 // Display - Active Mode Brightness Thresholds 1062 HysteresisLevels screenBrightnessThresholds = 1063 mDisplayDeviceConfig.getScreenBrightnessHysteresis(); 1064 1065 // Ambient Lux - Idle Screen Brightness Thresholds 1066 HysteresisLevels ambientBrightnessThresholdsIdle = 1067 mDisplayDeviceConfig.getAmbientBrightnessIdleHysteresis(); 1068 1069 // Display - Idle Screen Brightness Thresholds 1070 HysteresisLevels screenBrightnessThresholdsIdle = 1071 mDisplayDeviceConfig.getScreenBrightnessIdleHysteresis(); 1072 1073 long brighteningLightDebounce = mDisplayDeviceConfig 1074 .getAutoBrightnessBrighteningLightDebounce(); 1075 long darkeningLightDebounce = mDisplayDeviceConfig 1076 .getAutoBrightnessDarkeningLightDebounce(); 1077 long brighteningLightDebounceIdle = mDisplayDeviceConfig 1078 .getAutoBrightnessBrighteningLightDebounceIdle(); 1079 long darkeningLightDebounceIdle = mDisplayDeviceConfig 1080 .getAutoBrightnessDarkeningLightDebounceIdle(); 1081 boolean autoBrightnessResetAmbientLuxAfterWarmUp = context.getResources().getBoolean( 1082 R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp); 1083 1084 int lightSensorWarmUpTimeConfig = context.getResources().getInteger( 1085 R.integer.config_lightSensorWarmupTime); 1086 int lightSensorRate = context.getResources().getInteger( 1087 R.integer.config_autoBrightnessLightSensorRate); 1088 int initialLightSensorRate = context.getResources().getInteger( 1089 R.integer.config_autoBrightnessInitialLightSensorRate); 1090 if (initialLightSensorRate == -1) { 1091 initialLightSensorRate = lightSensorRate; 1092 } else if (initialLightSensorRate > lightSensorRate) { 1093 Slog.w(mTag, "Expected config_autoBrightnessInitialLightSensorRate (" 1094 + initialLightSensorRate + ") to be less than or equal to " 1095 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ")."); 1096 } 1097 1098 loadAmbientLightSensor(); 1099 // BrightnessTracker should only use one light sensor, we want to use the light sensor 1100 // from the default display and not e.g. temporary displays when switching layouts. 1101 if (mBrightnessTracker != null && mDisplayId == Display.DEFAULT_DISPLAY) { 1102 mBrightnessTracker.setLightSensor(mLightSensor); 1103 } 1104 1105 if (mAutomaticBrightnessController != null) { 1106 mAutomaticBrightnessController.stop(); 1107 } 1108 mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController( 1109 this, handler.getLooper(), mSensorManager, mLightSensor, 1110 brightnessMappers, lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN, 1111 PowerManager.BRIGHTNESS_MAX, mDozeScaleFactor, lightSensorRate, 1112 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, 1113 brighteningLightDebounceIdle, darkeningLightDebounceIdle, 1114 autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds, 1115 screenBrightnessThresholds, ambientBrightnessThresholdsIdle, 1116 screenBrightnessThresholdsIdle, mContext, mBrightnessRangeController, 1117 mBrightnessThrottler, mDisplayDeviceConfig.getAmbientHorizonShort(), 1118 mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userNits, 1119 mBrightnessClamperController, mFlags); 1120 mDisplayBrightnessController.setUpAutoBrightness( 1121 mAutomaticBrightnessController, mSensorManager, mDisplayDeviceConfig, mHandler, 1122 defaultModeBrightnessMapper, mIsEnabled, mLeadDisplayId); 1123 mBrightnessEventRingBuffer = 1124 new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX); 1125 if (!mFlags.isRefactorDisplayPowerControllerEnabled()) { 1126 if (mScreenOffBrightnessSensorController != null) { 1127 mScreenOffBrightnessSensorController.stop(); 1128 mScreenOffBrightnessSensorController = null; 1129 } 1130 loadScreenOffBrightnessSensor(); 1131 int[] sensorValueToLux = 1132 mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux(); 1133 if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) { 1134 mScreenOffBrightnessSensorController = 1135 mInjector.getScreenOffBrightnessSensorController( 1136 mSensorManager, 1137 mScreenOffBrightnessSensor, 1138 mHandler, 1139 SystemClock::uptimeMillis, 1140 sensorValueToLux, 1141 defaultModeBrightnessMapper); 1142 } 1143 } 1144 } else { 1145 mUseSoftwareAutoBrightnessConfig = false; 1146 } 1147 } 1148 loadBrightnessRampRates()1149 private void loadBrightnessRampRates() { 1150 mBrightnessRampRateFastDecrease = mDisplayDeviceConfig.getBrightnessRampFastDecrease(); 1151 mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease(); 1152 mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease(); 1153 mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease(); 1154 mBrightnessRampRateSlowDecreaseIdle = 1155 mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle(); 1156 mBrightnessRampRateSlowIncreaseIdle = 1157 mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(); 1158 mBrightnessRampDecreaseMaxTimeMillis = 1159 mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(); 1160 mBrightnessRampIncreaseMaxTimeMillis = 1161 mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(); 1162 mBrightnessRampDecreaseMaxTimeIdleMillis = 1163 mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis(); 1164 mBrightnessRampIncreaseMaxTimeIdleMillis = 1165 mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis(); 1166 } 1167 loadNitsRange(Resources resources)1168 private void loadNitsRange(Resources resources) { 1169 if (mDisplayDeviceConfig != null && mDisplayDeviceConfig.getNits() != null) { 1170 mNitsRange = mDisplayDeviceConfig.getNits(); 1171 } else { 1172 Slog.w(mTag, "Screen brightness nits configuration is unavailable; falling back"); 1173 mNitsRange = BrightnessMappingStrategy.getFloatArray(resources 1174 .obtainTypedArray(R.array.config_screenBrightnessNits)); 1175 } 1176 } 1177 reloadReduceBrightColours()1178 private void reloadReduceBrightColours() { 1179 if (mCdsi != null && mCdsi.isReduceBrightColorsActivated()) { 1180 applyReduceBrightColorsSplineAdjustment(); 1181 } 1182 } 1183 1184 @Override setAutomaticScreenBrightnessMode( @utomaticBrightnessController.AutomaticBrightnessMode int mode)1185 public void setAutomaticScreenBrightnessMode( 1186 @AutomaticBrightnessController.AutomaticBrightnessMode int mode) { 1187 Message msg = mHandler.obtainMessage(); 1188 msg.what = MSG_SWITCH_AUTOBRIGHTNESS_MODE; 1189 msg.arg1 = mode; 1190 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 1191 } 1192 setAnimatorRampSpeeds(boolean isIdle)1193 private void setAnimatorRampSpeeds(boolean isIdle) { 1194 if (mScreenBrightnessRampAnimator == null) { 1195 return; 1196 } 1197 if (mFlags.isAdaptiveTone1Enabled() && isIdle) { 1198 mScreenBrightnessRampAnimator.setAnimationTimeLimits( 1199 mBrightnessRampIncreaseMaxTimeIdleMillis, 1200 mBrightnessRampDecreaseMaxTimeIdleMillis); 1201 } else { 1202 mScreenBrightnessRampAnimator.setAnimationTimeLimits( 1203 mBrightnessRampIncreaseMaxTimeMillis, 1204 mBrightnessRampDecreaseMaxTimeMillis); 1205 } 1206 } 1207 1208 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { 1209 @Override 1210 public void onAnimationStart(Animator animation) { 1211 } 1212 1213 @Override 1214 public void onAnimationEnd(Animator animation) { 1215 sendUpdatePowerState(); 1216 } 1217 1218 @Override 1219 public void onAnimationRepeat(Animator animation) { 1220 } 1221 1222 @Override 1223 public void onAnimationCancel(Animator animation) { 1224 } 1225 }; 1226 1227 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() { 1228 @Override 1229 public void onAnimationEnd() { 1230 sendUpdatePowerState(); 1231 Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_RAMP_DONE); 1232 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 1233 } 1234 }; 1235 1236 /** Clean up all resources that are accessed via the {@link #mHandler} thread. */ cleanupHandlerThreadAfterStop()1237 private void cleanupHandlerThreadAfterStop() { 1238 mDisplayPowerProximityStateController.cleanup(); 1239 mBrightnessRangeController.stop(); 1240 mBrightnessThrottler.stop(); 1241 mBrightnessClamperController.stop(); 1242 mHandler.removeCallbacksAndMessages(null); 1243 1244 // Release any outstanding wakelocks we're still holding because of pending messages. 1245 mWakelockController.releaseAll(); 1246 1247 final float brightness = mPowerState != null 1248 ? mPowerState.getScreenBrightness() 1249 : PowerManager.BRIGHTNESS_MIN; 1250 reportStats(brightness); 1251 1252 if (mPowerState != null) { 1253 mPowerState.stop(); 1254 mPowerState = null; 1255 } 1256 1257 if (!mFlags.isRefactorDisplayPowerControllerEnabled() 1258 && mScreenOffBrightnessSensorController != null) { 1259 mScreenOffBrightnessSensorController.stop(); 1260 } 1261 1262 if (mDisplayWhiteBalanceController != null) { 1263 mDisplayWhiteBalanceController.setEnabled(false); 1264 } 1265 } 1266 1267 // Call from handler thread updatePowerState()1268 private void updatePowerState() { 1269 Trace.traceBegin(Trace.TRACE_TAG_POWER, 1270 "DisplayPowerController#updatePowerState"); 1271 updatePowerStateInternal(); 1272 Trace.traceEnd(Trace.TRACE_TAG_POWER); 1273 } 1274 updatePowerStateInternal()1275 private void updatePowerStateInternal() { 1276 // Update the power state request. 1277 boolean mustNotify = false; 1278 final int previousPolicy; 1279 boolean mustInitialize = false; 1280 mBrightnessReasonTemp.set(null); 1281 mTempBrightnessEvent.reset(); 1282 SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers; 1283 synchronized (mLock) { 1284 if (mStopped) { 1285 return; 1286 } 1287 mPendingUpdatePowerStateLocked = false; 1288 if (mPendingRequestLocked == null) { 1289 return; // wait until first actual power request 1290 } 1291 1292 if (mPowerRequest == null) { 1293 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); 1294 mDisplayPowerProximityStateController.updatePendingProximityRequestsLocked(); 1295 mPendingRequestChangedLocked = false; 1296 mustInitialize = true; 1297 // Assume we're on and bright until told otherwise, since that's the state we turn 1298 // on in. 1299 previousPolicy = DisplayPowerRequest.POLICY_BRIGHT; 1300 } else if (mPendingRequestChangedLocked) { 1301 previousPolicy = mPowerRequest.policy; 1302 mPowerRequest.copyFrom(mPendingRequestLocked); 1303 mDisplayPowerProximityStateController.updatePendingProximityRequestsLocked(); 1304 mPendingRequestChangedLocked = false; 1305 mDisplayReadyLocked = false; 1306 } else { 1307 previousPolicy = mPowerRequest.policy; 1308 } 1309 1310 mustNotify = !mDisplayReadyLocked; 1311 1312 displayBrightnessFollowers = mDisplayBrightnessFollowers.clone(); 1313 } 1314 1315 final Pair<Integer, Integer> stateAndReason = 1316 mDisplayStateController 1317 .updateDisplayState(mPowerRequest, mIsEnabled, mIsInTransition); 1318 int state = stateAndReason.first; 1319 1320 // Initialize things the first time the power state is changed. 1321 if (mustInitialize) { 1322 initialize(readyToUpdateDisplayState() ? state : Display.STATE_UNKNOWN); 1323 } 1324 1325 if (mFlags.isOffloadDozeOverrideHoldsWakelockEnabled()) { 1326 // Sometimes, a display-state change can come without an associated PowerRequest, 1327 // as with DisplayOffload. For those cases, we have to make sure to also mark the 1328 // display as "not ready" so that we can inform power-manager when the state-change is 1329 // complete. 1330 if (mPowerState.getScreenState() != state) { 1331 final boolean wasReady; 1332 synchronized (mLock) { 1333 wasReady = mDisplayReadyLocked; 1334 mDisplayReadyLocked = false; 1335 mustNotify = true; 1336 } 1337 1338 if (wasReady) { 1339 // If we went from ready to not-ready from the state-change (instead of a 1340 // PowerRequest) there's a good chance that nothing is keeping PowerManager 1341 // from suspending. Grab the unfinished business suspend blocker to keep the 1342 // device awake until the display-state change goes into effect. 1343 mWakelockController.acquireWakelock( 1344 WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS); 1345 } 1346 } 1347 } 1348 1349 // Animate the screen state change unless already animating. 1350 // The transition may be deferred, so after this point we will use the 1351 // actual state instead of the desired one. 1352 animateScreenStateChange( 1353 state, /* reason= */ stateAndReason.second, 1354 mDisplayStateController.shouldPerformScreenOffTransition()); 1355 state = mPowerState.getScreenState(); 1356 1357 DisplayBrightnessState displayBrightnessState = mDisplayBrightnessController 1358 .updateBrightness(mPowerRequest, state, mDisplayOffloadSession); 1359 float brightnessState = displayBrightnessState.getBrightness(); 1360 float rawBrightnessState = displayBrightnessState.getBrightness(); 1361 mBrightnessReasonTemp.set(displayBrightnessState.getBrightnessReason()); 1362 boolean slowChange = displayBrightnessState.isSlowChange(); 1363 // custom transition duration 1364 float customAnimationRate = displayBrightnessState.getCustomAnimationRate(); 1365 int brightnessAdjustmentFlags = displayBrightnessState.getBrightnessAdjustmentFlag(); 1366 final boolean userSetBrightnessChanged = 1367 mDisplayBrightnessController.getIsUserSetScreenBrightnessUpdated(); 1368 if (displayBrightnessState.getBrightnessEvent() != null) { 1369 mTempBrightnessEvent.copyFrom(displayBrightnessState.getBrightnessEvent()); 1370 } 1371 1372 boolean allowAutoBrightnessWhileDozing = 1373 mDisplayBrightnessController.isAllowAutoBrightnessWhileDozing(); 1374 1375 if (!mFlags.isRefactorDisplayPowerControllerEnabled()) { 1376 // Set up the ScreenOff controller used when coming out of SCREEN_OFF and the ALS sensor 1377 // doesn't yet have a valid lux value to use with auto-brightness. 1378 if (mScreenOffBrightnessSensorController != null) { 1379 mScreenOffBrightnessSensorController 1380 .setLightSensorEnabled(displayBrightnessState.getShouldUseAutoBrightness() 1381 && mIsEnabled && (state == Display.STATE_OFF 1382 || (state == Display.STATE_DOZE && !allowAutoBrightnessWhileDozing)) 1383 && mLeadDisplayId == Layout.NO_LEAD_DISPLAY); 1384 } 1385 } 1386 1387 // Take note if the short term model was already active before applying the current 1388 // request changes. 1389 final boolean wasShortTermModelActive = 1390 mAutomaticBrightnessStrategy.isShortTermModelActive(); 1391 boolean userInitiatedChange = displayBrightnessState.isUserInitiatedChange(); 1392 1393 if (!mFlags.isRefactorDisplayPowerControllerEnabled()) { 1394 // Switch to doze auto-brightness mode if needed 1395 if (mFlags.areAutoBrightnessModesEnabled() && mAutomaticBrightnessController != null 1396 && !mAutomaticBrightnessController.isInIdleMode()) { 1397 // Set sendUpdate to false, we're already in updatePowerState() so there's no need 1398 // to trigger it again 1399 mAutomaticBrightnessController.switchMode(Display.isDozeState(state) 1400 ? AUTO_BRIGHTNESS_MODE_DOZE : AUTO_BRIGHTNESS_MODE_DEFAULT, 1401 /* sendUpdate= */ false); 1402 } 1403 1404 mAutomaticBrightnessStrategy.setAutoBrightnessState(state, 1405 allowAutoBrightnessWhileDozing, mBrightnessReasonTemp.getReason(), 1406 mPowerRequest.policy, 1407 mDisplayBrightnessController.getLastUserSetScreenBrightness(), 1408 userSetBrightnessChanged); 1409 1410 // If the brightness is already set then it's been overridden by something other than 1411 // the user, or is a temporary adjustment. 1412 userInitiatedChange = (Float.isNaN(brightnessState)) 1413 && (mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged() 1414 || userSetBrightnessChanged); 1415 } 1416 1417 1418 final int autoBrightnessState = mAutomaticBrightnessStrategy.isAutoBrightnessEnabled() 1419 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED 1420 : mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff() 1421 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE 1422 : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED; 1423 1424 mBrightnessRangeController.setAutoBrightnessEnabled(autoBrightnessState); 1425 1426 boolean updateScreenBrightnessSetting = 1427 displayBrightnessState.shouldUpdateScreenBrightnessSetting(); 1428 float currentBrightnessSetting = mDisplayBrightnessController.getCurrentBrightness(); 1429 1430 if (!mFlags.isRefactorDisplayPowerControllerEnabled()) { 1431 // AutomaticBrightnessStrategy has higher priority than OffloadBrightnessStrategy 1432 if (Float.isNaN(brightnessState) 1433 || mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_OFFLOAD) { 1434 if (mAutomaticBrightnessStrategy.isAutoBrightnessEnabled()) { 1435 brightnessState = mAutomaticBrightnessStrategy.getAutomaticScreenBrightness( 1436 mTempBrightnessEvent); 1437 if (BrightnessUtils.isValidBrightnessValue(brightnessState) 1438 || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) { 1439 rawBrightnessState = mAutomaticBrightnessController 1440 .getRawAutomaticScreenBrightness(); 1441 // slowly adapt to auto-brightness 1442 // TODO(b/253226419): slowChange should be decided by 1443 // strategy.updateBrightness 1444 slowChange = mAutomaticBrightnessStrategy.hasAppliedAutoBrightness() 1445 && !mAutomaticBrightnessStrategy 1446 .getAutoBrightnessAdjustmentChanged(); 1447 brightnessAdjustmentFlags = 1448 mAutomaticBrightnessStrategy 1449 .getAutoBrightnessAdjustmentReasonsFlags(); 1450 updateScreenBrightnessSetting = currentBrightnessSetting != brightnessState; 1451 mAutomaticBrightnessStrategy.setAutoBrightnessApplied(true); 1452 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); 1453 if (mScreenOffBrightnessSensorController != null) { 1454 mScreenOffBrightnessSensorController.setLightSensorEnabled(false); 1455 } 1456 setBrightnessFromOffload(PowerManager.BRIGHTNESS_INVALID_FLOAT); 1457 } else { 1458 mAutomaticBrightnessStrategy.setAutoBrightnessApplied(false); 1459 // Restore the lower-priority brightness strategy 1460 brightnessState = displayBrightnessState.getBrightness(); 1461 } 1462 } 1463 } else { 1464 mAutomaticBrightnessStrategy.setAutoBrightnessApplied(false); 1465 } 1466 } 1467 1468 if (!Float.isNaN(brightnessState)) { 1469 brightnessState = clampScreenBrightness(brightnessState); 1470 } 1471 1472 if (Display.isDozeState(state)) { 1473 // TODO(b/329676661): Introduce a config property to choose between this brightness 1474 // strategy and DOZE_DEFAULT 1475 // On some devices, when auto-brightness is disabled and the device is dozing, we use 1476 // the current brightness setting scaled by the doze scale factor 1477 if ((Float.isNaN(brightnessState) 1478 || displayBrightnessState.getDisplayBrightnessStrategyName() 1479 .equals(DisplayBrightnessStrategyConstants.FALLBACK_BRIGHTNESS_STRATEGY_NAME)) 1480 && mFlags.isDisplayOffloadEnabled() 1481 && mDisplayOffloadSession != null 1482 && (mAutomaticBrightnessController == null 1483 || !mAutomaticBrightnessStrategy.shouldUseAutoBrightness())) { 1484 rawBrightnessState = getDozeBrightnessForOffload(); 1485 brightnessState = clampScreenBrightness(rawBrightnessState); 1486 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_MANUAL); 1487 mTempBrightnessEvent.setFlags( 1488 mTempBrightnessEvent.getFlags() | BrightnessEvent.FLAG_DOZE_SCALE); 1489 } 1490 1491 // Use default brightness when dozing unless overridden. 1492 if (Float.isNaN(brightnessState) && Display.isDozeState(state) 1493 && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()) { 1494 rawBrightnessState = mScreenBrightnessDozeConfig; 1495 brightnessState = clampScreenBrightness(rawBrightnessState); 1496 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT); 1497 } 1498 } 1499 1500 if (!mFlags.isRefactorDisplayPowerControllerEnabled()) { 1501 // The ALS is not available yet - use the screen off sensor to determine the initial 1502 // brightness 1503 if (Float.isNaN(brightnessState) 1504 && mAutomaticBrightnessStrategy.isAutoBrightnessEnabled() 1505 && mScreenOffBrightnessSensorController != null) { 1506 rawBrightnessState = 1507 mScreenOffBrightnessSensorController.getAutomaticScreenBrightness(); 1508 brightnessState = rawBrightnessState; 1509 if (BrightnessUtils.isValidBrightnessValue(brightnessState)) { 1510 brightnessState = clampScreenBrightness(brightnessState); 1511 updateScreenBrightnessSetting = 1512 mDisplayBrightnessController.getCurrentBrightness() 1513 != brightnessState; 1514 mBrightnessReasonTemp.setReason( 1515 BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR); 1516 } 1517 } 1518 } 1519 1520 // Apply manual brightness. 1521 if (Float.isNaN(brightnessState) && !mFlags.isRefactorDisplayPowerControllerEnabled()) { 1522 rawBrightnessState = currentBrightnessSetting; 1523 brightnessState = clampScreenBrightness(rawBrightnessState); 1524 if (brightnessState != currentBrightnessSetting) { 1525 // The manually chosen screen brightness is outside of the currently allowed 1526 // range (i.e., high-brightness-mode), make sure we tell the rest of the system 1527 // by updating the setting. 1528 updateScreenBrightnessSetting = true; 1529 } 1530 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL); 1531 } 1532 1533 float ambientLux = mAutomaticBrightnessController == null ? 0 1534 : mAutomaticBrightnessController.getAmbientLux(); 1535 for (int i = 0; i < displayBrightnessFollowers.size(); i++) { 1536 DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i); 1537 follower.setBrightnessToFollow(rawBrightnessState, 1538 mDisplayBrightnessController.convertToNits(rawBrightnessState), 1539 ambientLux, slowChange); 1540 } 1541 1542 // Now that a desired brightness has been calculated, apply brightness throttling. The 1543 // dimming and low power transformations that follow can only dim brightness further. 1544 // 1545 // We didn't do this earlier through brightness clamping because we need to know both 1546 // unthrottled (unclamped/ideal) and throttled brightness levels for subsequent operations. 1547 // Note throttling effectively changes the allowed brightness range, so, similarly to HBM, 1548 // we broadcast this change through setting. 1549 final float unthrottledBrightnessState = brightnessState; 1550 DisplayBrightnessState clampedState = mBrightnessClamperController.clamp(mPowerRequest, 1551 brightnessState, slowChange, /* displayState= */ state); 1552 1553 brightnessState = clampedState.getBrightness(); 1554 slowChange = clampedState.isSlowChange(); 1555 // faster rate wins, at this point customAnimationRate == -1, strategy does not control 1556 // customAnimationRate. Should be revisited if strategy start setting this value 1557 customAnimationRate = Math.max(customAnimationRate, clampedState.getCustomAnimationRate()); 1558 mBrightnessReasonTemp.addModifier(clampedState.getBrightnessReason().getModifier()); 1559 1560 if (updateScreenBrightnessSetting) { 1561 // Tell the rest of the system about the new brightness in case we had to change it 1562 // for things like auto-brightness or high-brightness-mode. Note that we do this 1563 // only considering maxBrightness (ignoring brightness modifiers like low power or dim) 1564 // so that the slider accurately represents the full possible range, 1565 // even if they range changes what it means in absolute terms. 1566 mDisplayBrightnessController.updateScreenBrightnessSetting( 1567 MathUtils.constrain(unthrottledBrightnessState, 1568 clampedState.getMinBrightness(), clampedState.getMaxBrightness()), 1569 Math.min(mBrightnessRangeController.getCurrentBrightnessMax(), 1570 clampedState.getMaxBrightness())); 1571 } 1572 1573 // The current brightness to use has been calculated at this point, and HbmController should 1574 // be notified so that it can accurately calculate HDR or HBM levels. We specifically do it 1575 // here instead of having HbmController listen to the brightness setting because certain 1576 // brightness sources (such as an app override) are not saved to the setting, but should be 1577 // reflected in HBM calculations. 1578 mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState, 1579 mBrightnessClamperController.getBrightnessMaxReason()); 1580 1581 // Animate the screen brightness when the screen is on or dozing. 1582 // Skip the animation when the screen is off or suspended. 1583 boolean brightnessAdjusted = false; 1584 final boolean brightnessIsTemporary = 1585 (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_TEMPORARY) 1586 || mAutomaticBrightnessStrategy 1587 .isTemporaryAutoBrightnessAdjustmentApplied(); 1588 if (!mPendingScreenOff) { 1589 if (mSkipScreenOnBrightnessRamp) { 1590 if (state == Display.STATE_ON) { 1591 if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) { 1592 mInitialAutoBrightness = brightnessState; 1593 mSkipRampState = RAMP_STATE_SKIP_INITIAL; 1594 } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL 1595 && mUseSoftwareAutoBrightnessConfig 1596 && !BrightnessSynchronizer.floatEquals(brightnessState, 1597 mInitialAutoBrightness)) { 1598 mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT; 1599 } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) { 1600 mSkipRampState = RAMP_STATE_SKIP_NONE; 1601 } 1602 } else { 1603 mSkipRampState = RAMP_STATE_SKIP_NONE; 1604 } 1605 } 1606 1607 final boolean initialRampSkip = (state == Display.STATE_ON && mSkipRampState 1608 != RAMP_STATE_SKIP_NONE) || mDisplayPowerProximityStateController 1609 .shouldSkipRampBecauseOfProximityChangeToNegative(); 1610 // While dozing, sometimes the brightness is split into buckets. Rather than animating 1611 // through the buckets, which is unlikely to be smooth in the first place, just jump 1612 // right to the suggested brightness. 1613 final boolean hasBrightnessBuckets = 1614 Display.isDozeState(state) && mBrightnessBucketsInDozeConfig; 1615 // If the color fade is totally covering the screen then we can change the backlight 1616 // level without it being a noticeable jump since any actual content isn't yet visible. 1617 final boolean isDisplayContentVisible = 1618 mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f; 1619 // We only want to animate the brightness if it is between 0.0f and 1.0f. 1620 // brightnessState can contain the values -1.0f and NaN, which we do not want to 1621 // animate to. To avoid this, we check the value first. 1622 // If the brightnessState is off (-1.0f) we still want to animate to the minimum 1623 // brightness (0.0f) to accommodate for LED displays, which can appear bright to the 1624 // user even when the display is all black. We also clamp here in case some 1625 // transformations to the brightness have pushed it outside of the currently 1626 // allowed range. 1627 float animateValue = clampScreenBrightness(brightnessState); 1628 1629 // If there are any HDR layers on the screen, we have a special brightness value that we 1630 // use instead. We still preserve the calculated brightness for Standard Dynamic Range 1631 // (SDR) layers, but the main brightness value will be the one for HDR. 1632 float sdrAnimateValue = animateValue; 1633 // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be 1634 // done in HighBrightnessModeController. 1635 if (mBrightnessRangeController.getHighBrightnessMode() 1636 == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR 1637 && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0 1638 && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER) 1639 == 0) { 1640 // We want to scale HDR brightness level with the SDR level, we also need to restore 1641 // SDR brightness immediately when entering dim or low power mode. 1642 animateValue = mBrightnessRangeController.getHdrBrightnessValue(); 1643 customAnimationRate = Math.max(customAnimationRate, 1644 mBrightnessRangeController.getHdrTransitionRate()); 1645 mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_HDR); 1646 } 1647 1648 // if doze or suspend state is requested, we want to finish brightnes animation fast 1649 // to allow state animation to start 1650 if (mPowerRequest.policy == POLICY_DOZE 1651 && (mPowerRequest.dozeScreenState == Display.STATE_UNKNOWN // dozing 1652 || mPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND 1653 || mPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND)) { 1654 customAnimationRate = DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET; 1655 slowChange = false; 1656 } 1657 1658 final float currentBrightness = mPowerState.getScreenBrightness(); 1659 final float currentSdrBrightness = mPowerState.getSdrScreenBrightness(); 1660 1661 if (BrightnessUtils.isValidBrightnessValue(animateValue) 1662 && (animateValue != currentBrightness 1663 || sdrAnimateValue != currentSdrBrightness)) { 1664 boolean skipAnimation = initialRampSkip || hasBrightnessBuckets 1665 || !isDisplayContentVisible || brightnessIsTemporary; 1666 final boolean isHdrOnlyChange = BrightnessSynchronizer.floatEquals( 1667 sdrAnimateValue, currentSdrBrightness); 1668 if (mFlags.isFastHdrTransitionsEnabled() && !skipAnimation && isHdrOnlyChange) { 1669 // SDR brightness is unchanged, so animate quickly as this is only impacting 1670 // a likely minority amount of display content 1671 // ie, the highlights of an HDR video or UltraHDR image 1672 // Ideally we'd do this as fast as possible (ie, skip the animation entirely), 1673 // but this requires display support and would need an entry in the 1674 // display configuration. For now just do the fast animation 1675 slowChange = false; 1676 } 1677 if (skipAnimation) { 1678 animateScreenBrightness(animateValue, sdrAnimateValue, 1679 SCREEN_ANIMATION_RATE_MINIMUM); 1680 } else if (customAnimationRate > 0) { 1681 animateScreenBrightness(animateValue, sdrAnimateValue, 1682 customAnimationRate, /* ignoreAnimationLimits = */true); 1683 } else { 1684 boolean isIncreasing = animateValue > currentBrightness; 1685 final float rampSpeed; 1686 final boolean idle = mAutomaticBrightnessController != null 1687 && mAutomaticBrightnessController.isInIdleMode(); 1688 if (isIncreasing && slowChange) { 1689 rampSpeed = idle ? mBrightnessRampRateSlowIncreaseIdle 1690 : mBrightnessRampRateSlowIncrease; 1691 } else if (isIncreasing && !slowChange) { 1692 rampSpeed = mBrightnessRampRateFastIncrease; 1693 } else if (!isIncreasing && slowChange) { 1694 rampSpeed = idle ? mBrightnessRampRateSlowDecreaseIdle 1695 : mBrightnessRampRateSlowDecrease; 1696 } else { 1697 rampSpeed = mBrightnessRampRateFastDecrease; 1698 } 1699 animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed); 1700 } 1701 } 1702 1703 notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange, 1704 wasShortTermModelActive, mAutomaticBrightnessStrategy.isAutoBrightnessEnabled(), 1705 brightnessIsTemporary, displayBrightnessState.getShouldUseAutoBrightness()); 1706 1707 // We save the brightness info *after* the brightness setting has been changed and 1708 // adjustments made so that the brightness info reflects the latest value. 1709 brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting(), 1710 animateValue, clampedState); 1711 } else { 1712 brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting(), clampedState); 1713 } 1714 1715 // Only notify if the brightness adjustment is not temporary (i.e. slider has been released) 1716 if (brightnessAdjusted && !brightnessIsTemporary) { 1717 postBrightnessChangeRunnable(); 1718 } 1719 1720 // Log any changes to what is currently driving the brightness setting. 1721 if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) { 1722 Slog.v(mTag, "Brightness [" + brightnessState + "] reason changing to: '" 1723 + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags) 1724 + "', previous reason: '" + mBrightnessReason + "'."); 1725 mBrightnessReason.set(mBrightnessReasonTemp); 1726 } else if (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_MANUAL 1727 && userSetBrightnessChanged) { 1728 Slog.v(mTag, "Brightness [" + brightnessState + "] manual adjustment."); 1729 } 1730 1731 1732 // Log brightness events when a detail of significance has changed. Generally this is the 1733 // brightness itself changing, but also includes data like HBM cap, thermal throttling 1734 // brightness cap, RBC state, etc. 1735 mTempBrightnessEvent.setTime(System.currentTimeMillis()); 1736 mTempBrightnessEvent.setBrightness(brightnessState); 1737 mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId); 1738 mTempBrightnessEvent.setDisplayState(state); 1739 mTempBrightnessEvent.setDisplayPolicy(mPowerRequest.policy); 1740 mTempBrightnessEvent.setReason(mBrightnessReason); 1741 mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax()); 1742 mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode()); 1743 mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags() 1744 | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0) 1745 | (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0)); 1746 mTempBrightnessEvent.setRbcStrength(mCdsi != null 1747 ? mCdsi.getReduceBrightColorsStrength() : -1); 1748 mTempBrightnessEvent.setPowerFactor(mPowerRequest.screenLowPowerBrightnessFactor); 1749 mTempBrightnessEvent.setWasShortTermModelActive(wasShortTermModelActive); 1750 mTempBrightnessEvent.setDisplayBrightnessStrategyName(displayBrightnessState 1751 .getDisplayBrightnessStrategyName()); 1752 mTempBrightnessEvent.setAutomaticBrightnessEnabled( 1753 displayBrightnessState.getShouldUseAutoBrightness()); 1754 // Temporary is what we use during slider interactions. We avoid logging those so that 1755 // we don't spam logcat when the slider is being used. 1756 boolean tempToTempTransition = 1757 mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY 1758 && mLastBrightnessEvent.getReason().getReason() 1759 == BrightnessReason.REASON_TEMPORARY; 1760 // Purely for dumpsys; 1761 final boolean isRbcEvent = 1762 mLastBrightnessEvent.isRbcEnabled() != mTempBrightnessEvent.isRbcEnabled(); 1763 1764 if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition) 1765 || brightnessAdjustmentFlags != 0) { 1766 mTempBrightnessEvent.setInitialBrightness(mLastBrightnessEvent.getBrightness()); 1767 mLastBrightnessEvent.copyFrom(mTempBrightnessEvent); 1768 BrightnessEvent newEvent = new BrightnessEvent(mTempBrightnessEvent); 1769 // Adjustment flags (and user-set flag) only get added after the equality checks since 1770 // they are transient. 1771 newEvent.setAdjustmentFlags(brightnessAdjustmentFlags); 1772 newEvent.setFlags(newEvent.getFlags() | (userSetBrightnessChanged 1773 ? BrightnessEvent.FLAG_USER_SET : 0)); 1774 Slog.i(mTag, newEvent.toString(/* includeTime= */ false)); 1775 1776 if (userSetBrightnessChanged 1777 || newEvent.getReason().getReason() != BrightnessReason.REASON_TEMPORARY) { 1778 logBrightnessEvent(newEvent, unthrottledBrightnessState); 1779 } 1780 if (mBrightnessEventRingBuffer != null) { 1781 mBrightnessEventRingBuffer.append(newEvent); 1782 } 1783 if (isRbcEvent) { 1784 mRbcEventRingBuffer.append(newEvent); 1785 } 1786 1787 } 1788 1789 // Update display white-balance. 1790 if (mDisplayWhiteBalanceController != null) { 1791 if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) { 1792 mDisplayWhiteBalanceController.setEnabled(true); 1793 mDisplayWhiteBalanceController.updateDisplayColorTemperature(); 1794 } else { 1795 mDisplayWhiteBalanceController.setEnabled(false); 1796 } 1797 } 1798 1799 // Determine whether the display is ready for use in the newly requested state. 1800 // Note that we do not wait for the brightness ramp animation to complete before 1801 // reporting the display is ready because we only need to ensure the screen is in the 1802 // right power state even as it continues to converge on the desired brightness. 1803 final boolean ready = mPendingScreenOnUnblocker == null 1804 && mPendingScreenOnUnblockerByDisplayOffload == null 1805 && (!mColorFadeEnabled || (!mColorFadeOnAnimator.isStarted() 1806 && !mColorFadeOffAnimator.isStarted())) 1807 && mPowerState.waitUntilClean(mCleanListener); 1808 final boolean finished = ready 1809 && !mScreenBrightnessRampAnimator.isAnimating(); 1810 1811 // Notify policy about screen turned on. 1812 if (ready && state != Display.STATE_OFF 1813 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) { 1814 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON); 1815 mWindowManagerPolicy.screenTurnedOn(mDisplayId); 1816 } 1817 1818 // Grab a wake lock if we have unfinished business. 1819 if (!finished) { 1820 mWakelockController.acquireWakelock(WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS); 1821 } 1822 1823 // Notify the power manager when ready. 1824 if (ready && mustNotify) { 1825 // Send state change. 1826 synchronized (mLock) { 1827 if (!mPendingRequestChangedLocked) { 1828 mDisplayReadyLocked = true; 1829 1830 if (DEBUG) { 1831 Slog.d(mTag, "Display ready!"); 1832 } 1833 } 1834 } 1835 sendOnStateChangedWithWakelock(); 1836 } 1837 1838 // Release the wake lock when we have no unfinished business. 1839 if (finished) { 1840 mWakelockController.releaseWakelock(WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS); 1841 } 1842 1843 // Record if dozing for future comparison. 1844 mDozing = state != Display.STATE_ON; 1845 1846 if (previousPolicy != mPowerRequest.policy) { 1847 logDisplayPolicyChanged(mPowerRequest.policy); 1848 } 1849 } 1850 setDwbcOverride(float cct)1851 private void setDwbcOverride(float cct) { 1852 if (mDisplayWhiteBalanceController != null) { 1853 mDisplayWhiteBalanceController.setAmbientColorTemperatureOverride(cct); 1854 // The ambient color temperature override is only applied when the ambient color 1855 // temperature changes or is updated, so it doesn't necessarily change the screen color 1856 // temperature immediately. So, let's make it! 1857 // We can call this directly, since we're already on the handler thread. 1858 updatePowerState(); 1859 } 1860 } 1861 setDwbcStrongMode(int arg)1862 private void setDwbcStrongMode(int arg) { 1863 if (mDisplayWhiteBalanceController != null) { 1864 final boolean isIdle = (arg == AUTO_BRIGHTNESS_MODE_IDLE); 1865 mDisplayWhiteBalanceController.setStrongModeEnabled(isIdle); 1866 } 1867 } 1868 setDwbcLoggingEnabled(int arg)1869 private void setDwbcLoggingEnabled(int arg) { 1870 if (mDisplayWhiteBalanceController != null) { 1871 final boolean enabled = (arg == 1); 1872 mDisplayWhiteBalanceController.setLoggingEnabled(enabled); 1873 mDisplayWhiteBalanceSettings.setLoggingEnabled(enabled); 1874 } 1875 } 1876 1877 @Override updateBrightness()1878 public void updateBrightness() { 1879 sendUpdatePowerState(); 1880 } 1881 1882 /** 1883 * Ignores the proximity sensor until the sensor state changes, but only if the sensor is 1884 * currently enabled and forcing the screen to be dark. 1885 */ 1886 @Override ignoreProximitySensorUntilChanged()1887 public void ignoreProximitySensorUntilChanged() { 1888 mDisplayPowerProximityStateController.ignoreProximitySensorUntilChanged(); 1889 } 1890 1891 @Override setBrightnessConfiguration(BrightnessConfiguration c, boolean shouldResetShortTermModel)1892 public void setBrightnessConfiguration(BrightnessConfiguration c, 1893 boolean shouldResetShortTermModel) { 1894 Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, 1895 shouldResetShortTermModel ? 1 : 0, /* unused */ 0, c); 1896 msg.sendToTarget(); 1897 } 1898 1899 @Override setTemporaryBrightness(float brightness)1900 public void setTemporaryBrightness(float brightness) { 1901 Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS, 1902 Float.floatToIntBits(brightness), 0 /*unused*/); 1903 msg.sendToTarget(); 1904 } 1905 1906 @Override setTemporaryAutoBrightnessAdjustment(float adjustment)1907 public void setTemporaryAutoBrightnessAdjustment(float adjustment) { 1908 Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT, 1909 Float.floatToIntBits(adjustment), 0 /*unused*/); 1910 msg.sendToTarget(); 1911 } 1912 1913 @Override setBrightnessFromOffload(float brightness)1914 public void setBrightnessFromOffload(float brightness) { 1915 Message msg = mHandler.obtainMessage(MSG_SET_BRIGHTNESS_FROM_OFFLOAD, 1916 Float.floatToIntBits(brightness), 0 /*unused*/); 1917 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 1918 } 1919 1920 @Override getAutoBrightnessLevels( @utomaticBrightnessController.AutomaticBrightnessMode int mode)1921 public float[] getAutoBrightnessLevels( 1922 @AutomaticBrightnessController.AutomaticBrightnessMode int mode) { 1923 int preset = Settings.System.getIntForUser(mContext.getContentResolver(), 1924 Settings.System.SCREEN_BRIGHTNESS_FOR_ALS, 1925 Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL, UserHandle.USER_CURRENT); 1926 return mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(mode, preset); 1927 } 1928 1929 @Override getAutoBrightnessLuxLevels( @utomaticBrightnessController.AutomaticBrightnessMode int mode)1930 public float[] getAutoBrightnessLuxLevels( 1931 @AutomaticBrightnessController.AutomaticBrightnessMode int mode) { 1932 int preset = Settings.System.getIntForUser(mContext.getContentResolver(), 1933 Settings.System.SCREEN_BRIGHTNESS_FOR_ALS, 1934 Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL, UserHandle.USER_CURRENT); 1935 return mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(mode, preset); 1936 } 1937 1938 @Override getBrightnessInfo()1939 public BrightnessInfo getBrightnessInfo() { 1940 synchronized (mCachedBrightnessInfo) { 1941 return new BrightnessInfo( 1942 mCachedBrightnessInfo.brightness.value, 1943 mCachedBrightnessInfo.adjustedBrightness.value, 1944 mCachedBrightnessInfo.brightnessMin.value, 1945 mCachedBrightnessInfo.brightnessMax.value, 1946 mCachedBrightnessInfo.hbmMode.value, 1947 mCachedBrightnessInfo.hbmTransitionPoint.value, 1948 mCachedBrightnessInfo.brightnessMaxReason.value); 1949 } 1950 } 1951 1952 @Override onBootCompleted()1953 public void onBootCompleted() { 1954 Message msg = mHandler.obtainMessage(MSG_BOOT_COMPLETED); 1955 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 1956 } 1957 saveBrightnessInfo(float brightness)1958 private boolean saveBrightnessInfo(float brightness) { 1959 return saveBrightnessInfo(brightness, /* state= */ null); 1960 } 1961 saveBrightnessInfo(float brightness, @Nullable DisplayBrightnessState state)1962 private boolean saveBrightnessInfo(float brightness, @Nullable DisplayBrightnessState state) { 1963 return saveBrightnessInfo(brightness, brightness, state); 1964 } 1965 saveBrightnessInfo(float brightness, float adjustedBrightness, @Nullable DisplayBrightnessState state)1966 private boolean saveBrightnessInfo(float brightness, float adjustedBrightness, 1967 @Nullable DisplayBrightnessState state) { 1968 synchronized (mCachedBrightnessInfo) { 1969 float stateMax = state != null ? state.getMaxBrightness() : PowerManager.BRIGHTNESS_MAX; 1970 float stateMin = state != null ? state.getMinBrightness() : PowerManager.BRIGHTNESS_MAX; 1971 final float minBrightness = Math.max(stateMin, Math.min( 1972 mBrightnessRangeController.getCurrentBrightnessMin(), stateMax)); 1973 final float maxBrightness = Math.min( 1974 mBrightnessRangeController.getCurrentBrightnessMax(), stateMax); 1975 boolean changed = false; 1976 1977 changed |= 1978 mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightness, 1979 brightness); 1980 changed |= 1981 mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.adjustedBrightness, 1982 adjustedBrightness); 1983 changed |= 1984 mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMin, 1985 minBrightness); 1986 changed |= 1987 mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMax, 1988 maxBrightness); 1989 changed |= 1990 mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode, 1991 mBrightnessRangeController.getHighBrightnessMode()); 1992 changed |= 1993 mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint, 1994 mBrightnessRangeController.getTransitionPoint()); 1995 changed |= 1996 mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason, 1997 mBrightnessClamperController.getBrightnessMaxReason()); 1998 return changed; 1999 } 2000 } 2001 postBrightnessChangeRunnable()2002 void postBrightnessChangeRunnable() { 2003 if (!mHandler.hasCallbacks(mOnBrightnessChangeRunnable)) { 2004 mHandler.post(mOnBrightnessChangeRunnable); 2005 } 2006 } 2007 createHbmControllerLocked( HighBrightnessModeMetadata hbmMetadata, Runnable modeChangeCallback)2008 private HighBrightnessModeController createHbmControllerLocked( 2009 HighBrightnessModeMetadata hbmMetadata, Runnable modeChangeCallback) { 2010 final DisplayDeviceConfig ddConfig = mDisplayDevice.getDisplayDeviceConfig(); 2011 final IBinder displayToken = mDisplayDevice.getDisplayTokenLocked(); 2012 final String displayUniqueId = mDisplayDevice.getUniqueId(); 2013 final DisplayDeviceConfig.HighBrightnessModeData hbmData = 2014 ddConfig != null ? ddConfig.getHighBrightnessModeData() : null; 2015 final DisplayDeviceInfo info = mDisplayDevice.getDisplayDeviceInfoLocked(); 2016 return mInjector.getHighBrightnessModeController(mHandler, info.width, info.height, 2017 displayToken, displayUniqueId, PowerManager.BRIGHTNESS_MIN, 2018 PowerManager.BRIGHTNESS_MAX, hbmData, (sdrBrightness, maxDesiredHdrSdrRatio) -> 2019 mDisplayDeviceConfig.getHdrBrightnessFromSdr(sdrBrightness, 2020 maxDesiredHdrSdrRatio), modeChangeCallback, hbmMetadata, mContext); 2021 } 2022 createBrightnessThrottlerLocked()2023 private BrightnessThrottler createBrightnessThrottlerLocked() { 2024 final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); 2025 final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); 2026 return new BrightnessThrottler(mHandler, 2027 () -> { 2028 sendUpdatePowerState(); 2029 postBrightnessChangeRunnable(); 2030 }, mUniqueDisplayId, 2031 mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId, 2032 ddConfig); 2033 } 2034 blockScreenOn()2035 private void blockScreenOn() { 2036 if (mPendingScreenOnUnblocker == null) { 2037 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0); 2038 mPendingScreenOnUnblocker = new ScreenOnUnblocker(); 2039 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime(); 2040 Slog.i(mTag, "Blocking screen on until initial contents have been drawn."); 2041 } 2042 } 2043 unblockScreenOn()2044 private void unblockScreenOn() { 2045 if (mPendingScreenOnUnblocker != null) { 2046 mPendingScreenOnUnblocker = null; 2047 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime; 2048 Slog.i(mTag, "Unblocked screen on after " + delay + " ms"); 2049 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0); 2050 } 2051 } 2052 blockScreenOff()2053 private void blockScreenOff() { 2054 if (mPendingScreenOffUnblocker == null) { 2055 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0); 2056 mPendingScreenOffUnblocker = new ScreenOffUnblocker(); 2057 mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime(); 2058 Slog.i(mTag, "Blocking screen off"); 2059 } 2060 } 2061 unblockScreenOff()2062 private void unblockScreenOff() { 2063 if (mPendingScreenOffUnblocker != null) { 2064 mPendingScreenOffUnblocker = null; 2065 long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime; 2066 Slog.i(mTag, "Unblocked screen off after " + delay + " ms"); 2067 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0); 2068 } 2069 } 2070 blockScreenOnByDisplayOffload(DisplayOffloadSession displayOffloadSession)2071 private void blockScreenOnByDisplayOffload(DisplayOffloadSession displayOffloadSession) { 2072 if (mPendingScreenOnUnblockerByDisplayOffload != null || displayOffloadSession == null) { 2073 return; 2074 } 2075 mScreenTurningOnWasBlockedByDisplayOffload = true; 2076 2077 Trace.asyncTraceBegin( 2078 Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME, 0); 2079 mScreenOnBlockByDisplayOffloadStartRealTime = SystemClock.elapsedRealtime(); 2080 2081 mPendingScreenOnUnblockerByDisplayOffload = 2082 () -> onDisplayOffloadUnblockScreenOn(displayOffloadSession); 2083 if (!displayOffloadSession.blockScreenOn(mPendingScreenOnUnblockerByDisplayOffload)) { 2084 mPendingScreenOnUnblockerByDisplayOffload = null; 2085 long delay = 2086 SystemClock.elapsedRealtime() - mScreenOnBlockByDisplayOffloadStartRealTime; 2087 Slog.w(mTag, "Tried blocking screen on for offloading but failed. So, end trace after " 2088 + delay + " ms."); 2089 Trace.asyncTraceEnd( 2090 Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME, 0); 2091 return; 2092 } 2093 Slog.i(mTag, "Blocking screen on for offloading."); 2094 } 2095 onDisplayOffloadUnblockScreenOn(DisplayOffloadSession displayOffloadSession)2096 private void onDisplayOffloadUnblockScreenOn(DisplayOffloadSession displayOffloadSession) { 2097 Message msg = mHandler.obtainMessage(MSG_OFFLOADING_SCREEN_ON_UNBLOCKED, 2098 displayOffloadSession); 2099 mHandler.sendMessage(msg); 2100 } 2101 unblockScreenOnByDisplayOffload()2102 private void unblockScreenOnByDisplayOffload() { 2103 if (mPendingScreenOnUnblockerByDisplayOffload == null) { 2104 return; 2105 } 2106 mPendingScreenOnUnblockerByDisplayOffload = null; 2107 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockByDisplayOffloadStartRealTime; 2108 Slog.i(mTag, "Unblocked screen on for offloading after " + delay + " ms"); 2109 Trace.asyncTraceEnd( 2110 Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME, 0); 2111 } 2112 setScreenState(int state, @Display.StateReason int reason)2113 private boolean setScreenState(int state, @Display.StateReason int reason) { 2114 return setScreenState(state, reason, false /*reportOnly*/); 2115 } 2116 setScreenState(int state, @Display.StateReason int reason, boolean reportOnly)2117 private boolean setScreenState(int state, @Display.StateReason int reason, boolean reportOnly) { 2118 final boolean isOff = (state == Display.STATE_OFF); 2119 final boolean isOn = (state == Display.STATE_ON); 2120 final boolean changed = mPowerState.getScreenState() != state; 2121 2122 // If the screen is turning on, give displayoffload a chance to do something before the 2123 // screen actually turns on. 2124 // TODO(b/316941732): add tests for this displayoffload screen-on blocker. 2125 if (isOn && changed && !mScreenTurningOnWasBlockedByDisplayOffload) { 2126 blockScreenOnByDisplayOffload(mDisplayOffloadSession); 2127 } else if (!isOn && mScreenTurningOnWasBlockedByDisplayOffload) { 2128 // No longer turning screen on, so unblock previous screen on blocking immediately. 2129 unblockScreenOnByDisplayOffload(); 2130 mScreenTurningOnWasBlockedByDisplayOffload = false; 2131 } 2132 2133 if (changed || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) { 2134 // If we are trying to turn screen off, give policy a chance to do something before we 2135 // actually turn the screen off. 2136 if (isOff && !mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) { 2137 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON 2138 || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) { 2139 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF); 2140 blockScreenOff(); 2141 mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker); 2142 unblockScreenOff(); 2143 } else if (mPendingScreenOffUnblocker != null) { 2144 // Abort doing the state change until screen off is unblocked. 2145 return false; 2146 } 2147 } 2148 2149 if (!reportOnly && changed && readyToUpdateDisplayState() 2150 && mPendingScreenOffUnblocker == null 2151 && mPendingScreenOnUnblockerByDisplayOffload == null) { 2152 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state); 2153 2154 String propertyKey = "debug.tracing.screen_state"; 2155 String propertyValue = String.valueOf(state); 2156 try { 2157 // TODO(b/153319140) remove when we can get this from the above trace invocation 2158 SystemProperties.set(propertyKey, propertyValue); 2159 } catch (RuntimeException e) { 2160 Slog.e(mTag, "Failed to set a system property: key=" + propertyKey 2161 + " value=" + propertyValue + " " + e.getMessage()); 2162 } 2163 2164 mPowerState.setScreenState(state, reason); 2165 // Tell battery stats about the transition. 2166 noteScreenState(state, reason); 2167 } 2168 } 2169 2170 // Tell the window manager policy when the screen is turned off or on unless it's due 2171 // to the proximity sensor. We temporarily block turning the screen on until the 2172 // window manager is ready by leaving a black surface covering the screen. 2173 // This surface is essentially the final state of the color fade animation and 2174 // it is only removed once the window manager tells us that the activity has 2175 // finished drawing underneath. 2176 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF 2177 && !mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) { 2178 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF); 2179 unblockScreenOn(); 2180 mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition); 2181 } else if (!isOff 2182 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) { 2183 2184 // We told policy already that screen was turning off, but now we changed our minds. 2185 // Complete the full state transition on -> turningOff -> off. 2186 unblockScreenOff(); 2187 mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition); 2188 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF); 2189 } 2190 if (!isOff 2191 && (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF 2192 || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) { 2193 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON); 2194 if (mPowerState.getColorFadeLevel() == 0.0f) { 2195 blockScreenOn(); 2196 } else { 2197 unblockScreenOn(); 2198 } 2199 mWindowManagerPolicy.screenTurningOn(mDisplayId, mPendingScreenOnUnblocker); 2200 } 2201 2202 // Return true if the screen isn't blocked. 2203 return mPendingScreenOnUnblocker == null 2204 && mPendingScreenOnUnblockerByDisplayOffload == null; 2205 } 2206 setReportedScreenState(int state)2207 private void setReportedScreenState(int state) { 2208 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state); 2209 mReportedScreenStateToPolicy = state; 2210 if (state == REPORTED_TO_POLICY_SCREEN_ON) { 2211 mScreenTurningOnWasBlockedByDisplayOffload = false; 2212 } 2213 } 2214 loadAmbientLightSensor()2215 private void loadAmbientLightSensor() { 2216 final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY 2217 ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK; 2218 mLightSensor = SensorUtils.findSensor(mSensorManager, 2219 mDisplayDeviceConfig.getAmbientLightSensor(), fallbackType); 2220 } 2221 loadScreenOffBrightnessSensor()2222 private void loadScreenOffBrightnessSensor() { 2223 mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager, 2224 mDisplayDeviceConfig.getScreenOffBrightnessSensor(), SensorUtils.NO_FALLBACK); 2225 } 2226 clampScreenBrightness(float value)2227 private float clampScreenBrightness(float value) { 2228 if (Float.isNaN(value)) { 2229 value = PowerManager.BRIGHTNESS_MIN; 2230 } 2231 return MathUtils.constrain(value, mBrightnessRangeController.getCurrentBrightnessMin(), 2232 mBrightnessRangeController.getCurrentBrightnessMax()); 2233 } 2234 animateScreenBrightness(float target, float sdrTarget, float rate)2235 private void animateScreenBrightness(float target, float sdrTarget, float rate) { 2236 animateScreenBrightness(target, sdrTarget, rate, /* ignoreAnimationLimits = */false); 2237 } 2238 animateScreenBrightness(float target, float sdrTarget, float rate, boolean ignoreAnimationLimits)2239 private void animateScreenBrightness(float target, float sdrTarget, float rate, 2240 boolean ignoreAnimationLimits) { 2241 if (DEBUG) { 2242 Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget 2243 + ", rate=" + rate); 2244 } 2245 if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate, 2246 ignoreAnimationLimits)) { 2247 Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target); 2248 2249 String propertyKey = "debug.tracing.screen_brightness"; 2250 String propertyValue = String.valueOf(target); 2251 try { 2252 // TODO(b/153319140) remove when we can get this from the above trace invocation 2253 SystemProperties.set(propertyKey, propertyValue); 2254 } catch (RuntimeException e) { 2255 Slog.e(mTag, "Failed to set a system property: key=" + propertyKey 2256 + " value=" + propertyValue + " " + e.getMessage()); 2257 } 2258 2259 noteScreenBrightness(target); 2260 } 2261 } 2262 animateScreenStateChange( int target, @Display.StateReason int reason, boolean performScreenOffTransition)2263 private void animateScreenStateChange( 2264 int target, @Display.StateReason int reason, boolean performScreenOffTransition) { 2265 // If there is already an animation in progress, don't interfere with it. 2266 if (mColorFadeEnabled 2267 && (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) { 2268 if (target != Display.STATE_ON) { 2269 return; 2270 } 2271 // If display state changed to on, proceed and stop the color fade and turn screen on. 2272 mPendingScreenOff = false; 2273 } 2274 2275 if (mDisplayBlanksAfterDozeConfig 2276 && Display.isDozeState(mPowerState.getScreenState()) 2277 && !Display.isDozeState(target)) { 2278 // Skip the screen off animation and add a black surface to hide the 2279 // contents of the screen. 2280 mPowerState.prepareColorFade(mContext, 2281 mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP); 2282 if (mColorFadeOffAnimator != null) { 2283 mColorFadeOffAnimator.end(); 2284 } 2285 // Some display hardware will blank itself on the transition between doze and non-doze 2286 // but still on display states. In this case we want to report to policy that the 2287 // display has turned off so it can prepare the appropriate power on animation, but we 2288 // don't want to actually transition to the fully off state since that takes 2289 // significantly longer to transition from. 2290 setScreenState(Display.STATE_OFF, reason, target != Display.STATE_OFF /*reportOnly*/); 2291 } 2292 2293 // If we were in the process of turning off the screen but didn't quite 2294 // finish. Then finish up now to prevent a jarring transition back 2295 // to screen on if we skipped blocking screen on as usual. 2296 if (mPendingScreenOff && target != Display.STATE_OFF) { 2297 setScreenState(Display.STATE_OFF, reason); 2298 mPendingScreenOff = false; 2299 mPowerState.dismissColorFadeResources(); 2300 } 2301 2302 if (target == Display.STATE_ON) { 2303 // Want screen on. The contents of the screen may not yet 2304 // be visible if the color fade has not been dismissed because 2305 // its last frame of animation is solid black. 2306 if (!setScreenState(Display.STATE_ON, reason)) { 2307 return; // screen on blocked 2308 } 2309 if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) { 2310 // Perform screen on animation. 2311 if (mPowerState.getColorFadeLevel() == 1.0f) { 2312 mPowerState.dismissColorFade(); 2313 } else if (mPowerState.prepareColorFade(mContext, 2314 mColorFadeFadesConfig 2315 ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP)) { 2316 mColorFadeOnAnimator.start(); 2317 } else { 2318 mColorFadeOnAnimator.end(); 2319 } 2320 } else { 2321 // Skip screen on animation. 2322 mPowerState.setColorFadeLevel(1.0f); 2323 mPowerState.dismissColorFade(); 2324 } 2325 } else if (target == Display.STATE_DOZE) { 2326 // Want screen dozing. 2327 // Wait for brightness animation to complete beforehand when entering doze 2328 // from screen on to prevent a perceptible jump because brightness may operate 2329 // differently when the display is configured for dozing. 2330 if (mScreenBrightnessRampAnimator.isAnimating() 2331 && mPowerState.getScreenState() == Display.STATE_ON) { 2332 return; 2333 } 2334 2335 // Set screen state. 2336 if (!setScreenState(Display.STATE_DOZE, reason)) { 2337 return; // screen on blocked 2338 } 2339 2340 // Dismiss the black surface without fanfare. 2341 mPowerState.setColorFadeLevel(1.0f); 2342 mPowerState.dismissColorFade(); 2343 } else if (target == Display.STATE_DOZE_SUSPEND) { 2344 // Want screen dozing and suspended. 2345 // Wait for brightness animation to complete beforehand unless already 2346 // suspended because we may not be able to change it after suspension. 2347 if (mScreenBrightnessRampAnimator.isAnimating() 2348 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { 2349 return; 2350 } 2351 2352 // If not already suspending, temporarily set the state to doze until the 2353 // screen on is unblocked, then suspend. 2354 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { 2355 if (!setScreenState(Display.STATE_DOZE, reason)) { 2356 return; // screen on blocked 2357 } 2358 setScreenState(Display.STATE_DOZE_SUSPEND, reason); // already on so can't block 2359 } 2360 2361 // Dismiss the black surface without fanfare. 2362 mPowerState.setColorFadeLevel(1.0f); 2363 mPowerState.dismissColorFade(); 2364 } else if (target == Display.STATE_ON_SUSPEND) { 2365 // Want screen full-power and suspended. 2366 // Wait for brightness animation to complete beforehand unless already 2367 // suspended because we may not be able to change it after suspension. 2368 if (mScreenBrightnessRampAnimator.isAnimating() 2369 && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) { 2370 return; 2371 } 2372 2373 // If not already suspending, temporarily set the state to on until the 2374 // screen on is unblocked, then suspend. 2375 if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) { 2376 if (!setScreenState(Display.STATE_ON, reason)) { 2377 return; 2378 } 2379 setScreenState(Display.STATE_ON_SUSPEND, reason); 2380 } 2381 2382 // Dismiss the black surface without fanfare. 2383 mPowerState.setColorFadeLevel(1.0f); 2384 mPowerState.dismissColorFade(); 2385 } else { 2386 // Want screen off. 2387 mPendingScreenOff = true; 2388 if (!mColorFadeEnabled) { 2389 mPowerState.setColorFadeLevel(0.0f); 2390 } 2391 2392 if (mPowerState.getColorFadeLevel() == 0.0f) { 2393 // Turn the screen off. 2394 // A black surface is already hiding the contents of the screen. 2395 setScreenState(Display.STATE_OFF, reason); 2396 mPendingScreenOff = false; 2397 mPowerState.dismissColorFadeResources(); 2398 } else if (performScreenOffTransition 2399 && mPowerState.prepareColorFade(mContext, 2400 mColorFadeFadesConfig 2401 ? ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN) 2402 && mPowerState.getScreenState() != Display.STATE_OFF) { 2403 // Perform the screen off animation. 2404 mColorFadeOffAnimator.start(); 2405 } else { 2406 // Skip the screen off animation and add a black surface to hide the 2407 // contents of the screen. 2408 mColorFadeOffAnimator.end(); 2409 } 2410 } 2411 } 2412 2413 private final Runnable mCleanListener = this::sendUpdatePowerState; 2414 sendOnStateChangedWithWakelock()2415 private void sendOnStateChangedWithWakelock() { 2416 boolean wakeLockAcquired = mWakelockController.acquireWakelock( 2417 WakelockController.WAKE_LOCK_STATE_CHANGED); 2418 if (wakeLockAcquired) { 2419 mHandler.post(mWakelockController.getOnStateChangedRunnable()); 2420 } 2421 } 2422 logDisplayPolicyChanged(int newPolicy)2423 private void logDisplayPolicyChanged(int newPolicy) { 2424 LogMaker log = new LogMaker(MetricsEvent.DISPLAY_POLICY); 2425 log.setType(MetricsEvent.TYPE_UPDATE); 2426 log.setSubtype(newPolicy); 2427 MetricsLogger.action(log); 2428 } 2429 handleSettingsChange()2430 private void handleSettingsChange() { 2431 mDisplayBrightnessController 2432 .setPendingScreenBrightness(mDisplayBrightnessController 2433 .getScreenBrightnessSetting()); 2434 mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(); 2435 sendUpdatePowerState(); 2436 } 2437 handleBrightnessModeChange()2438 private void handleBrightnessModeChange() { 2439 final int screenBrightnessModeSetting = Settings.System.getIntForUser( 2440 mContext.getContentResolver(), 2441 Settings.System.SCREEN_BRIGHTNESS_MODE, 2442 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT); 2443 mAutomaticBrightnessStrategy.setUseAutoBrightness(screenBrightnessModeSetting 2444 == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 2445 } 2446 2447 2448 @Override getScreenBrightnessSetting()2449 public float getScreenBrightnessSetting() { 2450 return mDisplayBrightnessController.getScreenBrightnessSetting(); 2451 } 2452 2453 @Override getDozeBrightnessForOffload()2454 public float getDozeBrightnessForOffload() { 2455 return mDisplayBrightnessController.getCurrentBrightness() * mDozeScaleFactor; 2456 } 2457 2458 @Override setBrightness(float brightness)2459 public void setBrightness(float brightness) { 2460 // After HBMController and NBMController migration to Clampers framework 2461 // currentBrightnessMax should be taken from clampers controller 2462 // TODO(b/263362199) 2463 mDisplayBrightnessController.setBrightness(clampScreenBrightness(brightness), 2464 mBrightnessRangeController.getCurrentBrightnessMax()); 2465 } 2466 2467 @Override setBrightness(float brightness, int userSerial)2468 public void setBrightness(float brightness, int userSerial) { 2469 // After HBMController and NBMController migration to Clampers framework 2470 // currentBrightnessMax should be taken from clampers controller 2471 // TODO(b/263362199) 2472 mDisplayBrightnessController.setBrightness(clampScreenBrightness(brightness), userSerial, 2473 mBrightnessRangeController.getCurrentBrightnessMax()); 2474 } 2475 2476 @Override getDisplayId()2477 public int getDisplayId() { 2478 return mDisplayId; 2479 } 2480 2481 @Override getLeadDisplayId()2482 public int getLeadDisplayId() { 2483 return mLeadDisplayId; 2484 } 2485 2486 @Override setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux, boolean slowChange)2487 public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux, 2488 boolean slowChange) { 2489 mBrightnessRangeController.onAmbientLuxChange(ambientLux); 2490 if (nits == BrightnessMappingStrategy.INVALID_NITS) { 2491 mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness, slowChange); 2492 } else { 2493 float brightness = mDisplayBrightnessController.getBrightnessFromNits(nits); 2494 if (BrightnessUtils.isValidBrightnessValue(brightness)) { 2495 mDisplayBrightnessController.setBrightnessToFollow(brightness, slowChange); 2496 } else { 2497 // The device does not support nits 2498 mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness, 2499 slowChange); 2500 } 2501 } 2502 sendUpdatePowerState(); 2503 } 2504 notifyBrightnessTrackerChanged(float brightness, boolean userInitiated, boolean wasShortTermModelActive, boolean autobrightnessEnabled, boolean brightnessIsTemporary, boolean shouldUseAutoBrightness)2505 private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated, 2506 boolean wasShortTermModelActive, boolean autobrightnessEnabled, 2507 boolean brightnessIsTemporary, boolean shouldUseAutoBrightness) { 2508 2509 final float brightnessInNits = 2510 mDisplayBrightnessController.convertToAdjustedNits(brightness); 2511 // Don't report brightness to brightnessTracker: 2512 // If brightness is temporary (ie the slider has not been released) 2513 // or if we are in idle screen brightness mode. 2514 // or display is not on 2515 // or we shouldn't be using autobrightness 2516 // or the nits is invalid. 2517 if (brightnessIsTemporary 2518 || mAutomaticBrightnessController == null 2519 || mAutomaticBrightnessController.isInIdleMode() 2520 || !autobrightnessEnabled 2521 || mBrightnessTracker == null 2522 || !shouldUseAutoBrightness 2523 || brightnessInNits < 0.0f) { 2524 return; 2525 } 2526 2527 if (userInitiated && (mAutomaticBrightnessController == null 2528 || !mAutomaticBrightnessController.hasValidAmbientLux())) { 2529 // If we don't have a valid lux reading we can't report a valid 2530 // slider event so notify as if the system changed the brightness. 2531 userInitiated = false; 2532 } 2533 2534 // We only want to track changes on devices that can actually map the display backlight 2535 // values into a physical brightness unit since the value provided by the API is in 2536 // nits and not using the arbitrary backlight units. 2537 final float powerFactor = mPowerRequest.lowPowerMode 2538 ? mPowerRequest.screenLowPowerBrightnessFactor 2539 : 1.0f; 2540 mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated, 2541 powerFactor, wasShortTermModelActive, 2542 mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId, 2543 mAutomaticBrightnessController.getLastSensorValues(), 2544 mAutomaticBrightnessController.getLastSensorTimestamps()); 2545 } 2546 2547 @Override addDisplayBrightnessFollower(DisplayPowerControllerInterface follower)2548 public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) { 2549 synchronized (mLock) { 2550 mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower); 2551 sendUpdatePowerStateLocked(); 2552 } 2553 } 2554 2555 @Override removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower)2556 public void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower) { 2557 synchronized (mLock) { 2558 mDisplayBrightnessFollowers.remove(follower.getDisplayId()); 2559 mHandler.postAtTime(() -> follower.setBrightnessToFollow( 2560 PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS, 2561 /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis()); 2562 } 2563 } 2564 2565 @GuardedBy("mLock") clearDisplayBrightnessFollowersLocked()2566 private void clearDisplayBrightnessFollowersLocked() { 2567 for (int i = 0; i < mDisplayBrightnessFollowers.size(); i++) { 2568 DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i); 2569 mHandler.postAtTime(() -> follower.setBrightnessToFollow( 2570 PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS, 2571 /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis()); 2572 } 2573 mDisplayBrightnessFollowers.clear(); 2574 } 2575 2576 @Override dump(final PrintWriter pw)2577 public void dump(final PrintWriter pw) { 2578 synchronized (mLock) { 2579 pw.println(); 2580 pw.println("Display Power Controller:"); 2581 pw.println(" mDisplayId=" + mDisplayId); 2582 pw.println(" mLeadDisplayId=" + mLeadDisplayId); 2583 pw.println(" mLightSensor=" + mLightSensor); 2584 pw.println(" mDisplayBrightnessFollowers=" + mDisplayBrightnessFollowers); 2585 2586 pw.println(); 2587 pw.println("Display Power Controller Locked State:"); 2588 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked); 2589 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked); 2590 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked); 2591 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked); 2592 } 2593 2594 pw.println(); 2595 pw.println("Display Power Controller Configuration:"); 2596 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); 2597 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig); 2598 pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp); 2599 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig); 2600 pw.println(" mColorFadeEnabled=" + mColorFadeEnabled); 2601 pw.println(" mIsDisplayInternal=" + mIsDisplayInternal); 2602 synchronized (mCachedBrightnessInfo) { 2603 pw.println(" mCachedBrightnessInfo.brightness=" 2604 + mCachedBrightnessInfo.brightness.value); 2605 pw.println(" mCachedBrightnessInfo.adjustedBrightness=" 2606 + mCachedBrightnessInfo.adjustedBrightness.value); 2607 pw.println(" mCachedBrightnessInfo.brightnessMin=" 2608 + mCachedBrightnessInfo.brightnessMin.value); 2609 pw.println(" mCachedBrightnessInfo.brightnessMax=" 2610 + mCachedBrightnessInfo.brightnessMax.value); 2611 pw.println(" mCachedBrightnessInfo.hbmMode=" + mCachedBrightnessInfo.hbmMode.value); 2612 pw.println(" mCachedBrightnessInfo.hbmTransitionPoint=" 2613 + mCachedBrightnessInfo.hbmTransitionPoint.value); 2614 pw.println(" mCachedBrightnessInfo.brightnessMaxReason =" 2615 + mCachedBrightnessInfo.brightnessMaxReason.value); 2616 } 2617 pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig); 2618 pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig); 2619 pw.println(" mDozeScaleFactor=" + mDozeScaleFactor); 2620 mHandler.runWithScissors(() -> dumpLocal(pw), 1000); 2621 } 2622 dumpLocal(PrintWriter pw)2623 private void dumpLocal(PrintWriter pw) { 2624 pw.println(); 2625 pw.println("Display Power Controller Thread State:"); 2626 pw.println(" mPowerRequest=" + mPowerRequest); 2627 pw.println(" mBrightnessReason=" + mBrightnessReason); 2628 pw.println(" mAppliedDimming=" + mAppliedDimming); 2629 pw.println(" mAppliedThrottling=" + mAppliedThrottling); 2630 pw.println(" mDozing=" + mDozing); 2631 pw.println(" mSkipRampState=" + skipRampStateToString(mSkipRampState)); 2632 pw.println(" mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime); 2633 pw.println(" mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime); 2634 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker); 2635 pw.println(" mPendingScreenOffUnblocker=" + mPendingScreenOffUnblocker); 2636 pw.println(" mPendingScreenOff=" + mPendingScreenOff); 2637 pw.println(" mReportedToPolicy=" 2638 + reportedToPolicyToString(mReportedScreenStateToPolicy)); 2639 pw.println(" mIsRbcActive=" + mIsRbcActive); 2640 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 2641 mAutomaticBrightnessStrategy.dump(ipw); 2642 2643 if (mScreenBrightnessRampAnimator != null) { 2644 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" 2645 + mScreenBrightnessRampAnimator.isAnimating()); 2646 } 2647 2648 if (mColorFadeOnAnimator != null) { 2649 pw.println(" mColorFadeOnAnimator.isStarted()=" 2650 + mColorFadeOnAnimator.isStarted()); 2651 } 2652 if (mColorFadeOffAnimator != null) { 2653 pw.println(" mColorFadeOffAnimator.isStarted()=" 2654 + mColorFadeOffAnimator.isStarted()); 2655 } 2656 2657 if (mPowerState != null) { 2658 mPowerState.dump(pw); 2659 } 2660 2661 if (mAutomaticBrightnessController != null) { 2662 mAutomaticBrightnessController.dump(pw); 2663 dumpBrightnessEvents(pw); 2664 } 2665 2666 dumpRbcEvents(pw); 2667 2668 if (mScreenOffBrightnessSensorController != null) { 2669 mScreenOffBrightnessSensorController.dump(pw); 2670 } 2671 2672 if (mBrightnessRangeController != null) { 2673 mBrightnessRangeController.dump(pw); 2674 } 2675 2676 if (mBrightnessThrottler != null) { 2677 mBrightnessThrottler.dump(pw); 2678 } 2679 2680 pw.println(); 2681 if (mDisplayWhiteBalanceController != null) { 2682 mDisplayWhiteBalanceController.dump(pw); 2683 mDisplayWhiteBalanceSettings.dump(pw); 2684 } 2685 2686 pw.println(); 2687 2688 if (mWakelockController != null) { 2689 mWakelockController.dumpLocal(pw); 2690 } 2691 2692 pw.println(); 2693 if (mDisplayBrightnessController != null) { 2694 mDisplayBrightnessController.dump(pw); 2695 } 2696 2697 pw.println(); 2698 if (mDisplayStateController != null) { 2699 mDisplayStateController.dumpsys(pw); 2700 } 2701 2702 pw.println(); 2703 if (mBrightnessClamperController != null) { 2704 mBrightnessClamperController.dump(ipw); 2705 } 2706 } 2707 2708 reportedToPolicyToString(int state)2709 private static String reportedToPolicyToString(int state) { 2710 switch (state) { 2711 case REPORTED_TO_POLICY_SCREEN_OFF: 2712 return "REPORTED_TO_POLICY_SCREEN_OFF"; 2713 case REPORTED_TO_POLICY_SCREEN_TURNING_ON: 2714 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON"; 2715 case REPORTED_TO_POLICY_SCREEN_ON: 2716 return "REPORTED_TO_POLICY_SCREEN_ON"; 2717 default: 2718 return Integer.toString(state); 2719 } 2720 } 2721 skipRampStateToString(int state)2722 private static String skipRampStateToString(int state) { 2723 switch (state) { 2724 case RAMP_STATE_SKIP_NONE: 2725 return "RAMP_STATE_SKIP_NONE"; 2726 case RAMP_STATE_SKIP_INITIAL: 2727 return "RAMP_STATE_SKIP_INITIAL"; 2728 case RAMP_STATE_SKIP_AUTOBRIGHT: 2729 return "RAMP_STATE_SKIP_AUTOBRIGHT"; 2730 default: 2731 return Integer.toString(state); 2732 } 2733 } 2734 dumpBrightnessEvents(PrintWriter pw)2735 private void dumpBrightnessEvents(PrintWriter pw) { 2736 int size = mBrightnessEventRingBuffer.size(); 2737 if (size < 1) { 2738 pw.println("No Automatic Brightness Adjustments"); 2739 return; 2740 } 2741 2742 pw.println("Automatic Brightness Adjustments Last " + size + " Events: "); 2743 BrightnessEvent[] eventArray = mBrightnessEventRingBuffer.toArray(); 2744 for (int i = 0; i < mBrightnessEventRingBuffer.size(); i++) { 2745 pw.println(" " + eventArray[i].toString()); 2746 } 2747 } 2748 dumpRbcEvents(PrintWriter pw)2749 private void dumpRbcEvents(PrintWriter pw) { 2750 int size = mRbcEventRingBuffer.size(); 2751 if (size < 1) { 2752 pw.println("No Reduce Bright Colors Adjustments"); 2753 return; 2754 } 2755 2756 pw.println("Reduce Bright Colors Adjustments Last " + size + " Events: "); 2757 BrightnessEvent[] eventArray = mRbcEventRingBuffer.toArray(); 2758 for (int i = 0; i < mRbcEventRingBuffer.size(); i++) { 2759 pw.println(" " + eventArray[i]); 2760 } 2761 } 2762 2763 noteScreenState(int screenState, @Display.StateReason int reason)2764 private void noteScreenState(int screenState, @Display.StateReason int reason) { 2765 // Log screen state change with display id 2766 FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED_V2, 2767 screenState, mDisplayStatsId, reason); 2768 if (mBatteryStats != null) { 2769 try { 2770 // TODO(multi-display): make this multi-display 2771 mBatteryStats.noteScreenState(screenState); 2772 } catch (RemoteException e) { 2773 // same process 2774 } 2775 } 2776 } 2777 2778 @SuppressLint("AndroidFrameworkRequiresPermission") noteScreenBrightness(float brightness)2779 private void noteScreenBrightness(float brightness) { 2780 if (mBatteryStats != null) { 2781 try { 2782 // TODO(brightnessfloat): change BatteryStats to use float 2783 int brightnessInt = mFlags.isBrightnessIntRangeUserPerceptionEnabled() 2784 ? BrightnessSynchronizer.brightnessFloatToIntSetting(mContext, brightness) 2785 : BrightnessSynchronizer.brightnessFloatToInt(brightness); 2786 mBatteryStats.noteScreenBrightness(brightnessInt); 2787 } catch (RemoteException e) { 2788 // same process 2789 } 2790 } 2791 } 2792 reportStats(float brightness)2793 private void reportStats(float brightness) { 2794 if (mLastStatsBrightness == brightness) { 2795 return; 2796 } 2797 2798 float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX; 2799 synchronized (mCachedBrightnessInfo) { 2800 if (mCachedBrightnessInfo.hbmTransitionPoint == null) { 2801 return; 2802 } 2803 hbmTransitionPoint = mCachedBrightnessInfo.hbmTransitionPoint.value; 2804 } 2805 2806 final boolean aboveTransition = brightness > hbmTransitionPoint; 2807 final boolean oldAboveTransition = mLastStatsBrightness > hbmTransitionPoint; 2808 2809 if (aboveTransition || oldAboveTransition) { 2810 mLastStatsBrightness = brightness; 2811 mHandler.removeMessages(MSG_STATSD_HBM_BRIGHTNESS); 2812 if (aboveTransition != oldAboveTransition) { 2813 // report immediately 2814 logHbmBrightnessStats(brightness, mDisplayStatsId); 2815 } else { 2816 // delay for rate limiting 2817 Message msg = mHandler.obtainMessage(); 2818 msg.what = MSG_STATSD_HBM_BRIGHTNESS; 2819 msg.arg1 = Float.floatToIntBits(brightness); 2820 msg.arg2 = mDisplayStatsId; 2821 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis() 2822 + BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS); 2823 } 2824 } 2825 } 2826 logHbmBrightnessStats(float brightness, int displayStatsId)2827 private void logHbmBrightnessStats(float brightness, int displayStatsId) { 2828 synchronized (mHandler) { 2829 FrameworkStatsLog.write( 2830 FrameworkStatsLog.DISPLAY_HBM_BRIGHTNESS_CHANGED, displayStatsId, brightness); 2831 } 2832 } 2833 2834 // Return bucket index of range_[left]_[right] where 2835 // left <= nits < right nitsToRangeIndex(float nits)2836 private int nitsToRangeIndex(float nits) { 2837 for (int i = 0; i < BRIGHTNESS_RANGE_BOUNDARIES.length; i++) { 2838 if (nits < BRIGHTNESS_RANGE_BOUNDARIES[i]) { 2839 return BRIGHTNESS_RANGE_INDEX[i]; 2840 } 2841 } 2842 return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3000_INF; 2843 } 2844 convertBrightnessReasonToStatsEnum(int brightnessReason)2845 private int convertBrightnessReasonToStatsEnum(int brightnessReason) { 2846 switch(brightnessReason) { 2847 case BrightnessReason.REASON_UNKNOWN: 2848 return FrameworkStatsLog 2849 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN; 2850 case BrightnessReason.REASON_MANUAL: 2851 return FrameworkStatsLog 2852 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_MANUAL; 2853 case BrightnessReason.REASON_DOZE: 2854 return FrameworkStatsLog 2855 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE; 2856 case BrightnessReason.REASON_DOZE_DEFAULT: 2857 return FrameworkStatsLog 2858 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE_DEFAULT; 2859 case BrightnessReason.REASON_AUTOMATIC: 2860 return FrameworkStatsLog 2861 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_AUTOMATIC; 2862 case BrightnessReason.REASON_SCREEN_OFF: 2863 return FrameworkStatsLog 2864 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF; 2865 case BrightnessReason.REASON_OVERRIDE: 2866 return FrameworkStatsLog 2867 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_OVERRIDE; 2868 case BrightnessReason.REASON_TEMPORARY: 2869 return FrameworkStatsLog 2870 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_TEMPORARY; 2871 case BrightnessReason.REASON_BOOST: 2872 return FrameworkStatsLog 2873 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_BOOST; 2874 case BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: 2875 return FrameworkStatsLog 2876 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF_BRIGHTNESS_SENSOR; 2877 case BrightnessReason.REASON_FOLLOWER: 2878 return FrameworkStatsLog 2879 .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_FOLLOWER; 2880 } 2881 return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN; 2882 } 2883 logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness)2884 private void logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness) { 2885 int modifier = event.getReason().getModifier(); 2886 int flags = event.getFlags(); 2887 // It's easier to check if the brightness is at maximum level using the brightness 2888 // value untouched by any modifiers 2889 boolean brightnessIsMax = unmodifiedBrightness == event.getHbmMax(); 2890 float brightnessInNits = 2891 mDisplayBrightnessController.convertToAdjustedNits(event.getBrightness()); 2892 float appliedLowPowerMode = event.isLowPowerModeSet() ? event.getPowerFactor() : -1f; 2893 int appliedRbcStrength = event.isRbcEnabled() ? event.getRbcStrength() : -1; 2894 float appliedHbmMaxNits = 2895 event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF 2896 ? -1f : mDisplayBrightnessController.convertToAdjustedNits(event.getHbmMax()); 2897 // thermalCapNits set to -1 if not currently capping max brightness 2898 float appliedThermalCapNits = 2899 event.getThermalMax() == PowerManager.BRIGHTNESS_MAX 2900 ? -1f : mDisplayBrightnessController.convertToAdjustedNits(event.getThermalMax()); 2901 if (mIsDisplayInternal) { 2902 FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED, 2903 mDisplayBrightnessController 2904 .convertToAdjustedNits(event.getInitialBrightness()), 2905 brightnessInNits, 2906 event.getLux(), 2907 event.getPhysicalDisplayId(), 2908 event.wasShortTermModelActive(), 2909 appliedLowPowerMode, 2910 appliedRbcStrength, 2911 appliedHbmMaxNits, 2912 appliedThermalCapNits, 2913 event.isAutomaticBrightnessEnabled(), 2914 FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL, 2915 convertBrightnessReasonToStatsEnum(event.getReason().getReason()), 2916 nitsToRangeIndex(brightnessInNits), 2917 brightnessIsMax, 2918 event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT, 2919 event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR, 2920 (modifier & BrightnessReason.MODIFIER_LOW_POWER) > 0, 2921 mBrightnessClamperController.getBrightnessMaxReason(), 2922 // TODO: (flc) add brightnessMinReason here too. 2923 (modifier & BrightnessReason.MODIFIER_DIMMED) > 0, 2924 event.isRbcEnabled(), 2925 (flags & BrightnessEvent.FLAG_INVALID_LUX) > 0, 2926 (flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0, 2927 (flags & BrightnessEvent.FLAG_USER_SET) > 0, 2928 event.getAutoBrightnessMode() == AUTO_BRIGHTNESS_MODE_IDLE, 2929 (flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0); 2930 } 2931 } 2932 2933 /** 2934 * Indicates whether the display state is ready to update. If this is the default display, we 2935 * want to update it right away so that we can draw the boot animation on it. If it is not 2936 * the default display, drawing the boot animation on it would look incorrect, so we need 2937 * to wait until boot is completed. 2938 * @return True if the display state is ready to update 2939 */ readyToUpdateDisplayState()2940 private boolean readyToUpdateDisplayState() { 2941 return mDisplayId == Display.DEFAULT_DISPLAY || mBootCompleted; 2942 } 2943 2944 private final class DisplayControllerHandler extends Handler { DisplayControllerHandler(Looper looper)2945 DisplayControllerHandler(Looper looper) { 2946 super(looper, null, true /*async*/); 2947 } 2948 2949 @Override handleMessage(Message msg)2950 public void handleMessage(Message msg) { 2951 switch (msg.what) { 2952 case MSG_UPDATE_POWER_STATE: 2953 updatePowerState(); 2954 break; 2955 2956 case MSG_SCREEN_ON_UNBLOCKED: 2957 if (mPendingScreenOnUnblocker == msg.obj) { 2958 unblockScreenOn(); 2959 updatePowerState(); 2960 } 2961 break; 2962 case MSG_SCREEN_OFF_UNBLOCKED: 2963 if (mPendingScreenOffUnblocker == msg.obj) { 2964 unblockScreenOff(); 2965 updatePowerState(); 2966 } 2967 break; 2968 case MSG_OFFLOADING_SCREEN_ON_UNBLOCKED: 2969 if (mDisplayOffloadSession == msg.obj) { 2970 unblockScreenOnByDisplayOffload(); 2971 updatePowerState(); 2972 } 2973 break; 2974 case MSG_CONFIGURE_BRIGHTNESS: 2975 BrightnessConfiguration brightnessConfiguration = 2976 (BrightnessConfiguration) msg.obj; 2977 mAutomaticBrightnessStrategy.setBrightnessConfiguration(brightnessConfiguration, 2978 msg.arg1 == 1); 2979 if (mBrightnessTracker != null) { 2980 mBrightnessTracker 2981 .setShouldCollectColorSample(brightnessConfiguration != null 2982 && brightnessConfiguration.shouldCollectColorSamples()); 2983 } 2984 updatePowerState(); 2985 break; 2986 2987 case MSG_SET_TEMPORARY_BRIGHTNESS: 2988 // TODO: Should we have a a timeout for the temporary brightness? 2989 mDisplayBrightnessController 2990 .setTemporaryBrightness(Float.intBitsToFloat(msg.arg1)); 2991 updatePowerState(); 2992 break; 2993 2994 case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT: 2995 mAutomaticBrightnessStrategy 2996 .setTemporaryAutoBrightnessAdjustment(Float.intBitsToFloat(msg.arg1)); 2997 updatePowerState(); 2998 break; 2999 3000 case MSG_STOP: 3001 cleanupHandlerThreadAfterStop(); 3002 break; 3003 3004 case MSG_UPDATE_BRIGHTNESS: 3005 if (mStopped) { 3006 return; 3007 } 3008 handleSettingsChange(); 3009 break; 3010 3011 case MSG_UPDATE_RBC: 3012 handleRbcChanged(); 3013 break; 3014 3015 case MSG_BRIGHTNESS_RAMP_DONE: 3016 if (mPowerState != null) { 3017 final float brightness = mPowerState.getScreenBrightness(); 3018 reportStats(brightness); 3019 } 3020 break; 3021 3022 case MSG_STATSD_HBM_BRIGHTNESS: 3023 logHbmBrightnessStats(Float.intBitsToFloat(msg.arg1), msg.arg2); 3024 break; 3025 3026 case MSG_SWITCH_USER: 3027 float newBrightness = msg.obj instanceof Float ? (float) msg.obj 3028 : PowerManager.BRIGHTNESS_INVALID_FLOAT; 3029 handleOnSwitchUser(msg.arg1, msg.arg2, newBrightness); 3030 break; 3031 3032 case MSG_BOOT_COMPLETED: 3033 mBootCompleted = true; 3034 updatePowerState(); 3035 break; 3036 3037 case MSG_SWITCH_AUTOBRIGHTNESS_MODE: 3038 boolean isIdle = msg.arg1 == AUTO_BRIGHTNESS_MODE_IDLE; 3039 if (mAutomaticBrightnessController != null) { 3040 mAutomaticBrightnessController.switchMode(msg.arg1, /* sendUpdate= */ true); 3041 setAnimatorRampSpeeds(isIdle); 3042 } 3043 setDwbcStrongMode(msg.arg1); 3044 break; 3045 3046 case MSG_SET_DWBC_COLOR_OVERRIDE: 3047 final float cct = Float.intBitsToFloat(msg.arg1); 3048 setDwbcOverride(cct); 3049 break; 3050 3051 case MSG_SET_DWBC_LOGGING_ENABLED: 3052 setDwbcLoggingEnabled(msg.arg1); 3053 break; 3054 case MSG_SET_BRIGHTNESS_FROM_OFFLOAD: 3055 if (mDisplayBrightnessController.setBrightnessFromOffload( 3056 Float.intBitsToFloat(msg.arg1))) { 3057 updatePowerState(); 3058 } 3059 break; 3060 } 3061 } 3062 } 3063 3064 3065 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)3066 SettingsObserver(Handler handler) { 3067 super(handler); 3068 } 3069 3070 @Override onChange(boolean selfChange, Uri uri)3071 public void onChange(boolean selfChange, Uri uri) { 3072 if (uri.equals(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE))) { 3073 mHandler.postAtTime(() -> { 3074 handleBrightnessModeChange(); 3075 updatePowerState(); 3076 }, mClock.uptimeMillis()); 3077 } else if (uri.equals(Settings.System.getUriFor( 3078 Settings.System.SCREEN_BRIGHTNESS_FOR_ALS))) { 3079 int preset = Settings.System.getIntForUser(mContext.getContentResolver(), 3080 Settings.System.SCREEN_BRIGHTNESS_FOR_ALS, 3081 Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL, 3082 UserHandle.USER_CURRENT); 3083 Slog.i(mTag, "Setting up auto-brightness for preset " 3084 + autoBrightnessPresetToString(preset)); 3085 setUpAutoBrightness(mContext, mHandler); 3086 sendUpdatePowerState(); 3087 } else { 3088 handleSettingsChange(); 3089 } 3090 } 3091 } 3092 3093 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener { 3094 @Override onScreenOn()3095 public void onScreenOn() { 3096 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this); 3097 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 3098 } 3099 } 3100 3101 private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener { 3102 @Override onScreenOff()3103 public void onScreenOff() { 3104 Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this); 3105 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); 3106 } 3107 } 3108 3109 @Override setAutoBrightnessLoggingEnabled(boolean enabled)3110 public void setAutoBrightnessLoggingEnabled(boolean enabled) { 3111 if (mAutomaticBrightnessController != null) { 3112 mAutomaticBrightnessController.setLoggingEnabled(enabled); 3113 } 3114 } 3115 3116 @Override // DisplayWhiteBalanceController.Callbacks updateWhiteBalance()3117 public void updateWhiteBalance() { 3118 sendUpdatePowerState(); 3119 } 3120 3121 @Override setDisplayWhiteBalanceLoggingEnabled(boolean enabled)3122 public void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) { 3123 Message msg = mHandler.obtainMessage(); 3124 msg.what = MSG_SET_DWBC_LOGGING_ENABLED; 3125 msg.arg1 = enabled ? 1 : 0; 3126 msg.sendToTarget(); 3127 } 3128 3129 @Override setAmbientColorTemperatureOverride(float cct)3130 public void setAmbientColorTemperatureOverride(float cct) { 3131 Message msg = mHandler.obtainMessage(); 3132 msg.what = MSG_SET_DWBC_COLOR_OVERRIDE; 3133 msg.arg1 = Float.floatToIntBits(cct); 3134 msg.sendToTarget(); 3135 } 3136 3137 /** Functional interface for providing time. */ 3138 @VisibleForTesting 3139 interface Clock { 3140 /** 3141 * Returns current time in milliseconds since boot, not counting time spent in deep sleep. 3142 */ uptimeMillis()3143 long uptimeMillis(); 3144 } 3145 3146 @VisibleForTesting 3147 static class Injector { getClock()3148 Clock getClock() { 3149 return SystemClock::uptimeMillis; 3150 } 3151 getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState)3152 DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, 3153 int displayId, int displayState) { 3154 return new DisplayPowerState(blanker, colorFade, displayId, displayState); 3155 } 3156 getDualRampAnimator(DisplayPowerState dps, FloatProperty<DisplayPowerState> firstProperty, FloatProperty<DisplayPowerState> secondProperty)3157 DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps, 3158 FloatProperty<DisplayPowerState> firstProperty, 3159 FloatProperty<DisplayPowerState> secondProperty) { 3160 return new DualRampAnimator(dps, firstProperty, secondProperty); 3161 } 3162 getWakelockController(int displayId, DisplayPowerCallbacks displayPowerCallbacks)3163 WakelockController getWakelockController(int displayId, 3164 DisplayPowerCallbacks displayPowerCallbacks) { 3165 return new WakelockController(displayId, displayPowerCallbacks); 3166 } 3167 getDisplayPowerProximityStateController( WakelockController wakelockController, DisplayDeviceConfig displayDeviceConfig, Looper looper, Runnable nudgeUpdatePowerState, int displayId, SensorManager sensorManager)3168 DisplayPowerProximityStateController getDisplayPowerProximityStateController( 3169 WakelockController wakelockController, DisplayDeviceConfig displayDeviceConfig, 3170 Looper looper, Runnable nudgeUpdatePowerState, 3171 int displayId, SensorManager sensorManager) { 3172 return new DisplayPowerProximityStateController(wakelockController, displayDeviceConfig, 3173 looper, nudgeUpdatePowerState, 3174 displayId, sensorManager, /* injector= */ null); 3175 } 3176 getAutomaticBrightnessController( AutomaticBrightnessController.Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, long brighteningLightDebounceConfigIdle, long darkeningLightDebounceConfigIdle, boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds, HysteresisLevels screenBrightnessThresholds, HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, BrightnessRangeController brightnessModeController, BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux, float userNits, BrightnessClamperController brightnessClamperController, DisplayManagerFlags displayManagerFlags)3177 AutomaticBrightnessController getAutomaticBrightnessController( 3178 AutomaticBrightnessController.Callbacks callbacks, Looper looper, 3179 SensorManager sensorManager, Sensor lightSensor, 3180 SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, 3181 int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, 3182 float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, 3183 long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, 3184 long brighteningLightDebounceConfigIdle, long darkeningLightDebounceConfigIdle, 3185 boolean resetAmbientLuxAfterWarmUpConfig, 3186 HysteresisLevels ambientBrightnessThresholds, 3187 HysteresisLevels screenBrightnessThresholds, 3188 HysteresisLevels ambientBrightnessThresholdsIdle, 3189 HysteresisLevels screenBrightnessThresholdsIdle, Context context, 3190 BrightnessRangeController brightnessModeController, 3191 BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, 3192 int ambientLightHorizonLong, float userLux, float userNits, 3193 BrightnessClamperController brightnessClamperController, 3194 DisplayManagerFlags displayManagerFlags) { 3195 3196 return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor, 3197 brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin, 3198 brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate, 3199 brighteningLightDebounceConfig, darkeningLightDebounceConfig, 3200 brighteningLightDebounceConfigIdle, darkeningLightDebounceConfigIdle, 3201 resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds, 3202 screenBrightnessThresholds, ambientBrightnessThresholdsIdle, 3203 screenBrightnessThresholdsIdle, context, brightnessModeController, 3204 brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux, 3205 userNits, displayManagerFlags); 3206 } 3207 getDefaultModeBrightnessMapper(Context context, DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController displayWhiteBalanceController)3208 BrightnessMappingStrategy getDefaultModeBrightnessMapper(Context context, 3209 DisplayDeviceConfig displayDeviceConfig, 3210 DisplayWhiteBalanceController displayWhiteBalanceController) { 3211 return BrightnessMappingStrategy.create(context, displayDeviceConfig, 3212 AUTO_BRIGHTNESS_MODE_DEFAULT, displayWhiteBalanceController); 3213 } 3214 getScreenOffBrightnessSensorController( SensorManager sensorManager, Sensor lightSensor, Handler handler, ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux, BrightnessMappingStrategy brightnessMapper)3215 ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController( 3216 SensorManager sensorManager, 3217 Sensor lightSensor, 3218 Handler handler, 3219 ScreenOffBrightnessSensorController.Clock clock, 3220 int[] sensorValueToLux, 3221 BrightnessMappingStrategy brightnessMapper) { 3222 return new ScreenOffBrightnessSensorController( 3223 sensorManager, 3224 lightSensor, 3225 handler, 3226 clock, 3227 sensorValueToLux, 3228 brightnessMapper 3229 ); 3230 } 3231 getHighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken, String displayUniqueId, float brightnessMin, float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData, HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg, Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context)3232 HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width, 3233 int height, IBinder displayToken, String displayUniqueId, float brightnessMin, 3234 float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData, 3235 HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg, 3236 Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, 3237 Context context) { 3238 return new HighBrightnessModeController(handler, width, height, displayToken, 3239 displayUniqueId, brightnessMin, brightnessMax, hbmData, hdrBrightnessCfg, 3240 hbmChangeCallback, hbmMetadata, context); 3241 } 3242 getBrightnessRangeController( HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info)3243 BrightnessRangeController getBrightnessRangeController( 3244 HighBrightnessModeController hbmController, Runnable modeChangeCallback, 3245 DisplayDeviceConfig displayDeviceConfig, Handler handler, 3246 DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { 3247 return new BrightnessRangeController(hbmController, 3248 modeChangeCallback, displayDeviceConfig, handler, flags, displayToken, info); 3249 } 3250 getBrightnessClamperController(Handler handler, BrightnessClamperController.ClamperChangeListener clamperChangeListener, BrightnessClamperController.DisplayDeviceData data, Context context, DisplayManagerFlags flags, SensorManager sensorManager)3251 BrightnessClamperController getBrightnessClamperController(Handler handler, 3252 BrightnessClamperController.ClamperChangeListener clamperChangeListener, 3253 BrightnessClamperController.DisplayDeviceData data, Context context, 3254 DisplayManagerFlags flags, SensorManager sensorManager) { 3255 3256 return new BrightnessClamperController(handler, clamperChangeListener, data, context, 3257 flags, sensorManager); 3258 } 3259 getDisplayWhiteBalanceController(Handler handler, SensorManager sensorManager, Resources resources)3260 DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler, 3261 SensorManager sensorManager, Resources resources) { 3262 return DisplayWhiteBalanceFactory.create(handler, 3263 sensorManager, resources); 3264 } 3265 isColorFadeEnabled()3266 boolean isColorFadeEnabled() { 3267 return !ActivityManager.isLowRamDeviceStatic(); 3268 } 3269 } 3270 3271 static class CachedBrightnessInfo { 3272 public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT); 3273 public MutableFloat adjustedBrightness = 3274 new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT); 3275 public MutableFloat brightnessMin = 3276 new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT); 3277 public MutableFloat brightnessMax = 3278 new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT); 3279 public MutableInt hbmMode = new MutableInt(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF); 3280 public MutableFloat hbmTransitionPoint = 3281 new MutableFloat(HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID); 3282 public MutableInt brightnessMaxReason = 3283 new MutableInt(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); 3284 checkAndSetFloat(MutableFloat mf, float f)3285 public boolean checkAndSetFloat(MutableFloat mf, float f) { 3286 if (mf.value != f) { 3287 mf.value = f; 3288 return true; 3289 } 3290 return false; 3291 } 3292 checkAndSetInt(MutableInt mi, int i)3293 public boolean checkAndSetInt(MutableInt mi, int i) { 3294 if (mi.value != i) { 3295 mi.value = i; 3296 return true; 3297 } 3298 return false; 3299 } 3300 } 3301 } 3302