• 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 
17 package com.android.server.display.config;
18 
19 import android.annotation.Nullable;
20 import android.util.Slog;
21 import android.util.Spline;
22 import android.view.SurfaceControl;
23 
24 import com.android.internal.annotations.VisibleForTesting;
25 
26 import java.math.BigDecimal;
27 import java.util.function.Function;
28 
29 /**
30  * Container for high brightness mode configuration data.
31  */
32 public class HighBrightnessModeData {
33     private static final String TAG = "HighBrightnessModeData";
34 
35     static final float HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT = 0.5f;
36 
37     /** Minimum lux needed to enter high brightness mode */
38     public final float minimumLux;
39 
40     /** Brightness level at which we transition from normal to high-brightness. */
41     public final float transitionPoint;
42 
43     /** Whether HBM is allowed when {@code Settings.Global.LOW_POWER_MODE} is active. */
44     public final boolean allowInLowPowerMode;
45 
46     /** Time window for HBM. */
47     public final long timeWindowMillis;
48 
49     /** Maximum time HBM is allowed to be during in a {@code timeWindowMillis}. */
50     public final long timeMaxMillis;
51 
52     /** Minimum time that HBM can be on before being enabled. */
53     public final long timeMinMillis;
54 
55     /** Minimum HDR video size to enter high brightness mode */
56     public final float minimumHdrPercentOfScreen;
57 
58     @Nullable
59     public final Spline sdrToHdrRatioSpline;
60 
61     @Nullable
62     public final SurfaceControl.RefreshRateRange refreshRateLimit;
63 
64     public final boolean isHighBrightnessModeEnabled;
65 
66     @VisibleForTesting
HighBrightnessModeData(float minimumLux, float transitionPoint, long timeWindowMillis, long timeMaxMillis, long timeMinMillis, boolean allowInLowPowerMode, float minimumHdrPercentOfScreen, @Nullable Spline sdrToHdrRatioSpline, @Nullable SurfaceControl.RefreshRateRange refreshRateLimit, boolean isHighBrightnessModeEnabled)67     public HighBrightnessModeData(float minimumLux, float transitionPoint, long timeWindowMillis,
68             long timeMaxMillis, long timeMinMillis, boolean allowInLowPowerMode,
69             float minimumHdrPercentOfScreen, @Nullable Spline sdrToHdrRatioSpline,
70             @Nullable SurfaceControl.RefreshRateRange refreshRateLimit,
71             boolean isHighBrightnessModeEnabled) {
72         this.minimumLux = minimumLux;
73         this.transitionPoint = transitionPoint;
74         this.timeWindowMillis = timeWindowMillis;
75         this.timeMaxMillis = timeMaxMillis;
76         this.timeMinMillis = timeMinMillis;
77         this.allowInLowPowerMode = allowInLowPowerMode;
78         this.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen;
79         this.sdrToHdrRatioSpline = sdrToHdrRatioSpline;
80         this.refreshRateLimit = refreshRateLimit;
81         this.isHighBrightnessModeEnabled = isHighBrightnessModeEnabled;
82     }
83 
84     @Override
toString()85     public String toString() {
86         return "HBM{"
87                 + "minLux: " + minimumLux
88                 + ", transition: " + transitionPoint
89                 + ", timeWindow: " + timeWindowMillis + "ms"
90                 + ", timeMax: " + timeMaxMillis + "ms"
91                 + ", timeMin: " + timeMinMillis + "ms"
92                 + ", allowInLowPowerMode: " + allowInLowPowerMode
93                 + ", minimumHdrPercentOfScreen: " + minimumHdrPercentOfScreen
94                 + ", mSdrToHdrRatioSpline=" + sdrToHdrRatioSpline
95                 + ", refreshRateLimit=" + refreshRateLimit
96                 + ", isHighBrightnessModeEnabled=" + isHighBrightnessModeEnabled
97                 + "} ";
98     }
99 
100     /**
101      * Loads HighBrightnessModeData from DisplayConfiguration
102      */
loadHighBrightnessModeData(DisplayConfiguration config, Function<HighBrightnessMode, Float> transitionPointProvider)103     public static HighBrightnessModeData loadHighBrightnessModeData(DisplayConfiguration config,
104             Function<HighBrightnessMode, Float> transitionPointProvider) {
105         final HighBrightnessMode hbm = config.getHighBrightnessMode();
106         float minimumLux = 0f;
107         float transitionPoint = 0f;
108         long timeWindowMillis = 0L;
109         long timeMaxMillis = 0L;
110         long timeMinMillis = 0L;
111         boolean allowInLowPowerMode = false;
112         float minimumHdrPercentOfScreen = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
113         Spline sdrToHdrRatioSpline = null;
114         SurfaceControl.RefreshRateRange refreshRateLimit = null;
115         boolean isEnabled = false;
116 
117         if (hbm != null) {
118             minimumLux = hbm.getMinimumLux_all().floatValue();
119             transitionPoint = transitionPointProvider.apply(hbm);
120             HbmTiming hbmTiming = hbm.getTiming_all();
121             timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
122             timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
123             timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
124             allowInLowPowerMode = hbm.getAllowInLowPowerMode_all();
125             BigDecimal minHdrPctOfScreen = hbm.getMinimumHdrPercentOfScreen_all();
126             if (minHdrPctOfScreen != null) {
127                 minimumHdrPercentOfScreen = minHdrPctOfScreen.floatValue();
128                 if (minimumHdrPercentOfScreen > 1 || minimumHdrPercentOfScreen < 0) {
129                     Slog.w(TAG, "Invalid minimum HDR percent of screen: "
130                             + minimumHdrPercentOfScreen);
131                     minimumHdrPercentOfScreen = HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
132                 }
133             }
134 
135             sdrToHdrRatioSpline = loadSdrHdrRatioMap(hbm);
136             RefreshRateRange rr = hbm.getRefreshRate_all();
137             if (rr != null) {
138                 refreshRateLimit = new SurfaceControl.RefreshRateRange(
139                         rr.getMinimum().floatValue(), rr.getMaximum().floatValue());
140             }
141             isEnabled = hbm.getEnabled();
142         }
143         return new HighBrightnessModeData(minimumLux, transitionPoint,
144                 timeWindowMillis, timeMaxMillis, timeMinMillis, allowInLowPowerMode,
145                 minimumHdrPercentOfScreen, sdrToHdrRatioSpline, refreshRateLimit, isEnabled);
146 
147     }
148 
loadSdrHdrRatioMap(HighBrightnessMode hbmConfig)149     private static Spline loadSdrHdrRatioMap(HighBrightnessMode hbmConfig) {
150         final SdrHdrRatioMap sdrHdrRatioMap = hbmConfig.getSdrHdrRatioMap_all();
151         if (sdrHdrRatioMap == null) {
152             return null;
153         }
154         return DisplayDeviceConfigUtils.createSpline(sdrHdrRatioMap.getPoint(),
155                 SdrHdrRatioPoint::getSdrNits, SdrHdrRatioPoint::getHdrRatio);
156     }
157 }
158