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