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