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