• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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