Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6fd7d66 authored by Kenny Guy's avatar Kenny Guy
Browse files

Add an API to BrightnessConfiguration to enable colour sampling.

Default colour sampling off and add an API to enable it.

Bug: 143556482
Test: atest BrightnessTrackerTest
Test: atest BrightnessConfigurationTest
Change-Id: I955fa683d6410c7851e8f6ad503d5bfbdf0677f5
parent 1b14a1cc
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1999,6 +1999,7 @@ package android.hardware.display {
    method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int);
    method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(@NonNull String);
    method public android.util.Pair<float[],float[]> getCurve();
    method public boolean shouldCollectColorSamples();
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR;
  }
@@ -2011,6 +2012,7 @@ package android.hardware.display {
    method public int getMaxCorrectionsByCategory();
    method public int getMaxCorrectionsByPackageName();
    method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setDescription(@Nullable String);
    method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShouldCollectColorSamples(boolean);
  }
  public final class BrightnessCorrection implements android.os.Parcelable {
+2 −0
Original line number Diff line number Diff line
@@ -1018,6 +1018,7 @@ package android.hardware.display {
    method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int);
    method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(@NonNull String);
    method public android.util.Pair<float[],float[]> getCurve();
    method public boolean shouldCollectColorSamples();
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR;
  }
