Merge "Add information about brightness config to slider events."
diff --git a/api/system-current.txt b/api/system-current.txt
index 87269d0..62cc2a3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1147,11 +1147,14 @@
     field public final float batteryLevel;
     field public final float brightness;
     field public final int colorTemperature;
+    field public final boolean isDefaultBrightnessConfig;
+    field public final boolean isUserSetBrightness;
     field public final float lastBrightness;
     field public final long[] luxTimestamps;
     field public final float[] luxValues;
     field public final boolean nightMode;
     field public final java.lang.String packageName;
+    field public final float powerBrightnessFactor;
     field public final long timeStamp;
   }
 
diff --git a/api/test-current.txt b/api/test-current.txt
index bf00343..9af80e3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -305,11 +305,14 @@
     field public final float batteryLevel;
     field public final float brightness;
     field public final int colorTemperature;
+    field public final boolean isDefaultBrightnessConfig;
+    field public final boolean isUserSetBrightness;
     field public final float lastBrightness;
     field public final long[] luxTimestamps;
     field public final float[] luxValues;
     field public final boolean nightMode;
     field public final java.lang.String packageName;
+    field public final float powerBrightnessFactor;
     field public final long timeStamp;
   }
 
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java
index 2301824..02eb28c 100644
--- a/core/java/android/hardware/display/BrightnessChangeEvent.java
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.java
@@ -54,19 +54,30 @@
     /** Most recent battery level when brightness was changed or Float.NaN */
     public final float batteryLevel;
 
+    /** Factor applied to brightness due to battery level, 0.0-1.0 */
+    public final float powerBrightnessFactor;
+
     /** Color filter active to provide night mode */
     public final boolean nightMode;
 
     /** If night mode color filter is active this will be the temperature in kelvin */
     public final int colorTemperature;
 
-    /** Brightness le vel before slider adjustment */
+    /** Brightness level before slider adjustment */
     public final float lastBrightness;
 
+    /** Whether brightness configuration is default version */
+    public final boolean isDefaultBrightnessConfig;
+
+    /** Whether brightness curve includes a user brightness point */
+    public final boolean isUserSetBrightness;
+
+
     /** @hide */
     private BrightnessChangeEvent(float brightness, long timeStamp, String packageName,
             int userId, float[] luxValues, long[] luxTimestamps, float batteryLevel,
-            boolean nightMode, int colorTemperature, float lastBrightness) {
+            float powerBrightnessFactor, boolean nightMode, int colorTemperature,
+            float lastBrightness, boolean isDefaultBrightnessConfig, boolean isUserSetBrightness) {
         this.brightness = brightness;
         this.timeStamp = timeStamp;
         this.packageName = packageName;
@@ -74,9 +85,12 @@
         this.luxValues = luxValues;
         this.luxTimestamps = luxTimestamps;
         this.batteryLevel = batteryLevel;
+        this.powerBrightnessFactor = powerBrightnessFactor;
         this.nightMode = nightMode;
         this.colorTemperature = colorTemperature;
         this.lastBrightness = lastBrightness;
+        this.isDefaultBrightnessConfig = isDefaultBrightnessConfig;
+        this.isUserSetBrightness = isUserSetBrightness;
     }
 
     /** @hide */
@@ -88,9 +102,12 @@
         this.luxValues = other.luxValues;
         this.luxTimestamps = other.luxTimestamps;
         this.batteryLevel = other.batteryLevel;
+        this.powerBrightnessFactor = other.powerBrightnessFactor;
         this.nightMode = other.nightMode;
         this.colorTemperature = other.colorTemperature;
         this.lastBrightness = other.lastBrightness;
+        this.isDefaultBrightnessConfig = other.isDefaultBrightnessConfig;
+        this.isUserSetBrightness = other.isUserSetBrightness;
     }
 
     private BrightnessChangeEvent(Parcel source) {
@@ -101,9 +118,12 @@
         luxValues = source.createFloatArray();
         luxTimestamps = source.createLongArray();
         batteryLevel = source.readFloat();
+        powerBrightnessFactor = source.readFloat();
         nightMode = source.readBoolean();
         colorTemperature = source.readInt();
         lastBrightness = source.readFloat();
+        isDefaultBrightnessConfig = source.readBoolean();
+        isUserSetBrightness = source.readBoolean();
     }
 
     public static final Creator<BrightnessChangeEvent> CREATOR =
