1 /* 2 * Copyright (C) 2024 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 android.annotation.Nullable; 21 import android.content.Context; 22 import android.hardware.display.BrightnessConfiguration; 23 import android.os.PowerManager; 24 import android.os.UserHandle; 25 import android.provider.Settings; 26 import android.view.Display; 27 28 import com.android.internal.annotations.VisibleForTesting; 29 import com.android.server.display.AutomaticBrightnessController; 30 import com.android.server.display.brightness.BrightnessEvent; 31 import com.android.server.display.brightness.BrightnessReason; 32 import com.android.server.display.brightness.BrightnessUtils; 33 import com.android.server.display.feature.DisplayManagerFlags; 34 35 import java.io.PrintWriter; 36 37 /** 38 * Helps manage the brightness based on the ambient environment (Ambient Light/lux sensor) using 39 * mappings from lux to nits to brightness, configured in the 40 * {@link com.android.server.display.DisplayDeviceConfig} class. This class inherently assumes 41 * that it is being executed from the power thread, and hence doesn't synchronize 42 * any of its resources 43 * 44 * @deprecated This class is relevant only while the 45 * {@link DisplayManagerFlags#isRefactorDisplayPowerControllerEnabled()} is not fully rolled out. 46 * Till then, please replicated your changes to {@link AutomaticBrightnessStrategy} as well. 47 */ 48 @Deprecated 49 public class AutomaticBrightnessStrategy2 { 50 private final Context mContext; 51 // The DisplayId of the associated logical display 52 private final int mDisplayId; 53 // The last auto brightness adjustment that was set by the user and is not temporary. Set to 54 // Float.NaN when an auto-brightness adjustment hasn't been recorded yet. 55 private float mAutoBrightnessAdjustment; 56 // The pending auto brightness adjustment that will take effect on the next power state update. 57 private float mPendingAutoBrightnessAdjustment; 58 // The temporary auto brightness adjustment. This was historically used when a user interacts 59 // with the adjustment slider but hasn't settled on a choice yet. 60 // Set to PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set. 61 private float mTemporaryAutoBrightnessAdjustment; 62 // Indicates if the temporary auto brightness adjustment has been applied while updating the 63 // associated display brightness 64 private boolean mAppliedTemporaryAutoBrightnessAdjustment; 65 // Indicates if the auto brightness adjustment has happened. 66 private boolean mAutoBrightnessAdjustmentChanged; 67 // Indicates the reasons for the auto-brightness adjustment 68 private int mAutoBrightnessAdjustmentReasonsFlags = 0; 69 // Indicates if the short term model should be reset before fetching the new brightness 70 // Todo(273543270): Short term model is an internal information of 71 // AutomaticBrightnessController and shouldn't be exposed outside of that class 72 private boolean mShouldResetShortTermModel = false; 73 // Remembers whether the auto-brightness has been applied in the latest brightness update. 74 private boolean mAppliedAutoBrightness = false; 75 // The controller for the automatic brightness level. 76 @Nullable 77 private AutomaticBrightnessController mAutomaticBrightnessController; 78 // The system setting denoting if the auto-brightness for the current user is enabled or not 79 private boolean mUseAutoBrightness = false; 80 // Indicates if the auto-brightness is currently enabled or not. It's possible that even if 81 // the user has enabled the auto-brightness from the settings, it is disabled because the 82 // display is off 83 private boolean mIsAutoBrightnessEnabled = false; 84 // Indicates if auto-brightness is disabled due to the display being off. Needed for metric 85 // purposes. 86 private boolean mAutoBrightnessDisabledDueToDisplayOff; 87 // If the auto-brightness model for the last manual changes done by the user. 88 private boolean mIsShortTermModelActive = false; 89 90 // The BrightnessConfiguration currently being used 91 // Todo(273543270): BrightnessConfiguration is an internal implementation detail of 92 // AutomaticBrightnessController, and AutomaticBrightnessStrategy shouldn't be aware of its 93 // existence. 94 @Nullable 95 private BrightnessConfiguration mBrightnessConfiguration; 96 AutomaticBrightnessStrategy2(Context context, int displayId)97 public AutomaticBrightnessStrategy2(Context context, int displayId) { 98 mContext = context; 99 mDisplayId = displayId; 100 mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); 101 mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; 102 mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; 103 } 104 105 /** 106 * Sets up the automatic brightness states of this class. Also configures 107 * AutomaticBrightnessController accounting for any manual changes made by the user. 108 */ setAutoBrightnessState(int targetDisplayState, boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy, boolean useNormalBrightnessForDoze, float lastUserSetScreenBrightness, boolean userSetBrightnessChanged, boolean isBedtimeModeEnabled)109 public void setAutoBrightnessState(int targetDisplayState, 110 boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy, 111 boolean useNormalBrightnessForDoze, float lastUserSetScreenBrightness, 112 boolean userSetBrightnessChanged, boolean isBedtimeModeEnabled) { 113 // If the policy is POLICY_DOZE and the display state is not STATE_OFF, auto-brightness 114 // should only be enabled if the config allows it 115 final boolean autoBrightnessEnabledInDoze = allowAutoBrightnessWhileDozingConfig 116 && policy == POLICY_DOZE && targetDisplayState != Display.STATE_OFF; 117 118 mIsAutoBrightnessEnabled = shouldUseAutoBrightness() 119 && ((targetDisplayState == Display.STATE_ON && policy != POLICY_DOZE) 120 || autoBrightnessEnabledInDoze) 121 && brightnessReason != BrightnessReason.REASON_OVERRIDE 122 && mAutomaticBrightnessController != null; 123 mAutoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness() 124 && !((targetDisplayState == Display.STATE_ON && policy != POLICY_DOZE) 125 || autoBrightnessEnabledInDoze); 126 final int autoBrightnessState = mIsAutoBrightnessEnabled 127 && brightnessReason != BrightnessReason.REASON_FOLLOWER 128 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED 129 : mAutoBrightnessDisabledDueToDisplayOff 130 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE 131 : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED; 132 133 accommodateUserBrightnessChanges(userSetBrightnessChanged, lastUserSetScreenBrightness, 134 policy, targetDisplayState, useNormalBrightnessForDoze, mBrightnessConfiguration, 135 autoBrightnessState); 136 } 137 isAutoBrightnessEnabled()138 public boolean isAutoBrightnessEnabled() { 139 return mIsAutoBrightnessEnabled; 140 } 141 isAutoBrightnessDisabledDueToDisplayOff()142 public boolean isAutoBrightnessDisabledDueToDisplayOff() { 143 return mAutoBrightnessDisabledDueToDisplayOff; 144 } 145 146 /** 147 * Updates the {@link BrightnessConfiguration} that is currently being used by the associated 148 * display. 149 */ setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration, boolean shouldResetShortTermModel)150 public void setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration, 151 boolean shouldResetShortTermModel) { 152 mBrightnessConfiguration = brightnessConfiguration; 153 setShouldResetShortTermModel(shouldResetShortTermModel); 154 } 155 156 /** 157 * Promotes the pending auto-brightness adjustments which are yet to be applied to the current 158 * adjustments. Note that this is not applying the new adjustments to the AutoBrightness mapping 159 * strategies, but is only accommodating the changes in this class. 160 */ processPendingAutoBrightnessAdjustments()161 public boolean processPendingAutoBrightnessAdjustments() { 162 mAutoBrightnessAdjustmentChanged = false; 163 if (Float.isNaN(mPendingAutoBrightnessAdjustment)) { 164 return false; 165 } 166 if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) { 167 mPendingAutoBrightnessAdjustment = Float.NaN; 168 return false; 169 } 170 mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment; 171 mPendingAutoBrightnessAdjustment = Float.NaN; 172 mTemporaryAutoBrightnessAdjustment = Float.NaN; 173 mAutoBrightnessAdjustmentChanged = true; 174 return true; 175 } 176 177 /** 178 * Updates the associated AutomaticBrightnessController 179 */ setAutomaticBrightnessController( AutomaticBrightnessController automaticBrightnessController)180 public void setAutomaticBrightnessController( 181 AutomaticBrightnessController automaticBrightnessController) { 182 if (automaticBrightnessController == mAutomaticBrightnessController) { 183 return; 184 } 185 if (mAutomaticBrightnessController != null) { 186 mAutomaticBrightnessController.stop(); 187 } 188 mAutomaticBrightnessController = automaticBrightnessController; 189 } 190 191 /** 192 * Returns if the auto-brightness of the associated display has been enabled or not 193 */ shouldUseAutoBrightness()194 public boolean shouldUseAutoBrightness() { 195 return mUseAutoBrightness; 196 } 197 198 /** 199 * Sets the auto-brightness state of the associated display. Called when the user makes a change 200 * in the system setting to enable/disable the auto-brightness. 201 */ setUseAutoBrightness(boolean useAutoBrightness)202 public void setUseAutoBrightness(boolean useAutoBrightness) { 203 mUseAutoBrightness = useAutoBrightness; 204 } 205 206 /** 207 * Returns if the user made brightness change events(Typically when they interact with the 208 * brightness slider) were accommodated in the auto-brightness mapping strategies. This doesn't 209 * account for the latest changes that have been made by the user. 210 */ isShortTermModelActive()211 public boolean isShortTermModelActive() { 212 return mIsShortTermModelActive; 213 } 214 215 /** 216 * Sets the pending auto-brightness adjustments in the system settings. Executed 217 * when there is a change in the brightness system setting, or when there is a user switch. 218 */ updatePendingAutoBrightnessAdjustments()219 public void updatePendingAutoBrightnessAdjustments() { 220 final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(), 221 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT); 222 mPendingAutoBrightnessAdjustment = Float.isNaN(adj) ? Float.NaN 223 : BrightnessUtils.clampBrightnessAdjustment(adj); 224 } 225 226 /** 227 * Sets the temporary auto-brightness adjustments 228 */ setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment)229 public void setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment) { 230 mTemporaryAutoBrightnessAdjustment = temporaryAutoBrightnessAdjustment; 231 } 232 233 /** 234 * Dumps the state of this class. 235 */ dump(PrintWriter writer)236 public void dump(PrintWriter writer) { 237 writer.println("AutomaticBrightnessStrategy:"); 238 writer.println(" mDisplayId=" + mDisplayId); 239 writer.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); 240 writer.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment); 241 writer.println( 242 " mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment); 243 writer.println(" mShouldResetShortTermModel=" + mShouldResetShortTermModel); 244 writer.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness); 245 writer.println(" mAutoBrightnessAdjustmentChanged=" + mAutoBrightnessAdjustmentChanged); 246 writer.println(" mAppliedTemporaryAutoBrightnessAdjustment=" 247 + mAppliedTemporaryAutoBrightnessAdjustment); 248 writer.println(" mUseAutoBrightness=" + mUseAutoBrightness); 249 writer.println(" mWasShortTermModelActive=" + mIsShortTermModelActive); 250 writer.println(" mAutoBrightnessAdjustmentReasonsFlags=" 251 + mAutoBrightnessAdjustmentReasonsFlags); 252 } 253 254 /** 255 * Indicates if any auto-brightness adjustments have happened since the last auto-brightness was 256 * set. 257 */ getAutoBrightnessAdjustmentChanged()258 public boolean getAutoBrightnessAdjustmentChanged() { 259 return mAutoBrightnessAdjustmentChanged; 260 } 261 262 /** 263 * Returns whether the latest temporary auto-brightness adjustments have been applied or not 264 */ isTemporaryAutoBrightnessAdjustmentApplied()265 public boolean isTemporaryAutoBrightnessAdjustmentApplied() { 266 return mAppliedTemporaryAutoBrightnessAdjustment; 267 } 268 269 /** 270 * Evaluates the target automatic brightness of the associated display. 271 * @param brightnessEvent Event object to populate with details about why the specific 272 * brightness was chosen. 273 */ getAutomaticScreenBrightness(BrightnessEvent brightnessEvent)274 public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) { 275 float brightness = (mAutomaticBrightnessController != null) 276 ? mAutomaticBrightnessController.getAutomaticScreenBrightness(brightnessEvent) 277 : PowerManager.BRIGHTNESS_INVALID_FLOAT; 278 adjustAutomaticBrightnessStateIfValid(brightness); 279 return brightness; 280 } 281 282 /** 283 * Gets the auto-brightness adjustment flag change reason 284 */ getAutoBrightnessAdjustmentReasonsFlags()285 public int getAutoBrightnessAdjustmentReasonsFlags() { 286 return mAutoBrightnessAdjustmentReasonsFlags; 287 } 288 289 /** 290 * Returns if the auto brightness has been applied 291 */ hasAppliedAutoBrightness()292 public boolean hasAppliedAutoBrightness() { 293 return mAppliedAutoBrightness; 294 } 295 296 /** 297 * Used to adjust the state of this class when the automatic brightness value for the 298 * associated display is valid 299 */ 300 @VisibleForTesting adjustAutomaticBrightnessStateIfValid(float brightnessState)301 void adjustAutomaticBrightnessStateIfValid(float brightnessState) { 302 mAutoBrightnessAdjustmentReasonsFlags = isTemporaryAutoBrightnessAdjustmentApplied() 303 ? BrightnessReason.ADJUSTMENT_AUTO_TEMP 304 : BrightnessReason.ADJUSTMENT_AUTO; 305 float newAutoBrightnessAdjustment = 306 (mAutomaticBrightnessController != null) 307 ? mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment() 308 : 0.0f; 309 if (!Float.isNaN(newAutoBrightnessAdjustment) 310 && mAutoBrightnessAdjustment != newAutoBrightnessAdjustment) { 311 // If the auto-brightness controller has decided to change the adjustment value 312 // used, make sure that's reflected in settings. 313 putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment); 314 } else { 315 mAutoBrightnessAdjustmentReasonsFlags = 0; 316 } 317 } 318 319 /** 320 * Sets up the system to reset the short term model. Note that this will not reset the model 321 * right away, but ensures that the reset happens whenever the next brightness change happens 322 */ 323 @VisibleForTesting setShouldResetShortTermModel(boolean shouldResetShortTermModel)324 void setShouldResetShortTermModel(boolean shouldResetShortTermModel) { 325 mShouldResetShortTermModel = shouldResetShortTermModel; 326 } 327 328 @VisibleForTesting shouldResetShortTermModel()329 boolean shouldResetShortTermModel() { 330 return mShouldResetShortTermModel; 331 } 332 333 @VisibleForTesting getAutoBrightnessAdjustment()334 float getAutoBrightnessAdjustment() { 335 return mAutoBrightnessAdjustment; 336 } 337 338 @VisibleForTesting getPendingAutoBrightnessAdjustment()339 float getPendingAutoBrightnessAdjustment() { 340 return mPendingAutoBrightnessAdjustment; 341 } 342 343 @VisibleForTesting getTemporaryAutoBrightnessAdjustment()344 float getTemporaryAutoBrightnessAdjustment() { 345 return mTemporaryAutoBrightnessAdjustment; 346 } 347 348 @VisibleForTesting putAutoBrightnessAdjustmentSetting(float adjustment)349 void putAutoBrightnessAdjustmentSetting(float adjustment) { 350 if (mDisplayId == Display.DEFAULT_DISPLAY) { 351 mAutoBrightnessAdjustment = adjustment; 352 Settings.System.putFloatForUser(mContext.getContentResolver(), 353 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, 354 UserHandle.USER_CURRENT); 355 } 356 } 357 358 /** 359 * Sets if the auto-brightness is applied on the latest brightness change. 360 */ setAutoBrightnessApplied(boolean autoBrightnessApplied)361 public void setAutoBrightnessApplied(boolean autoBrightnessApplied) { 362 mAppliedAutoBrightness = autoBrightnessApplied; 363 } 364 365 /** 366 * Accommodates the latest manual changes made by the user. Also updates {@link 367 * AutomaticBrightnessController} about the changes and configures it accordingly. 368 */ 369 @VisibleForTesting accommodateUserBrightnessChanges(boolean userSetBrightnessChanged, float lastUserSetScreenBrightness, int policy, int displayState, boolean useNormalBrightnessForDoze, BrightnessConfiguration brightnessConfiguration, int autoBrightnessState)370 void accommodateUserBrightnessChanges(boolean userSetBrightnessChanged, 371 float lastUserSetScreenBrightness, int policy, int displayState, 372 boolean useNormalBrightnessForDoze, BrightnessConfiguration brightnessConfiguration, 373 int autoBrightnessState) { 374 // Update the pending auto-brightness adjustments if any. This typically checks and adjusts 375 // the state of the class if the user moves the brightness slider and has settled to a 376 // different value 377 processPendingAutoBrightnessAdjustments(); 378 // Update the temporary auto-brightness adjustments if any. This typically checks and 379 // adjusts the state of this class if the user is in the process of moving the brightness 380 // slider, but hasn't settled to any value yet 381 float autoBrightnessAdjustment = updateTemporaryAutoBrightnessAdjustments(); 382 mIsShortTermModelActive = false; 383 // Configure auto-brightness. 384 if (mAutomaticBrightnessController != null) { 385 // Accommodate user changes if any in the auto-brightness model 386 mAutomaticBrightnessController.configure(autoBrightnessState, 387 brightnessConfiguration, 388 lastUserSetScreenBrightness, 389 userSetBrightnessChanged, autoBrightnessAdjustment, 390 mAutoBrightnessAdjustmentChanged, 391 policy, 392 displayState, 393 useNormalBrightnessForDoze, 394 mShouldResetShortTermModel); 395 mShouldResetShortTermModel = false; 396 // We take note if the user brightness point is still being used in the current 397 // auto-brightness model. 398 mIsShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints(); 399 } 400 } 401 402 /** 403 * Evaluates if there are any temporary auto-brightness adjustments which is not applied yet. 404 * Temporary brightness adjustments happen when the user moves the brightness slider in the 405 * auto-brightness mode, but hasn't settled to a value yet 406 */ updateTemporaryAutoBrightnessAdjustments()407 private float updateTemporaryAutoBrightnessAdjustments() { 408 mAppliedTemporaryAutoBrightnessAdjustment = 409 !Float.isNaN(mTemporaryAutoBrightnessAdjustment); 410 // We do not update the mAutoBrightnessAdjustment with mTemporaryAutoBrightnessAdjustment 411 // since we have not settled to a value yet 412 return mAppliedTemporaryAutoBrightnessAdjustment 413 ? mTemporaryAutoBrightnessAdjustment : mAutoBrightnessAdjustment; 414 } 415 416 /** 417 * Returns the auto-brightness adjustment that is set in the system setting. 418 */ getAutoBrightnessAdjustmentSetting()419 private float getAutoBrightnessAdjustmentSetting() { 420 final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(), 421 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT); 422 return Float.isNaN(adj) ? 0.0f : BrightnessUtils.clampBrightnessAdjustment(adj); 423 } 424 } 425