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