@@ -130,9 +150,12 @@
         dest.writeFloatArray(luxValues);
         dest.writeLongArray(luxTimestamps);
         dest.writeFloat(batteryLevel);
+        dest.writeFloat(powerBrightnessFactor);
         dest.writeBoolean(nightMode);
         dest.writeInt(colorTemperature);
         dest.writeFloat(lastBrightness);
+        dest.writeBoolean(isDefaultBrightnessConfig);
+        dest.writeBoolean(isUserSetBrightness);
     }
 
     /** @hide */
@@ -144,9 +167,12 @@
         private float[] mLuxValues;
         private long[] mLuxTimestamps;
         private float mBatteryLevel;
+        private float mPowerBrightnessFactor;
         private boolean mNightMode;
         private int mColorTemperature;
         private float mLastBrightness;
+        private boolean mIsDefaultBrightnessConfig;
+        private boolean mIsUserSetBrightness;
 
         /** {@see BrightnessChangeEvent#brightness} */
         public Builder setBrightness(float brightness) {
@@ -190,6 +216,12 @@
             return this;
         }
 
+        /** {@see BrightnessChangeEvent#powerSaveBrightness} */
+        public Builder setPowerBrightnessFactor(float powerBrightnessFactor) {
+            mPowerBrightnessFactor = powerBrightnessFactor;
+            return this;
+        }
+
         /** {@see BrightnessChangeEvent#nightMode} */
         public Builder setNightMode(boolean nightMode) {
             mNightMode = nightMode;
@@ -208,11 +240,24 @@
             return this;
         }
 
+        /** {@see BrightnessChangeEvent#isDefaultBrightnessConfig} */
+        public Builder setIsDefaultBrightnessConfig(boolean isDefaultBrightnessConfig) {
+            mIsDefaultBrightnessConfig = isDefaultBrightnessConfig;
+            return this;
+        }
+
+        /** {@see BrightnessChangeEvent#userBrightnessPoint} */
+        public Builder setUserBrightnessPoint(boolean isUserSetBrightness) {
+            mIsUserSetBrightness = isUserSetBrightness;
+            return this;
+        }
+
         /** Builds a BrightnessChangeEvent */
         public BrightnessChangeEvent build() {
             return new BrightnessChangeEvent(mBrightness, mTimeStamp,
                     mPackageName, mUserId, mLuxValues, mLuxTimestamps, mBatteryLevel,
-                    mNightMode, mColorTemperature, mLastBrightness);
+                    mPowerBrightnessFactor, mNightMode, mColorTemperature, mLastBrightness,
+                    mIsDefaultBrightnessConfig, mIsUserSetBrightness);
         }
     }
 }
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 6a88b1e..e2aee88 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -269,6 +269,14 @@
         }
     }
 
