1 /* 2 * Copyright (C) 2023 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 package com.android.server.display.brightness.strategy; 17 18 import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE; 19 20 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR; 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 24 import android.annotation.Nullable; 25 import android.content.Context; 26 import android.hardware.display.BrightnessConfiguration; 27 import android.os.PowerManager; 28 import android.os.UserHandle; 29 import android.provider.Settings; 30 import android.view.Display; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.server.display.AutomaticBrightnessController; 34 import com.android.server.display.DisplayBrightnessState; 35 import com.android.server.display.brightness.BrightnessEvent; 36 import com.android.server.display.brightness.BrightnessReason; 37 import com.android.server.display.brightness.BrightnessUtils; 38 import com.android.server.display.brightness.StrategyExecutionRequest; 39 import com.android.server.display.brightness.StrategySelectionNotifyRequest; 40 import com.android.server.display.feature.DisplayManagerFlags; 41 42 import java.io.PrintWriter; 43 44 /** 45 * Helps manage the brightness based on the ambient environment (Ambient Light/lux sensor) using 46 * mappings from lux to nits to brightness, configured in the 47 * {@link com.android.server.display.DisplayDeviceConfig} class. This class inherently assumes 48 * that it is being executed from the power thread, and hence doesn't synchronize 49 * any of its resources 50 */ 51 public class AutomaticBrightnessStrategy extends AutomaticBrightnessStrategy2 52 implements DisplayBrightnessStrategy{ 53 private final Context mContext; 54 // The DisplayId of the associated logical display 55 private final int mDisplayId; 56 // The last auto brightness adjustment that was set by the user and is not temporary. Set to 57 // Float.NaN when an auto-brightness adjustment hasn't been recorded yet. 58 private float mAutoBrightnessAdjustment; 59 // The pending auto brightness adjustment that will take effect on the next power state update. 60 private float mPendingAutoBrightnessAdjustment; 61 // The temporary auto brightness adjustment. This was historically used when a user interacts 62 // with the adjustment slider but hasn't settled on a choice yet. 63 // Set to PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set. 64 private float mTemporaryAutoBrightnessAdjustment; 65 // Indicates if the temporary auto brightness adjustment has been applied while updating the 66 // associated display brightness 67 private boolean mAppliedTemporaryAutoBrightnessAdjustment; 68 // Indicates if the auto brightness adjustment has happened. 69 private boolean mAutoBrightnessAdjustmentChanged; 70 // Indicates the reasons for the auto-brightness adjustment 71 private int mAutoBrightnessAdjustmentReasonsFlags = 0; 72 // Indicates if the short term model should be reset before fetching the new brightness 73 // Todo(273543270): Short term model is an internal information of 74 // AutomaticBrightnessController and shouldn't be exposed outside of that class 75 private boolean mShouldResetShortTermModel = false; 76 // Remembers whether the auto-brightness has been applied in the latest brightness update. 77 private boolean mAppliedAutoBrightness = false; 78 // The controller for the automatic brightness level. 79 @Nullable 80 private AutomaticBrightnessController mAutomaticBrightnessController; 81 // The system setting denoting if the auto-brightness for the current user is enabled or not 82 private boolean mUseAutoBrightness = false; 83 // Indicates if the auto-brightness is currently enabled or not. It's possible that even if 84 // the user has enabled the auto-brightness from the settings, it is disabled because the 85 // display is off 86 private boolean mIsAutoBrightnessEnabled = false; 87 // Indicates if auto-brightness is disabled due to the display being off. Needed for metric 88 // purposes. 89 private boolean mAutoBrightnessDisabledDueToDisplayOff; 90 // If the auto-brightness model for the last manual changes done by the user. 91 private boolean mIsShortTermModelActive = false; 92 93 // The BrightnessConfiguration currently being used 94 // Todo(273543270): BrightnessConfiguration is an internal implementation detail of 95 // AutomaticBrightnessController, and AutomaticBrightnessStrategy shouldn't be aware of its 96 // existence. 97 @Nullable 98 private BrightnessConfiguration mBrightnessConfiguration; 99 100 // Indicates if the strategy is already configured for a request, in which case we wouldn't 101 // want to re-evaluate the auto-brightness state 102 private boolean mIsConfigured; 103 104 private Injector mInjector; 105 106 private DisplayManagerFlags mDisplayManagerFlags; 107 108 // Indicates if the current auto-brightness should be ramped up or down slowly. 109 private boolean mIsSlowChange; 110 111 @VisibleForTesting AutomaticBrightnessStrategy(Context context, int displayId, Injector injector, DisplayManagerFlags displayManagerFlags)112 AutomaticBrightnessStrategy(Context context, int displayId, Injector injector, 113 DisplayManagerFlags displayManagerFlags) { 114 super(context, displayId); 115 mContext = context; 116 mDisplayId = displayId; 117 mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); 118 mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; 119 mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; 120 mDisplayManagerFlags = displayManagerFlags; 121 mInjector = (injector == null) ? new RealInjector() : injector; 122 } 123 AutomaticBrightnessStrategy(Context context, int displayId, DisplayManagerFlags displayManagerFlags)124 public AutomaticBrightnessStrategy(Context context, int displayId, 125 DisplayManagerFlags displayManagerFlags) { 126 this(context, displayId, null, displayManagerFlags); 127 } 128 129 /** 130 * Sets up the automatic brightness states of this class. Also configures 131 * AutomaticBrightnessController accounting for any manual changes made by the user. 132 */ setAutoBrightnessState(int targetDisplayState, boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy, boolean useNormalBrightnessForDoze, float lastUserSetScreenBrightness, boolean userSetBrightnessChanged, boolean isBedtimeModeWearEnabled)133 public void setAutoBrightnessState(int targetDisplayState, 134 boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy, 135 boolean useNormalBrightnessForDoze, float lastUserSetScreenBrightness, 136 boolean userSetBrightnessChanged, boolean isBedtimeModeWearEnabled) { 137 // We are still in the process of updating the power state, so there's no need to trigger 138 // an update again 139 switchMode(targetDisplayState, useNormalBrightnessForDoze, policy, isBedtimeModeWearEnabled, 140 /* sendUpdate= */ false); 141 142 // If the policy is POLICY_DOZE and the display state is not STATE_OFF, auto-brightness 143 // should only be enabled if the config allows it 144 final boolean autoBrightnessEnabledInDoze = allowAutoBrightnessWhileDozingConfig 145 && policy == POLICY_DOZE && targetDisplayState != Display.STATE_OFF; 146 147 mIsAutoBrightnessEnabled = shouldUseAutoBrightness() 148 && ((targetDisplayState == Display.STATE_ON && policy != POLICY_DOZE) 149 || autoBrightnessEnabledInDoze) 150 && brightnessReason != BrightnessReason.REASON_OVERRIDE 151 && mAutomaticBrightnessController != null; 152 mAutoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness() 153 && !((targetDisplayState == Display.STATE_ON && policy != POLICY_DOZE) 154 || autoBrightnessEnabledInDoze); 155 final int autoBrightnessState = mIsAutoBrightnessEnabled 156 && brightnessReason != BrightnessReason.REASON_FOLLOWER 157 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED 158 : mAutoBrightnessDisabledDueToDisplayOff 159 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE 160 : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED; 161 162 accommodateUserBrightnessChanges(userSetBrightnessChanged, lastUserSetScreenBrightness, 163 policy, targetDisplayState, useNormalBrightnessForDoze, mBrightnessConfiguration, 164 autoBrightnessState); 165 mIsConfigured = true; 166 } 167 setIsConfigured(boolean configure)168 public void setIsConfigured(boolean configure) { 169 mIsConfigured = configure; 170 } 171 isAutoBrightnessEnabled()172 public boolean isAutoBrightnessEnabled() { 173 return mIsAutoBrightnessEnabled; 174 } 175 176 /** 177 * Validates if the auto-brightness strategy is valid or not considering the current system 178 * state. 179 */ isAutoBrightnessValid()180 public boolean isAutoBrightnessValid() { 181 boolean isValid = false; 182 if (isAutoBrightnessEnabled()) { 183 float brightness = getAutomaticScreenBrightness(null, 184 /* isAutomaticBrightnessAdjusted = */ false); 185 if (BrightnessUtils.isValidBrightnessValue(brightness) 186 || brightness == PowerManager.BRIGHTNESS_OFF_FLOAT) { 187 isValid = true; 188 } 189 } 190 191 // A change is slow when the auto-brightness was already applied, and there are no new 192 // auto-brightness adjustments from an external client(e.g. Moving the slider). As such, 193 // it is important to record this value before applying the current auto-brightness. 194 mIsSlowChange = hasAppliedAutoBrightness() && !getAutoBrightnessAdjustmentChanged(); 195 setAutoBrightnessApplied(isValid); 196 return isValid; 197 } 198 isAutoBrightnessDisabledDueToDisplayOff()199 public boolean isAutoBrightnessDisabledDueToDisplayOff() { 200 return mAutoBrightnessDisabledDueToDisplayOff; 201 } 202 203 /** 204 * Updates the {@link BrightnessConfiguration} that is currently being used by the associated 205 * display. 206 */ setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration, boolean shouldResetShortTermModel)207 public void setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration, 208 boolean shouldResetShortTermModel) { 209 mBrightnessConfiguration = brightnessConfiguration; 210 setShouldResetShortTermModel(shouldResetShortTermModel); 211 } 212 213 /** 214 * Promotes the pending auto-brightness adjustments which are yet to be applied to the current 215 * adjustments. Note that this is not applying the new adjustments to the AutoBrightness mapping 216 * strategies, but is only accommodating the changes in this class. 217 */ processPendingAutoBrightnessAdjustments()218 public boolean processPendingAutoBrightnessAdjustments() { 219 mAutoBrightnessAdjustmentChanged = false; 220 if (Float.isNaN(mPendingAutoBrightnessAdjustment)) { 221 return false; 222 } 223 if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) { 224 mPendingAutoBrightnessAdjustment = Float.NaN; 225 return false; 226 } 227 mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment; 228 mPendingAutoBrightnessAdjustment = Float.NaN; 229 mTemporaryAutoBrightnessAdjustment = Float.NaN; 230 mAutoBrightnessAdjustmentChanged = true; 231 return true; 232 } 233 234 /** 235 * Updates the associated AutomaticBrightnessController 236 */ setAutomaticBrightnessController( AutomaticBrightnessController automaticBrightnessController)237 public void setAutomaticBrightnessController( 238 AutomaticBrightnessController automaticBrightnessController) { 239 if (automaticBrightnessController == mAutomaticBrightnessController) { 240 return; 241 } 242 if (mAutomaticBrightnessController != null) { 243 mAutomaticBrightnessController.stop(); 244 } 245 mAutomaticBrightnessController = automaticBrightnessController; 246 } 247 248 /** 249 * Returns if the auto-brightness of the associated display has been enabled or not 250 */ shouldUseAutoBrightness()251 public boolean shouldUseAutoBrightness() { 252 return mUseAutoBrightness; 253 } 254 255 /** 256 * Sets the auto-brightness state of the associated display. Called when the user makes a change 257 * in the system setting to enable/disable the auto-brightness. 258 */ setUseAutoBrightness(boolean useAutoBrightness)259 public void setUseAutoBrightness(boolean useAutoBrightness) { 260 mUseAutoBrightness = useAutoBrightness; 261 } 262 263 /** 264 * Returns if the user made brightness change events(Typically when they interact with the 265 * brightness slider) were accommodated in the auto-brightness mapping strategies. This doesn't 266 * account for the latest changes that have been made by the user. 267 */ isShortTermModelActive()268 public boolean isShortTermModelActive() { 269 return mIsShortTermModelActive; 270 } 271 272 /** 273 * Sets the pending auto-brightness adjustments in the system settings. Executed 274 * when there is a change in the brightness system setting, or when there is a user switch. 275 */ updatePendingAutoBrightnessAdjustments()276 public void updatePendingAutoBrightnessAdjustments() { 277 final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(), 278 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT); 279 mPendingAutoBrightnessAdjustment = Float.isNaN(adj) ? Float.NaN 280 : BrightnessUtils.clampBrightnessAdjustment(adj); 281 } 282 283 /** 284 * Sets the temporary auto-brightness adjustments 285 */ setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment)286 public void setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment) { 287 mTemporaryAutoBrightnessAdjustment = temporaryAutoBrightnessAdjustment; 288 } 289 290 @Override updateBrightness( StrategyExecutionRequest strategyExecutionRequest)291 public DisplayBrightnessState updateBrightness( 292 StrategyExecutionRequest strategyExecutionRequest) { 293 BrightnessReason brightnessReason = new BrightnessReason(); 294 brightnessReason.setReason(BrightnessReason.REASON_AUTOMATIC); 295 BrightnessEvent brightnessEvent = mInjector.getBrightnessEvent(mDisplayId); 296 297 // AutoBrightness adjustments were already applied while checking the validity of this 298 // strategy. Reapplying them again will result in incorrect adjustment reason flags as we 299 // might end up assuming no adjustments are applied 300 float brightness = getAutomaticScreenBrightness(brightnessEvent, 301 /* isAutomaticBrightnessAdjusted = */ true); 302 return new DisplayBrightnessState.Builder() 303 .setBrightness(brightness) 304 .setBrightnessReason(brightnessReason) 305 .setDisplayBrightnessStrategyName(getName()) 306 .setIsSlowChange(mIsSlowChange) 307 .setBrightnessEvent(brightnessEvent) 308 .setBrightnessAdjustmentFlag(mAutoBrightnessAdjustmentReasonsFlags) 309 .setShouldUpdateScreenBrightnessSetting( 310 brightness != strategyExecutionRequest.getCurrentScreenBrightness()) 311 .setIsUserInitiatedChange(getAutoBrightnessAdjustmentChanged() 312 || strategyExecutionRequest.isUserSetBrightnessChanged()) 313 .build(); 314 } 315 316 @Override getName()317 public String getName() { 318 return "AutomaticBrightnessStrategy"; 319 } 320 321 /** 322 * Dumps the state of this class. 323 */ dump(PrintWriter writer)324 public void dump(PrintWriter writer) { 325 writer.println("AutomaticBrightnessStrategy:"); 326 writer.println(" mDisplayId=" + mDisplayId); 327 writer.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); 328 writer.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment); 329 writer.println( 330 " mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment); 331 writer.println(" mShouldResetShortTermModel=" + mShouldResetShortTermModel); 332 writer.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness); 333 writer.println(" mAutoBrightnessAdjustmentChanged=" + mAutoBrightnessAdjustmentChanged); 334 writer.println(" mAppliedTemporaryAutoBrightnessAdjustment=" 335 + mAppliedTemporaryAutoBrightnessAdjustment); 336 writer.println(" mUseAutoBrightness=" + mUseAutoBrightness); 337 writer.println(" mWasShortTermModelActive=" + mIsShortTermModelActive); 338 writer.println(" mAutoBrightnessAdjustmentReasonsFlags=" 339 + mAutoBrightnessAdjustmentReasonsFlags); 340 } 341 342 @Override strategySelectionPostProcessor( StrategySelectionNotifyRequest strategySelectionNotifyRequest)343 public void strategySelectionPostProcessor( 344 StrategySelectionNotifyRequest strategySelectionNotifyRequest) { 345 if (!mIsConfigured) { 346 setAutoBrightnessState(strategySelectionNotifyRequest.getTargetDisplayState(), 347 strategySelectionNotifyRequest.isAllowAutoBrightnessWhileDozingConfig(), 348 strategySelectionNotifyRequest.getSelectedDisplayBrightnessStrategy() 349 .getReason(), 350 strategySelectionNotifyRequest.getDisplayPowerRequest().policy, 351 strategySelectionNotifyRequest.getDisplayPowerRequest() 352 .useNormalBrightnessForDoze, 353 strategySelectionNotifyRequest.getLastUserSetScreenBrightness(), 354 strategySelectionNotifyRequest.isUserSetBrightnessChanged(), 355 strategySelectionNotifyRequest.isBedtimeModeWearEnabled()); 356 } 357 mIsConfigured = false; 358 } 359 360 @Override getReason()361 public int getReason() { 362 return BrightnessReason.REASON_AUTOMATIC; 363 } 364 365 /** 366 * Indicates if any auto-brightness adjustments have happened since the last auto-brightness was 367 * set. 368 */ getAutoBrightnessAdjustmentChanged()369 public boolean getAutoBrightnessAdjustmentChanged() { 370 return mAutoBrightnessAdjustmentChanged; 371 } 372 373 /** 374 * Returns whether the latest temporary auto-brightness adjustments have been applied or not 375 */ isTemporaryAutoBrightnessAdjustmentApplied()376 public boolean isTemporaryAutoBrightnessAdjustmentApplied() { 377 return mAppliedTemporaryAutoBrightnessAdjustment; 378 } 379 380 /** 381 * Evaluates the target automatic brightness of the associated display. 382 * @param brightnessEvent Event object to populate with details about why the specific 383 * brightness was chosen. 384 */ getAutomaticScreenBrightness(BrightnessEvent brightnessEvent, boolean isAutomaticBrightnessAdjusted)385 public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent, 386 boolean isAutomaticBrightnessAdjusted) { 387 float brightness = (mAutomaticBrightnessController != null) 388 ? mAutomaticBrightnessController.getAutomaticScreenBrightness(brightnessEvent) 389 : PowerManager.BRIGHTNESS_INVALID_FLOAT; 390 if (!isAutomaticBrightnessAdjusted) { 391 adjustAutomaticBrightnessStateIfValid(brightness); 392 } 393 return brightness; 394 } 395 396 /** 397 * Returns if the auto brightness has been applied 398 */ hasAppliedAutoBrightness()399 public boolean hasAppliedAutoBrightness() { 400 return mAppliedAutoBrightness; 401 } 402 403 /** 404 * Used to adjust the state of this class when the automatic brightness value for the 405 * associated display is valid 406 */ 407 @VisibleForTesting adjustAutomaticBrightnessStateIfValid(float brightnessState)408 void adjustAutomaticBrightnessStateIfValid(float brightnessState) { 409 mAutoBrightnessAdjustmentReasonsFlags = isTemporaryAutoBrightnessAdjustmentApplied() 410 ? BrightnessReason.ADJUSTMENT_AUTO_TEMP 411 : BrightnessReason.ADJUSTMENT_AUTO; 412 float newAutoBrightnessAdjustment = 413 (mAutomaticBrightnessController != null) 414 ? mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment() 415 : 0.0f; 416 if (!Float.isNaN(newAutoBrightnessAdjustment) 417 && mAutoBrightnessAdjustment != newAutoBrightnessAdjustment) { 418 // If the auto-brightness controller has decided to change the adjustment value 419 // used, make sure that's reflected in settings. 420 putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment); 421 } else { 422 mAutoBrightnessAdjustmentReasonsFlags = 0; 423 } 424 } 425 426 /** 427 * Sets up the system to reset the short term model. Note that this will not reset the model 428 * right away, but ensures that the reset happens whenever the next brightness change happens 429 */ 430 @VisibleForTesting setShouldResetShortTermModel(boolean shouldResetShortTermModel)431 void setShouldResetShortTermModel(boolean shouldResetShortTermModel) { 432 mShouldResetShortTermModel = shouldResetShortTermModel; 433 } 434 435 @VisibleForTesting shouldResetShortTermModel()436 boolean shouldResetShortTermModel() { 437 return mShouldResetShortTermModel; 438 } 439 440 @VisibleForTesting getAutoBrightnessAdjustment()441 float getAutoBrightnessAdjustment() { 442 return mAutoBrightnessAdjustment; 443 } 444 445 @VisibleForTesting getPendingAutoBrightnessAdjustment()446 float getPendingAutoBrightnessAdjustment() { 447 return mPendingAutoBrightnessAdjustment; 448 } 449 450 @VisibleForTesting getTemporaryAutoBrightnessAdjustment()451 float getTemporaryAutoBrightnessAdjustment() { 452 return mTemporaryAutoBrightnessAdjustment; 453 } 454 455 @VisibleForTesting putAutoBrightnessAdjustmentSetting(float adjustment)456 void putAutoBrightnessAdjustmentSetting(float adjustment) { 457 if (mDisplayId == Display.DEFAULT_DISPLAY) { 458 mAutoBrightnessAdjustment = adjustment; 459 Settings.System.putFloatForUser(mContext.getContentResolver(), 460 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, 461 UserHandle.USER_CURRENT); 462 } 463 } 464 465 /** 466 * Sets if the auto-brightness is applied on the latest brightness change. 467 */ setAutoBrightnessApplied(boolean autoBrightnessApplied)468 public void setAutoBrightnessApplied(boolean autoBrightnessApplied) { 469 mAppliedAutoBrightness = autoBrightnessApplied; 470 } 471 472 /** 473 * Accommodates the latest manual changes made by the user. Also updates {@link 474 * AutomaticBrightnessController} about the changes and configures it accordingly. 475 */ 476 @VisibleForTesting accommodateUserBrightnessChanges(boolean userSetBrightnessChanged, float lastUserSetScreenBrightness, int policy, int displayState, boolean useNormalBrightnessForDoze, BrightnessConfiguration brightnessConfiguration, int autoBrightnessState)477 void accommodateUserBrightnessChanges(boolean userSetBrightnessChanged, 478 float lastUserSetScreenBrightness, int policy, int displayState, 479 boolean useNormalBrightnessForDoze, BrightnessConfiguration brightnessConfiguration, 480 int autoBrightnessState) { 481 // Update the pending auto-brightness adjustments if any. This typically checks and adjusts 482 // the state of the class if the user moves the brightness slider and has settled to a 483 // different value 484 processPendingAutoBrightnessAdjustments(); 485 // Update the temporary auto-brightness adjustments if any. This typically checks and 486 // adjusts the state of this class if the user is in the process of moving the brightness 487 // slider, but hasn't settled to any value yet 488 float autoBrightnessAdjustment = updateTemporaryAutoBrightnessAdjustments(); 489 mIsShortTermModelActive = false; 490 // Configure auto-brightness. 491 if (mAutomaticBrightnessController != null) { 492 // Accommodate user changes if any in the auto-brightness model 493 mAutomaticBrightnessController.configure(autoBrightnessState, 494 brightnessConfiguration, 495 lastUserSetScreenBrightness, 496 userSetBrightnessChanged, 497 autoBrightnessAdjustment, 498 mAutoBrightnessAdjustmentChanged, 499 policy, 500 displayState, 501 useNormalBrightnessForDoze, 502 mShouldResetShortTermModel); 503 mShouldResetShortTermModel = false; 504 // We take note if the user brightness point is still being used in the current 505 // auto-brightness model. 506 mIsShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints(); 507 } 508 } 509 switchMode(int state, boolean useNormalBrightnessForDoze, int policy, boolean isWearBedtimeModeEnabled, boolean sendUpdate)510 private void switchMode(int state, boolean useNormalBrightnessForDoze, int policy, 511 boolean isWearBedtimeModeEnabled, boolean sendUpdate) { 512 if (!mDisplayManagerFlags.areAutoBrightnessModesEnabled() 513 || mAutomaticBrightnessController == null 514 || mAutomaticBrightnessController.isInIdleMode()) { 515 return; 516 } 517 518 final boolean shouldUseBedtimeMode = 519 mDisplayManagerFlags.isAutoBrightnessModeBedtimeWearEnabled() 520 && isWearBedtimeModeEnabled; 521 if (shouldUseBedtimeMode) { 522 mAutomaticBrightnessController.switchMode(AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR, 523 sendUpdate); 524 return; 525 } 526 527 final boolean shouldUseDozeMode = 528 mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext) 529 ? (!useNormalBrightnessForDoze && policy == POLICY_DOZE) 530 || Display.isDozeState(state) 531 : Display.isDozeState(state); 532 if (shouldUseDozeMode) { 533 mAutomaticBrightnessController.switchMode(AUTO_BRIGHTNESS_MODE_DOZE, sendUpdate); 534 return; 535 } 536 537 mAutomaticBrightnessController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT, sendUpdate); 538 } 539 540 /** 541 * Evaluates if there are any temporary auto-brightness adjustments which is not applied yet. 542 * Temporary brightness adjustments happen when the user moves the brightness slider in the 543 * auto-brightness mode, but hasn't settled to a value yet 544 */ updateTemporaryAutoBrightnessAdjustments()545 private float updateTemporaryAutoBrightnessAdjustments() { 546 mAppliedTemporaryAutoBrightnessAdjustment = 547 !Float.isNaN(mTemporaryAutoBrightnessAdjustment); 548 // We do not update the mAutoBrightnessAdjustment with mTemporaryAutoBrightnessAdjustment 549 // since we have not settled to a value yet 550 return mAppliedTemporaryAutoBrightnessAdjustment 551 ? mTemporaryAutoBrightnessAdjustment : mAutoBrightnessAdjustment; 552 } 553 554 /** 555 * Returns the auto-brightness adjustment that is set in the system setting. 556 */ getAutoBrightnessAdjustmentSetting()557 private float getAutoBrightnessAdjustmentSetting() { 558 final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(), 559 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT); 560 return Float.isNaN(adj) ? 0.0f : BrightnessUtils.clampBrightnessAdjustment(adj); 561 } 562 563 @VisibleForTesting 564 interface Injector { getBrightnessEvent(int displayId)565 BrightnessEvent getBrightnessEvent(int displayId); 566 } 567 568 static class RealInjector implements Injector { getBrightnessEvent(int displayId)569 public BrightnessEvent getBrightnessEvent(int displayId) { 570 return new BrightnessEvent(displayId); 571 } 572 } 573 } 574