@@ -1030,6 +1031,7 @@ package android.hardware.display {
    method public int getMaxCorrectionsByCategory();
    method public int getMaxCorrectionsByPackageName();
    method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setDescription(@Nullable String);
    method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShouldCollectColorSamples(boolean);
  }

  public final class BrightnessCorrection implements android.os.Parcelable {
+4 −2
Original line number Diff line number Diff line
@@ -79,7 +79,8 @@ public final class BrightnessChangeEvent implements Parcelable {
    /**
     * Histogram counting how many times a pixel of a given value was displayed onscreen for the
     * Value component of HSV if the device supports color sampling, if the device does not support
     * color sampling the value will be null.
     * color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is false the
     * value will be null.
     *
     * The buckets of the histogram are evenly weighted, the number of buckets is device specific.
     * The units are in pixels * milliseconds, with 1 pixel millisecond being 1 pixel displayed
@@ -94,7 +95,8 @@ public final class BrightnessChangeEvent implements Parcelable {

    /**
     * How many milliseconds of data are contained in the colorValueBuckets, if the device does
     * not support color sampling the value will be 0L.
     * not support color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is
     * false the value will be 0L.
     *
     * {@see #colorValueBuckets}
     */
+49 −5
Original line number Diff line number Diff line
@@ -49,26 +49,31 @@ public final class BrightnessConfiguration implements Parcelable {
    private static final String TAG_BRIGHTNESS_POINT = "brightness-point";
    private static final String TAG_BRIGHTNESS_CORRECTIONS = "brightness-corrections";
    private static final String TAG_BRIGHTNESS_CORRECTION = "brightness-correction";
    private static final String TAG_BRIGHTNESS_PARAMS = "brightness-params";
    private static final String ATTR_LUX = "lux";
    private static final String ATTR_NITS = "nits";
    private static final String ATTR_DESCRIPTION = "description";
    private static final String ATTR_PACKAGE_NAME = "package-name";
    private static final String ATTR_CATEGORY = "category";
    private static final String ATTR_COLLECT_COLOR = "collect-color";

    private final float[] mLux;
    private final float[] mNits;
    private final Map<String, BrightnessCorrection> mCorrectionsByPackageName;
    private final Map<Integer, BrightnessCorrection> mCorrectionsByCategory;
    private final String mDescription;
    private final boolean mShouldCollectColorSamples;

    private BrightnessConfiguration(float[] lux, float[] nits,
            Map<String, BrightnessCorrection> correctionsByPackageName,
            Map<Integer, BrightnessCorrection> correctionsByCategory, String description) {
            Map<Integer, BrightnessCorrection> correctionsByCategory, String description,
            boolean shouldCollectColorSamples) {
        mLux = lux;
        mNits = nits;
        mCorrectionsByPackageName = correctionsByPackageName;
        mCorrectionsByCategory = correctionsByCategory;
        mDescription = description;
        mShouldCollectColorSamples = shouldCollectColorSamples;
    }

    /**
@@ -119,6 +124,14 @@ public final class BrightnessConfiguration implements Parcelable {
        return mDescription;
    }

    /**
     * Returns whether color samples should be collected in
     * {@link BrightnessChangeEvent#colorValueBuckets}.
     */
    public boolean shouldCollectColorSamples() {
        return mShouldCollectColorSamples;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeFloatArray(mLux);
@@ -138,6 +151,7 @@ public final class BrightnessConfiguration implements Parcelable {
            correction.writeToParcel(dest, flags);
        }
        dest.writeString(mDescription);
        dest.writeBoolean(mShouldCollectColorSamples);
    }

    @Override
@@ -167,6 +181,7 @@ public final class BrightnessConfiguration implements Parcelable {
        if (mDescription != null) {
            sb.append(mDescription);
        }
        sb.append(", shouldCollectColorSamples = " + mShouldCollectColorSamples);
        sb.append("'}");
        return sb.toString();
    }
@@ -181,6 +196,7 @@ public final class BrightnessConfiguration implements Parcelable {
        if (mDescription != null) {
            result = result * 31 + mDescription.hashCode();
        }
        result = result * 31 + Boolean.hashCode(mShouldCollectColorSamples);
        return result;
    }

@@ -196,7 +212,8 @@ public final class BrightnessConfiguration implements Parcelable {
        return Arrays.equals(mLux, other.mLux) && Arrays.equals(mNits, other.mNits)
                && mCorrectionsByPackageName.equals(other.mCorrectionsByPackageName)
                && mCorrectionsByCategory.equals(other.mCorrectionsByCategory)
                && Objects.equals(mDescription, other.mDescription);
                && Objects.equals(mDescription, other.mDescription)
                && mShouldCollectColorSamples == other.mShouldCollectColorSamples;
    }

    public static final @android.annotation.NonNull Creator<BrightnessConfiguration> CREATOR =
@@ -224,6 +241,8 @@ public final class BrightnessConfiguration implements Parcelable {

            final String description = in.readString();
            builder.setDescription(description);
            final boolean shouldCollectColorSamples = in.readBoolean();
            builder.setShouldCollectColorSamples(shouldCollectColorSamples);
            return builder.build();
        }

@@ -252,6 +271,7 @@ public final class BrightnessConfiguration implements Parcelable {
            serializer.endTag(null, TAG_BRIGHTNESS_POINT);
        }
        serializer.endTag(null, TAG_BRIGHTNESS_CURVE);

        serializer.startTag(null, TAG_BRIGHTNESS_CORRECTIONS);
        for (Map.Entry<String, BrightnessCorrection> entry :
                mCorrectionsByPackageName.entrySet()) {
@@ -271,6 +291,12 @@ public final class BrightnessConfiguration implements Parcelable {
            serializer.endTag(null, TAG_BRIGHTNESS_CORRECTION);
        }
        serializer.endTag(null, TAG_BRIGHTNESS_CORRECTIONS);

        serializer.startTag(null, TAG_BRIGHTNESS_PARAMS);
        if (mShouldCollectColorSamples) {
            serializer.attribute(null, ATTR_COLLECT_COLOR, Boolean.toString(true));
        }
        serializer.endTag(null, TAG_BRIGHTNESS_PARAMS);
    }

    /**
@@ -293,6 +319,7 @@ public final class BrightnessConfiguration implements Parcelable {
        List<Float> nitsList = new ArrayList<>();
        Map<String, BrightnessCorrection> correctionsByPackageName = new HashMap<>();
        Map<Integer, BrightnessCorrection> correctionsByCategory = new HashMap<>();
        boolean shouldCollectColorSamples = false;
        final int configDepth = parser.getDepth();
        while (XmlUtils.nextElementWithin(parser, configDepth)) {
            if (TAG_BRIGHTNESS_CURVE.equals(parser.getName())) {
@@ -307,8 +334,7 @@ public final class BrightnessConfiguration implements Parcelable {
                    luxList.add(lux);
                    nitsList.add(nits);
                }
            }
            if (TAG_BRIGHTNESS_CORRECTIONS.equals(parser.getName())) {
            } else if (TAG_BRIGHTNESS_CORRECTIONS.equals(parser.getName())) {
                final int correctionsDepth = parser.getDepth();
                while (XmlUtils.nextElementWithin(parser, correctionsDepth)) {
                    if (!TAG_BRIGHTNESS_CORRECTION.equals(parser.getName())) {
@@ -328,6 +354,9 @@ public final class BrightnessConfiguration implements Parcelable {
                        }
                    }
                }
            } else if (TAG_BRIGHTNESS_PARAMS.equals(parser.getName())) {
                shouldCollectColorSamples =
                        Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_COLLECT_COLOR));
            }
        }
        final int n = luxList.size();
@@ -350,6 +379,7 @@ public final class BrightnessConfiguration implements Parcelable {
            final BrightnessCorrection correction = entry.getValue();
            builder.addCorrectionByCategory(category, correction);
        }
        builder.setShouldCollectColorSamples(shouldCollectColorSamples);
        return builder.build();
    }

@@ -374,6 +404,7 @@ public final class BrightnessConfiguration implements Parcelable {
        private Map<String, BrightnessCorrection> mCorrectionsByPackageName;
        private Map<Integer, BrightnessCorrection> mCorrectionsByCategory;
        private String mDescription;
        private boolean mShouldCollectColorSamples;

        /**
         * Constructs the builder with the control points for the brightness curve.
@@ -497,6 +528,19 @@ public final class BrightnessConfiguration implements Parcelable {
            return this;
        }

        /**
         * Control whether screen color samples should be returned in
         * {@link BrightnessChangeEvent#colorValueBuckets} if supported by the device.
         *
         * @param shouldCollectColorSamples true if color samples should be collected.
         * @return
         */
        @NonNull
        public Builder setShouldCollectColorSamples(boolean shouldCollectColorSamples) {
            mShouldCollectColorSamples = shouldCollectColorSamples;
            return this;
        }

        /**
         * Builds the {@link BrightnessConfiguration}.
         */
@@ -506,7 +550,7 @@ public final class BrightnessConfiguration implements Parcelable {
                throw new IllegalStateException("A curve must be set!");
            }
            return new BrightnessConfiguration(mCurveLux, mCurveNits, mCorrectionsByPackageName,
                    mCorrectionsByCategory, mDescription);
                    mCorrectionsByCategory, mDescription, mShouldCollectColorSamples);
        }

        private static void checkMonotonic(float[] vals, boolean strictlyIncreasing, String name) {
+76 −2
Original line number Diff line number Diff line
@@ -23,13 +23,23 @@ import static org.junit.Assert.fail;

import android.os.Parcel;
import android.util.Pair;
import android.util.Xml;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.internal.util.FastXmlSerializer;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

@SmallTest
@@ -104,11 +114,15 @@ public class BrightnessConfigurationTest {
        });
    }


    @Test
    public void testParceledConfigIsEquivalent() {
        BrightnessConfiguration.Builder builder =
                new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
        builder.setShouldCollectColorSamples(true);
        builder.addCorrectionByCategory(3,
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        builder.addCorrectionByPackageName("a.package.name",
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        BrightnessConfiguration config = builder.build();
        Parcel p = Parcel.obtain();
        p.writeParcelable(config, 0 /*flags*/);
@@ -118,13 +132,50 @@ public class BrightnessConfigurationTest {
        assertEquals(config, newConfig);
    }

    @Test
    public void testWriteReadXml() throws IOException, XmlPullParserException {
        BrightnessConfiguration.Builder builder =
                new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
        builder.setShouldCollectColorSamples(true);
        builder.addCorrectionByCategory(3,
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        builder.addCorrectionByPackageName("a.package.name",
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        BrightnessConfiguration config = builder.build();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        XmlSerializer out = new FastXmlSerializer();
        out.setOutput(baos, StandardCharsets.UTF_8.name());
        out.startDocument(null, true);
        config.saveToXml(out);
        out.endDocument();
        baos.flush();

        ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(input, StandardCharsets.UTF_8.name());
        BrightnessConfiguration loadedConfig = BrightnessConfiguration.loadFromXml(parser);

        assertEquals(config, loadedConfig);
    }

    @Test
    public void testEquals() {
        BrightnessConfiguration.Builder builder =
                new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
        builder.setShouldCollectColorSamples(true);
        builder.addCorrectionByCategory(3,
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        builder.addCorrectionByPackageName("a.package.name",
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        BrightnessConfiguration baseConfig = builder.build();

        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
        builder.setShouldCollectColorSamples(true);
        builder.addCorrectionByCategory(3,
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        builder.addCorrectionByPackageName("a.package.name",
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        BrightnessConfiguration identicalConfig = builder.build();
        assertEquals(baseConfig, identicalConfig);
        assertEquals("hashCodes must be equal for identical configs",
@@ -133,14 +184,37 @@ public class BrightnessConfigurationTest {
        float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
        lux[lux.length - 1] = lux[lux.length - 1] * 2;
        builder = new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
        builder.setShouldCollectColorSamples(true);
        builder.addCorrectionByCategory(3,
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        builder.addCorrectionByPackageName("a.package.name",
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        BrightnessConfiguration luxDifferConfig = builder.build();
        assertNotEquals(baseConfig, luxDifferConfig);

        float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
        nits[nits.length - 1] = nits[nits.length - 1] * 2;
        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
        builder.setShouldCollectColorSamples(true);
        builder.addCorrectionByCategory(3,
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        builder.addCorrectionByPackageName("a.package.name",
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        BrightnessConfiguration nitsDifferConfig = builder.build();
        assertNotEquals(baseConfig, nitsDifferConfig);

        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
        builder.addCorrectionByCategory(3,
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        builder.addCorrectionByPackageName("a.package.name",
                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
        BrightnessConfiguration colorCollectionDiffers = builder.build();
        assertNotEquals(baseConfig, colorCollectionDiffers);

        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
        builder.setShouldCollectColorSamples(true);
        BrightnessConfiguration correctionsDiffer = builder.build();
        assertNotEquals(baseConfig, correctionsDiffer);
    }

    private static void assertArrayEquals(float[] expected, float[] actual, String name) {
Loading