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 17 package com.android.server.display; 18 19 import android.hardware.display.BrightnessInfo; 20 import android.os.Handler; 21 import android.os.IBinder; 22 23 import com.android.internal.annotations.VisibleForTesting; 24 import com.android.server.display.brightness.clamper.HdrClamper; 25 import com.android.server.display.feature.DisplayManagerFlags; 26 27 import java.io.PrintWriter; 28 import java.util.function.BooleanSupplier; 29 30 class BrightnessRangeController { 31 32 private final HighBrightnessModeController mHbmController; 33 private final NormalBrightnessModeController mNormalBrightnessModeController; 34 35 private final HdrClamper mHdrClamper; 36 37 private final Runnable mModeChangeCallback; 38 private final boolean mUseNbmController; 39 40 private final boolean mUseHdrClamper; 41 42 BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info)43 BrightnessRangeController(HighBrightnessModeController hbmController, 44 Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler, 45 DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { 46 this(hbmController, modeChangeCallback, displayDeviceConfig, 47 new NormalBrightnessModeController(), 48 new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), flags, 49 displayToken, info); 50 } 51 52 @VisibleForTesting BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, NormalBrightnessModeController normalBrightnessModeController, HdrClamper hdrClamper, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info)53 BrightnessRangeController(HighBrightnessModeController hbmController, 54 Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, 55 NormalBrightnessModeController normalBrightnessModeController, 56 HdrClamper hdrClamper, DisplayManagerFlags flags, IBinder displayToken, 57 DisplayDeviceInfo info) { 58 mHbmController = hbmController; 59 mModeChangeCallback = modeChangeCallback; 60 mHdrClamper = hdrClamper; 61 mNormalBrightnessModeController = normalBrightnessModeController; 62 mUseHdrClamper = flags.isHdrClamperEnabled(); 63 mUseNbmController = flags.isNbmControllerEnabled(); 64 if (mUseNbmController) { 65 mNormalBrightnessModeController.resetNbmData( 66 displayDeviceConfig.getLuxThrottlingData()); 67 } 68 updateHdrClamper(info, displayToken, displayDeviceConfig); 69 } 70 dump(PrintWriter pw)71 void dump(PrintWriter pw) { 72 pw.println("BrightnessRangeController:"); 73 pw.println(" mUseNormalBrightnessController=" + mUseNbmController); 74 pw.println(" mUseHdrClamper=" + mUseHdrClamper); 75 mHbmController.dump(pw); 76 mNormalBrightnessModeController.dump(pw); 77 mHdrClamper.dump(pw); 78 } 79 onAmbientLuxChange(float ambientLux)80 void onAmbientLuxChange(float ambientLux) { 81 applyChanges( 82 () -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux), 83 () -> mHbmController.onAmbientLuxChange(ambientLux) 84 ); 85 if (mUseHdrClamper) { 86 mHdrClamper.onAmbientLuxChange(ambientLux); 87 } 88 } 89 getNormalBrightnessMax()90 float getNormalBrightnessMax() { 91 return mHbmController.getNormalBrightnessMax(); 92 } 93 loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token, DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig)94 void loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token, 95 DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig) { 96 applyChanges( 97 () -> mNormalBrightnessModeController.resetNbmData( 98 displayDeviceConfig.getLuxThrottlingData()), 99 () -> { 100 mHbmController.setHighBrightnessModeMetadata(hbmMetadata); 101 mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, 102 displayDeviceConfig.getHighBrightnessModeData(), 103 displayDeviceConfig::getHdrBrightnessFromSdr); 104 } 105 ); 106 updateHdrClamper(info, token, displayDeviceConfig); 107 } 108 stop()109 void stop() { 110 mHbmController.stop(); 111 mHdrClamper.stop(); 112 } 113 setAutoBrightnessEnabled(int state)114 void setAutoBrightnessEnabled(int state) { 115 applyChanges( 116 () -> mNormalBrightnessModeController.setAutoBrightnessState(state), 117 () -> mHbmController.setAutoBrightnessEnabled(state) 118 ); 119 mHdrClamper.setAutoBrightnessState(state); 120 } 121 onBrightnessChanged(float brightness, float unthrottledBrightness, @BrightnessInfo.BrightnessMaxReason int throttlingReason)122 void onBrightnessChanged(float brightness, float unthrottledBrightness, 123 @BrightnessInfo.BrightnessMaxReason int throttlingReason) { 124 mHbmController.onBrightnessChanged(brightness, unthrottledBrightness, throttlingReason); 125 } 126 getCurrentBrightnessMin()127 float getCurrentBrightnessMin() { 128 return mHbmController.getCurrentBrightnessMin(); 129 } 130 131 getCurrentBrightnessMax()132 float getCurrentBrightnessMax() { 133 // nbmController might adjust maxBrightness only if device does not support HBM or 134 // hbm is currently not allowed 135 if (mUseNbmController 136 && (!mHbmController.deviceSupportsHbm() 137 || !mHbmController.isHbmCurrentlyAllowed())) { 138 return Math.min(mHbmController.getCurrentBrightnessMax(), 139 mNormalBrightnessModeController.getCurrentBrightnessMax()); 140 } 141 return mHbmController.getCurrentBrightnessMax(); 142 } 143 getHighBrightnessMode()144 int getHighBrightnessMode() { 145 return mHbmController.getHighBrightnessMode(); 146 } 147 getHdrBrightnessValue()148 float getHdrBrightnessValue() { 149 float hdrBrightness = mHbmController.getHdrBrightnessValue(); 150 return mUseHdrClamper ? mHdrClamper.clamp(hdrBrightness) : hdrBrightness; 151 } 152 getTransitionPoint()153 float getTransitionPoint() { 154 return mHbmController.getTransitionPoint(); 155 } 156 updateHdrClamper(DisplayDeviceInfo info, IBinder token, DisplayDeviceConfig displayDeviceConfig)157 private void updateHdrClamper(DisplayDeviceInfo info, IBinder token, 158 DisplayDeviceConfig displayDeviceConfig) { 159 if (mUseHdrClamper) { 160 DisplayDeviceConfig.HighBrightnessModeData hbmData = 161 displayDeviceConfig.getHighBrightnessModeData(); 162 float minimumHdrPercentOfScreen = 163 hbmData == null ? -1f : hbmData.minimumHdrPercentOfScreen; 164 mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData(), info.width, 165 info.height, minimumHdrPercentOfScreen, token); 166 } 167 } 168 applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc)169 private void applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc) { 170 if (mUseNbmController) { 171 boolean nbmTransitionChanged = nbmChangesFunc.getAsBoolean(); 172 hbmChangesFunc.run(); 173 // if nbm transition changed - trigger callback 174 // HighBrightnessModeController handles sending changes itself 175 if (nbmTransitionChanged) { 176 mModeChangeCallback.run(); 177 } 178 } else { 179 hbmChangesFunc.run(); 180 } 181 } 182 getHdrTransitionRate()183 public float getHdrTransitionRate() { 184 return mUseHdrClamper ? mHdrClamper.getTransitionRate() : -1; 185 } 186 } 187