1 /*
2  * Copyright 2017 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 android.hardware.display;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SystemApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.util.Arrays;
26 import java.util.Objects;
27 
28 /**
29  * Data about a brightness settings change.
30  *
31  * {@see DisplayManager.getBrightnessEvents()}
32  * @hide
33  */
34 @SystemApi
35 public final class BrightnessChangeEvent implements Parcelable {
36     /** Brightness in nits */
37     public final float brightness;
38 
39     /** Timestamp of the change {@see System.currentTimeMillis()} */
40     public final long timeStamp;
41 
42     /** Package name of focused activity when brightness was changed.
43      *  This will be null if the caller of {@see DisplayManager.getBrightnessEvents()}
44      *  does not have access to usage stats {@see UsageStatsManager} */
45     public final String packageName;
46 
47     /** User id of of the user running when brightness was changed.
48      * @hide */
49     public final int userId;
50 
51     /** The unique id of the screen on which the brightness was changed */
52     @NonNull
53     public final String uniqueDisplayId;
54 
55     /** Lux values of recent sensor data */
56     public final float[] luxValues;
57 
58     /** Timestamps of the lux sensor readings {@see System.currentTimeMillis()} */
59     public final long[] luxTimestamps;
60 
61     /** Most recent battery level when brightness was changed or Float.NaN */
62     public final float batteryLevel;
63 
64     /** Factor applied to brightness due to battery level, 0.0-1.0 */
65     public final float powerBrightnessFactor;
66 
67     /** Color filter active to provide night mode */
68     public final boolean nightMode;
69 
70     /** If night mode color filter is active this will be the temperature in kelvin */
71     public final int colorTemperature;
72 
73     /** Whether the bright color reduction color transform is active */
74     public final boolean reduceBrightColors;
75 
76     /** How strong the bright color reduction color transform is set (only applicable if active),
77      *  specified as an integer from 0 - 100, inclusive. This value (scaled to 0-1, inclusive) is
78      *  then used in Ynew = (a * scaledStrength^2 + b * scaledStrength + c) * Ycurrent, where a, b,
79      *  and c are coefficients provided in the bright color reduction coefficient matrix, and
80      *  Ycurrent is the current hardware brightness in nits.
81      */
82     public final int reduceBrightColorsStrength;
83 
84     /** Applied offset for the bright color reduction color transform (only applicable if active).
85      *  The offset is computed by summing the coefficients a, b, and c, from the coefficient matrix
86      *  and multiplying by the current brightness.
87      */
88     public final float reduceBrightColorsOffset;
89 
90     /** Brightness level before slider adjustment */
91     public final float lastBrightness;
92 
93     /** Whether brightness configuration is default version */
94     public final boolean isDefaultBrightnessConfig;
95 
96     /** Whether brightness curve includes a user brightness point */
97     public final boolean isUserSetBrightness;
98 
99     /**
100      * Histogram counting how many times a pixel of a given value was displayed onscreen for the
101      * Value component of HSV if the device supports color sampling, if the device does not support
102      * color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is false the
103      * value will be null.
104      *
105      * The buckets of the histogram are evenly weighted, the number of buckets is device specific.
106      * The units are in pixels * milliseconds, with 1 pixel millisecond being 1 pixel displayed
107      * for 1 millisecond.
108      * For example if we had {100, 50, 30, 20}, value component was onscreen for 100 pixel
109      * milliseconds in range 0x00->0x3F, 30 pixel milliseconds in range 0x40->0x7F, etc.
110      *
111      * {@see #colorSampleDuration}
112      */
113     @Nullable
114     public final long[] colorValueBuckets;
115 
116     /**
117      * How many milliseconds of data are contained in the colorValueBuckets, if the device does
118      * not support color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is
119      * false the value will be 0L.
120      *
121      * {@see #colorValueBuckets}
122      */
123     public final long colorSampleDuration;
124 
125 
126     /** @hide */
BrightnessChangeEvent(float brightness, long timeStamp, String packageName, int userId, String uniqueDisplayId, float[] luxValues, long[] luxTimestamps, float batteryLevel, float powerBrightnessFactor, boolean nightMode, int colorTemperature, boolean reduceBrightColors, int reduceBrightColorsStrength, float reduceBrightColorsOffset, float lastBrightness, boolean isDefaultBrightnessConfig, boolean isUserSetBrightness, long[] colorValueBuckets, long colorSampleDuration)127     private BrightnessChangeEvent(float brightness, long timeStamp, String packageName,
128             int userId, String uniqueDisplayId, float[] luxValues, long[] luxTimestamps,
129             float batteryLevel, float powerBrightnessFactor, boolean nightMode,
130             int colorTemperature, boolean reduceBrightColors, int reduceBrightColorsStrength,
131             float reduceBrightColorsOffset, float lastBrightness, boolean isDefaultBrightnessConfig,
132             boolean isUserSetBrightness, long[] colorValueBuckets, long colorSampleDuration) {
133         this.brightness = brightness;
134         this.timeStamp = timeStamp;
135         this.packageName = packageName;
136         this.userId = userId;
137         this.uniqueDisplayId = uniqueDisplayId;
138         this.luxValues = luxValues;
139         this.luxTimestamps = luxTimestamps;
140         this.batteryLevel = batteryLevel;
141         this.powerBrightnessFactor = powerBrightnessFactor;
142         this.nightMode = nightMode;
143         this.colorTemperature = colorTemperature;
144         this.reduceBrightColors = reduceBrightColors;
145         this.reduceBrightColorsStrength = reduceBrightColorsStrength;
146         this.reduceBrightColorsOffset = reduceBrightColorsOffset;
147         this.lastBrightness = lastBrightness;
148         this.isDefaultBrightnessConfig = isDefaultBrightnessConfig;
149         this.isUserSetBrightness = isUserSetBrightness;
150         this.colorValueBuckets = colorValueBuckets;
151         this.colorSampleDuration = colorSampleDuration;
152     }
153 
154     /** @hide */
BrightnessChangeEvent(BrightnessChangeEvent other, boolean redactPackage)155     public BrightnessChangeEvent(BrightnessChangeEvent other, boolean redactPackage) {
156         this.brightness = other.brightness;
157         this.timeStamp = other.timeStamp;
158         this.packageName = redactPackage ? null : other.packageName;
159         this.userId = other.userId;
160         this.uniqueDisplayId = other.uniqueDisplayId;
161         this.luxValues = other.luxValues;
162         this.luxTimestamps = other.luxTimestamps;
163         this.batteryLevel = other.batteryLevel;
164         this.powerBrightnessFactor = other.powerBrightnessFactor;
165         this.nightMode = other.nightMode;
166         this.colorTemperature = other.colorTemperature;
167         this.reduceBrightColors = other.reduceBrightColors;
168         this.reduceBrightColorsStrength = other.reduceBrightColorsStrength;
169         this.reduceBrightColorsOffset = other.reduceBrightColorsOffset;
170         this.lastBrightness = other.lastBrightness;
171         this.isDefaultBrightnessConfig = other.isDefaultBrightnessConfig;
172         this.isUserSetBrightness = other.isUserSetBrightness;
173         this.colorValueBuckets = other.colorValueBuckets;
174         this.colorSampleDuration = other.colorSampleDuration;
175     }
176 
BrightnessChangeEvent(Parcel source)177     private BrightnessChangeEvent(Parcel source) {
178         brightness = source.readFloat();
179         timeStamp = source.readLong();
180         packageName = source.readString();
181         userId = source.readInt();
182         uniqueDisplayId = source.readString();
183         luxValues = source.createFloatArray();
184         luxTimestamps = source.createLongArray();
185         batteryLevel = source.readFloat();
186         powerBrightnessFactor = source.readFloat();
187         nightMode = source.readBoolean();
188         colorTemperature = source.readInt();
189         reduceBrightColors = source.readBoolean();
190         reduceBrightColorsStrength = source.readInt();
191         reduceBrightColorsOffset = source.readFloat();
192         lastBrightness = source.readFloat();
193         isDefaultBrightnessConfig = source.readBoolean();
194         isUserSetBrightness = source.readBoolean();
195         colorValueBuckets = source.createLongArray();
196         colorSampleDuration = source.readLong();
197     }
198 
199     public static final @android.annotation.NonNull Creator<BrightnessChangeEvent> CREATOR =
200             new Creator<BrightnessChangeEvent>() {
201                 public BrightnessChangeEvent createFromParcel(Parcel source) {
202                     return new BrightnessChangeEvent(source);
203                 }
204                 public BrightnessChangeEvent[] newArray(int size) {
205                     return new BrightnessChangeEvent[size];
206                 }
207             };
208 
209     @Override
describeContents()210     public int describeContents() {
211         return 0;
212     }
213 
214     @Override
writeToParcel(Parcel dest, int flags)215     public void writeToParcel(Parcel dest, int flags) {
216         dest.writeFloat(brightness);
217         dest.writeLong(timeStamp);
218         dest.writeString(packageName);
219         dest.writeInt(userId);
220         dest.writeString(uniqueDisplayId);
221         dest.writeFloatArray(luxValues);
222         dest.writeLongArray(luxTimestamps);
223         dest.writeFloat(batteryLevel);
224         dest.writeFloat(powerBrightnessFactor);
225         dest.writeBoolean(nightMode);
226         dest.writeInt(colorTemperature);
227         dest.writeBoolean(reduceBrightColors);
228         dest.writeInt(reduceBrightColorsStrength);
229         dest.writeFloat(reduceBrightColorsOffset);
230         dest.writeFloat(lastBrightness);
231         dest.writeBoolean(isDefaultBrightnessConfig);
232         dest.writeBoolean(isUserSetBrightness);
233         dest.writeLongArray(colorValueBuckets);
234         dest.writeLong(colorSampleDuration);
235     }
236 
237     @Override
toString()238     public String toString() {
239         return "BrightnessChangeEvent{"
240                 + "brightness: " + brightness
241                 + ", timeStamp: " + timeStamp
242                 + ", packageName: " + packageName
243                 + ", userId: " + userId
244                 + ", uniqueDisplayId: " + uniqueDisplayId
245                 + ", luxValues: " + Arrays.toString(luxValues)
246                 + ", luxTimestamps: " + Arrays.toString(luxTimestamps)
247                 + ", batteryLevel: " + batteryLevel
248                 + ", powerBrightnessFactor: " + powerBrightnessFactor
249                 + ", nightMode: " + nightMode
250                 + ", colorTemperature: " + colorTemperature
251                 + ", reduceBrightColors: " + reduceBrightColors
252                 + ", reduceBrightColorsStrength: " + reduceBrightColorsStrength
253                 + ", reduceBrightColorsOffset: " + reduceBrightColorsOffset
254                 + ", lastBrightness: " + lastBrightness
255                 + ", isDefaultBrightnessConfig: " + isDefaultBrightnessConfig
256                 + ", isUserSetBrightness: " + isUserSetBrightness
257                 + ", colorValueBuckets: " + Arrays.toString(colorValueBuckets)
258                 + ", colorSampleDuration: " + colorSampleDuration
259                 + "}";
260     }
261 
262     /** @hide */
263     public static class Builder {
264         private float mBrightness;
265         private long mTimeStamp;
266         private String mPackageName;
267         private int mUserId;
268         private String mUniqueDisplayId;
269         private float[] mLuxValues;
270         private long[] mLuxTimestamps;
271         private float mBatteryLevel;
272         private float mPowerBrightnessFactor;
273         private boolean mNightMode;
274         private int mColorTemperature;
275         private boolean mReduceBrightColors;
276         private int mReduceBrightColorsStrength;
277         private float mReduceBrightColorsOffset;
278         private float mLastBrightness;
279         private boolean mIsDefaultBrightnessConfig;
280         private boolean mIsUserSetBrightness;
281         private long[] mColorValueBuckets;
282         private long mColorSampleDuration;
283 
284         /** {@see BrightnessChangeEvent#brightness} */
setBrightness(float brightness)285         public Builder setBrightness(float brightness) {
286             mBrightness = brightness;
287             return this;
288         }
289 
290         /** {@see BrightnessChangeEvent#timeStamp} */
setTimeStamp(long timeStamp)291         public Builder setTimeStamp(long timeStamp) {
292             mTimeStamp = timeStamp;
293             return this;
294         }
295 
296         /** {@see BrightnessChangeEvent#packageName} */
setPackageName(String packageName)297         public Builder setPackageName(String packageName) {
298             mPackageName = packageName;
299             return this;
300         }
301 
302         /** {@see BrightnessChangeEvent#userId} */
setUserId(int userId)303         public Builder setUserId(int userId) {
304             mUserId = userId;
305             return this;
306         }
307 
308         /** {@see BrightnessChangeEvent#uniqueScreenId} */
setUniqueDisplayId(String uniqueId)309         public Builder setUniqueDisplayId(String uniqueId) {
310             mUniqueDisplayId = uniqueId;
311             return this;
312         }
313 
314         /** {@see BrightnessChangeEvent#luxValues} */
setLuxValues(float[] luxValues)315         public Builder setLuxValues(float[] luxValues) {
316             mLuxValues = luxValues;
317             return this;
318         }
319 
320         /** {@see BrightnessChangeEvent#luxTimestamps} */
setLuxTimestamps(long[] luxTimestamps)321         public Builder setLuxTimestamps(long[] luxTimestamps) {
322             mLuxTimestamps = luxTimestamps;
323             return this;
324         }
325 
326         /** {@see BrightnessChangeEvent#batteryLevel} */
setBatteryLevel(float batteryLevel)327         public Builder setBatteryLevel(float batteryLevel) {
328             mBatteryLevel = batteryLevel;
329             return this;
330         }
331 
332         /** {@see BrightnessChangeEvent#powerSaveBrightness} */
setPowerBrightnessFactor(float powerBrightnessFactor)333         public Builder setPowerBrightnessFactor(float powerBrightnessFactor) {
334             mPowerBrightnessFactor = powerBrightnessFactor;
335             return this;
336         }
337 
338         /** {@see BrightnessChangeEvent#nightMode} */
setNightMode(boolean nightMode)339         public Builder setNightMode(boolean nightMode) {
340             mNightMode = nightMode;
341             return this;
342         }
343 
344         /** {@see BrightnessChangeEvent#colorTemperature} */
setColorTemperature(int colorTemperature)345         public Builder setColorTemperature(int colorTemperature) {
346             mColorTemperature = colorTemperature;
347             return this;
348         }
349 
350         /** {@see BrightnessChangeEvent#reduceBrightColors} */
setReduceBrightColors(boolean reduceBrightColors)351         public Builder setReduceBrightColors(boolean reduceBrightColors) {
352             mReduceBrightColors = reduceBrightColors;
353             return this;
354         }
355 
356         /** {@see BrightnessChangeEvent#reduceBrightColorsStrength} */
setReduceBrightColorsStrength(int strength)357         public Builder setReduceBrightColorsStrength(int strength) {
358             mReduceBrightColorsStrength = strength;
359             return this;
360         }
361 
362         /** {@see BrightnessChangeEvent#reduceBrightColorsOffset} */
setReduceBrightColorsOffset(float offset)363         public Builder setReduceBrightColorsOffset(float offset) {
364             mReduceBrightColorsOffset = offset;
365             return this;
366         }
367 
368         /** {@see BrightnessChangeEvent#lastBrightness} */
setLastBrightness(float lastBrightness)369         public Builder setLastBrightness(float lastBrightness) {
370             mLastBrightness = lastBrightness;
371             return this;
372         }
373 
374         /** {@see BrightnessChangeEvent#isDefaultBrightnessConfig} */
setIsDefaultBrightnessConfig(boolean isDefaultBrightnessConfig)375         public Builder setIsDefaultBrightnessConfig(boolean isDefaultBrightnessConfig) {
376             mIsDefaultBrightnessConfig = isDefaultBrightnessConfig;
377             return this;
378         }
379 
380         /** {@see BrightnessChangeEvent#userBrightnessPoint} */
setUserBrightnessPoint(boolean isUserSetBrightness)381         public Builder setUserBrightnessPoint(boolean isUserSetBrightness) {
382             mIsUserSetBrightness = isUserSetBrightness;
383             return this;
384         }
385 
386         /** {@see BrightnessChangeEvent#colorValueBuckets}
387          *  {@see BrightnessChangeEvent#colorSampleDuration} */
setColorValues(@onNull long[] colorValueBuckets, long colorSampleDuration)388         public Builder setColorValues(@NonNull long[] colorValueBuckets, long colorSampleDuration) {
389             Objects.requireNonNull(colorValueBuckets);
390             mColorValueBuckets = colorValueBuckets;
391             mColorSampleDuration = colorSampleDuration;
392             return this;
393         }
394 
395         /** Builds a BrightnessChangeEvent */
build()396         public BrightnessChangeEvent build() {
397             return new BrightnessChangeEvent(mBrightness, mTimeStamp,
398                     mPackageName, mUserId, mUniqueDisplayId, mLuxValues, mLuxTimestamps,
399                     mBatteryLevel, mPowerBrightnessFactor, mNightMode, mColorTemperature,
400                     mReduceBrightColors, mReduceBrightColorsStrength, mReduceBrightColorsOffset,
401                     mLastBrightness, mIsDefaultBrightnessConfig, mIsUserSetBrightness,
402                     mColorValueBuckets, mColorSampleDuration);
403         }
404     }
405 }
406