diff options
9 files changed, 147 insertions, 38 deletions
diff --git a/api/current.txt b/api/current.txt index 43cae61..61f907e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -34006,6 +34006,7 @@ package android.util { method public static void readEvents(int[], java.util.Collection<android.util.EventLog.Event>) throws java.io.IOException; method public static int writeEvent(int, int); method public static int writeEvent(int, long); + method public static int writeEvent(int, float); method public static int writeEvent(int, java.lang.String); method public static int writeEvent(int, java.lang.Object...); } diff --git a/api/system-current.txt b/api/system-current.txt index ead078a..3bbfb8a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -36208,6 +36208,7 @@ package android.util { method public static void readEvents(int[], java.util.Collection<android.util.EventLog.Event>) throws java.io.IOException; method public static int writeEvent(int, int); method public static int writeEvent(int, long); + method public static int writeEvent(int, float); method public static int writeEvent(int, java.lang.String); method public static int writeEvent(int, java.lang.Object...); } diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index adab9be..02793f1 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -182,6 +182,10 @@ public abstract class DisplayManagerInternal { // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter). public float screenAutoBrightnessAdjustment; + // Set to true if screenBrightness and screenAutoBrightnessAdjustment were both + // set by the user as opposed to being programmatically controlled by apps. + public boolean brightnessSetByUser; + // If true, enables automatic brightness control. public boolean useAutoBrightness; @@ -229,6 +233,7 @@ public abstract class DisplayManagerInternal { useProximitySensor = other.useProximitySensor; screenBrightness = other.screenBrightness; screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment; + brightnessSetByUser = other.brightnessSetByUser; useAutoBrightness = other.useAutoBrightness; blockScreenOn = other.blockScreenOn; lowPowerMode = other.lowPowerMode; @@ -249,6 +254,7 @@ public abstract class DisplayManagerInternal { && useProximitySensor == other.useProximitySensor && screenBrightness == other.screenBrightness && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment + && brightnessSetByUser == other.brightnessSetByUser && useAutoBrightness == other.useAutoBrightness && blockScreenOn == other.blockScreenOn && lowPowerMode == other.lowPowerMode @@ -268,6 +274,7 @@ public abstract class DisplayManagerInternal { + ", useProximitySensor=" + useProximitySensor + ", screenBrightness=" + screenBrightness + ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment + + ", brightnessSetByUser=" + brightnessSetByUser + ", useAutoBrightness=" + useAutoBrightness + ", blockScreenOn=" + blockScreenOn + ", lowPowerMode=" + lowPowerMode diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java index aefced8..558b8f5 100644 --- a/core/java/android/util/EventLog.java +++ b/core/java/android/util/EventLog.java @@ -74,6 +74,7 @@ public class EventLog { private static final byte LONG_TYPE = 1; private static final byte STRING_TYPE = 2; private static final byte LIST_TYPE = 3; + private static final byte FLOAT_TYPE = 4; /** @param data containing event, read from the system */ /*package*/ Event(byte[] data) { @@ -106,7 +107,7 @@ public class EventLog { return mBuffer.getInt(offset); } - /** @return one of Integer, Long, String, null, or Object[] of same. */ + /** @return one of Integer, Long, Float, String, null, or Object[] of same. */ public synchronized Object getData() { try { int offset = mBuffer.getShort(HEADER_SIZE_OFFSET); @@ -130,10 +131,13 @@ public class EventLog { byte type = mBuffer.get(); switch (type) { case INT_TYPE: - return (Integer) mBuffer.getInt(); + return mBuffer.getInt(); case LONG_TYPE: - return (Long) mBuffer.getLong(); + return mBuffer.getLong(); + + case FLOAT_TYPE: + return mBuffer.getFloat(); case STRING_TYPE: try { @@ -180,6 +184,14 @@ public class EventLog { /** * Record an event log message. * @param tag The event type tag code + * @param value A value to log + * @return The number of bytes written + */ + public static native int writeEvent(int tag, float value); + + /** + * Record an event log message. + * @param tag The event type tag code * @param str A value to log * @return The number of bytes written */ diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp index 5cb8b2e..05bc125 100644 --- a/core/jni/android_util_EventLog.cpp +++ b/core/jni/android_util_EventLog.cpp @@ -40,6 +40,9 @@ static jfieldID gIntegerValueID; static jclass gLongClass; static jfieldID gLongValueID; +static jclass gFloatClass; +static jfieldID gFloatValueID; + static jclass gStringClass; /* @@ -66,6 +69,17 @@ static jint android_util_EventLog_writeEvent_Long(JNIEnv* env UNUSED, /* * In class android.util.EventLog: + * static native int writeEvent(long tag, float value) + */ +static jint android_util_EventLog_writeEvent_Float(JNIEnv* env UNUSED, + jobject clazz UNUSED, + jint tag, jfloat value) +{ + return android_btWriteLog(tag, EVENT_TYPE_FLOAT, &value, sizeof(value)); +} + +/* + * In class android.util.EventLog: * static native int writeEvent(int tag, String value) */ static jint android_util_EventLog_writeEvent_String(JNIEnv* env, @@ -128,6 +142,12 @@ static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz, buf[pos++] = EVENT_TYPE_LONG; memcpy(&buf[pos], &longVal, sizeof(longVal)); pos += sizeof(longVal); + } else if (env->IsInstanceOf(item, gFloatClass)) { + jfloat floatVal = env->GetFloatField(item, gFloatValueID); + if (pos + 1 + sizeof(floatVal) > max) break; + buf[pos++] = EVENT_TYPE_FLOAT; + memcpy(&buf[pos], &floatVal, sizeof(floatVal)); + pos += sizeof(floatVal); } else { jniThrowException(env, "java/lang/IllegalArgumentException", @@ -233,6 +253,7 @@ static JNINativeMethod gRegisterMethods[] = { /* name, signature, funcPtr */ { "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer }, { "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long }, + { "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float }, { "writeEvent", "(ILjava/lang/String;)I", (void*) android_util_EventLog_writeEvent_String @@ -251,6 +272,7 @@ static struct { const char *name; jclass *clazz; } gClasses[] = { { "android/util/EventLog$Event", &gEventClass }, { "java/lang/Integer", &gIntegerClass }, { "java/lang/Long", &gLongClass }, + { "java/lang/Float", &gFloatClass }, { "java/lang/String", &gStringClass }, { "java/util/Collection", &gCollectionClass }, }; @@ -258,6 +280,7 @@ static struct { const char *name; jclass *clazz; } gClasses[] = { static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = { { &gIntegerClass, "value", "I", &gIntegerValueID }, { &gLongClass, "value", "J", &gLongValueID }, + { &gFloatClass, "value", "F", &gFloatValueID }, }; static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = { diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index abd2ca0..ef9d0c3 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -180,6 +180,11 @@ option java_package com.android.server 34001 device_idle_step 34002 device_idle_wake_from_idle (is_idle|1|5), (reason|3) +# --------------------------- +# DisplayManagerService.java +# --------------------------- +# Auto-brightness adjustments by the user. +35000 auto_brightness_adj (old_adj|5),(old_lux|5),(old_brightness|5),(old_gamma|5),(new_adj|5),(new_lux|5),(new_brightness|5),(new_gamma|5) # --------------------------- # ConnectivityService.java diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 93d37f1..e15bca6 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -16,6 +16,7 @@ package com.android.server.display; +import com.android.server.EventLogTags; import com.android.server.LocalServices; import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; @@ -31,13 +32,13 @@ import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; import android.text.format.DateUtils; +import android.util.EventLog; import android.util.MathUtils; import android.util.Spline; import android.util.Slog; import android.util.TimeUtils; import java.io.PrintWriter; -import java.util.Arrays; class AutomaticBrightnessController { private static final String TAG = "AutomaticBrightnessController"; @@ -87,7 +88,12 @@ class AutomaticBrightnessController { // well after dusk. private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2; + // Debounce for sampling user-initiated changes in display brightness to ensure + // the user is satisfied with the result before storing the sample. + private static final int BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS = 10000; + private static final int MSG_UPDATE_AMBIENT_LUX = 1; + private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2; // Callbacks for requesting updates to the the display's power state private final Callbacks mCallbacks; @@ -179,6 +185,14 @@ class AutomaticBrightnessController { // Are we going to adjust brightness while dozing. private boolean mDozing; + // True if we are collecting a brightness adjustment sample, along with some data + // for the initial state of the sample. + private boolean mBrightnessAdjustmentSamplePending; + private float mBrightnessAdjustmentSampleOldAdjustment; + private float mBrightnessAdjustmentSampleOldLux; + private int mBrightnessAdjustmentSampleOldBrightness; + private float mBrightnessAdjustmentSampleOldGamma; + public AutomaticBrightnessController(Callbacks callbacks, Looper looper, SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, @@ -216,7 +230,8 @@ class AutomaticBrightnessController { return mScreenAutoBrightness; } - public void configure(boolean enable, float adjustment, boolean dozing) { + public void configure(boolean enable, float adjustment, boolean dozing, + boolean userInitiatedChange) { // While dozing, the application processor may be suspended which will prevent us from // receiving new information from the light sensor. On some devices, we may be able to // switch to a wake-up light sensor instead but for now we will simply disable the sensor @@ -228,6 +243,9 @@ class AutomaticBrightnessController { if (changed) { updateAutoBrightness(false /*sendUpdate*/); } + if (enable && !dozing && userInitiatedChange) { + prepareBrightnessAdjustmentSample(); + } } public void dump(PrintWriter pw) { @@ -486,7 +504,7 @@ class AutomaticBrightnessController { } int newScreenAutoBrightness = - clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); + clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); if (mScreenAutoBrightness != newScreenAutoBrightness) { if (DEBUG) { Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness=" @@ -507,6 +525,54 @@ class AutomaticBrightnessController { mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); } + private void prepareBrightnessAdjustmentSample() { + if (!mBrightnessAdjustmentSamplePending) { + mBrightnessAdjustmentSamplePending = true; + mBrightnessAdjustmentSampleOldAdjustment = mScreenAutoBrightnessAdjustment; + mBrightnessAdjustmentSampleOldLux = mAmbientLuxValid ? mAmbientLux : -1; + mBrightnessAdjustmentSampleOldBrightness = mScreenAutoBrightness; + mBrightnessAdjustmentSampleOldGamma = mLastScreenAutoBrightnessGamma; + } else { + mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE); + } + + mHandler.sendEmptyMessageDelayed(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE, + BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS); + } + + private void cancelBrightnessAdjustmentSample() { + if (mBrightnessAdjustmentSamplePending) { + mBrightnessAdjustmentSamplePending = false; + mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE); + } + } + + private void collectBrightnessAdjustmentSample() { + if (mBrightnessAdjustmentSamplePending) { + mBrightnessAdjustmentSamplePending = false; + if (mAmbientLuxValid && mScreenAutoBrightness >= 0) { + if (DEBUG) { + Slog.d(TAG, "Auto-brightness adjustment changed by user: " + + "adj=" + mScreenAutoBrightnessAdjustment + + ", lux=" + mAmbientLux + + ", brightness=" + mScreenAutoBrightness + + ", gamma=" + mLastScreenAutoBrightnessGamma + + ", ring=" + mAmbientLightRingBuffer); + } + + EventLog.writeEvent(EventLogTags.AUTO_BRIGHTNESS_ADJ, + mBrightnessAdjustmentSampleOldAdjustment, + mBrightnessAdjustmentSampleOldLux, + mBrightnessAdjustmentSampleOldBrightness, + mBrightnessAdjustmentSampleOldGamma, + mScreenAutoBrightnessAdjustment, + mAmbientLux, + mScreenAutoBrightness, + mLastScreenAutoBrightnessGamma); + } + } + } + private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) { if (lastSunset < 0 || nextSunrise < 0 || now < lastSunset || now > nextSunrise) { @@ -537,6 +603,10 @@ class AutomaticBrightnessController { case MSG_UPDATE_AMBIENT_LUX: updateAmbientLux(); break; + + case MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE: + collectBrightnessAdjustmentSample(); + break; } } } @@ -584,11 +654,7 @@ class AutomaticBrightnessController { private int mCount; public AmbientLightRingBuffer(long lightSensorRate) { - this((int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate)); - } - - public AmbientLightRingBuffer(int initialCapacity) { - mCapacity = initialCapacity; + mCapacity = (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate); mRingLux = new float[mCapacity]; mRingTime = new long[mCapacity]; } @@ -664,10 +730,6 @@ class AutomaticBrightnessController { return mCount; } - public boolean isEmpty() { - return mCount == 0; - } - public void clear() { mStart = 0; mEnd = 0; @@ -676,27 +738,20 @@ class AutomaticBrightnessController { @Override public String toString() { - final int length = mCapacity - mStart; - float[] lux = new float[mCount]; - long[] time = new long[mCount]; - - if (mCount <= length) { - System.arraycopy(mRingLux, mStart, lux, 0, mCount); - System.arraycopy(mRingTime, mStart, time, 0, mCount); - } else { - System.arraycopy(mRingLux, mStart, lux, 0, length); - System.arraycopy(mRingLux, 0, lux, length, mCount - length); - - System.arraycopy(mRingTime, mStart, time, 0, length); - System.arraycopy(mRingTime, 0, time, length, mCount - length); + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < mCount; i++) { + final long next = i + 1 < mCount ? getTime(i + 1) : SystemClock.uptimeMillis(); + if (i != 0) { + buf.append(", "); + } + buf.append(getLux(i)); + buf.append(" / "); + buf.append(next - getTime(i)); + buf.append("ms"); } - return "AmbientLightRingBuffer{mCapacity=" + mCapacity - + ", mStart=" + mStart - + ", mEnd=" + mEnd - + ", mCount=" + mCount - + ", mRingLux=" + Arrays.toString(lux) - + ", mRingTime=" + Arrays.toString(time) - + "}"; + buf.append(']'); + return buf.toString(); } private int offsetOf(int index) { diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index f74601e..35fbef6 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -70,12 +70,11 @@ import java.io.PrintWriter; */ final class DisplayPowerController implements AutomaticBrightnessController.Callbacks { private static final String TAG = "DisplayPowerController"; + private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked"; private static boolean DEBUG = false; private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false; - private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked"; - // If true, uses the color fade on animation. // We might want to turn this off if we cannot get a guarantee that the screen // actually turns on and starts showing new content after the call to set the @@ -599,8 +598,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call autoBrightnessEnabled = mPowerRequest.useAutoBrightness && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) && brightness < 0; + final boolean userInitiatedChange = autoBrightnessAdjustmentChanged + && mPowerRequest.brightnessSetByUser; mAutomaticBrightnessController.configure(autoBrightnessEnabled, - mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON); + mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON, + userInitiatedChange); } // Apply brightness boost. diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 6c8959c..f790f75 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -1819,6 +1819,7 @@ public final class PowerManagerService extends SystemService mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); // Determine appropriate screen brightness and auto-brightness adjustments. + boolean brightnessSetByUser = true; int screenBrightness = mScreenBrightnessSettingDefault; float screenAutoBrightnessAdjustment = 0.0f; boolean autoBrightness = (mScreenBrightnessModeSetting == @@ -1826,6 +1827,7 @@ public final class PowerManagerService extends SystemService if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) { screenBrightness = mScreenBrightnessOverrideFromWindowManager; autoBrightness = false; + brightnessSetByUser = false; } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) { screenBrightness = mTemporaryScreenBrightnessSettingOverride; } else if (isValidBrightness(mScreenBrightnessSetting)) { @@ -1851,6 +1853,7 @@ public final class PowerManagerService extends SystemService mDisplayPowerRequest.screenBrightness = screenBrightness; mDisplayPowerRequest.screenAutoBrightnessAdjustment = screenAutoBrightnessAdjustment; + mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser; mDisplayPowerRequest.useAutoBrightness = autoBrightness; mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked(); mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled; |
