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