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.NonNull; 20 import android.annotation.Nullable; 21 import android.content.Context; 22 import android.hardware.display.DisplayManagerInternal; 23 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; 24 import android.util.IndentingPrintWriter; 25 import android.util.Slog; 26 import android.view.Display; 27 28 import com.android.internal.R; 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.server.display.brightness.strategy.AutoBrightnessFallbackStrategy; 31 import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy; 32 import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2; 33 import com.android.server.display.brightness.strategy.BoostBrightnessStrategy; 34 import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy; 35 import com.android.server.display.brightness.strategy.DozeBrightnessStrategy; 36 import com.android.server.display.brightness.strategy.FallbackBrightnessStrategy; 37 import com.android.server.display.brightness.strategy.FollowerBrightnessStrategy; 38 import com.android.server.display.brightness.strategy.InvalidBrightnessStrategy; 39 import com.android.server.display.brightness.strategy.OffloadBrightnessStrategy; 40 import com.android.server.display.brightness.strategy.OverrideBrightnessStrategy; 41 import com.android.server.display.brightness.strategy.ScreenOffBrightnessStrategy; 42 import com.android.server.display.brightness.strategy.TemporaryBrightnessStrategy; 43 import com.android.server.display.feature.DisplayManagerFlags; 44 45 import java.io.PrintWriter; 46 47 /** 48 * This maintains the logic needed to decide the eligible display brightness strategy. 49 */ 50 public class DisplayBrightnessStrategySelector { 51 private static final String TAG = "DisplayBrightnessStrategySelector"; 52 // True if the config to use the light sensor to automatically determine doze screen brightness 53 // is enabled. Note that the actual value representing if the auto-brightness is to be kept 54 // enabled while dozing can differ, but is dependent on this 55 private final boolean mAllowAutoBrightnessWhileDozingConfig; 56 57 // True if light sensor is to be used to automatically determine doze screen brightness. 58 private boolean mAllowAutoBrightnessWhileDozing; 59 60 // The brightness strategy used to manage the brightness state when the display is dozing. 61 private final DozeBrightnessStrategy mDozeBrightnessStrategy; 62 // The brightness strategy used to manage the brightness state when the display is in 63 // screen off state. 64 private final ScreenOffBrightnessStrategy mScreenOffBrightnessStrategy; 65 // The brightness strategy used to manage the brightness state when the request state is 66 // invalid. 67 private final OverrideBrightnessStrategy mOverrideBrightnessStrategy; 68 // The brightness strategy used to manage the brightness state in temporary state 69 private final TemporaryBrightnessStrategy mTemporaryBrightnessStrategy; 70 // The brightness strategy used to manage the brightness state when boost is requested 71 private final BoostBrightnessStrategy mBoostBrightnessStrategy; 72 // The brightness strategy used for additional displays 73 private final FollowerBrightnessStrategy mFollowerBrightnessStrategy; 74 // The brightness strategy used to manage the brightness state when the request is invalid. 75 private final InvalidBrightnessStrategy mInvalidBrightnessStrategy; 76 // Controls brightness when automatic (adaptive) brightness is running. 77 private final AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy; 78 79 // The automatic strategy which controls the brightness when adaptive mode is ON. 80 private final AutomaticBrightnessStrategy mAutomaticBrightnessStrategy1; 81 82 // The deprecated AutomaticBrightnessStrategy. Avoid using it for any new features without 83 // consulting with the display frameworks team. Use {@link AutomaticBrightnessStrategy} instead. 84 // This will be removed once the flag 85 // {@link DisplayManagerFlags#isRefactorDisplayPowerControllerEnabled is fully rolled out 86 private final AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy2; 87 // Controls the brightness if adaptive brightness is on and there exists an active offload 88 // session. Brightness value is provided by the offload session. 89 @Nullable 90 private final OffloadBrightnessStrategy mOffloadBrightnessStrategy; 91 92 @Nullable 93 private final AutoBrightnessFallbackStrategy mAutoBrightnessFallbackStrategy; 94 95 @Nullable 96 private final FallbackBrightnessStrategy mFallbackBrightnessStrategy; 97 98 // A collective representation of all the strategies that the selector is aware of. This is 99 // non null, but the strategies this is tracking can be null 100 @NonNull 101 @VisibleForTesting 102 final DisplayBrightnessStrategy[] mDisplayBrightnessStrategies; 103 104 @NonNull 105 private final DisplayManagerFlags mDisplayManagerFlags; 106 107 // We take note of the old brightness strategy so that we can know when the strategy changes. 108 private String mOldBrightnessStrategyName; 109 110 private final int mDisplayId; 111 112 private final Context mContext; 113 114 /** 115 * The constructor of DozeBrightnessStrategy. 116 */ DisplayBrightnessStrategySelector(Context context, Injector injector, int displayId, DisplayManagerFlags flags)117 public DisplayBrightnessStrategySelector(Context context, Injector injector, int displayId, 118 DisplayManagerFlags flags) { 119 if (injector == null) { 120 injector = new Injector(); 121 } 122 mContext = context; 123 mDisplayManagerFlags = flags; 124 mDisplayId = displayId; 125 mDozeBrightnessStrategy = injector.getDozeBrightnessStrategy(); 126 mScreenOffBrightnessStrategy = injector.getScreenOffBrightnessStrategy(); 127 mOverrideBrightnessStrategy = injector.getOverrideBrightnessStrategy(); 128 mTemporaryBrightnessStrategy = injector.getTemporaryBrightnessStrategy(); 129 mBoostBrightnessStrategy = injector.getBoostBrightnessStrategy(); 130 mFollowerBrightnessStrategy = injector.getFollowerBrightnessStrategy(displayId); 131 mInvalidBrightnessStrategy = injector.getInvalidBrightnessStrategy(); 132 mAutomaticBrightnessStrategy1 = 133 (!mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) ? null 134 : injector.getAutomaticBrightnessStrategy1(context, displayId, 135 mDisplayManagerFlags); 136 mAutomaticBrightnessStrategy2 = 137 (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) ? null 138 : injector.getAutomaticBrightnessStrategy2(context, displayId); 139 mAutomaticBrightnessStrategy = 140 (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) 141 ? mAutomaticBrightnessStrategy1 : mAutomaticBrightnessStrategy2; 142 mAutoBrightnessFallbackStrategy = (mDisplayManagerFlags 143 .isRefactorDisplayPowerControllerEnabled()) 144 ? injector.getAutoBrightnessFallbackStrategy() : null; 145 if (flags.isDisplayOffloadEnabled()) { 146 mOffloadBrightnessStrategy = injector 147 .getOffloadBrightnessStrategy(mDisplayManagerFlags); 148 } else { 149 mOffloadBrightnessStrategy = null; 150 } 151 mFallbackBrightnessStrategy = (mDisplayManagerFlags 152 .isRefactorDisplayPowerControllerEnabled()) 153 ? injector.getFallbackBrightnessStrategy() : null; 154 mDisplayBrightnessStrategies = new DisplayBrightnessStrategy[]{mInvalidBrightnessStrategy, 155 mScreenOffBrightnessStrategy, mDozeBrightnessStrategy, mFollowerBrightnessStrategy, 156 mBoostBrightnessStrategy, mOverrideBrightnessStrategy, mTemporaryBrightnessStrategy, 157 mAutomaticBrightnessStrategy1, mOffloadBrightnessStrategy, 158 mAutoBrightnessFallbackStrategy, mFallbackBrightnessStrategy}; 159 mAllowAutoBrightnessWhileDozingConfig = context.getResources().getBoolean( 160 R.bool.config_allowAutoBrightnessWhileDozing); 161 mAllowAutoBrightnessWhileDozing = mAllowAutoBrightnessWhileDozingConfig; 162 mOldBrightnessStrategyName = mInvalidBrightnessStrategy.getName(); 163 } 164 165 /** 166 * Selects the appropriate DisplayBrightnessStrategy based on the request and the display state 167 * to which the display is transitioning 168 */ 169 @NonNull selectStrategy( StrategySelectionRequest strategySelectionRequest)170 public DisplayBrightnessStrategy selectStrategy( 171 StrategySelectionRequest strategySelectionRequest) { 172 DisplayBrightnessStrategy displayBrightnessStrategy = mInvalidBrightnessStrategy; 173 int targetDisplayState = strategySelectionRequest.getTargetDisplayState(); 174 DisplayPowerRequest displayPowerRequest = strategySelectionRequest 175 .getDisplayPowerRequest(); 176 setAllowAutoBrightnessWhileDozing(strategySelectionRequest.getDisplayOffloadSession()); 177 if (targetDisplayState == Display.STATE_OFF) { 178 displayBrightnessStrategy = mScreenOffBrightnessStrategy; 179 } else if (shouldUseDozeBrightnessStrategy(displayPowerRequest)) { 180 displayBrightnessStrategy = mDozeBrightnessStrategy; 181 } else if (BrightnessUtils.isValidBrightnessValue( 182 mFollowerBrightnessStrategy.getBrightnessToFollow())) { 183 displayBrightnessStrategy = mFollowerBrightnessStrategy; 184 } else if (displayPowerRequest.boostScreenBrightness) { 185 displayBrightnessStrategy = mBoostBrightnessStrategy; 186 } else if (BrightnessUtils.isValidBrightnessValue( 187 displayPowerRequest.screenBrightnessOverride) 188 || BrightnessUtils.isValidBrightnessValue( 189 mOverrideBrightnessStrategy.getWindowManagerBrightnessOverride())) { 190 displayBrightnessStrategy = mOverrideBrightnessStrategy; 191 } else if (BrightnessUtils.isValidBrightnessValue( 192 mTemporaryBrightnessStrategy.getTemporaryScreenBrightness())) { 193 displayBrightnessStrategy = mTemporaryBrightnessStrategy; 194 } else if (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled() 195 && isAutomaticBrightnessStrategyValid(strategySelectionRequest)) { 196 displayBrightnessStrategy = mAutomaticBrightnessStrategy1; 197 } else if (mAutomaticBrightnessStrategy.shouldUseAutoBrightness() 198 && mOffloadBrightnessStrategy != null && BrightnessUtils.isValidBrightnessValue( 199 mOffloadBrightnessStrategy.getOffloadScreenBrightness())) { 200 displayBrightnessStrategy = mOffloadBrightnessStrategy; 201 } else if (isAutoBrightnessFallbackStrategyValid()) { 202 displayBrightnessStrategy = mAutoBrightnessFallbackStrategy; 203 } else { 204 // This will become the ultimate fallback strategy once the flag has been fully rolled 205 // out 206 if (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) { 207 displayBrightnessStrategy = mFallbackBrightnessStrategy; 208 } 209 } 210 211 if (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) { 212 postProcess(constructStrategySelectionNotifyRequest(displayBrightnessStrategy, 213 strategySelectionRequest)); 214 } 215 216 if (!mOldBrightnessStrategyName.equals(displayBrightnessStrategy.getName())) { 217 Slog.i(TAG, 218 "Changing the DisplayBrightnessStrategy from " + mOldBrightnessStrategyName 219 + " to " + displayBrightnessStrategy.getName() + " for display " 220 + mDisplayId); 221 mOldBrightnessStrategyName = displayBrightnessStrategy.getName(); 222 } 223 return displayBrightnessStrategy; 224 } 225 getTemporaryDisplayBrightnessStrategy()226 public TemporaryBrightnessStrategy getTemporaryDisplayBrightnessStrategy() { 227 return mTemporaryBrightnessStrategy; 228 } 229 getFollowerDisplayBrightnessStrategy()230 public FollowerBrightnessStrategy getFollowerDisplayBrightnessStrategy() { 231 return mFollowerBrightnessStrategy; 232 } 233 getAutomaticBrightnessStrategy()234 public AutomaticBrightnessStrategy2 getAutomaticBrightnessStrategy() { 235 return mAutomaticBrightnessStrategy; 236 } 237 238 @Nullable getOffloadBrightnessStrategy()239 public OffloadBrightnessStrategy getOffloadBrightnessStrategy() { 240 return mOffloadBrightnessStrategy; 241 } 242 243 /** 244 * Returns a boolean flag indicating if the light sensor is to be used to decide the screen 245 * brightness when dozing 246 */ isAllowAutoBrightnessWhileDozing()247 public boolean isAllowAutoBrightnessWhileDozing() { 248 return mAllowAutoBrightnessWhileDozing; 249 } 250 251 /** 252 * Returns the config value indicating whether auto brightness while dozing is to be 253 * allowed ot not 254 */ isAllowAutoBrightnessWhileDozingConfig()255 public boolean isAllowAutoBrightnessWhileDozingConfig() { 256 return mAllowAutoBrightnessWhileDozingConfig; 257 } 258 259 @Nullable getAutoBrightnessFallbackStrategy()260 public AutoBrightnessFallbackStrategy getAutoBrightnessFallbackStrategy() { 261 return mAutoBrightnessFallbackStrategy; 262 } 263 getOverrideBrightnessStrategy()264 public OverrideBrightnessStrategy getOverrideBrightnessStrategy() { 265 return mOverrideBrightnessStrategy; 266 } 267 268 /** 269 * Dumps the state of this class. 270 */ dump(PrintWriter writer)271 public void dump(PrintWriter writer) { 272 writer.println(); 273 writer.println("DisplayBrightnessStrategySelector:"); 274 writer.println("----------------------------------"); 275 writer.println(" mDisplayId= " + mDisplayId); 276 writer.println(" mOldBrightnessStrategyName= " + mOldBrightnessStrategyName); 277 writer.println( 278 " mAllowAutoBrightnessWhileDozingConfig= " 279 + mAllowAutoBrightnessWhileDozingConfig); 280 writer.println( 281 " mAllowAutoBrightnessWhileDozing= " + mAllowAutoBrightnessWhileDozing); 282 IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " "); 283 for (DisplayBrightnessStrategy displayBrightnessStrategy : mDisplayBrightnessStrategies) { 284 if (displayBrightnessStrategy != null) { 285 displayBrightnessStrategy.dump(ipw); 286 } 287 } 288 } 289 290 @VisibleForTesting setAllowAutoBrightnessWhileDozing( DisplayManagerInternal.DisplayOffloadSession displayOffloadSession)291 void setAllowAutoBrightnessWhileDozing( 292 DisplayManagerInternal.DisplayOffloadSession displayOffloadSession) { 293 mAllowAutoBrightnessWhileDozing = mAllowAutoBrightnessWhileDozingConfig; 294 if (mDisplayManagerFlags.isDisplayOffloadEnabled() 295 && displayOffloadSession != null) { 296 mAllowAutoBrightnessWhileDozing &= displayOffloadSession.allowAutoBrightnessInDoze(); 297 } 298 } 299 isAutoBrightnessFallbackStrategyValid()300 private boolean isAutoBrightnessFallbackStrategyValid() { 301 return mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled() 302 && mAutoBrightnessFallbackStrategy != null 303 && getAutomaticBrightnessStrategy().shouldUseAutoBrightness() 304 && mAutoBrightnessFallbackStrategy.isValid(); 305 } 306 isAutomaticBrightnessStrategyValid( StrategySelectionRequest strategySelectionRequest)307 private boolean isAutomaticBrightnessStrategyValid( 308 StrategySelectionRequest strategySelectionRequest) { 309 mAutomaticBrightnessStrategy1.setAutoBrightnessState( 310 strategySelectionRequest.getTargetDisplayState(), 311 mAllowAutoBrightnessWhileDozing, 312 BrightnessReason.REASON_UNKNOWN, 313 strategySelectionRequest.getDisplayPowerRequest().policy, 314 strategySelectionRequest.getDisplayPowerRequest().useNormalBrightnessForDoze, 315 strategySelectionRequest.getLastUserSetScreenBrightness(), 316 strategySelectionRequest.isUserSetBrightnessChanged(), 317 strategySelectionRequest.isWearBedtimeModeEnabled()); 318 return !strategySelectionRequest.isStylusBeingUsed() 319 && mAutomaticBrightnessStrategy1.isAutoBrightnessValid(); 320 } 321 constructStrategySelectionNotifyRequest( DisplayBrightnessStrategy selectedDisplayBrightnessStrategy, StrategySelectionRequest strategySelectionRequest)322 private StrategySelectionNotifyRequest constructStrategySelectionNotifyRequest( 323 DisplayBrightnessStrategy selectedDisplayBrightnessStrategy, 324 StrategySelectionRequest strategySelectionRequest) { 325 return new StrategySelectionNotifyRequest( 326 strategySelectionRequest.getDisplayPowerRequest(), 327 strategySelectionRequest.getTargetDisplayState(), 328 selectedDisplayBrightnessStrategy, 329 strategySelectionRequest.getLastUserSetScreenBrightness(), 330 strategySelectionRequest.isUserSetBrightnessChanged(), 331 mAllowAutoBrightnessWhileDozing, 332 getAutomaticBrightnessStrategy().shouldUseAutoBrightness(), 333 strategySelectionRequest.isWearBedtimeModeEnabled()); 334 } 335 postProcess(StrategySelectionNotifyRequest strategySelectionNotifyRequest)336 private void postProcess(StrategySelectionNotifyRequest strategySelectionNotifyRequest) { 337 for (DisplayBrightnessStrategy displayBrightnessStrategy : mDisplayBrightnessStrategies) { 338 if (displayBrightnessStrategy != null) { 339 displayBrightnessStrategy.strategySelectionPostProcessor( 340 strategySelectionNotifyRequest); 341 } 342 } 343 } 344 345 /** 346 * Validates if the conditions are met to qualify for the DozeBrightnessStrategy. 347 */ shouldUseDozeBrightnessStrategy(DisplayPowerRequest displayPowerRequest)348 private boolean shouldUseDozeBrightnessStrategy(DisplayPowerRequest displayPowerRequest) { 349 // We are not checking the targetDisplayState, but rather relying on the policy because 350 // a user can define a different display state(displayPowerRequest.dozeScreenState) too 351 // in the request with the Doze policy and user might request an override to force certain 352 // brightness. 353 return (!mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext) 354 || !displayPowerRequest.useNormalBrightnessForDoze) 355 && displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE 356 && !mAllowAutoBrightnessWhileDozing 357 && BrightnessUtils.isValidBrightnessValue(displayPowerRequest.dozeScreenBrightness); 358 } 359 360 @VisibleForTesting 361 static class Injector { getScreenOffBrightnessStrategy()362 ScreenOffBrightnessStrategy getScreenOffBrightnessStrategy() { 363 return new ScreenOffBrightnessStrategy(); 364 } 365 getDozeBrightnessStrategy()366 DozeBrightnessStrategy getDozeBrightnessStrategy() { 367 return new DozeBrightnessStrategy(); 368 } 369 getOverrideBrightnessStrategy()370 OverrideBrightnessStrategy getOverrideBrightnessStrategy() { 371 return new OverrideBrightnessStrategy(); 372 } 373 getTemporaryBrightnessStrategy()374 TemporaryBrightnessStrategy getTemporaryBrightnessStrategy() { 375 return new TemporaryBrightnessStrategy(); 376 } 377 getBoostBrightnessStrategy()378 BoostBrightnessStrategy getBoostBrightnessStrategy() { 379 return new BoostBrightnessStrategy(); 380 } 381 getFollowerBrightnessStrategy(int displayId)382 FollowerBrightnessStrategy getFollowerBrightnessStrategy(int displayId) { 383 return new FollowerBrightnessStrategy(displayId); 384 } 385 getInvalidBrightnessStrategy()386 InvalidBrightnessStrategy getInvalidBrightnessStrategy() { 387 return new InvalidBrightnessStrategy(); 388 } 389 getAutomaticBrightnessStrategy1(Context context, int displayId, DisplayManagerFlags displayManagerFlags)390 AutomaticBrightnessStrategy getAutomaticBrightnessStrategy1(Context context, 391 int displayId, DisplayManagerFlags displayManagerFlags) { 392 return new AutomaticBrightnessStrategy(context, displayId, displayManagerFlags); 393 } 394 getAutomaticBrightnessStrategy2(Context context, int displayId)395 AutomaticBrightnessStrategy2 getAutomaticBrightnessStrategy2(Context context, 396 int displayId) { 397 return new AutomaticBrightnessStrategy2(context, displayId); 398 } 399 getOffloadBrightnessStrategy( DisplayManagerFlags displayManagerFlags)400 OffloadBrightnessStrategy getOffloadBrightnessStrategy( 401 DisplayManagerFlags displayManagerFlags) { 402 return new OffloadBrightnessStrategy(displayManagerFlags); 403 } 404 getAutoBrightnessFallbackStrategy()405 AutoBrightnessFallbackStrategy getAutoBrightnessFallbackStrategy() { 406 return new AutoBrightnessFallbackStrategy(/* injector= */ null); 407 } 408 getFallbackBrightnessStrategy()409 FallbackBrightnessStrategy getFallbackBrightnessStrategy() { 410 return new FallbackBrightnessStrategy(); 411 } 412 } 413 } 414