• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 
17 package com.android.server.display.brightness;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.hardware.SensorManager;
22 import android.hardware.display.DisplayManagerInternal;
23 import android.os.Handler;
24 import android.os.HandlerExecutor;
25 import android.os.PowerManager;
26 import android.util.IndentingPrintWriter;
27 import android.view.Display;
28 
29 import com.android.internal.annotations.GuardedBy;
30 import com.android.internal.annotations.VisibleForTesting;
31 import com.android.internal.display.BrightnessSynchronizer;
32 import com.android.server.display.AutomaticBrightnessController;
33 import com.android.server.display.BrightnessMappingStrategy;
34 import com.android.server.display.BrightnessSetting;
35 import com.android.server.display.DisplayBrightnessState;
36 import com.android.server.display.DisplayDeviceConfig;
37 import com.android.server.display.brightness.strategy.AutoBrightnessFallbackStrategy;
38 import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2;
39 import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy;
40 import com.android.server.display.feature.DisplayManagerFlags;
41 
42 import java.io.PrintWriter;
43 
44 /**
45  * Deploys different DozeBrightnessStrategy to choose the current brightness for a specified
46  * display. Applies the chosen brightness.
47  */
48 public final class DisplayBrightnessController {
49 
50     // The ID of the display tied to this DisplayBrightnessController
51     private final int mDisplayId;
52 
53     // The lock which is to be used to synchronize the resources being used in this class
54     private final Object mLock = new Object();
55 
56     // The default screen brightness to be used when no value is available in BrightnessSetting.
57     private final float mScreenBrightnessDefault;
58 
59     // This is used to persist the changes happening to the brightness.
60     private final BrightnessSetting mBrightnessSetting;
61 
62     // A runnable to update the clients registered via DisplayManagerGlobal
63     // .EVENT_DISPLAY_BRIGHTNESS_CHANGED about the brightness change. Called when
64     // mCurrentScreenBrightness is updated.
65     private Runnable mOnBrightnessChangeRunnable;
66 
67     // The screen brightness that has changed but not taken effect yet. If this is different
68     // from the current screen brightness then this is coming from something other than us
69     // and should be considered a user interaction.
70     @GuardedBy("mLock")
71     private float mPendingScreenBrightness;
72 
73     // The last observed screen brightness, either set by us or by the settings app on
74     // behalf of the user.
75     @GuardedBy("mLock")
76     private float mCurrentScreenBrightness;
77 
78     // The last brightness that was set by the user and not temporary. Set to
79     // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded.
80     @GuardedBy("mLock")
81     private float mLastUserSetScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
82 
83     // Represents if the system has adjusted the brightness based on the user suggested value. Will
84     // be false if the brightness change is coming from a non-user source
85     private boolean mUserSetScreenBrightnessUpdated;
86 
87     // The listener which is to be notified everytime there is a change in the brightness in the
88     // BrightnessSetting.
89     private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
90 
91     // Selects an appropriate strategy based on the request provided by the clients.
92     @GuardedBy("mLock")
93     private DisplayBrightnessStrategySelector mDisplayBrightnessStrategySelector;
94 
95     // Currently selected DisplayBrightnessStrategy.
96     @GuardedBy("mLock")
97     private DisplayBrightnessStrategy mDisplayBrightnessStrategy;
98 
99     // The executor on which the mOnBrightnessChangeRunnable is executed. This ensures that the
100     // callback is not executed in sync and is not blocking the thread from which it is called.
101     private final HandlerExecutor mBrightnessChangeExecutor;
102 
103     // True if we want to persist the brightness value in nits even if the underlying display
104     // device changes.
105     private final boolean mPersistBrightnessNitsForDefaultDisplay;
106 
107     // The controller for the automatic brightness level.
108     // TODO(b/265415257): Move to the automatic brightness strategy
109     @Nullable
110     @VisibleForTesting
111     AutomaticBrightnessController mAutomaticBrightnessController;
112 
113     // True if the stylus is being used
114     private boolean mIsStylusBeingUsed;
115 
116     /**
117      * The constructor of DisplayBrightnessController.
118      */
DisplayBrightnessController(Context context, Injector injector, int displayId, float defaultScreenBrightness, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable, HandlerExecutor brightnessChangeExecutor, DisplayManagerFlags flags)119     public DisplayBrightnessController(Context context, Injector injector, int displayId,
120             float defaultScreenBrightness, BrightnessSetting brightnessSetting,
121             Runnable onBrightnessChangeRunnable, HandlerExecutor brightnessChangeExecutor,
122             DisplayManagerFlags flags) {
123         if (injector == null) {
124             injector = new Injector();
125         }
126         mDisplayId = displayId;
127         // TODO: b/186428377 update brightness setting when display changes
128         mBrightnessSetting = brightnessSetting;
129         mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
130         mScreenBrightnessDefault = BrightnessUtils.clampAbsoluteBrightness(defaultScreenBrightness);
131         mCurrentScreenBrightness = getScreenBrightnessSetting();
132         mOnBrightnessChangeRunnable = onBrightnessChangeRunnable;
133         mDisplayBrightnessStrategySelector = injector.getDisplayBrightnessStrategySelector(context,
134                 displayId, flags);
135         mBrightnessChangeExecutor = brightnessChangeExecutor;
136         mPersistBrightnessNitsForDefaultDisplay = context.getResources().getBoolean(
137                 com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay);
138     }
139 
140     /**
141      * Updates the display brightness. This delegates the responsibility of selecting an appropriate
142      * strategy to DisplayBrightnessStrategySelector, which is then applied to evaluate the
143      * DisplayBrightnessState. In the future,
144      * 1. This will account for clamping the brightness if needed.
145      * 2. This will notify the system about the updated brightness
146      *
147      * @param displayPowerRequest The request to update the brightness
148      * @param targetDisplayState  The target display state of the system
149      */
updateBrightness( DisplayManagerInternal.DisplayPowerRequest displayPowerRequest, int targetDisplayState, DisplayManagerInternal.DisplayOffloadSession displayOffloadSession, boolean isBedtimeModeWearEnabled)150     public DisplayBrightnessState updateBrightness(
151             DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
152             int targetDisplayState,
153             DisplayManagerInternal.DisplayOffloadSession displayOffloadSession,
154             boolean isBedtimeModeWearEnabled) {
155         DisplayBrightnessState state;
156         synchronized (mLock) {
157             mDisplayBrightnessStrategy = mDisplayBrightnessStrategySelector.selectStrategy(
158                     constructStrategySelectionRequest(displayPowerRequest, targetDisplayState,
159                             displayOffloadSession, isBedtimeModeWearEnabled));
160             state = mDisplayBrightnessStrategy
161                         .updateBrightness(constructStrategyExecutionRequest(displayPowerRequest));
162         }
163 
164         // This is a temporary measure until AutomaticBrightnessStrategy works as a traditional
165         // strategy.
166         // TODO: Remove when AutomaticBrightnessStrategy is populating the values directly.
167         if (state != null) {
168             state = addAutomaticBrightnessState(state);
169         }
170         return state;
171     }
172 
173     /**
174      * Sets the temporary brightness
175      */
setTemporaryBrightness(Float temporaryBrightness)176     public void setTemporaryBrightness(Float temporaryBrightness) {
177         synchronized (mLock) {
178             setTemporaryBrightnessLocked(temporaryBrightness);
179         }
180     }
181 
182     /**
183      * Updates the brightness override from WindowManager.
184      *
185      * @param request The request to override the brightness
186      * @return whether this request will result in a change of the brightness
187      */
updateWindowManagerBrightnessOverride( DisplayManagerInternal.DisplayBrightnessOverrideRequest request)188     public boolean updateWindowManagerBrightnessOverride(
189             DisplayManagerInternal.DisplayBrightnessOverrideRequest request) {
190         synchronized (mLock) {
191             return mDisplayBrightnessStrategySelector.getOverrideBrightnessStrategy()
192                     .updateWindowManagerBrightnessOverride(request);
193         }
194     }
195 
196     /**
197      * Sets the brightness to follow
198      */
setBrightnessToFollow(float brightnessToFollow, boolean slowChange)199     public void setBrightnessToFollow(float brightnessToFollow, boolean slowChange) {
200         synchronized (mLock) {
201             mDisplayBrightnessStrategySelector.getFollowerDisplayBrightnessStrategy()
202                     .setBrightnessToFollow(brightnessToFollow, slowChange);
203         }
204     }
205 
206     /**
207      * Sets the brightness from the offload session.
208      * @return Whether the offload brightness has changed
209      */
setBrightnessFromOffload(float brightness)210     public boolean setBrightnessFromOffload(float brightness) {
211         synchronized (mLock) {
212             if (mDisplayBrightnessStrategySelector.getOffloadBrightnessStrategy() != null
213                     && !BrightnessSynchronizer.floatEquals(mDisplayBrightnessStrategySelector
214                     .getOffloadBrightnessStrategy().getOffloadScreenBrightness(), brightness)) {
215                 mDisplayBrightnessStrategySelector.getOffloadBrightnessStrategy()
216                         .setOffloadScreenBrightness(brightness);
217                 return true;
218             }
219         }
220         return false;
221     }
222 
223     /**
224      * Returns a boolean flag indicating if the light sensor is to be used to decide the screen
225      * brightness when dozing
226      */
isAllowAutoBrightnessWhileDozing()227     public boolean isAllowAutoBrightnessWhileDozing() {
228         synchronized (mLock) {
229             return mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing();
230         }
231     }
232 
233     /**
234      * Returns the config value indicating the auto brightness while dozing is to be
235      * allowed ot not. Note that this is a config value, but the actual status can differ from this.
236      */
isAllowAutoBrightnessWhileDozingConfig()237     public boolean isAllowAutoBrightnessWhileDozingConfig() {
238         synchronized (mLock) {
239             return mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozingConfig();
240         }
241     }
242 
243     /**
244      * Sets the current screen brightness to the supplied value, and notifies all the listeners
245      * requesting for change events on brightness change.
246      */
setAndNotifyCurrentScreenBrightness(float brightnessValue)247     public void setAndNotifyCurrentScreenBrightness(float brightnessValue) {
248         final boolean hasBrightnessChanged;
249         synchronized (mLock) {
250             hasBrightnessChanged = (brightnessValue != mCurrentScreenBrightness);
251             setCurrentScreenBrightnessLocked(brightnessValue);
252         }
253         if (hasBrightnessChanged) {
254             notifyCurrentScreenBrightness();
255         }
256     }
257 
258     /**
259      * Returns the last observed screen brightness.
260      */
getCurrentBrightness()261     public float getCurrentBrightness() {
262         synchronized (mLock) {
263             return mCurrentScreenBrightness;
264         }
265     }
266 
267     /**
268      * Returns the screen brightness which has changed but has not taken any effect so far.
269      */
getPendingScreenBrightness()270     public float getPendingScreenBrightness() {
271         synchronized (mLock) {
272             return mPendingScreenBrightness;
273         }
274     }
275 
276     /**
277      * Sets the pending screen brightness setting, representing a value which is requested, but not
278      * yet processed.
279      * @param brightnessValue The value to which the pending screen brightness is to be set.
280      */
setPendingScreenBrightness(float brightnessValue)281     public void setPendingScreenBrightness(float brightnessValue) {
282         synchronized (mLock) {
283             mPendingScreenBrightness = brightnessValue;
284         }
285     }
286 
287     /**
288      * Returns if the system has adjusted the brightness based on the user suggested value. Will
289      * be false if the brightness change is coming from a non-user source.
290      *
291      * Todo: 294444204 This is a temporary workaround, and should be moved to the manual brightness
292      * strategy once that is introduced
293      */
getIsUserSetScreenBrightnessUpdated()294     public boolean getIsUserSetScreenBrightnessUpdated() {
295         return mUserSetScreenBrightnessUpdated;
296     }
297 
298     /**
299      * Registers the BrightnessSettingListener with the BrightnessSetting, which will be notified
300      * everytime there is a change in the brightness.
301      */
registerBrightnessSettingChangeListener( BrightnessSetting.BrightnessSettingListener brightnessSettingListener)302     public void registerBrightnessSettingChangeListener(
303             BrightnessSetting.BrightnessSettingListener brightnessSettingListener) {
304         mBrightnessSettingListener = brightnessSettingListener;
305         mBrightnessSetting.registerListener(mBrightnessSettingListener);
306     }
307 
308     /**
309      * Returns the last user set brightness which is not temporary.
310      */
getLastUserSetScreenBrightness()311     public float getLastUserSetScreenBrightness() {
312         synchronized (mLock) {
313             return mLastUserSetScreenBrightness;
314         }
315     }
316 
317     /**
318      * Returns the current screen brightnessSetting which is responsible for saving the brightness
319      * in the persistent store
320      */
getScreenBrightnessSetting()321     public float getScreenBrightnessSetting() {
322         float brightness = mBrightnessSetting.getBrightness();
323         synchronized (mLock) {
324             if (Float.isNaN(brightness)) {
325                 brightness = mScreenBrightnessDefault;
326             }
327             return BrightnessUtils.clampAbsoluteBrightness(brightness);
328         }
329     }
330 
331     /**
332      * Notifies the brightnessSetting to persist the supplied brightness value.
333      */
setBrightness(float brightnessValue, float maxBrightness)334     public void setBrightness(float brightnessValue, float maxBrightness) {
335         // Update the setting, which will eventually call back into DPC to have us actually
336         // update the display with the new value.
337         mBrightnessSetting.setBrightness(brightnessValue);
338         if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
339             float nits = convertToNits(brightnessValue);
340             float currentlyStoredNits = mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
341             // Don't override settings if the brightness is set to max, but the currently
342             // stored value is greater. On multi-screen device, when switching between a
343             // screen with a wider brightness range and one with a narrower brightness range,
344             // the stored value shouldn't change.
345             if (nits >= 0 && !(brightnessValue == maxBrightness && currentlyStoredNits > nits)) {
346                 mBrightnessSetting.setBrightnessNitsForDefaultDisplay(nits);
347             }
348         }
349     }
350 
351     /**
352      * Notifies the brightnessSetting to persist the supplied brightness value for a user.
353      */
setBrightness(float brightnessValue, int userSerial, float maxBrightness)354     public void setBrightness(float brightnessValue, int userSerial, float maxBrightness) {
355         mBrightnessSetting.setUserSerial(userSerial);
356         setBrightness(brightnessValue, maxBrightness);
357     }
358 
359     /**
360      * Flush the brightness update that has been made to the persistent data store.
361      */
saveBrightnessIfNeeded()362     public void saveBrightnessIfNeeded() {
363         mBrightnessSetting.saveIfNeeded();
364     }
365 
366     /**
367      * Sets the current screen brightness, and notifies the BrightnessSetting about the change.
368      */
updateScreenBrightnessSetting(float brightnessValue, float maxBrightness)369     public void updateScreenBrightnessSetting(float brightnessValue, float maxBrightness) {
370         synchronized (mLock) {
371             if (!BrightnessUtils.isValidBrightnessValue(brightnessValue)
372                     || brightnessValue == mCurrentScreenBrightness) {
373                 return;
374             }
375             setCurrentScreenBrightnessLocked(brightnessValue);
376         }
377         notifyCurrentScreenBrightness();
378         setBrightness(brightnessValue, maxBrightness);
379     }
380 
381     /**
382      * Sets up the auto brightness and the relevant state for the associated display
383      */
setUpAutoBrightness(AutomaticBrightnessController automaticBrightnessController, SensorManager sensorManager, DisplayDeviceConfig displayDeviceConfig, Handler handler, BrightnessMappingStrategy brightnessMappingStrategy, boolean isDisplayEnabled, int leadDisplayId)384     public void setUpAutoBrightness(AutomaticBrightnessController automaticBrightnessController,
385             SensorManager sensorManager,
386             DisplayDeviceConfig displayDeviceConfig, Handler handler,
387             BrightnessMappingStrategy brightnessMappingStrategy, boolean isDisplayEnabled,
388             int leadDisplayId) {
389         setAutomaticBrightnessController(automaticBrightnessController);
390         setUpAutoBrightnessFallbackStrategy(sensorManager, displayDeviceConfig, handler,
391                 brightnessMappingStrategy, isDisplayEnabled, leadDisplayId);
392     }
393 
394     /**
395      * TODO(b/253226419): Remove once auto-brightness is a fully-functioning strategy.
396      */
getAutomaticBrightnessStrategy()397     public AutomaticBrightnessStrategy2 getAutomaticBrightnessStrategy() {
398         return mDisplayBrightnessStrategySelector.getAutomaticBrightnessStrategy();
399     }
400 
401     /**
402      * Convert a brightness float scale value to a nit value. Adjustments, such as RBC, are not
403      * applied. This is used when storing the brightness in nits for the default display and when
404      * passing the brightness value to follower displays.
405      *
406      * @param brightness The float scale value
407      * @return The nit value or {@link BrightnessMappingStrategy.INVALID_NITS} if no conversion is
408      * possible.
409      */
convertToNits(float brightness)410     public float convertToNits(float brightness) {
411         if (mAutomaticBrightnessController == null) {
412             return BrightnessMappingStrategy.INVALID_NITS;
413         }
414         return mAutomaticBrightnessController.convertToNits(brightness);
415     }
416 
417     /**
418      * Convert a brightness float scale value to a nit value. Adjustments, such as RBC are applied.
419      * This is used when sending the brightness value to
420      * {@link com.android.server.display.BrightnessTracker}.
421      *
422      * @param brightness The float scale value
423      * @return The nit value or {@link BrightnessMappingStrategy.INVALID_NITS} if no conversion is
424      * possible.
425      */
convertToAdjustedNits(float brightness)426     public float convertToAdjustedNits(float brightness) {
427         if (mAutomaticBrightnessController == null) {
428             return BrightnessMappingStrategy.INVALID_NITS;
429         }
430         return mAutomaticBrightnessController.convertToAdjustedNits(brightness);
431     }
432 
433     /**
434      * Convert a brightness nit value to a float scale value. It is assumed that the nit value
435      * provided does not have adjustments, such as RBC, applied.
436      *
437      * @param nits The nit value
438      * @return The float scale value or {@link PowerManager.BRIGHTNESS_INVALID_FLOAT} if no
439      * conversion is possible.
440      */
getBrightnessFromNits(float nits)441     public float getBrightnessFromNits(float nits) {
442         if (mAutomaticBrightnessController == null) {
443             return PowerManager.BRIGHTNESS_INVALID_FLOAT;
444         }
445         return mAutomaticBrightnessController.getBrightnessFromNits(nits);
446     }
447 
448     /**
449      * Stops the associated listeners when the display is stopped. Invoked when the {@link
450      * #mDisplayId} is being removed.
451      */
stop()452     public void stop() {
453         if (mBrightnessSetting != null) {
454             mBrightnessSetting.unregisterListener(mBrightnessSettingListener);
455         }
456         AutoBrightnessFallbackStrategy autoBrightnessFallbackStrategy =
457                 getAutoBrightnessFallbackStrategy();
458         if (autoBrightnessFallbackStrategy != null) {
459             autoBrightnessFallbackStrategy.stop();
460         }
461     }
462 
getAutoBrightnessFallbackStrategy()463     private AutoBrightnessFallbackStrategy getAutoBrightnessFallbackStrategy() {
464         synchronized (mLock) {
465             return mDisplayBrightnessStrategySelector.getAutoBrightnessFallbackStrategy();
466         }
467     }
468 
469     /**
470      * Used to dump the state.
471      *
472      * @param writer The PrintWriter used to dump the state.
473      */
dump(PrintWriter writer)474     public void dump(PrintWriter writer) {
475         writer.println();
476         writer.println("DisplayBrightnessController:");
477         writer.println("  mDisplayId=: " + mDisplayId);
478         writer.println("  mScreenBrightnessDefault=" + mScreenBrightnessDefault);
479         writer.println("  mPersistBrightnessNitsForDefaultDisplay="
480                 + mPersistBrightnessNitsForDefaultDisplay);
481         writer.println("  mIsStylusBeingUsed="
482                 + mIsStylusBeingUsed);
483         synchronized (mLock) {
484             writer.println("  mPendingScreenBrightness=" + mPendingScreenBrightness);
485             writer.println("  mCurrentScreenBrightness=" + mCurrentScreenBrightness);
486             writer.println("  mLastUserSetScreenBrightness="
487                     + mLastUserSetScreenBrightness);
488             if (mDisplayBrightnessStrategy != null) {
489                 writer.println("  Last selected DisplayBrightnessStrategy= "
490                         + mDisplayBrightnessStrategy.getName());
491             }
492             IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " ");
493             mDisplayBrightnessStrategySelector.dump(ipw);
494         }
495     }
496 
497     /**
498      * We want to return true if the user has set the screen brightness.
499      * RBC on, off, and intensity changes will return false.
500      * Slider interactions whilst in RBC will return true, just as when in non-rbc.
501      */
502     @VisibleForTesting
updateUserSetScreenBrightness()503     boolean updateUserSetScreenBrightness() {
504         mUserSetScreenBrightnessUpdated = false;
505         synchronized (mLock) {
506             if (!BrightnessUtils.isValidBrightnessValue(mPendingScreenBrightness)) {
507                 return false;
508             }
509             if (mCurrentScreenBrightness == mPendingScreenBrightness) {
510                 mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
511                 setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT);
512                 return false;
513             }
514             setCurrentScreenBrightnessLocked(mPendingScreenBrightness);
515             mLastUserSetScreenBrightness = mPendingScreenBrightness;
516             mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
517             setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT);
518         }
519         notifyCurrentScreenBrightness();
520         mUserSetScreenBrightnessUpdated = true;
521         return true;
522     }
523 
524     /**
525      * Notifies if the stylus is currently being used or not.
526      */
setStylusBeingUsed(boolean isEnabled)527     public void setStylusBeingUsed(boolean isEnabled) {
528         mIsStylusBeingUsed = isEnabled;
529     }
530 
531     @VisibleForTesting
isStylusBeingUsed()532     boolean isStylusBeingUsed() {
533         return mIsStylusBeingUsed;
534     }
535 
536     @VisibleForTesting
537     static class Injector {
getDisplayBrightnessStrategySelector(Context context, int displayId, DisplayManagerFlags flags)538         DisplayBrightnessStrategySelector getDisplayBrightnessStrategySelector(Context context,
539                 int displayId, DisplayManagerFlags flags) {
540             return new DisplayBrightnessStrategySelector(context, /* injector= */ null, displayId,
541                     flags);
542         }
543     }
544 
545     @VisibleForTesting
getBrightnessSettingListener()546     BrightnessSetting.BrightnessSettingListener getBrightnessSettingListener() {
547         return mBrightnessSettingListener;
548     }
549 
550     /**
551      * Returns the current selected DisplayBrightnessStrategy
552      */
553     @VisibleForTesting
getCurrentDisplayBrightnessStrategy()554     DisplayBrightnessStrategy getCurrentDisplayBrightnessStrategy() {
555         synchronized (mLock) {
556             return mDisplayBrightnessStrategy;
557         }
558     }
559 
560     /**
561      * Set the {@link AutomaticBrightnessController} which is needed to perform nit-to-float-scale
562      * conversion.
563      * @param automaticBrightnessController The ABC
564      */
565     @VisibleForTesting
setAutomaticBrightnessController( AutomaticBrightnessController automaticBrightnessController)566     void setAutomaticBrightnessController(
567             AutomaticBrightnessController automaticBrightnessController) {
568         mAutomaticBrightnessController = automaticBrightnessController;
569         getAutomaticBrightnessStrategy()
570                 .setAutomaticBrightnessController(automaticBrightnessController);
571         loadNitBasedBrightnessSetting();
572     }
573 
setUpAutoBrightnessFallbackStrategy(SensorManager sensorManager, DisplayDeviceConfig displayDeviceConfig, Handler handler, BrightnessMappingStrategy brightnessMappingStrategy, boolean isDisplayEnabled, int leadDisplayId)574     private void setUpAutoBrightnessFallbackStrategy(SensorManager sensorManager,
575             DisplayDeviceConfig displayDeviceConfig, Handler handler,
576             BrightnessMappingStrategy brightnessMappingStrategy, boolean isDisplayEnabled,
577             int leadDisplayId) {
578         AutoBrightnessFallbackStrategy autoBrightnessFallbackStrategy =
579                 getAutoBrightnessFallbackStrategy();
580         if (autoBrightnessFallbackStrategy != null) {
581             autoBrightnessFallbackStrategy.setupAutoBrightnessFallbackSensor(
582                     sensorManager, displayDeviceConfig, handler, brightnessMappingStrategy,
583                     isDisplayEnabled, leadDisplayId);
584         }
585     }
586 
587     /**
588      * TODO(b/253226419): Remove once auto-brightness is a fully-functioning strategy.
589      */
addAutomaticBrightnessState(DisplayBrightnessState state)590     private DisplayBrightnessState addAutomaticBrightnessState(DisplayBrightnessState state) {
591         AutomaticBrightnessStrategy2 autoStrat = getAutomaticBrightnessStrategy();
592 
593         DisplayBrightnessState.Builder builder = DisplayBrightnessState.Builder.from(state);
594         builder.setShouldUseAutoBrightness(
595                 autoStrat != null && autoStrat.shouldUseAutoBrightness());
596         return builder.build();
597     }
598 
599     @GuardedBy("mLock")
setTemporaryBrightnessLocked(float temporaryBrightness)600     private void setTemporaryBrightnessLocked(float temporaryBrightness) {
601         mDisplayBrightnessStrategySelector.getTemporaryDisplayBrightnessStrategy()
602                 .setTemporaryScreenBrightness(temporaryBrightness);
603     }
604 
605     @GuardedBy("mLock")
setCurrentScreenBrightnessLocked(float brightnessValue)606     private void setCurrentScreenBrightnessLocked(float brightnessValue) {
607         if (brightnessValue != mCurrentScreenBrightness) {
608             mCurrentScreenBrightness = brightnessValue;
609         }
610     }
611 
notifyCurrentScreenBrightness()612     private void notifyCurrentScreenBrightness() {
613         mBrightnessChangeExecutor.execute(mOnBrightnessChangeRunnable);
614     }
615 
616     /**
617      * Loads the brightness value. If this is the default display and the config says that we should
618      * persist the nit value, the nit value for the default display will be loaded.
619      */
loadNitBasedBrightnessSetting()620     private void loadNitBasedBrightnessSetting() {
621         float currentBrightnessSetting = Float.NaN;
622         if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
623             float brightnessNitsForDefaultDisplay =
624                     mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
625             if (brightnessNitsForDefaultDisplay >= 0) {
626                 float brightnessForDefaultDisplay = getBrightnessFromNits(
627                         brightnessNitsForDefaultDisplay);
628                 if (BrightnessUtils.isValidBrightnessValue(brightnessForDefaultDisplay)) {
629                     mBrightnessSetting.setBrightnessNoNotify(brightnessForDefaultDisplay);
630                     currentBrightnessSetting = brightnessForDefaultDisplay;
631                 }
632             }
633         }
634 
635         if (Float.isNaN(currentBrightnessSetting)) {
636             currentBrightnessSetting = getScreenBrightnessSetting();
637         }
638 
639         synchronized (mLock) {
640             mCurrentScreenBrightness = currentBrightnessSetting;
641         }
642     }
643 
constructStrategySelectionRequest( DisplayManagerInternal.DisplayPowerRequest displayPowerRequest, int targetDisplayState, DisplayManagerInternal.DisplayOffloadSession displayOffloadSession, boolean isBedtimeModeEnabled)644     private StrategySelectionRequest constructStrategySelectionRequest(
645             DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
646             int targetDisplayState,
647             DisplayManagerInternal.DisplayOffloadSession displayOffloadSession,
648             boolean isBedtimeModeEnabled) {
649         boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
650         float lastUserSetScreenBrightness;
651         synchronized (mLock) {
652             lastUserSetScreenBrightness = mLastUserSetScreenBrightness;
653         }
654         return new StrategySelectionRequest(displayPowerRequest, targetDisplayState,
655                 lastUserSetScreenBrightness, userSetBrightnessChanged, displayOffloadSession,
656                 mIsStylusBeingUsed, isBedtimeModeEnabled);
657     }
658 
constructStrategyExecutionRequest( DisplayManagerInternal.DisplayPowerRequest displayPowerRequest)659     private StrategyExecutionRequest constructStrategyExecutionRequest(
660             DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
661         float currentScreenBrightness = getCurrentBrightness();
662         return new StrategyExecutionRequest(displayPowerRequest, currentScreenBrightness,
663                 mUserSetScreenBrightnessUpdated, mIsStylusBeingUsed);
664     }
665 }
666