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.content.Context; 21 import android.hardware.display.DisplayManagerInternal; 22 import android.util.IndentingPrintWriter; 23 import android.util.Slog; 24 import android.view.Display; 25 26 import com.android.internal.R; 27 import com.android.internal.annotations.VisibleForTesting; 28 import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy; 29 import com.android.server.display.brightness.strategy.BoostBrightnessStrategy; 30 import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy; 31 import com.android.server.display.brightness.strategy.DozeBrightnessStrategy; 32 import com.android.server.display.brightness.strategy.FollowerBrightnessStrategy; 33 import com.android.server.display.brightness.strategy.InvalidBrightnessStrategy; 34 import com.android.server.display.brightness.strategy.OverrideBrightnessStrategy; 35 import com.android.server.display.brightness.strategy.ScreenOffBrightnessStrategy; 36 import com.android.server.display.brightness.strategy.TemporaryBrightnessStrategy; 37 38 import java.io.PrintWriter; 39 40 /** 41 * This maintains the logic needed to decide the eligible display brightness strategy. 42 */ 43 public class DisplayBrightnessStrategySelector { 44 private static final String TAG = "DisplayBrightnessStrategySelector"; 45 // True if light sensor is to be used to automatically determine doze screen brightness. 46 private final boolean mAllowAutoBrightnessWhileDozingConfig; 47 48 // The brightness strategy used to manage the brightness state when the display is dozing. 49 private final DozeBrightnessStrategy mDozeBrightnessStrategy; 50 // The brightness strategy used to manage the brightness state when the display is in 51 // screen off state. 52 private final ScreenOffBrightnessStrategy mScreenOffBrightnessStrategy; 53 // The brightness strategy used to manage the brightness state when the request state is 54 // invalid. 55 private final OverrideBrightnessStrategy mOverrideBrightnessStrategy; 56 // The brightness strategy used to manage the brightness state in temporary state 57 private final TemporaryBrightnessStrategy mTemporaryBrightnessStrategy; 58 // The brightness strategy used to manage the brightness state when boost is requested 59 private final BoostBrightnessStrategy mBoostBrightnessStrategy; 60 // The brightness strategy used for additional displays 61 private final FollowerBrightnessStrategy mFollowerBrightnessStrategy; 62 // The brightness strategy used to manage the brightness state when the request is invalid. 63 private final InvalidBrightnessStrategy mInvalidBrightnessStrategy; 64 // Controls brightness when automatic (adaptive) brightness is running. 65 private final AutomaticBrightnessStrategy mAutomaticBrightnessStrategy; 66 67 // We take note of the old brightness strategy so that we can know when the strategy changes. 68 private String mOldBrightnessStrategyName; 69 70 private final int mDisplayId; 71 72 /** 73 * The constructor of DozeBrightnessStrategy. 74 */ DisplayBrightnessStrategySelector(Context context, Injector injector, int displayId)75 public DisplayBrightnessStrategySelector(Context context, Injector injector, int displayId) { 76 if (injector == null) { 77 injector = new Injector(); 78 } 79 mDisplayId = displayId; 80 mDozeBrightnessStrategy = injector.getDozeBrightnessStrategy(); 81 mScreenOffBrightnessStrategy = injector.getScreenOffBrightnessStrategy(); 82 mOverrideBrightnessStrategy = injector.getOverrideBrightnessStrategy(); 83 mTemporaryBrightnessStrategy = injector.getTemporaryBrightnessStrategy(); 84 mBoostBrightnessStrategy = injector.getBoostBrightnessStrategy(); 85 mFollowerBrightnessStrategy = injector.getFollowerBrightnessStrategy(displayId); 86 mInvalidBrightnessStrategy = injector.getInvalidBrightnessStrategy(); 87 mAutomaticBrightnessStrategy = injector.getAutomaticBrightnessStrategy(context, displayId); 88 mAllowAutoBrightnessWhileDozingConfig = context.getResources().getBoolean( 89 R.bool.config_allowAutoBrightnessWhileDozing); 90 mOldBrightnessStrategyName = mInvalidBrightnessStrategy.getName(); 91 } 92 93 /** 94 * Selects the appropriate DisplayBrightnessStrategy based on the request and the display state 95 * to which the display is transitioning 96 */ 97 @NonNull selectStrategy( DisplayManagerInternal.DisplayPowerRequest displayPowerRequest, int targetDisplayState)98 public DisplayBrightnessStrategy selectStrategy( 99 DisplayManagerInternal.DisplayPowerRequest displayPowerRequest, 100 int targetDisplayState) { 101 DisplayBrightnessStrategy displayBrightnessStrategy = mInvalidBrightnessStrategy; 102 if (targetDisplayState == Display.STATE_OFF) { 103 displayBrightnessStrategy = mScreenOffBrightnessStrategy; 104 } else if (shouldUseDozeBrightnessStrategy(displayPowerRequest)) { 105 displayBrightnessStrategy = mDozeBrightnessStrategy; 106 } else if (BrightnessUtils.isValidBrightnessValue( 107 mFollowerBrightnessStrategy.getBrightnessToFollow())) { 108 displayBrightnessStrategy = mFollowerBrightnessStrategy; 109 } else if (displayPowerRequest.boostScreenBrightness) { 110 displayBrightnessStrategy = mBoostBrightnessStrategy; 111 } else if (BrightnessUtils 112 .isValidBrightnessValue(displayPowerRequest.screenBrightnessOverride)) { 113 displayBrightnessStrategy = mOverrideBrightnessStrategy; 114 } else if (BrightnessUtils.isValidBrightnessValue( 115 mTemporaryBrightnessStrategy.getTemporaryScreenBrightness())) { 116 displayBrightnessStrategy = mTemporaryBrightnessStrategy; 117 } 118 119 if (!mOldBrightnessStrategyName.equals(displayBrightnessStrategy.getName())) { 120 Slog.i(TAG, 121 "Changing the DisplayBrightnessStrategy from " + mOldBrightnessStrategyName 122 + " to" + displayBrightnessStrategy.getName() + " for display " 123 + mDisplayId); 124 mOldBrightnessStrategyName = displayBrightnessStrategy.getName(); 125 } 126 return displayBrightnessStrategy; 127 } 128 getTemporaryDisplayBrightnessStrategy()129 public TemporaryBrightnessStrategy getTemporaryDisplayBrightnessStrategy() { 130 return mTemporaryBrightnessStrategy; 131 } 132 getFollowerDisplayBrightnessStrategy()133 public FollowerBrightnessStrategy getFollowerDisplayBrightnessStrategy() { 134 return mFollowerBrightnessStrategy; 135 } 136 getAutomaticBrightnessStrategy()137 public AutomaticBrightnessStrategy getAutomaticBrightnessStrategy() { 138 return mAutomaticBrightnessStrategy; 139 } 140 141 /** 142 * Returns a boolean flag indicating if the light sensor is to be used to decide the screen 143 * brightness when dozing 144 */ isAllowAutoBrightnessWhileDozingConfig()145 public boolean isAllowAutoBrightnessWhileDozingConfig() { 146 return mAllowAutoBrightnessWhileDozingConfig; 147 } 148 149 /** 150 * Dumps the state of this class. 151 */ dump(PrintWriter writer)152 public void dump(PrintWriter writer) { 153 writer.println(); 154 writer.println("DisplayBrightnessStrategySelector:"); 155 writer.println(" mDisplayId= " + mDisplayId); 156 writer.println(" mOldBrightnessStrategyName= " + mOldBrightnessStrategyName); 157 writer.println( 158 " mAllowAutoBrightnessWhileDozingConfig= " 159 + mAllowAutoBrightnessWhileDozingConfig); 160 IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " "); 161 mTemporaryBrightnessStrategy.dump(ipw); 162 } 163 164 /** 165 * Validates if the conditions are met to qualify for the DozeBrightnessStrategy. 166 */ shouldUseDozeBrightnessStrategy( DisplayManagerInternal.DisplayPowerRequest displayPowerRequest)167 private boolean shouldUseDozeBrightnessStrategy( 168 DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) { 169 // We are not checking the targetDisplayState, but rather relying on the policy because 170 // a user can define a different display state(displayPowerRequest.dozeScreenState) too 171 // in the request with the Doze policy 172 if (displayPowerRequest.policy == DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE) { 173 if (!mAllowAutoBrightnessWhileDozingConfig) { 174 return true; 175 } 176 } 177 return false; 178 } 179 180 @VisibleForTesting 181 static class Injector { getScreenOffBrightnessStrategy()182 ScreenOffBrightnessStrategy getScreenOffBrightnessStrategy() { 183 return new ScreenOffBrightnessStrategy(); 184 } 185 getDozeBrightnessStrategy()186 DozeBrightnessStrategy getDozeBrightnessStrategy() { 187 return new DozeBrightnessStrategy(); 188 } 189 getOverrideBrightnessStrategy()190 OverrideBrightnessStrategy getOverrideBrightnessStrategy() { 191 return new OverrideBrightnessStrategy(); 192 } 193 getTemporaryBrightnessStrategy()194 TemporaryBrightnessStrategy getTemporaryBrightnessStrategy() { 195 return new TemporaryBrightnessStrategy(); 196 } 197 getBoostBrightnessStrategy()198 BoostBrightnessStrategy getBoostBrightnessStrategy() { 199 return new BoostBrightnessStrategy(); 200 } 201 getFollowerBrightnessStrategy(int displayId)202 FollowerBrightnessStrategy getFollowerBrightnessStrategy(int displayId) { 203 return new FollowerBrightnessStrategy(displayId); 204 } 205 getInvalidBrightnessStrategy()206 InvalidBrightnessStrategy getInvalidBrightnessStrategy() { 207 return new InvalidBrightnessStrategy(); 208 } 209 getAutomaticBrightnessStrategy(Context context, int displayId)210 AutomaticBrightnessStrategy getAutomaticBrightnessStrategy(Context context, int displayId) { 211 return new AutomaticBrightnessStrategy(context, displayId); 212 } 213 } 214 } 215