Merge "Track brightness changes in nits rather than backlight values."

This commit is contained in:
TreeHugger Robot
2018-01-04 17:51:29 +00:00
committed by Android (Google) Code Review
14 changed files with 496 additions and 440 deletions

View File

@@ -28,7 +28,7 @@ import android.os.Parcelable;
*/
public final class BrightnessChangeEvent implements Parcelable {
/** Brightness in nits */
public int brightness;
public float brightness;
/** Timestamp of the change {@see System.currentTimeMillis()} */
public long timeStamp;
@@ -58,7 +58,7 @@ public final class BrightnessChangeEvent implements Parcelable {
public int colorTemperature;
/** Brightness level before slider adjustment */
public int lastBrightness;
public float lastBrightness;
public BrightnessChangeEvent() {
}
@@ -78,7 +78,7 @@ public final class BrightnessChangeEvent implements Parcelable {
}
private BrightnessChangeEvent(Parcel source) {
brightness = source.readInt();
brightness = source.readFloat();
timeStamp = source.readLong();
packageName = source.readString();
userId = source.readInt();
@@ -87,7 +87,7 @@ public final class BrightnessChangeEvent implements Parcelable {
batteryLevel = source.readFloat();
nightMode = source.readBoolean();
colorTemperature = source.readInt();
lastBrightness = source.readInt();
lastBrightness = source.readFloat();
}
public static final Creator<BrightnessChangeEvent> CREATOR =
@@ -107,7 +107,7 @@ public final class BrightnessChangeEvent implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(brightness);
dest.writeFloat(brightness);
dest.writeLong(timeStamp);
dest.writeString(packageName);
dest.writeInt(userId);
@@ -116,6 +116,6 @@ public final class BrightnessChangeEvent implements Parcelable {
dest.writeFloat(batteryLevel);
dest.writeBoolean(nightMode);
dest.writeInt(colorTemperature);
dest.writeInt(lastBrightness);
dest.writeFloat(lastBrightness);
}
}

View File

@@ -627,13 +627,6 @@ public final class DisplayManager {
return mGlobal.getBrightnessEvents(mContext.getOpPackageName());
}
/**
* @hide STOPSHIP - remove when adaptive brightness accepts curves.
*/
public void setBrightness(int brightness) {
mGlobal.setBrightness(brightness);
}
/**
* Sets the global display brightness configuration.
*

View File

@@ -475,18 +475,6 @@ public final class DisplayManagerGlobal {
}
}
/**
* Set brightness but don't add a BrightnessChangeEvent
* STOPSHIP remove when adaptive brightness accepts curves.
*/
public void setBrightness(int brightness) {
try {
mDm.setBrightness(brightness);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
/**
* Sets the global brightness configuration for a given user.
*

View File

@@ -222,6 +222,11 @@ public abstract class DisplayManagerInternal {
// set by the user as opposed to being programmatically controlled by apps.
public boolean brightnessSetByUser;
// Set to true if screenBrightness or screenAutoBrightnessAdjustment are being set
// temporarily. This is typically set while the user has their finger on the brightness
// control, before they've selected the final brightness value.
public boolean brightnessIsTemporary;
// If true, enables automatic brightness control.
public boolean useAutoBrightness;
@@ -280,6 +285,7 @@ public abstract class DisplayManagerInternal {
screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
screenLowPowerBrightnessFactor = other.screenLowPowerBrightnessFactor;
brightnessSetByUser = other.brightnessSetByUser;
brightnessIsTemporary = other.brightnessIsTemporary;
useAutoBrightness = other.useAutoBrightness;
blockScreenOn = other.blockScreenOn;
lowPowerMode = other.lowPowerMode;
@@ -303,6 +309,7 @@ public abstract class DisplayManagerInternal {
&& screenLowPowerBrightnessFactor
== other.screenLowPowerBrightnessFactor
&& brightnessSetByUser == other.brightnessSetByUser
&& brightnessIsTemporary == other.brightnessIsTemporary
&& useAutoBrightness == other.useAutoBrightness
&& blockScreenOn == other.blockScreenOn
&& lowPowerMode == other.lowPowerMode
@@ -324,6 +331,7 @@ public abstract class DisplayManagerInternal {
+ ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
+ ", screenLowPowerBrightnessFactor=" + screenLowPowerBrightnessFactor
+ ", brightnessSetByUser=" + brightnessSetByUser
+ ", brightnessIsTemporary=" + brightnessIsTemporary
+ ", useAutoBrightness=" + useAutoBrightness
+ ", blockScreenOn=" + blockScreenOn
+ ", lowPowerMode=" + lowPowerMode

View File

@@ -87,10 +87,6 @@ interface IDisplayManager {
// Requires BRIGHTNESS_SLIDER_USAGE permission.
ParceledListSlice getBrightnessEvents(String callingPackage);
// STOPSHIP remove when adaptive brightness code is updated to accept curves.
// Requires BRIGHTNESS_SLIDER_USAGE permission.
void setBrightness(int brightness);
// Sets the global brightness configuration for a given user. Requires
// CONFIGURE_DISPLAY_BRIGHTNESS, and INTERACT_ACROSS_USER if the user being configured is not
// the same as the calling user.

View File

@@ -1302,8 +1302,8 @@
If this is defined then:
- config_autoBrightnessLcdBacklightValues should not be defined
- config_screenBrightnessMinimumNits must be defined
- config_screenBrightnessMaximumNits must be defined
- config_screenBrightnessNits must be defined
- config_screenBrightnessBacklight must be defined
This array should have size one greater than the size of the config_autoBrightnessLevels
array. The brightness values must be non-negative and non-decreasing. This must be
@@ -1347,28 +1347,23 @@
<item>200</item>
</integer-array>
<!-- The minimum brightness of the display in nits. On OLED displays this should be measured
with an all white image while the display is fully on and the backlight is set to
config_screenBrightnessSettingMinimum or config_screenBrightnessSettingDark, whichever
is darker.
<!-- An array describing the screen's backlight values corresponding to the brightness
values in the config_screenBrightnessNits array.
If this and config_screenBrightnessMinimumNits are set, then the display's brightness
range is assumed to be linear between
(config_screenBrightnessSettingMinimum, config_screenBrightnessMinimumNits) and
(config_screenBrightnessSettingMaximum, config_screenBrightnessMaximumNits). -->
<item name="config_screenBrightnessMinimumNits" format="float" type="dimen">-1.0</item>
This array should be equal in size to config_screenBrightnessBacklight. -->
<integer-array name="config_screenBrightnessBacklight">
</integer-array>
<!-- The maximum brightness of the display in nits. On OLED displays this should be measured
with an all white image while the display is fully on and the "backlight" is set to
config_screenBrightnessSettingMaximum. Note that this value should *not* reflect the
maximum brightness value for any high brightness modes but only the maximum brightness
value obtainable in a sustainable manner.
<!-- An array of floats describing the screen brightness in nits corresponding to the backlight
values in the config_screenBrightnessBacklight array. On OLED displays these values
should be measured with an all white image while the display is in the fully on state.
Note that this value should *not* reflect the maximum brightness value for any high
brightness modes but only the maximum brightness value obtainable in a sustainable manner.
This array should be equal in size to config_screenBrightnessBacklight -->
<array name="config_screenBrightnessNits">
</array>
If this and config_screenBrightnessMinimumNits are set to something non-negative, then the
display's brightness range is assumed to be linear between
(config_screenBrightnessSettingMinimum, config_screenBrightnessMaximumNits) and
(config_screenBrightnessSettingMaximum, config_screenBrightnessMaximumNits). -->
<item name="config_screenBrightnessMaximumNits" format="float" type="dimen">-1.0</item>
<!-- Array of ambient lux threshold values. This is used for determining hysteresis constraint
values by calculating the index to use for lookup and then setting the constraint value

View File

@@ -3197,7 +3197,7 @@
<java-symbol type="string" name="global_action_logout" />
<java-symbol type="drawable" name="ic_logout" />
<java-symbol type="dimen" name="config_screenBrightnessMinimumNits" />
<java-symbol type="dimen" name="config_screenBrightnessMaximumNits" />
<java-symbol type="array" name="config_autoBrightnessDisplayValuesNits" />
<java-symbol type="array" name="config_screenBrightnessBacklight" />
<java-symbol type="array" name="config_screenBrightnessNits" />
</resources>

View File

@@ -17,6 +17,8 @@
package com.android.server.display;
import android.annotation.Nullable;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.hardware.display.BrightnessConfiguration;
import android.os.PowerManager;
import android.util.MathUtils;
@@ -41,11 +43,30 @@ public abstract class BrightnessMappingStrategy {
private static final boolean DEBUG = false;
@Nullable
public static BrightnessMappingStrategy create(
float[] luxLevels, int[] brightnessLevelsBacklight, float[] brightnessLevelsNits,
float[] nitsRange, int[] backlightRange) {
public static BrightnessMappingStrategy create(Resources resources) {
float[] luxLevels = getLuxLevels(resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels));
int[] brightnessLevelsBacklight = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
float[] brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
float[] nitsRange = getFloatArray(resources.obtainTypedArray(
com.android.internal.R.array.config_screenBrightnessNits));
int[] backlightRange = resources.getIntArray(
com.android.internal.R.array.config_screenBrightnessBacklight);
if (isValidMapping(nitsRange, backlightRange)
&& isValidMapping(luxLevels, brightnessLevelsNits)) {
int minimumBacklight = resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessSettingMinimum);
int maximumBacklight = resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessSettingMaximum);
if (backlightRange[0] > minimumBacklight
|| backlightRange[backlightRange.length - 1] < maximumBacklight) {
Slog.w(TAG, "Screen brightness mapping does not cover whole range of available"
+ " backlight values, autobrightness functionality may be impaired.");
}
BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
builder.setCurve(luxLevels, brightnessLevelsNits);
return new PhysicalMappingStrategy(builder.build(), nitsRange, backlightRange);
@@ -56,6 +77,25 @@ public abstract class BrightnessMappingStrategy {
}
}
private static float[] getLuxLevels(int[] lux) {
// The first control point is implicit and always at 0 lux.
float[] levels = new float[lux.length + 1];
for (int i = 0; i < lux.length; i++) {
levels[i + 1] = (float) lux[i];
}
return levels;
}
private static float[] getFloatArray(TypedArray array) {
final int N = array.length();
float[] vals = new float[N];
for (int i = 0; i < N; i++) {
vals[i] = array.getFloat(i, -1.0f);
}
array.recycle();
return vals;
}
private static boolean isValidMapping(float[] x, float[] y) {
if (x == null || y == null || x.length == 0 || y.length == 0) {
return false;
@@ -124,10 +164,17 @@ public abstract class BrightnessMappingStrategy {
* brightness and 0 is the display at minimum brightness.
*
* @param lux The current ambient brightness in lux.
* @return The desired brightness of the display compressed to the range [0, 1.0].
* @return The desired brightness of the display normalized to the range [0, 1.0].
*/
public abstract float getBrightness(float lux);
/**
* Gets the display's brightness in nits for the given backlight value.
*
* Returns -1.0f if there's no available mapping for the backlight to nits.
*/
public abstract float getNits(int backlight);
public abstract void dump(PrintWriter pw);
private static float normalizeAbsoluteBrightness(int brightness) {
@@ -185,6 +232,11 @@ public abstract class BrightnessMappingStrategy {
return mSpline.interpolate(lux);
}
@Override
public float getNits(int backlight) {
return -1.0f;
}
@Override
public void dump(PrintWriter pw) {
pw.println("SimpleMappingStrategy");
@@ -209,7 +261,11 @@ public abstract class BrightnessMappingStrategy {
// A spline mapping from nits to the corresponding backlight value, normalized to the range
// [0, 1.0].
private final Spline mBacklightSpline;
private final Spline mNitsToBacklightSpline;
// A spline mapping from the device's backlight value, normalized to the range [0, 1.0], to
// a brightness in nits.
private final Spline mBacklightToNitsSpline;
// The default brightness configuration.
private final BrightnessConfiguration mDefaultConfig;
@@ -227,19 +283,18 @@ public abstract class BrightnessMappingStrategy {
// Setup the backlight spline
final int N = nits.length;
float[] x = new float[N];
float[] y = new float[N];
float[] normalizedBacklight = new float[N];
for (int i = 0; i < N; i++) {
x[i] = nits[i];
y[i] = normalizeAbsoluteBrightness(backlight[i]);
normalizedBacklight[i] = normalizeAbsoluteBrightness(backlight[i]);
}
mBacklightSpline = Spline.createSpline(x, y);
mNitsToBacklightSpline = Spline.createSpline(nits, normalizedBacklight);
mBacklightToNitsSpline = Spline.createSpline(normalizedBacklight, nits);
if (DEBUG) {
Slog.d(TAG, "Backlight spline: " + mBacklightSpline);
Slog.d(TAG, "Backlight spline: " + mNitsToBacklightSpline);
for (float v = 1f; v < nits[nits.length - 1] * 1.25f; v *= 1.25f) {
Slog.d(TAG, String.format(
" %7.1f: %7.1f", v, mBacklightSpline.interpolate(v)));
" %7.1f: %7.1f", v, mNitsToBacklightSpline.interpolate(v)));
}
}
@@ -275,7 +330,12 @@ public abstract class BrightnessMappingStrategy {
@Override
public float getBrightness(float lux) {
return mBacklightSpline.interpolate(mBrightnessSpline.interpolate(lux));
return mNitsToBacklightSpline.interpolate(mBrightnessSpline.interpolate(lux));
}
@Override
public float getNits(int backlight) {
return mBacklightToNitsSpline.interpolate(normalizeAbsoluteBrightness(backlight));
}
@Override
@@ -283,7 +343,7 @@ public abstract class BrightnessMappingStrategy {
pw.println("PhysicalMappingStrategy");
pw.println(" mConfig=" + mConfig);
pw.println(" mBrightnessSpline=" + mBrightnessSpline);
pw.println(" mBacklightSpline=" + mBacklightSpline);
pw.println(" mNitsToBacklightSpline=" + mNitsToBacklightSpline);
}
}
}

View File

@@ -24,7 +24,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ParceledListSlice;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -34,6 +33,8 @@ import android.net.Uri;
import android.os.BatteryManager;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -88,7 +89,7 @@ public class BrightnessTracker {
private static final String TAG_EVENTS = "events";
private static final String TAG_EVENT = "event";
private static final String ATTR_BRIGHTNESS = "brightness";
private static final String ATTR_NITS = "nits";
private static final String ATTR_TIMESTAMP = "timestamp";
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_USER = "user";
@@ -97,7 +98,10 @@ public class BrightnessTracker {
private static final String ATTR_BATTERY_LEVEL = "batteryLevel";
private static final String ATTR_NIGHT_MODE = "nightMode";
private static final String ATTR_COLOR_TEMPERATURE = "colorTemperature";
private static final String ATTR_LAST_BRIGHTNESS = "lastBrightness";
private static final String ATTR_LAST_NITS = "lastNits";
private static final int MSG_BACKGROUND_START = 0;
private static final int MSG_BRIGHTNESS_CHANGED = 1;
// Lock held while accessing mEvents, is held while writing events to flash.
private final Object mEventsLock = new Object();
@@ -113,9 +117,7 @@ public class BrightnessTracker {
private final Context mContext;
private final ContentResolver mContentResolver;
private Handler mBgHandler;
// mSettingsObserver, mBroadcastReceiver and mSensorListener should only be used on
// the mBgHandler thread.
private SettingsObserver mSettingsObserver;
// mBroadcastReceiver and mSensorListener should only be used on the mBgHandler thread.
private BroadcastReceiver mBroadcastReceiver;
private SensorListener mSensorListener;
@@ -126,9 +128,9 @@ public class BrightnessTracker {
@GuardedBy("mDataCollectionLock")
private float mLastBatteryLevel = Float.NaN;
@GuardedBy("mDataCollectionLock")
private int mIgnoreBrightness = -1;
private float mLastBrightness = -1;
@GuardedBy("mDataCollectionLock")
private int mLastBrightness = -1;
private boolean mStarted;
private final Injector mInjector;
@@ -144,33 +146,31 @@ public class BrightnessTracker {
}
}
/** Start listening for brightness slider events */
public void start() {
/**
* Start listening for brightness slider events
*
* @param brightness the initial screen brightness
*/
public void start(float initialBrightness) {
if (DEBUG) {
Slog.d(TAG, "Start");
}
mBgHandler = mInjector.getBackgroundHandler();
mBgHandler = new TrackerHandler(mInjector.getBackgroundHandler().getLooper());
mUserManager = mContext.getSystemService(UserManager.class);
mBgHandler.post(() -> backgroundStart());
mBgHandler.obtainMessage(MSG_BACKGROUND_START, (Float) initialBrightness).sendToTarget();
}
private void backgroundStart() {
private void backgroundStart(float initialBrightness) {
readEvents();
mLastBrightness = mInjector.getSystemIntForUser(mContentResolver,
Settings.System.SCREEN_BRIGHTNESS, -1,
UserHandle.USER_CURRENT);
mSensorListener = new SensorListener();
if (mInjector.isInteractive(mContext)) {
mInjector.registerSensorListener(mContext, mSensorListener, mBgHandler);
}
mSettingsObserver = new SettingsObserver(mBgHandler);
mInjector.registerBrightnessObserver(mContentResolver, mSettingsObserver);
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SHUTDOWN);
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
@@ -180,6 +180,10 @@ public class BrightnessTracker {
mInjector.registerReceiver(mContext, mBroadcastReceiver, intentFilter);
mInjector.scheduleIdleJob(mContext);
synchronized (mDataCollectionLock) {
mLastBrightness = initialBrightness;
mStarted = true;
}
}
/** Stop listening for events */
@@ -188,10 +192,14 @@ public class BrightnessTracker {
if (DEBUG) {
Slog.d(TAG, "Stop");
}
mBgHandler.removeMessages(MSG_BACKGROUND_START);
mInjector.unregisterSensorListener(mContext, mSensorListener);
mInjector.unregisterReceiver(mContext, mBroadcastReceiver);
mInjector.unregisterBrightnessObserver(mContext, mSettingsObserver);
mInjector.cancelIdleJob(mContext);
synchronized (mDataCollectionLock) {
mStarted = false;
}
}
/**
@@ -220,40 +228,45 @@ public class BrightnessTracker {
return new ParceledListSlice<>(out);
}
/** Sets brightness without logging the brightness change event */
public void setBrightness(int brightness, int userId) {
synchronized (mDataCollectionLock) {
mIgnoreBrightness = brightness;
}
mInjector.putSystemIntForUser(mContentResolver, Settings.System.SCREEN_BRIGHTNESS,
brightness, userId);
}
public void persistEvents() {
scheduleWriteEvents();
}
private void handleBrightnessChanged() {
/**
* Notify the BrightnessTracker that the user has changed the brightness of the display.
*/
public void notifyBrightnessChanged(float brightness, boolean userInitiated) {
if (DEBUG) {
Slog.d(TAG, "Brightness change");
Slog.d(TAG, String.format("notifyBrightnessChanged(brightness=%f, userInitiated=%b)",
brightness, userInitiated));
}
final BrightnessChangeEvent event = new BrightnessChangeEvent();
event.timeStamp = mInjector.currentTimeMillis();
int brightness = mInjector.getSystemIntForUser(mContentResolver,
Settings.System.SCREEN_BRIGHTNESS, -1,
UserHandle.USER_CURRENT);
Message m = mBgHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED,
userInitiated ? 1 : 0, 0 /*unused*/, (Float) brightness);
m.sendToTarget();
}
private void handleBrightnessChanged(float brightness, boolean userInitiated) {
final BrightnessChangeEvent event;
synchronized (mDataCollectionLock) {
int previousBrightness = mLastBrightness;
mLastBrightness = brightness;
if (brightness == -1 || brightness == mIgnoreBrightness) {
// Notified of brightness change but no setting or self change so ignore.
mIgnoreBrightness = -1;
if (!mStarted) {
// Not currently gathering brightness change information
return;
}
float previousBrightness = mLastBrightness;
mLastBrightness = brightness;
if (!userInitiated) {
// We want to record what current brightness is so that we know what the user
// changed it from, but if it wasn't user initiated then we don't want to record it
// as a BrightnessChangeEvent.
return;
}
event = new BrightnessChangeEvent();
event.timeStamp = mInjector.currentTimeMillis();
final int readingCount = mLastSensorReadings.size();
if (readingCount == 0) {
// No sensor data so ignore this.
@@ -386,7 +399,7 @@ public class BrightnessTracker {
if (userSerialNo != -1 && toWrite[i].timeStamp > timeCutOff) {
mEvents.append(toWrite[i]);
out.startTag(null, TAG_EVENT);
out.attribute(null, ATTR_BRIGHTNESS, Integer.toString(toWrite[i].brightness));
out.attribute(null, ATTR_NITS, Float.toString(toWrite[i].brightness));
out.attribute(null, ATTR_TIMESTAMP, Long.toString(toWrite[i].timeStamp));
out.attribute(null, ATTR_PACKAGE_NAME, toWrite[i].packageName);
out.attribute(null, ATTR_USER, Integer.toString(userSerialNo));
@@ -394,8 +407,8 @@ public class BrightnessTracker {
out.attribute(null, ATTR_NIGHT_MODE, Boolean.toString(toWrite[i].nightMode));
out.attribute(null, ATTR_COLOR_TEMPERATURE, Integer.toString(
toWrite[i].colorTemperature));
out.attribute(null, ATTR_LAST_BRIGHTNESS,
Integer.toString(toWrite[i].lastBrightness));
out.attribute(null, ATTR_LAST_NITS,
Float.toString(toWrite[i].lastBrightness));
StringBuilder luxValues = new StringBuilder();
StringBuilder luxTimestamps = new StringBuilder();
for (int j = 0; j < toWrite[i].luxValues.length; ++j) {
@@ -446,8 +459,8 @@ public class BrightnessTracker {
if (TAG_EVENT.equals(tag)) {
BrightnessChangeEvent event = new BrightnessChangeEvent();
String brightness = parser.getAttributeValue(null, ATTR_BRIGHTNESS);
event.brightness = Integer.parseInt(brightness);
String brightness = parser.getAttributeValue(null, ATTR_NITS);
event.brightness = Float.parseFloat(brightness);
String timestamp = parser.getAttributeValue(null, ATTR_TIMESTAMP);
event.timeStamp = Long.parseLong(timestamp);
event.packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
@@ -460,8 +473,8 @@ public class BrightnessTracker {
String colorTemperature =
parser.getAttributeValue(null, ATTR_COLOR_TEMPERATURE);
event.colorTemperature = Integer.parseInt(colorTemperature);
String lastBrightness = parser.getAttributeValue(null, ATTR_LAST_BRIGHTNESS);
event.lastBrightness = Integer.parseInt(lastBrightness);
String lastBrightness = parser.getAttributeValue(null, ATTR_LAST_NITS);
event.lastBrightness = Float.parseFloat(lastBrightness);
String luxValue = parser.getAttributeValue(null, ATTR_LUX);
String luxTimestamp = parser.getAttributeValue(null, ATTR_LUX_TIMESTAMPS);
@@ -582,22 +595,6 @@ public class BrightnessTracker {
}
}
private final class SettingsObserver extends ContentObserver {
public SettingsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
if (DEBUG) {
Slog.v(TAG, "settings change " + uri);
}
// Self change is based on observer passed to notifyObserver, SettingsProvider
// passes null so no changes are self changes.
handleBrightnessChanged();
}
}
private final class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@@ -623,6 +620,24 @@ public class BrightnessTracker {
}
}
private final class TrackerHandler extends Handler {
public TrackerHandler(Looper looper) {
super(looper, null, true /*async*/);
}
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_BACKGROUND_START:
backgroundStart((float)msg.obj /*initial brightness*/);
break;
case MSG_BRIGHTNESS_CHANGED:
float newBrightness = (float) msg.obj;
boolean userInitiatedChange = (msg.arg1 == 1);
handleBrightnessChanged(newBrightness, userInitiatedChange);
break;
}
}
}
@VisibleForTesting
static class Injector {
public void registerSensorListener(Context context,
@@ -638,18 +653,6 @@ public class BrightnessTracker {
sensorManager.unregisterListener(sensorListener);
}
public void registerBrightnessObserver(ContentResolver resolver,
ContentObserver settingsObserver) {
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS),
false, settingsObserver, UserHandle.USER_ALL);
}
public void unregisterBrightnessObserver(Context context,
ContentObserver settingsObserver) {
context.getContentResolver().unregisterContentObserver(settingsObserver);
}
public void registerReceiver(Context context,
BroadcastReceiver receiver, IntentFilter filter) {
context.registerReceiver(receiver, filter);
@@ -664,16 +667,6 @@ public class BrightnessTracker {
return BackgroundThread.getHandler();
}
public int getSystemIntForUser(ContentResolver resolver, String setting, int defaultValue,
int userId) {
return Settings.System.getIntForUser(resolver, setting, defaultValue, userId);
}
public void putSystemIntForUser(ContentResolver resolver, String setting, int value,
int userId) {
Settings.System.putIntForUser(resolver, setting, value, userId);
}
public int getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue,
int userId) {
return Settings.Secure.getIntForUser(resolver, setting, defaultValue, userId);

View File

@@ -270,8 +270,6 @@ public final class DisplayManagerService extends SystemService {
private final Injector mInjector;
private final BrightnessTracker mBrightnessTracker;
public DisplayManagerService(Context context) {
this(context, new Injector());
}
@@ -290,7 +288,6 @@ public final class DisplayManagerService extends SystemService {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
mBrightnessTracker = new BrightnessTracker(context, null);
mCurrentUserId = UserHandle.USER_SYSTEM;
}
@@ -1339,9 +1336,6 @@ public final class DisplayManagerService extends SystemService {
pw.println();
mPersistentDataStore.dump(pw);
pw.println();
mBrightnessTracker.dump(pw);
}
}
@@ -1418,10 +1412,6 @@ public final class DisplayManagerService extends SystemService {
break;
}
case MSG_REGISTER_BRIGHTNESS_TRACKER:
mBrightnessTracker.start();
break;
case MSG_LOAD_BRIGHTNESS_CONFIGURATION:
loadBrightnessConfiguration();
break;
@@ -1833,22 +1823,9 @@ public final class DisplayManagerService extends SystemService {
final int userId = UserHandle.getUserId(callingUid);
final long token = Binder.clearCallingIdentity();
try {
return mBrightnessTracker.getEvents(userId, hasUsageStats);
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override // Binder call
public void setBrightness(int brightness) {
// STOPSHIP - remove when adaptive brightness controller accepts curves.
mContext.enforceCallingOrSelfPermission(
Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
"Permission to set brightness.");
int userId = UserHandle.getUserId(Binder.getCallingUid());
final long token = Binder.clearCallingIdentity();
try {
mBrightnessTracker.setBrightness(brightness, userId);
synchronized (mSyncRoot) {
return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats);
}
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -2028,7 +2005,9 @@ public final class DisplayManagerService extends SystemService {
@Override
public void persistBrightnessSliderEvents() {
mBrightnessTracker.persistEvents();
synchronized (mSyncRoot) {
mDisplayPowerController.persistBrightnessSliderEvents();
}
}
}
}

View File

@@ -24,13 +24,16 @@ import com.android.server.policy.WindowManagerPolicy;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.display.BrightnessChangeEvent;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
@@ -96,7 +99,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
private static final int MSG_USER_SWITCH = 6;
private static final int PROXIMITY_UNKNOWN = -1;
private static final int PROXIMITY_NEGATIVE = 0;
@@ -151,9 +153,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// The dim screen brightness.
private final int mScreenBrightnessDimConfig;
// The minimum screen brightness to use in a very dark room.
private final int mScreenBrightnessDarkConfig;
// The minimum allowed brightness.
private final int mScreenBrightnessRangeMinimum;
@@ -261,6 +260,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private long mScreenOnBlockStartRealTime;
private long mScreenOffBlockStartRealTime;
// The last brightness that was set by the user and not temporary. Set to -1 when a brightness
// has yet to be recorded.
private int mLastBrightness;
// The last auto brightness adjustment that was set by the user and not temporary. Set to
// Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
private float mLastAutoBrightnessAdjustment;
// Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
private int mReportedScreenStateToPolicy;
@@ -289,6 +295,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// The controller for the automatic brightness level.
private AutomaticBrightnessController mAutomaticBrightnessController;
// The mapper between ambient lux, display backlight values, and display brightness.
@Nullable
private BrightnessMappingStrategy mBrightnessMapper;
// The default brightness configuration. Used for whenever we don't have a valid brightness
// configuration set. This is typically seen with users that don't have a brightness
// configuration that's different from the default.
@@ -302,6 +312,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private ObjectAnimator mColorFadeOffAnimator;
private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
// Tracker for brightness changes
private final BrightnessTracker mBrightnessTracker;
/**
* Creates the display power controller.
*/
@@ -309,6 +322,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker) {
mHandler = new DisplayControllerHandler(handler.getLooper());
mBrightnessTracker = new BrightnessTracker(context, null);
mCallbacks = callbacks;
mBatteryStats = BatteryStatsService.getService();
@@ -327,23 +341,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDim));
mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDark));
if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
Slog.w(TAG, "Expected config_screenBrightnessDark ("
+ mScreenBrightnessDarkConfig + ") to be less than or equal to "
+ "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
}
if (mScreenBrightnessDarkConfig > screenBrightnessSettingMinimum) {
Slog.w(TAG, "Expected config_screenBrightnessDark ("
+ mScreenBrightnessDarkConfig + ") to be less than or equal to "
+ "config_screenBrightnessSettingMinimum ("
+ screenBrightnessSettingMinimum + ").");
}
int screenBrightnessRangeMinimum = Math.min(Math.min(
screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),
mScreenBrightnessDarkConfig);
mScreenBrightnessRangeMinimum =
Math.min(screenBrightnessSettingMinimum, mScreenBrightnessDimConfig);
mScreenBrightnessRangeMaximum = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessSettingMaximum));
@@ -362,18 +361,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
if (mUseSoftwareAutoBrightnessConfig) {
float[] luxLevels = getLuxLevels(resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels));
int[] backlightValues = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
float[] brightnessValuesNits = getFloatArray(resources.obtainTypedArray(
com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
final float screenMinimumNits = resources.getFloat(
com.android.internal.R.dimen.config_screenBrightnessMinimumNits);
final float screenMaximumNits = resources.getFloat(
com.android.internal.R.dimen.config_screenBrightnessMaximumNits);
final float dozeScaleFactor = resources.getFraction(
com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
1, 1);
@@ -413,31 +400,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
+ "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
}
if (backlightValues != null && backlightValues.length > 0) {
final int bottom = backlightValues[0];
if (mScreenBrightnessDarkConfig > bottom) {
Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig
+ ") should be less than or equal to the first value of "
+ "config_autoBrightnessLcdBacklightValues ("
+ bottom + ").");
}
if (bottom < screenBrightnessRangeMinimum) {
screenBrightnessRangeMinimum = bottom;
}
}
float[] nitsRange = { screenMinimumNits, screenMaximumNits };
int[] backlightRange = { screenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum };
BrightnessMappingStrategy mapper = BrightnessMappingStrategy.create(
luxLevels, backlightValues, brightnessValuesNits,
nitsRange, backlightRange);
if (mapper != null) {
mBrightnessMapper = BrightnessMappingStrategy.create(resources);
if (mBrightnessMapper != null) {
mAutomaticBrightnessController = new AutomaticBrightnessController(this,
handler.getLooper(), sensorManager, mapper, lightSensorWarmUpTimeConfig,
screenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum,
dozeScaleFactor, lightSensorRate, initialLightSensorRate,
brighteningLightDebounce, darkeningLightDebounce,
handler.getLooper(), sensorManager, mBrightnessMapper,
lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,
mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
autoBrightnessAdjustmentMaxGamma, dynamicHysteresis);
} else {
@@ -445,9 +414,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic();
mColorFadeFadesConfig = resources.getBoolean(
com.android.internal.R.bool.config_animateScreenLights);
@@ -466,25 +432,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
}
private static float[] getLuxLevels(int[] lux) {
// The first control point is implicit and always at 0 lux.
float[] levels = new float[lux.length + 1];
for (int i = 0; i < lux.length; i++) {
levels[i + 1] = (float) lux[i];
}
return levels;
}
private static float[] getFloatArray(TypedArray array) {
final int N = array.length();
float[] vals = new float[N];
for (int i = 0; i < N; i++) {
vals[i] = array.getFloat(i, -1.0f);
}
array.recycle();
return vals;
mLastBrightness = -1;
mLastAutoBrightnessAdjustment = Float.NaN;
}
/**
@@ -494,6 +443,23 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return mProximitySensor != null;
}
/**
* Get the {@link BrightnessChangeEvent}s for the specified user.
* @param userId userId to fetch data for
* @param includePackage if false will null out the package name in events
*/
public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(
@UserIdInt int userId, boolean includePackage) {
return mBrightnessTracker.getEvents(userId, includePackage);
}
/**
* Persist the brightness slider events to disk.
*/
public void persistBrightnessSliderEvents() {
mBrightnessTracker.persistEvents();
}
/**
* Requests a new power state.
* The controller makes a copy of the provided object and then
@@ -588,6 +554,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
} catch (RemoteException ex) {
// same process
}
// Initialize all of the brightness tracking state
final float brightness = getNits(mPowerState.getScreenBrightness());
if (brightness >= 0.0f) {
mBrightnessTracker.start(brightness);
}
}
private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
@@ -722,16 +694,32 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
brightness = PowerManager.BRIGHTNESS_OFF;
}
// Configure auto-brightness.
boolean autoBrightnessEnabled = false;
if (mAutomaticBrightnessController != null) {
final boolean autoBrightnessEnabledInDoze =
mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
autoBrightnessEnabled = mPowerRequest.useAutoBrightness
final boolean autoBrightnessEnabledInDoze =
mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
&& brightness < 0;
final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
&& mPowerRequest.brightnessSetByUser;
&& brightness < 0
&& mAutomaticBrightnessController != null;
final boolean brightnessAdjustmentChanged =
!Float.isNaN(mLastAutoBrightnessAdjustment)
&& mPowerRequest.screenAutoBrightnessAdjustment != mLastAutoBrightnessAdjustment;
final boolean brightnessChanged = mLastBrightness >= 0
&& mPowerRequest.screenBrightness != mLastBrightness;
// Update the last set brightness values.
final boolean userInitiatedChange;
if (mPowerRequest.brightnessSetByUser && !mPowerRequest.brightnessIsTemporary) {
userInitiatedChange = autoBrightnessEnabled && brightnessAdjustmentChanged
|| !autoBrightnessEnabled && brightnessChanged;
mLastBrightness = mPowerRequest.screenBrightness;
mLastAutoBrightnessAdjustment = mPowerRequest.screenAutoBrightnessAdjustment;
} else {
userInitiatedChange = false;
}
// Configure auto-brightness.
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.configure(autoBrightnessEnabled,
mBrightnessConfiguration, mPowerRequest.screenAutoBrightnessAdjustment,
state != Display.STATE_ON, userInitiatedChange);
@@ -854,6 +842,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
animateScreenBrightness(brightness,
slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
}
final float brightnessInNits = getNits(brightness);
if (!mPowerRequest.brightnessIsTemporary && brightnessInNits >= 0.0f) {
// We only want to track changes made by the user and on devices that can actually
// map the display backlight values into a physical brightness unit.
mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiatedChange);
}
}
// Determine whether the display is ready for use in the newly requested state.
@@ -1312,6 +1307,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mHandler.post(mOnStateChangedRunnable);
}
private float getNits(int backlight) {
if (mBrightnessMapper != null) {
return mBrightnessMapper.getNits(backlight);
} else {
return -1.0f;
}
}
private final Runnable mOnStateChangedRunnable = new Runnable() {
@Override
public void run() {
@@ -1362,7 +1365,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println("Display Power Controller Configuration:");
pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
pw.println(" mScreenBrightnessDarkConfig=" + mScreenBrightnessDarkConfig);
pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
@@ -1383,7 +1385,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println("Display Power Controller Thread State:");
pw.println(" mPowerRequest=" + mPowerRequest);
pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
pw.println(" mProximitySensor=" + mProximitySensor);
pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
pw.println(" mProximityThreshold=" + mProximityThreshold);
@@ -1392,6 +1393,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println(" mPendingProximityDebounceTime="
+ TimeUtils.formatUptime(mPendingProximityDebounceTime));
pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
pw.println(" mLastBrightness=" + mLastBrightness);
pw.println(" mLastAutoBrightnessAdjustment=" + mLastAutoBrightnessAdjustment);
pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
pw.println(" mAppliedDimming=" + mAppliedDimming);
pw.println(" mAppliedLowPower=" + mAppliedLowPower);
@@ -1420,6 +1423,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAutomaticBrightnessController.dump(pw);
}
if (mBrightnessTracker != null) {
pw.println();
mBrightnessTracker.dump(pw);
}
}
private static String proximityToString(int state) {

View File

@@ -2452,6 +2452,7 @@ public final class PowerManagerService extends SystemService
float screenAutoBrightnessAdjustment = 0.0f;
boolean autoBrightness = (mScreenBrightnessModeSetting ==
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
boolean brightnessIsTemporary = false;
if (!mBootCompleted) {
// Keep the brightness steady during boot. This requires the
// bootloader brightness and the default brightness to be identical.
@@ -2466,6 +2467,7 @@ public final class PowerManagerService extends SystemService
brightnessSetByUser = false;
} else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
screenBrightness = mTemporaryScreenBrightnessSettingOverride;
brightnessIsTemporary = true;
} else if (isValidBrightness(mScreenBrightnessSetting)) {
screenBrightness = mScreenBrightnessSetting;
}
@@ -2475,6 +2477,7 @@ public final class PowerManagerService extends SystemService
mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
screenAutoBrightnessAdjustment =
mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
brightnessIsTemporary = true;
} else if (isValidAutoBrightnessAdjustment(
mScreenAutoBrightnessAdjustmentSetting)) {
screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
@@ -2490,6 +2493,7 @@ public final class PowerManagerService extends SystemService
mDisplayPowerRequest.screenAutoBrightnessAdjustment =
screenAutoBrightnessAdjustment;
mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
mDisplayPowerRequest.brightnessIsTemporary = brightnessIsTemporary;
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();

View File

@@ -20,7 +20,13 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.PowerManager;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -35,18 +41,18 @@ import java.util.Arrays;
@RunWith(AndroidJUnit4.class)
public class BrightnessMappingStrategyTest {
private static final float[] LUX_LEVELS = {
0f,
5f,
20f,
40f,
100f,
325f,
600f,
1250f,
2200f,
4000f,
5000f
private static final int[] LUX_LEVELS = {
0,
5,
20,
40,
100,
325,
600,
1250,
2200,
4000,
5000
};
private static final float[] DISPLAY_LEVELS_NITS = {
@@ -80,11 +86,13 @@ public class BrightnessMappingStrategyTest {
private static final float[] DISPLAY_RANGE_NITS = { 2.685f, 478.5f };
private static final int[] BACKLIGHT_RANGE = { 1, 255 };
private static final float[] EMPTY_FLOAT_ARRAY = new float[0];
private static final int[] EMPTY_INT_ARRAY = new int[0];
@Test
public void testSimpleStrategyMappingAtControlPoints() {
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(
LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT);
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
for (int i = 0; i < LUX_LEVELS.length; i++) {
final float expectedLevel =
@@ -96,9 +104,8 @@ public class BrightnessMappingStrategyTest {
@Test
public void testSimpleStrategyMappingBetweenControlPoints() {
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(
LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT);
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
for (int i = 1; i < LUX_LEVELS.length; i++) {
final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
@@ -111,9 +118,9 @@ public class BrightnessMappingStrategyTest {
@Test
public void testPhysicalStrategyMappingAtControlPoints() {
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(
LUX_LEVELS, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_NITS,
DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", physical);
for (int i = 0; i < LUX_LEVELS.length; i++) {
final float expectedLevel = DISPLAY_LEVELS_NITS[i] / DISPLAY_RANGE_NITS[1];
@@ -124,9 +131,9 @@ public class BrightnessMappingStrategyTest {
@Test
public void testPhysicalStrategyMappingBetweenControlPoints() {
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(
LUX_LEVELS, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_NITS,
DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", physical);
Spline backlightToBrightness =
Spline.createSpline(toFloatArray(BACKLIGHT_RANGE), DISPLAY_RANGE_NITS);
@@ -141,82 +148,79 @@ public class BrightnessMappingStrategyTest {
@Test
public void testDefaultStrategyIsPhysical() {
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(
LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res);
assertTrue(strategy instanceof BrightnessMappingStrategy.PhysicalMappingStrategy);
}
@Test
public void testNonStrictlyIncreasingLuxLevelsFails() {
final float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
final int[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
final int idx = lux.length / 2;
float tmp = lux[idx];
int tmp = lux[idx];
lux[idx] = lux[idx+1];
lux[idx+1] = tmp;
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(
lux, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
Resources res = createResources(lux, DISPLAY_LEVELS_NITS,
DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
// And make sure we get the same result even if it's monotone but not increasing.
lux[idx] = lux[idx+1];
strategy = BrightnessMappingStrategy.create(
lux, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
res = createResources(lux, DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
}
@Test
public void testDifferentNumberOfControlPointValuesFails() {
//Extra lux level
final float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length+1);
final int[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length+1);
// Make sure it's strictly increasing so that the only failure is the differing array
// lengths
lux[lux.length - 1] = lux[lux.length - 2] + 1;
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(
lux, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
Resources res = createResources(lux, DISPLAY_LEVELS_NITS,
DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
strategy = BrightnessMappingStrategy.create(
lux, DISPLAY_LEVELS_BACKLIGHT,
null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
res = createResources(lux, DISPLAY_LEVELS_BACKLIGHT);
strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
// Extra backlight level
final int[] backlight = Arrays.copyOf(
DISPLAY_LEVELS_BACKLIGHT, DISPLAY_LEVELS_BACKLIGHT.length+1);
backlight[backlight.length - 1] = backlight[backlight.length - 2] + 1;
strategy = BrightnessMappingStrategy.create(
LUX_LEVELS, backlight,
null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
res = createResources(LUX_LEVELS, backlight);
strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
// Extra nits level
final float[] nits = Arrays.copyOf(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_NITS.length+1);
nits[nits.length - 1] = nits[nits.length - 2] + 1;
strategy = BrightnessMappingStrategy.create(
LUX_LEVELS, null /*brightnessLevelsBacklight*/,
nits, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
res = createResources(LUX_LEVELS, nits, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
}
@Test
public void testPhysicalStrategyRequiresNitsMapping() {
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(
LUX_LEVELS, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, null, BACKLIGHT_RANGE);
Resources res = createResources(LUX_LEVELS, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, EMPTY_FLOAT_ARRAY /*nitsRange*/, BACKLIGHT_RANGE);
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res);
assertNull(physical);
physical = BrightnessMappingStrategy.create(
LUX_LEVELS, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, null);
res = createResources(LUX_LEVELS, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, EMPTY_INT_ARRAY /*backlightRange*/);
physical = BrightnessMappingStrategy.create(res);
assertNull(physical);
physical = BrightnessMappingStrategy.create(
LUX_LEVELS, null /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, null, null);
res = createResources(LUX_LEVELS, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
DISPLAY_LEVELS_NITS, EMPTY_FLOAT_ARRAY /*nitsRange*/,
EMPTY_INT_ARRAY /*backlightRange*/);
physical = BrightnessMappingStrategy.create(res);
assertNull(physical);
}
@@ -227,4 +231,73 @@ public class BrightnessMappingStrategyTest {
}
return newVals;
}
private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight) {
return createResources(luxLevels, brightnessLevelsBacklight,
EMPTY_FLOAT_ARRAY /*brightnessLevelsNits*/, EMPTY_FLOAT_ARRAY /*nitsRange*/,
EMPTY_INT_ARRAY /*backlightRange*/);
}
private Resources createResources(int[] luxLevels, float[] brightnessLevelsNits,
float[] nitsRange, int[] backlightRange) {
return createResources(luxLevels, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
brightnessLevelsNits, nitsRange, backlightRange);
}
private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight,
float[] brightnessLevelsNits, float[] nitsRange, int[] backlightRange) {
Resources mockResources = mock(Resources.class);
// For historical reasons, the lux levels resource implicitly defines the first point as 0,
// so we need to chop it off of the array the mock resource object returns.
int[] luxLevelsResource = Arrays.copyOfRange(luxLevels, 1, luxLevels.length);
when(mockResources.getIntArray(com.android.internal.R.array.config_autoBrightnessLevels))
.thenReturn(luxLevelsResource);
when(mockResources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues))
.thenReturn(brightnessLevelsBacklight);
TypedArray mockBrightnessLevelNits = createFloatTypedArray(brightnessLevelsNits);
when(mockResources.obtainTypedArray(
com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
.thenReturn(mockBrightnessLevelNits);
TypedArray mockNitsRange = createFloatTypedArray(nitsRange);
when(mockResources.obtainTypedArray(
com.android.internal.R.array.config_screenBrightnessNits))
.thenReturn(mockNitsRange);
when(mockResources.getIntArray(
com.android.internal.R.array.config_screenBrightnessBacklight))
.thenReturn(backlightRange);
when(mockResources.getInteger(
com.android.internal.R.integer.config_screenBrightnessSettingMinimum))
.thenReturn(1);
when(mockResources.getInteger(
com.android.internal.R.integer.config_screenBrightnessSettingMaximum))
.thenReturn(255);
return mockResources;
}
private TypedArray createFloatTypedArray(float[] vals) {
TypedArray mockArray = mock(TypedArray.class);
when(mockArray.length()).thenAnswer(invocation -> {
return vals.length;
});
when(mockArray.getFloat(anyInt(), anyFloat())).thenAnswer(invocation -> {
final float def = (float) invocation.getArguments()[1];
if (vals == null) {
return def;
}
int idx = (int) invocation.getArguments()[0];
if (idx >= 0 && idx < vals.length) {
return vals[idx];
} else {
return def;
}
});
return mockArray;
}
}

View File

@@ -66,6 +66,8 @@ import java.util.concurrent.TimeUnit;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BrightnessTrackerTest {
private static final float DEFAULT_INITIAL_BRIGHTNESS = 2.5f;
private static final float FLOAT_DELTA = 0.01f;
private BrightnessTracker mTracker;
private TestInjector mInjector;
@@ -98,7 +100,6 @@ public class BrightnessTrackerTest {
mInjector.mInteractive = false;
startTracker(mTracker);
assertNull(mInjector.mSensorListener);
assertNotNull(mInjector.mSettingsObserver);
assertNotNull(mInjector.mBroadcastReceiver);
assertTrue(mInjector.mIdleScheduled);
Intent onIntent = new Intent();
@@ -119,7 +120,6 @@ public class BrightnessTrackerTest {
mTracker.stop();
assertNull(mInjector.mSensorListener);
assertNull(mInjector.mSettingsObserver);
assertNull(mInjector.mBroadcastReceiver);
assertFalse(mInjector.mIdleScheduled);
}
@@ -128,12 +128,10 @@ public class BrightnessTrackerTest {
public void testBrightnessEvent() {
final int brightness = 20;
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
startTracker(mTracker);
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, brightness);
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
mTracker.stop();
@@ -141,10 +139,11 @@ public class BrightnessTrackerTest {
BrightnessChangeEvent event = events.get(0);
assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
assertEquals(1, event.luxValues.length);
assertEquals(1.0f, event.luxValues[0], 0.1f);
assertEquals(1.0f, event.luxValues[0], FLOAT_DELTA);
assertEquals(mInjector.currentTimeMillis() - TimeUnit.SECONDS.toMillis(2),
event.luxTimestamps[0]);
assertEquals(brightness, event.brightness);
assertEquals(brightness, event.brightness, FLOAT_DELTA);
assertEquals(DEFAULT_INITIAL_BRIGHTNESS, event.lastBrightness, FLOAT_DELTA);
// System had no data so these should all be at defaults.
assertEquals(Float.NaN, event.batteryLevel, 0.0);
@@ -154,21 +153,18 @@ public class BrightnessTrackerTest {
@Test
public void testBrightnessFullPopulatedEvent() {
final int lastBrightness = 230;
final int initialBrightness = 230;
final int brightness = 130;
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, lastBrightness);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333);
startTracker(mTracker);
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
startTracker(mTracker, initialBrightness);
mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
batteryChangeEvent(30, 60));
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
final long sensorTime = mInjector.currentTimeMillis();
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, brightness);
List<BrightnessChangeEvent> eventsNoPackage
= mTracker.getEvents(0, false).getList();
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
@@ -179,9 +175,9 @@ public class BrightnessTrackerTest {
assertEquals(event.timeStamp, mInjector.currentTimeMillis());
assertArrayEquals(new float[] {1000.0f}, event.luxValues, 0.01f);
assertArrayEquals(new long[] {sensorTime}, event.luxTimestamps);
assertEquals(brightness, event.brightness);
assertEquals(lastBrightness, event.lastBrightness);
assertEquals(0.5, event.batteryLevel, 0.01);
assertEquals(brightness, event.brightness, FLOAT_DELTA);
assertEquals(initialBrightness, event.lastBrightness, FLOAT_DELTA);
assertEquals(0.5, event.batteryLevel, FLOAT_DELTA);
assertTrue(event.nightMode);
assertEquals(3333, event.colorTemperature);
assertEquals("a.package", event.packageName);
@@ -192,45 +188,34 @@ public class BrightnessTrackerTest {
}
@Test
public void testIgnoreSelfChange() {
public void testIgnoreAutomaticBrightnessChange() {
final int initialBrightness = 30;
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, initialBrightness);
startTracker(mTracker);
startTracker(mTracker, initialBrightness);
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
final int systemUpdatedBrightness = 20;
mTracker.setBrightness(systemUpdatedBrightness, 0);
assertEquals(systemUpdatedBrightness,
(int) mInjector.mSystemIntSettings.get(Settings.System.SCREEN_BRIGHTNESS));
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, systemUpdatedBrightness, false /*userInitiated*/);
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
// No events because we filtered out our change.
assertEquals(0, events.size());
final int firstUserUpdateBrightness = 20;
// Then change comes from somewhere else so we shouldn't filter.
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS,
firstUserUpdateBrightness);
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, firstUserUpdateBrightness);
// and with a different brightness value.
final int secondUserUpdateBrightness = 34;
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS,
secondUserUpdateBrightness);
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, secondUserUpdateBrightness);
events = mTracker.getEvents(0, true).getList();
assertEquals(2, events.size());
// First event is change from system update (20) to first user update (20)
assertEquals(systemUpdatedBrightness, events.get(0).lastBrightness);
assertEquals(firstUserUpdateBrightness, events.get(0).brightness);
assertEquals(systemUpdatedBrightness, events.get(0).lastBrightness, FLOAT_DELTA);
assertEquals(firstUserUpdateBrightness, events.get(0).brightness, FLOAT_DELTA);
// Second event is from first to second user update.
assertEquals(firstUserUpdateBrightness, events.get(1).lastBrightness);
assertEquals(secondUserUpdateBrightness, events.get(1).brightness);
assertEquals(firstUserUpdateBrightness, events.get(1).lastBrightness, FLOAT_DELTA);
assertEquals(secondUserUpdateBrightness, events.get(1).brightness, FLOAT_DELTA);
mTracker.stop();
}
@@ -243,9 +228,7 @@ public class BrightnessTrackerTest {
for (int brightness = 0; brightness <= 255; ++brightness) {
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
mInjector.incrementTime(TimeUnit.SECONDS.toNanos(1));
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, brightness);
}
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
mTracker.stop();
@@ -254,14 +237,13 @@ public class BrightnessTrackerTest {
assertEquals(100, events.size());
for (int i = 0; i < events.size(); i++) {
BrightnessChangeEvent event = events.get(i);
assertEquals(156 + i, event.brightness);
assertEquals(156 + i, event.brightness, FLOAT_DELTA);
}
}
@Test
public void testLimitedSensorEvents() {
final int brightness = 20;
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
startTracker(mTracker);
// 20 Sensor events 1 second apart.
@@ -269,8 +251,7 @@ public class BrightnessTrackerTest {
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
mInjector.mSensorListener.onSensorChanged(createSensorEvent(i + 1.0f));
}
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, 20);
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
mTracker.stop();
@@ -284,7 +265,7 @@ public class BrightnessTrackerTest {
assertEquals(event.luxTimestamps[11 - i],
mInjector.currentTimeMillis() - i * TimeUnit.SECONDS.toMillis(1));
}
assertEquals(brightness, event.brightness);
assertEquals(brightness, event.brightness, FLOAT_DELTA);
}
@Test
@@ -298,25 +279,25 @@ public class BrightnessTrackerTest {
String eventFile =
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<events>\n"
+ "<event brightness=\"194\" timestamp=\""
+ "<event nits=\"194.2\" timestamp=\""
+ Long.toString(someTimeAgo) + "\" packageName=\""
+ "com.example.app\" user=\"10\" "
+ "lastBrightness=\"32\" "
+ "lastNits=\"32.333\" "
+ "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
+ "lux=\"32.2,31.1\" luxTimestamps=\""
+ Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
+ "<event brightness=\"71\" timestamp=\""
+ "<event nits=\"71\" timestamp=\""
+ Long.toString(someTimeAgo) + "\" packageName=\""
+ "com.android.anapp\" user=\"11\" "
+ "lastBrightness=\"32\" "
+ "lastNits=\"32\" "
+ "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\"\n"
+ "lux=\"132.2,131.1\" luxTimestamps=\""
+ Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
// Event that is too old so shouldn't show up.
+ "<event brightness=\"142\" timestamp=\""
+ "<event nits=\"142\" timestamp=\""
+ Long.toString(twoMonthsAgo) + "\" packageName=\""
+ "com.example.app\" user=\"10\" "
+ "lastBrightness=\"32\" "
+ "lastNits=\"32\" "
+ "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
+ "lux=\"32.2,31.1\" luxTimestamps=\""
+ Long.toString(twoMonthsAgo) + "," + Long.toString(twoMonthsAgo) + "\"/>"
@@ -326,27 +307,27 @@ public class BrightnessTrackerTest {
assertEquals(1, events.size());
BrightnessChangeEvent event = events.get(0);
assertEquals(someTimeAgo, event.timeStamp);
assertEquals(194, event.brightness);
assertArrayEquals(new float[] {32.2f, 31.1f}, event.luxValues, 0.01f);
assertEquals(194.2, event.brightness, FLOAT_DELTA);
assertArrayEquals(new float[] {32.2f, 31.1f}, event.luxValues, FLOAT_DELTA);
assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
assertEquals(32, event.lastBrightness);
assertEquals(32.333, event.lastBrightness, FLOAT_DELTA);
assertEquals(0, event.userId);
assertFalse(event.nightMode);
assertEquals(1.0f, event.batteryLevel, 0.01);
assertEquals(1.0f, event.batteryLevel, FLOAT_DELTA);
assertEquals("com.example.app", event.packageName);
events = tracker.getEvents(1, true).getList();
assertEquals(1, events.size());
event = events.get(0);
assertEquals(someTimeAgo, event.timeStamp);
assertEquals(71, event.brightness);
assertArrayEquals(new float[] {132.2f, 131.1f}, event.luxValues, 0.01f);
assertEquals(71, event.brightness, FLOAT_DELTA);
assertArrayEquals(new float[] {132.2f, 131.1f}, event.luxValues, FLOAT_DELTA);
assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
assertEquals(32, event.lastBrightness);
assertEquals(32, event.lastBrightness, FLOAT_DELTA);
assertEquals(1, event.userId);
assertTrue(event.nightMode);
assertEquals(3235, event.colorTemperature);
assertEquals(0.5f, event.batteryLevel, 0.01);
assertEquals(0.5f, event.batteryLevel, FLOAT_DELTA);
assertEquals("com.android.anapp", event.packageName);
}
@@ -370,7 +351,7 @@ public class BrightnessTrackerTest {
eventFile =
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<events>\n"
+ "<event brightness=\"194\" timestamp=\"" + someTimeAgo + "\" packageName=\""
+ "<event nits=\"194\" timestamp=\"" + someTimeAgo + "\" packageName=\""
+ "com.example.app\" user=\"10\" "
+ "batteryLevel=\"0.7\" nightMode=\"false\" colorTemperature=\"0\" />\n"
+ "</events>";
@@ -386,7 +367,6 @@ public class BrightnessTrackerTest {
public void testWriteThenRead() throws Exception {
final int brightness = 20;
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339);
@@ -399,8 +379,7 @@ public class BrightnessTrackerTest {
mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
final long secondSensorTime = mInjector.currentTimeMillis();
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(3));
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, brightness);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
mTracker.writeEventsLocked(baos);
mTracker.stop();
@@ -414,10 +393,10 @@ public class BrightnessTrackerTest {
assertEquals(1, events.size());
BrightnessChangeEvent event = events.get(0);
assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, 0.01f);
assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, FLOAT_DELTA);
assertArrayEquals(new long[] {firstSensorTime, secondSensorTime}, event.luxTimestamps);
assertEquals(brightness, event.brightness);
assertEquals(0.3, event.batteryLevel, 0.01f);
assertEquals(brightness, event.brightness, FLOAT_DELTA);
assertEquals(0.3, event.batteryLevel, FLOAT_DELTA);
assertTrue(event.nightMode);
assertEquals(3339, event.colorTemperature);
}
@@ -426,7 +405,6 @@ public class BrightnessTrackerTest {
public void testWritePrunesOldEvents() throws Exception {
final int brightness = 20;
mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339);
@@ -437,14 +415,12 @@ public class BrightnessTrackerTest {
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f));
final long sensorTime = mInjector.currentTimeMillis();
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, brightness);
// 31 days later
mInjector.incrementTime(TimeUnit.DAYS.toMillis(31));
mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS));
notifyBrightnessChanged(mTracker, brightness);
final long eventTime = mInjector.currentTimeMillis();
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
@@ -460,10 +436,10 @@ public class BrightnessTrackerTest {
assertEquals(eventTime, event.timeStamp);
// We will keep one of the old sensor events because we keep 1 event outside the window.
assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, 0.01f);
assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, FLOAT_DELTA);
assertArrayEquals(new long[] {sensorTime, eventTime}, event.luxTimestamps);
assertEquals(brightness, event.brightness);
assertEquals(0.3, event.batteryLevel, 0.01f);
assertEquals(brightness, event.brightness, FLOAT_DELTA);
assertEquals(0.3, event.batteryLevel, FLOAT_DELTA);
assertTrue(event.nightMode);
assertEquals(3339, event.colorTemperature);
}
@@ -472,7 +448,7 @@ public class BrightnessTrackerTest {
public void testParcelUnParcel() {
Parcel parcel = Parcel.obtain();
BrightnessChangeEvent event = new BrightnessChangeEvent();
event.brightness = 23;
event.brightness = 23f;
event.timeStamp = 345L;
event.packageName = "com.example";
event.userId = 12;
@@ -485,7 +461,7 @@ public class BrightnessTrackerTest {
event.batteryLevel = 0.7f;
event.nightMode = false;
event.colorTemperature = 345;
event.lastBrightness = 50;
event.lastBrightness = 50f;
event.writeToParcel(parcel, 0);
byte[] parceled = parcel.marshall();
@@ -497,16 +473,16 @@ public class BrightnessTrackerTest {
BrightnessChangeEvent event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel);
parcel.recycle();
assertEquals(event.brightness, event2.brightness);
assertEquals(event.brightness, event2.brightness, FLOAT_DELTA);
assertEquals(event.timeStamp, event2.timeStamp);
assertEquals(event.packageName, event2.packageName);
assertEquals(event.userId, event2.userId);
assertArrayEquals(event.luxValues, event2.luxValues, 0.01f);
assertArrayEquals(event.luxValues, event2.luxValues, FLOAT_DELTA);
assertArrayEquals(event.luxTimestamps, event2.luxTimestamps);
assertEquals(event.batteryLevel, event2.batteryLevel, 0.01f);
assertEquals(event.batteryLevel, event2.batteryLevel, FLOAT_DELTA);
assertEquals(event.nightMode, event2.nightMode);
assertEquals(event.colorTemperature, event2.colorTemperature);
assertEquals(event.lastBrightness, event2.lastBrightness);
assertEquals(event.lastBrightness, event2.lastBrightness, FLOAT_DELTA);
parcel = Parcel.obtain();
event.batteryLevel = Float.NaN;
@@ -518,7 +494,7 @@ public class BrightnessTrackerTest {
parcel.unmarshall(parceled, 0, parceled.length);
parcel.setDataPosition(0);
event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel);
assertEquals(event.batteryLevel, event2.batteryLevel, 0.01f);
assertEquals(event.batteryLevel, event2.batteryLevel, FLOAT_DELTA);
}
private InputStream getInputStream(String data) {
@@ -550,7 +526,21 @@ public class BrightnessTrackerTest {
}
private void startTracker(BrightnessTracker tracker) {
tracker.start();
startTracker(tracker, DEFAULT_INITIAL_BRIGHTNESS);
}
private void startTracker(BrightnessTracker tracker, float initialBrightness) {
tracker.start(initialBrightness);
mInjector.waitForHandler();
}
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness) {
notifyBrightnessChanged(tracker, brightness, true /*userInitiated*/);
}
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
boolean userInitiated) {
tracker.notifyBrightnessChanged(brightness, userInitiated);
mInjector.waitForHandler();
}
@@ -578,7 +568,6 @@ public class BrightnessTrackerTest {
private class TestInjector extends BrightnessTracker.Injector {
SensorEventListener mSensorListener;
ContentObserver mSettingsObserver;
BroadcastReceiver mBroadcastReceiver;
Map<String, Integer> mSystemIntSettings = new HashMap<>();
Map<String, Integer> mSecureIntSettings = new HashMap<>();
@@ -609,18 +598,6 @@ public class BrightnessTrackerTest {
mSensorListener = null;
}
@Override
public void registerBrightnessObserver(ContentResolver resolver,
ContentObserver settingsObserver) {
mSettingsObserver = settingsObserver;
}
@Override
public void unregisterBrightnessObserver(Context context,
ContentObserver settingsObserver) {
mSettingsObserver = null;
}
@Override
public void registerReceiver(Context context,
BroadcastReceiver shutdownReceiver, IntentFilter shutdownFilter) {
@@ -646,23 +623,6 @@ public class BrightnessTrackerTest {
idle.waitForIdle();
}
@Override
public int getSystemIntForUser(ContentResolver resolver, String setting, int defaultValue,
int userId) {
Integer value = mSystemIntSettings.get(setting);
if (value == null) {
return defaultValue;
} else {
return value;
}
}
@Override
public void putSystemIntForUser(ContentResolver resolver, String setting, int value,
int userId) {
mSystemIntSettings.put(setting, value);
}
@Override
public int getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue,
int userId) {