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.annotation.Nullable; 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.config.HighBrightnessModeData; 26 import com.android.server.display.feature.DisplayManagerFlags; 27 28 import java.io.PrintWriter; 29 import java.util.function.BooleanSupplier; 30 31 class BrightnessRangeController { 32 33 private final HighBrightnessModeController mHbmController; 34 private final NormalBrightnessModeController mNormalBrightnessModeController; 35 36 private final HdrClamper mHdrClamper; 37 38 private final Runnable mModeChangeCallback; 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.useNewHdrBrightnessModifier(); 63 mNormalBrightnessModeController.resetNbmData( 64 displayDeviceConfig.getLuxThrottlingData()); 65 if (flags.useNewHdrBrightnessModifier()) { 66 // HDR boost is handled by HdrBrightnessModifier and should be disabled in HbmController 67 mHbmController.disableHdrBoost(); 68 } 69 updateHdrClamper(info, displayToken, displayDeviceConfig); 70 } 71 dump(PrintWriter pw)72 void dump(PrintWriter pw) { 73 pw.println("BrightnessRangeController:"); 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(@ullable HighBrightnessModeMetadata hbmMetadata, IBinder token, DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig)94 void loadFromConfig(@Nullable 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, DisplayBrightnessState state)122 void onBrightnessChanged(float brightness, float unthrottledBrightness, 123 DisplayBrightnessState state) { 124 mHbmController.onHdrBoostApplied( 125 state.getHdrBrightness() != DisplayBrightnessState.BRIGHTNESS_NOT_SET); 126 mHbmController.onBrightnessChanged(brightness, unthrottledBrightness, 127 state.getBrightnessMaxReason()); 128 } 129 getCurrentBrightnessMin()130 float getCurrentBrightnessMin() { 131 return mHbmController.getCurrentBrightnessMin(); 132 } 133 134 getCurrentBrightnessMax()135 float getCurrentBrightnessMax() { 136 // nbmController might adjust maxBrightness only if device does not support HBM or 137 // hbm is currently not allowed 138 if (!mHbmController.deviceSupportsHbm() || !mHbmController.isHbmCurrentlyAllowed()) { 139 return Math.min(mHbmController.getCurrentBrightnessMax(), 140 mNormalBrightnessModeController.getCurrentBrightnessMax()); 141 } 142 return mHbmController.getCurrentBrightnessMax(); 143 } 144 getHighBrightnessMode()145 int getHighBrightnessMode() { 146 return mHbmController.getHighBrightnessMode(); 147 } 148 getHdrBrightnessValue()149 float getHdrBrightnessValue() { 150 float hdrBrightness = mHbmController.getHdrBrightnessValue(); 151 return mUseHdrClamper ? mHdrClamper.clamp(hdrBrightness) : hdrBrightness; 152 } 153 getTransitionPoint()154 float getTransitionPoint() { 155 return mHbmController.getTransitionPoint(); 156 } 157 updateHdrClamper(DisplayDeviceInfo info, IBinder token, DisplayDeviceConfig displayDeviceConfig)158 private void updateHdrClamper(DisplayDeviceInfo info, IBinder token, 159 DisplayDeviceConfig displayDeviceConfig) { 160 if (mUseHdrClamper) { 161 HighBrightnessModeData hbmData = 162 displayDeviceConfig.getHighBrightnessModeData(); 163 float minimumHdrPercentOfScreen = 164 hbmData == null ? -1f : hbmData.minimumHdrPercentOfScreen; 165 mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData(), info.width, 166 info.height, minimumHdrPercentOfScreen, token); 167 } 168 } 169 applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc)170 private void applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc) { 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 } 179 getHdrTransitionRate()180 public float getHdrTransitionRate() { 181 return mUseHdrClamper ? mHdrClamper.getTransitionRate() : -1; 182 } 183 } 184