+    public boolean hasUserDataPoints() {
+        return mBrightnessMapper.hasUserDataPoints();
+    }
+
+    public boolean isDefaultConfig() {
+        return mBrightnessMapper.isDefaultConfig();
+    }
+
     private boolean setDisplayPolicy(int policy) {
         if (mDisplayPolicy == policy) {
             return false;
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 001d4d9..c0d2599 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -200,6 +200,12 @@
      */
     public abstract void clearUserDataPoints();
 
+    /** @return true if there are any short term adjustments applied to the curve */
+    public abstract boolean hasUserDataPoints();
+
+    /** @return true if the current brightness config is the default one */
+    public abstract boolean isDefaultConfig();
+
     public abstract void dump(PrintWriter pw);
 
     private static float normalizeAbsoluteBrightness(int brightness) {
@@ -390,6 +396,16 @@
         }
 
         @Override
+        public boolean hasUserDataPoints() {
+            return mUserLux != -1;
+        }
+
+        @Override
+        public boolean isDefaultConfig() {
+            return true;
+        }
+
+        @Override
         public void dump(PrintWriter pw) {
             pw.println("SimpleMappingStrategy");
             pw.println("  mSpline=" + mSpline);
@@ -507,6 +523,16 @@
         }
 
         @Override
+        public boolean hasUserDataPoints() {
+            return mUserLux != -1;
+        }
+
+        @Override
+        public boolean isDefaultConfig() {
+            return mDefaultConfig.equals(mConfig);
+        }
+
+        @Override
         public void dump(PrintWriter pw) {
             pw.println("PhysicalMappingStrategy");
             pw.println("  mConfig=" + mConfig);
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index bcf8bfe..e1f9a88 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -99,6 +99,9 @@
     private static final String ATTR_NIGHT_MODE = "nightMode";
     private static final String ATTR_COLOR_TEMPERATURE = "colorTemperature";
     private static final String ATTR_LAST_NITS = "lastNits";
+    private static final String ATTR_DEFAULT_CONFIG = "defaultConfig";
+    private static final String ATTR_POWER_SAVE = "powerSaveFactor";
+    private static final String ATTR_USER_POINT = "userPoint";
 
     private static final int MSG_BACKGROUND_START = 0;
     private static final int MSG_BRIGHTNESS_CHANGED = 1;
@@ -235,17 +238,22 @@
     /**
      * Notify the BrightnessTracker that the user has changed the brightness of the display.
      */
-    public void notifyBrightnessChanged(float brightness, boolean userInitiated) {
+    public void notifyBrightnessChanged(float brightness, boolean userInitiated,
+            float powerBrightnessFactor, boolean isUserSetBrightness,
+            boolean isDefaultBrightnessConfig) {
         if (DEBUG) {
             Slog.d(TAG, String.format("notifyBrightnessChanged(brightness=%f, userInitiated=%b)",
                         brightness, userInitiated));
         }
         Message m = mBgHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED,
-                userInitiated ? 1 : 0, 0 /*unused*/, (Float) brightness);
+                userInitiated ? 1 : 0, 0 /*unused*/, new BrightnessChangeValues(brightness,
+                        powerBrightnessFactor, isUserSetBrightness, isDefaultBrightnessConfig));
         m.sendToTarget();
     }
 
-    private void handleBrightnessChanged(float brightness, boolean userInitiated) {
+    private void handleBrightnessChanged(float brightness, boolean userInitiated,
+            float powerBrightnessFactor, boolean isUserSetBrightness,
+            boolean isDefaultBrightnessConfig) {
         BrightnessChangeEvent.Builder builder;
 
         synchronized (mDataCollectionLock) {
@@ -267,6 +275,9 @@
             builder = new BrightnessChangeEvent.Builder();
             builder.setBrightness(brightness);
             builder.setTimeStamp(mInjector.currentTimeMillis());
+            builder.setPowerBrightnessFactor(powerBrightnessFactor);
+            builder.setUserBrightnessPoint(isUserSetBrightness);
+            builder.setIsDefaultBrightnessConfig(isDefaultBrightnessConfig);
 
             final int readingCount = mLastSensorReadings.size();
             if (readingCount == 0) {
@@ -412,6 +423,12 @@
                         toWrite[i].colorTemperature));
                 out.attribute(null, ATTR_LAST_NITS,
                         Float.toString(toWrite[i].lastBrightness));
+                out.attribute(null, ATTR_DEFAULT_CONFIG,
+                        Boolean.toString(toWrite[i].isDefaultBrightnessConfig));
+                out.attribute(null, ATTR_POWER_SAVE,
+                        Float.toString(toWrite[i].powerBrightnessFactor));
+                out.attribute(null, ATTR_USER_POINT,
+                        Boolean.toString(toWrite[i].isUserSetBrightness));
                 StringBuilder luxValues = new StringBuilder();
                 StringBuilder luxTimestamps = new StringBuilder();
                 for (int j = 0; j < toWrite[i].luxValues.length; ++j) {
@@ -496,6 +513,21 @@
                     builder.setLuxValues(luxValues);
                     builder.setLuxTimestamps(luxTimestamps);
 
+                    String defaultConfig = parser.getAttributeValue(null, ATTR_DEFAULT_CONFIG);
+                    if (defaultConfig != null) {
+                        builder.setIsDefaultBrightnessConfig(Boolean.parseBoolean(defaultConfig));
+                    }
+                    String powerSave = parser.getAttributeValue(null, ATTR_POWER_SAVE);
+                    if (powerSave != null) {
+                        builder.setPowerBrightnessFactor(Float.parseFloat(powerSave));
+                    } else {
+                        builder.setPowerBrightnessFactor(1.0f);
+                    }
+                    String userPoint = parser.getAttributeValue(null, ATTR_USER_POINT);
+                    if (userPoint != null) {
+                        builder.setUserBrightnessPoint(Boolean.parseBoolean(userPoint));
+                    }
+
                     BrightnessChangeEvent event = builder.build();
                     if (DEBUG) {
                         Slog.i(TAG, "Read event " + event.brightness
@@ -535,7 +567,11 @@
             BrightnessChangeEvent[] events = mEvents.toArray();
             for (int i = 0; i < events.length; ++i) {
                 pw.print("    " + events[i].timeStamp + ", " + events[i].userId);
-                pw.print(", " + events[i].lastBrightness + "->" + events[i].brightness + ", {");
+                pw.print(", " + events[i].lastBrightness + "->" + events[i].brightness);
+                pw.print(", isUserSetBrightness=" + events[i].isUserSetBrightness);
+                pw.print(", powerBrightnessFactor=" + events[i].powerBrightnessFactor);
+                pw.print(", isDefaultBrightnessConfig=" + events[i].isDefaultBrightnessConfig);
+                pw.print(" {");
                 for (int j = 0; j < events[i].luxValues.length; ++j){
                     if (j != 0) {
                         pw.print(", ");
@@ -637,14 +673,31 @@
                     backgroundStart((float)msg.obj /*initial brightness*/);
                     break;
                 case MSG_BRIGHTNESS_CHANGED:
-                    float newBrightness = (float) msg.obj;
+                    BrightnessChangeValues values = (BrightnessChangeValues) msg.obj;
                     boolean userInitiatedChange = (msg.arg1 == 1);
-                    handleBrightnessChanged(newBrightness, userInitiatedChange);
+                    handleBrightnessChanged(values.brightness, userInitiatedChange,
+                            values.powerBrightnessFactor, values.isUserSetBrightness,
+                            values.isDefaultBrightnessConfig);
                     break;
             }
         }
     }
 
+    private static class BrightnessChangeValues {
+        final float brightness;
+        final float powerBrightnessFactor;
+        final boolean isUserSetBrightness;
+        final boolean isDefaultBrightnessConfig;
+
+        BrightnessChangeValues(float brightness, float powerBrightnessFactor,
+                boolean isUserSetBrightness, boolean isDefaultBrightnessConfig) {
+            this.brightness = brightness;
+            this.powerBrightnessFactor = powerBrightnessFactor;
+            this.isUserSetBrightness = isUserSetBrightness;
+            this.isDefaultBrightnessConfig = isDefaultBrightnessConfig;
+        }
+    }
+
     @VisibleForTesting
     static class Injector {
         public void registerSensorListener(Context context,
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 80aec42..fa352ab 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -795,13 +795,15 @@
             brightness = PowerManager.BRIGHTNESS_ON;
         }
 
-        // If the brightness is already set then it's been overriden by something other than the
+        // If the brightness is already set then it's been overridden by something other than the
         // user, or is a temporary adjustment.
         final boolean userInitiatedChange = brightness < 0
                 && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
 
+        boolean hadUserBrightnessPoint = false;
         // Configure auto-brightness.
         if (mAutomaticBrightnessController != null) {
+            hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();
             mAutomaticBrightnessController.configure(autoBrightnessEnabled,
                     mBrightnessConfiguration,
                     mLastUserSetScreenBrightness / (float) PowerManager.BRIGHTNESS_ON,
@@ -930,7 +932,7 @@
             }
 
             if (!brightnessIsTemporary) {
-                notifyBrightnessChanged(brightness, userInitiatedChange);
+                notifyBrightnessChanged(brightness, userInitiatedChange, hadUserBrightnessPoint);
             }
 
         }
@@ -1469,13 +1471,19 @@
         return true;
     }
 
-    private void notifyBrightnessChanged(int brightness, boolean userInitiated) {
+    private void notifyBrightnessChanged(int brightness, boolean userInitiated,
+            boolean hadUserDataPoint) {
         final float brightnessInNits = convertToNits(brightness);
-        if (brightnessInNits >= 0.0f) {
+        if (brightnessInNits >= 0.0f && mAutomaticBrightnessController != null) {
             // We only want to track changes on devices that can actually map the display backlight
             // values into a physical brightness unit since the value provided by the API is in
             // nits and not using the arbitrary backlight units.
-            mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated);
+            final float powerFactor = mPowerRequest.lowPowerMode
+                    ? mPowerRequest.screenLowPowerBrightnessFactor
+                    : 1.0f;
+            mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
+                    powerFactor, hadUserDataPoint,
+                    mAutomaticBrightnessController.isDefaultConfig());
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index edc7d74..da8f8b3 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -30,7 +30,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.database.ContentObserver;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.display.BrightnessChangeEvent;
@@ -195,7 +194,9 @@
         mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
 
         final int systemUpdatedBrightness = 20;
-        notifyBrightnessChanged(mTracker, systemUpdatedBrightness, false /*userInitiated*/);
+        notifyBrightnessChanged(mTracker, systemUpdatedBrightness, false /*userInitiated*/,
+                0.5f /*powerBrightnessFactor(*/, false /*isUserSetBrightness*/,
+                false /*isDefaultBrightnessConfig*/);
         List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
         // No events because we filtered out our change.
         assertEquals(0, events.size());
@@ -285,7 +286,8 @@
                 + "lastNits=\"32.333\" "
                 + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
                 + "lux=\"32.2,31.1\" luxTimestamps=\""
-                + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
+                + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\""
+                + "defaultConfig=\"true\" powerSaveFactor=\"0.5\" userPoint=\"true\" />"
                 + "<event nits=\"71\" timestamp=\""
                 + Long.toString(someTimeAgo) + "\" packageName=\""
                 + "com.android.anapp\" user=\"11\" "
@@ -315,6 +317,9 @@
         assertFalse(event.nightMode);
         assertEquals(1.0f, event.batteryLevel, FLOAT_DELTA);
         assertEquals("com.example.app", event.packageName);
+        assertTrue(event.isDefaultBrightnessConfig);
+        assertEquals(0.5f, event.powerBrightnessFactor, FLOAT_DELTA);
+        assertTrue(event.isUserSetBrightness);
 
         events = tracker.getEvents(1, true).getList();
         assertEquals(1, events.size());
@@ -329,6 +334,10 @@
         assertEquals(3235, event.colorTemperature);
         assertEquals(0.5f, event.batteryLevel, FLOAT_DELTA);
         assertEquals("com.android.anapp", event.packageName);
+        // Not present in the event so default to false.
+        assertFalse(event.isDefaultBrightnessConfig);
+        assertEquals(1.0, event.powerBrightnessFactor, FLOAT_DELTA);
+        assertFalse(event.isUserSetBrightness);
     }
 
     @Test
@@ -379,7 +388,9 @@
         mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
         final long secondSensorTime = mInjector.currentTimeMillis();
         mInjector.incrementTime(TimeUnit.SECONDS.toMillis(3));
-        notifyBrightnessChanged(mTracker, brightness);
+        notifyBrightnessChanged(mTracker, brightness, true /*userInitiated*/,
+                0.5f /*powerPolicyDim(*/, true /*hasUserBrightnessPoints*/,
+                false /*isDefaultBrightnessConfig*/);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         mTracker.writeEventsLocked(baos);
         mTracker.stop();
@@ -399,6 +410,9 @@
         assertEquals(0.3, event.batteryLevel, FLOAT_DELTA);
         assertTrue(event.nightMode);
         assertEquals(3339, event.colorTemperature);
+        assertEquals(0.5f, event.powerBrightnessFactor, FLOAT_DELTA);
+        assertTrue(event.isUserSetBrightness);
+        assertFalse(event.isDefaultBrightnessConfig);
     }
 
     @Test
@@ -539,12 +553,16 @@
     }
 
     private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness) {
-        notifyBrightnessChanged(tracker, brightness, true /*userInitiated*/);
+        notifyBrightnessChanged(tracker, brightness, true /*userInitiated*/,
+                1.0f /*powerBrightnessFactor*/, false /*isUserSetBrightness*/,
+                false /*isDefaultBrightnessConfig*/);
     }
 
     private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
-            boolean userInitiated) {
-        tracker.notifyBrightnessChanged(brightness, userInitiated);
+            boolean userInitiated, float powerBrightnessFactor, boolean isUserSetBrightness,
+            boolean isDefaultBrightnessConfig) {
+        tracker.notifyBrightnessChanged(brightness, userInitiated, powerBrightnessFactor,
+                isUserSetBrightness, isDefaultBrightnessConfig);
         mInjector.waitForHandler();
     }
 
@@ -573,7 +591,6 @@
     private class TestInjector extends BrightnessTracker.Injector {
         SensorEventListener mSensorListener;
         BroadcastReceiver mBroadcastReceiver;
-        Map<String, Integer> mSystemIntSettings = new HashMap<>();
         Map<String, Integer> mSecureIntSettings = new HashMap<>();
         long mCurrentTimeMillis = System.currentTimeMillis();
         long mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();