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.Nullable; 20 import android.util.Slog; 21 22 import java.util.Objects; 23 24 /** 25 * Stores data about why the brightness was changed. Made up of one main 26 * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*} 27 * modifiers. 28 */ 29 public final class BrightnessReason { 30 private static final String TAG = "BrightnessReason"; 31 32 public static final int REASON_UNKNOWN = 0; 33 public static final int REASON_MANUAL = 1; 34 public static final int REASON_DOZE = 2; 35 public static final int REASON_DOZE_DEFAULT = 3; 36 public static final int REASON_AUTOMATIC = 4; 37 public static final int REASON_SCREEN_OFF = 5; 38 public static final int REASON_OVERRIDE = 6; 39 public static final int REASON_TEMPORARY = 7; 40 public static final int REASON_BOOST = 8; 41 public static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 9; 42 public static final int REASON_FOLLOWER = 10; 43 public static final int REASON_OFFLOAD = 11; 44 public static final int REASON_DOZE_MANUAL = 12; 45 public static final int REASON_MAX = REASON_DOZE_MANUAL; 46 47 public static final int MODIFIER_DIMMED = 0x1; 48 public static final int MODIFIER_LOW_POWER = 0x2; 49 public static final int MODIFIER_HDR = 0x4; 50 public static final int MODIFIER_THROTTLED = 0x8; 51 public static final int MODIFIER_MIN_LUX = 0x10; 52 public static final int MODIFIER_STYLUS_UNDER_USE = 0x20; 53 public static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR 54 | MODIFIER_THROTTLED | MODIFIER_MIN_LUX | MODIFIER_STYLUS_UNDER_USE; 55 56 // ADJUSTMENT_* 57 // These things can happen at any point, even if the main brightness reason doesn't 58 // fundamentally change, so they're not stored. 59 60 // Auto-brightness adjustment factor changed 61 public static final int ADJUSTMENT_AUTO_TEMP = 0x1; 62 // Temporary adjustment to the auto-brightness adjustment factor. 63 public static final int ADJUSTMENT_AUTO = 0x2; 64 65 // One of REASON_* 66 private int mReason; 67 // Any number of MODIFIER_* 68 private int mModifier; 69 70 // Tag used to identify the source of the brightness (usually a specific activity/window). 71 private CharSequence mTag; 72 BrightnessReason()73 public BrightnessReason() { 74 } 75 BrightnessReason(int reason)76 public BrightnessReason(int reason) { 77 setReason(reason); 78 } 79 80 /** 81 * A utility to clone a BrightnessReason from another BrightnessReason event 82 * 83 * @param other The BrightnessReason object which is to be cloned 84 */ set(BrightnessReason other)85 public void set(BrightnessReason other) { 86 setReason(other == null ? REASON_UNKNOWN : other.mReason); 87 setModifier(other == null ? 0 : other.mModifier); 88 setTag(other == null ? null : other.mTag); 89 } 90 91 /** 92 * A utility to add a modifier to the BrightnessReason object 93 * 94 * @param modifier The modifier which is to be added 95 */ addModifier(int modifier)96 public void addModifier(int modifier) { 97 setModifier(modifier | this.mModifier); 98 } 99 100 @Override equals(Object obj)101 public boolean equals(Object obj) { 102 if (!(obj instanceof BrightnessReason)) { 103 return false; 104 } 105 BrightnessReason other = (BrightnessReason) obj; 106 return other.mReason == mReason 107 && other.mModifier == mModifier 108 && Objects.equals(other.mTag != null ? other.mTag.toString() : null, mTag); 109 } 110 111 @Override hashCode()112 public int hashCode() { 113 return Objects.hash(mReason, mModifier, mTag); 114 } 115 116 @Override toString()117 public String toString() { 118 return toString(0); 119 } 120 121 /** 122 * A utility to stringify a BrightnessReason 123 * 124 * @param adjustments Indicates if the adjustments field is to be added in the stringify version 125 * of the BrightnessReason 126 * @return A stringified BrightnessReason 127 */ toString(int adjustments)128 public String toString(int adjustments) { 129 final StringBuilder sb = new StringBuilder(); 130 sb.append(reasonToString(mReason)); 131 132 if (mTag != null) { 133 sb.append("(").append(mTag).append(")"); 134 } 135 136 sb.append(" ["); 137 if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) { 138 sb.append(" temp_adj"); 139 } 140 if ((adjustments & ADJUSTMENT_AUTO) != 0) { 141 sb.append(" auto_adj"); 142 } 143 if ((mModifier & MODIFIER_LOW_POWER) != 0) { 144 sb.append(" low_pwr"); 145 } 146 if ((mModifier & MODIFIER_DIMMED) != 0) { 147 sb.append(" dim"); 148 } 149 if ((mModifier & MODIFIER_HDR) != 0) { 150 sb.append(" hdr"); 151 } 152 if ((mModifier & MODIFIER_THROTTLED) != 0) { 153 sb.append(" throttled"); 154 } 155 if ((mModifier & MODIFIER_MIN_LUX) != 0) { 156 sb.append(" lux_lower_bound"); 157 } 158 if ((mModifier & MODIFIER_STYLUS_UNDER_USE) != 0) { 159 sb.append(" stylus_under_use"); 160 } 161 int strlen = sb.length(); 162 if (sb.charAt(strlen - 1) == '[') { 163 sb.setLength(strlen - 2); 164 } else { 165 sb.append(" ]"); 166 } 167 return sb.toString(); 168 } 169 setTag(@ullable CharSequence tag)170 public void setTag(@Nullable CharSequence tag) { 171 mTag = tag; 172 } 173 174 /** 175 * Gets the tag to identify who requested the brightness. 176 */ getTag()177 @Nullable public CharSequence getTag() { 178 return mTag; 179 } 180 getReason()181 public int getReason() { 182 return mReason; 183 } 184 185 /** 186 * Sets the reason of the BrightnessReason object 187 * 188 * @param reason The value to which the reason is to be updated. 189 */ setReason(int reason)190 public void setReason(int reason) { 191 if (reason < REASON_UNKNOWN || reason > REASON_MAX) { 192 Slog.w(TAG, "brightness reason out of bounds: " + reason); 193 } else { 194 this.mReason = reason; 195 } 196 } 197 getModifier()198 public int getModifier() { 199 return mModifier; 200 } 201 202 /** 203 * Sets the modifier bitflags of the current BrightnessReason object 204 * 205 * @param modifier The value to which the modifier is to be updated 206 */ setModifier(int modifier)207 public void setModifier(int modifier) { 208 if ((modifier & ~MODIFIER_MASK) != 0) { 209 Slog.w(TAG, "brightness modifier out of bounds: 0x" 210 + Integer.toHexString(modifier)); 211 } else { 212 this.mModifier = modifier; 213 } 214 } 215 reasonToString(int reason)216 private String reasonToString(int reason) { 217 switch (reason) { 218 case REASON_MANUAL: 219 return "manual"; 220 case REASON_DOZE: 221 return "doze"; 222 case REASON_DOZE_DEFAULT: 223 return "doze_default"; 224 case REASON_AUTOMATIC: 225 return "automatic"; 226 case REASON_SCREEN_OFF: 227 return "screen_off"; 228 case REASON_OVERRIDE: 229 return "override"; 230 case REASON_TEMPORARY: 231 return "temporary"; 232 case REASON_BOOST: 233 return "boost"; 234 case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: 235 return "screen_off_brightness_sensor"; 236 case REASON_FOLLOWER: 237 return "follower"; 238 case REASON_OFFLOAD: 239 return "offload"; 240 case REASON_DOZE_MANUAL: 241 return "doze_manual"; 242 default: 243 return Integer.toString(reason); 244 } 245 } 246 } 247