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

Commit e3a08ab5 authored by Peeyush Agarwal's avatar Peeyush Agarwal
Browse files

Make ambient brightness day stats a system API

Test: atest android.hardware.display.AmbientBrightnessDayStatsTest
Bug: 69406079
Change-Id: I83f476f22a2100d324862cbea2a139eababa9d4e
parent 6464c8d2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1140,6 +1140,15 @@ package android.hardware.camera2.params {

package android.hardware.display {

  public final class AmbientBrightnessDayStats implements android.os.Parcelable {
    method public int describeContents();
    method public float[] getBucketBoundaries();
    method public java.time.LocalDate getLocalDate();
    method public float[] getStats();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.hardware.display.AmbientBrightnessDayStats> CREATOR;
  }

  public final class BrightnessChangeEvent implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
+9 −0
Original line number Diff line number Diff line
@@ -298,6 +298,15 @@ package android.hardware.camera2 {

package android.hardware.display {

  public final class AmbientBrightnessDayStats implements android.os.Parcelable {
    method public int describeContents();
    method public float[] getBucketBoundaries();
    method public java.time.LocalDate getLocalDate();
    method public float[] getStats();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.hardware.display.AmbientBrightnessDayStats> CREATOR;
  }

  public final class BrightnessChangeEvent implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
+30 −15
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.hardware.display;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;

@@ -28,11 +30,12 @@ import java.util.Arrays;
/**
 * AmbientBrightnessDayStats stores and manipulates brightness stats over a single day.
 * {@see DisplayManager.getAmbientBrightnessStats()}
 * TODO: Make this system API
 *
 * @hide
 */
public class AmbientBrightnessDayStats implements Parcelable {
@SystemApi
@TestApi
public final class AmbientBrightnessDayStats implements Parcelable {

    /** The localdate for which brightness stats are being tracked */
    private final LocalDate mLocalDate;
@@ -48,30 +51,30 @@ public class AmbientBrightnessDayStats implements Parcelable {
     */
    public AmbientBrightnessDayStats(@NonNull LocalDate localDate,
            @NonNull float[] bucketBoundaries) {
        Preconditions.checkNotNull(localDate);
        Preconditions.checkNotNull(bucketBoundaries);
        int numBuckets = bucketBoundaries.length;
        if (numBuckets < 1) {
            throw new IllegalArgumentException("Bucket boundaries must contain at least 1 value");
        }
        mLocalDate = localDate;
        mBucketBoundaries = bucketBoundaries;
        mStats = new float[numBuckets];
        this(localDate, bucketBoundaries, null);
    }

    /**
     * @hide
     */
    public AmbientBrightnessDayStats(@NonNull LocalDate localDate,
            @NonNull float[] bucketBoundaries, @NonNull float[] stats) {
            @NonNull float[] bucketBoundaries, float[] stats) {
        Preconditions.checkNotNull(localDate);
        Preconditions.checkNotNull(bucketBoundaries);
        Preconditions.checkNotNull(stats);
        Preconditions.checkArrayElementsInRange(bucketBoundaries, 0, Float.MAX_VALUE,
                "bucketBoundaries");
        if (bucketBoundaries.length < 1) {
            throw new IllegalArgumentException("Bucket boundaries must contain at least 1 value");
        }
        checkSorted(bucketBoundaries);
        if (stats == null) {
            stats = new float[bucketBoundaries.length];
        } else {
            Preconditions.checkArrayElementsInRange(stats, 0, Float.MAX_VALUE, "stats");
            if (bucketBoundaries.length != stats.length) {
            throw new IllegalArgumentException("Bucket boundaries and stats must be of same size.");
                throw new IllegalArgumentException(
                        "Bucket boundaries and stats must be of same size.");
            }
        }
        mLocalDate = localDate;
        mBucketBoundaries = bucketBoundaries;
@@ -193,4 +196,16 @@ public class AmbientBrightnessDayStats implements Parcelable {
        }
        return low;
    }

    private static void checkSorted(float[] values) {
        if (values.length <= 1) {
            return;
        }
        float prevValue = values[0];
        for (int i = 1; i < values.length; i++) {
            Preconditions.checkState(prevValue < values[i]);
            prevValue = values[i];
        }
        return;
    }
}
+102 −34
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

package android.hardware.display;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.os.Parcel;
import android.support.test.filters.SmallTest;
@@ -27,20 +30,53 @@ import org.junit.Test;
import org.junit.runner.RunWith;

import java.time.LocalDate;
import java.util.Arrays;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class AmbientBrightnessDayStatsTest {

    private static final LocalDate LOCAL_DATE = LocalDate.now();
    private static final float[] BUCKET_BOUNDARIES = {0, 1, 10, 100};
    private static final float[] STATS = {1.3f, 2.6f, 5.8f, 10};

    @Test
    public void testParamsMustNotBeNull() {
        assertThrows(NullPointerException.class,
                () -> new AmbientBrightnessDayStats(null, BUCKET_BOUNDARIES));

        assertThrows(NullPointerException.class,
                () -> new AmbientBrightnessDayStats(LOCAL_DATE, null));

        assertThrows(NullPointerException.class,
                () -> new AmbientBrightnessDayStats(null, BUCKET_BOUNDARIES, STATS));

        assertThrows(NullPointerException.class,
                () -> new AmbientBrightnessDayStats(LOCAL_DATE, null, STATS));
    }

    @Test(expected = IllegalArgumentException.class)
    public void testBucketBoundariesMustNotBeEmpty() {
        new AmbientBrightnessDayStats(LocalDate.now(), new float[]{});
    }

    @Test(expected = IllegalArgumentException.class)
    public void testStatsAndBoundariesMustHaveSameLength() {
        float[] stats = Arrays.copyOf(STATS, STATS.length + 1);
        stats[stats.length - 1] = 0;
        new AmbientBrightnessDayStats(LOCAL_DATE, BUCKET_BOUNDARIES, stats);
    }

    @Test
    public void testAmbientBrightnessDayStatsAdd() {
        AmbientBrightnessDayStats dayStats = new AmbientBrightnessDayStats(LocalDate.now(),
                new float[]{0, 1, 10, 100});
        AmbientBrightnessDayStats dayStats = new AmbientBrightnessDayStats(LOCAL_DATE,
                BUCKET_BOUNDARIES);
        dayStats.log(0, 1);
        dayStats.log(0.5f, 1.5f);
        dayStats.log(50, 12.5f);
        dayStats.log(2000, 1.24f);
        dayStats.log(-10, 0.5f);
        assertEquals(4, dayStats.getStats().length);
        assertEquals(2.5f, dayStats.getStats()[0], 0);
        assertEquals(0, dayStats.getStats()[1], 0);
        assertEquals(12.5f, dayStats.getStats()[2], 0);
@@ -48,38 +84,12 @@ public class AmbientBrightnessDayStatsTest {
    }

    @Test
    public void testAmbientBrightnessDayStatsEquals() {
        LocalDate today = LocalDate.now();
        AmbientBrightnessDayStats dayStats1 = new AmbientBrightnessDayStats(today,
                new float[]{0, 1, 10, 100});
        AmbientBrightnessDayStats dayStats2 = new AmbientBrightnessDayStats(today,
                new float[]{0, 1, 10, 100}, new float[4]);
        AmbientBrightnessDayStats dayStats3 = new AmbientBrightnessDayStats(today,
                new float[]{0, 1, 10, 100}, new float[]{1, 3, 5, 7});
        AmbientBrightnessDayStats dayStats4 = new AmbientBrightnessDayStats(today,
                new float[]{0, 1, 10, 100}, new float[]{1, 3, 5, 0});
        assertEquals(dayStats1, dayStats2);
        assertEquals(dayStats1.hashCode(), dayStats2.hashCode());
        assertNotEquals(dayStats1, dayStats3);
        assertNotEquals(dayStats1.hashCode(), dayStats3.hashCode());
        dayStats4.log(100, 7);
        assertEquals(dayStats3, dayStats4);
        assertEquals(dayStats3.hashCode(), dayStats4.hashCode());
    }

    @Test
    public void testAmbientBrightnessDayStatsIncorrectInit() {
        try {
            new AmbientBrightnessDayStats(LocalDate.now(), new float[]{1, 10, 100},
                    new float[]{1, 5, 6, 7});
        } catch (IllegalArgumentException e) {
            // Expected
        }
        try {
            new AmbientBrightnessDayStats(LocalDate.now(), new float[]{});
        } catch (IllegalArgumentException e) {
            // Expected
        }
    public void testGetters() {
        AmbientBrightnessDayStats dayStats = new AmbientBrightnessDayStats(LOCAL_DATE,
                BUCKET_BOUNDARIES, STATS);
        assertEquals(LOCAL_DATE, dayStats.getLocalDate());
        assertArrayEquals(BUCKET_BOUNDARIES, dayStats.getBucketBoundaries(), 0);
        assertArrayEquals(STATS, dayStats.getStats(), 0);
    }

    @Test
@@ -100,4 +110,62 @@ public class AmbientBrightnessDayStatsTest {
                parcel);
        assertEquals(stats, statsAgain);
    }

    @Test
    public void testAmbientBrightnessDayStatsEquals() {
        AmbientBrightnessDayStats emptyDayStats = new AmbientBrightnessDayStats(LOCAL_DATE,
                BUCKET_BOUNDARIES);
        AmbientBrightnessDayStats identicalEmptyDayStats = new AmbientBrightnessDayStats(LOCAL_DATE,
                BUCKET_BOUNDARIES, new float[BUCKET_BOUNDARIES.length]);
        assertEquals(emptyDayStats, identicalEmptyDayStats);
        assertEquals(emptyDayStats.hashCode(), identicalEmptyDayStats.hashCode());

        AmbientBrightnessDayStats dayStats = new AmbientBrightnessDayStats(LOCAL_DATE,
                BUCKET_BOUNDARIES, STATS);
        AmbientBrightnessDayStats identicalDayStats = new AmbientBrightnessDayStats(LOCAL_DATE,
                BUCKET_BOUNDARIES, STATS);
        assertEquals(dayStats, identicalDayStats);
        assertEquals(dayStats.hashCode(), identicalDayStats.hashCode());

        assertNotEquals(emptyDayStats, dayStats);
        assertNotEquals(emptyDayStats.hashCode(), dayStats.hashCode());

        AmbientBrightnessDayStats differentDateDayStats = new AmbientBrightnessDayStats(
                LOCAL_DATE.plusDays(1), BUCKET_BOUNDARIES, STATS);
        assertNotEquals(dayStats, differentDateDayStats);
        assertNotEquals(dayStats.hashCode(), differentDateDayStats.hashCode());

        float[] differentStats = Arrays.copyOf(STATS, STATS.length);
        differentStats[differentStats.length - 1] += 5f;
        AmbientBrightnessDayStats differentStatsDayStats = new AmbientBrightnessDayStats(LOCAL_DATE,
                BUCKET_BOUNDARIES, differentStats);
        assertNotEquals(dayStats, differentDateDayStats);
        assertNotEquals(dayStats.hashCode(), differentStatsDayStats.hashCode());

        float[] differentBucketBoundaries = Arrays.copyOf(BUCKET_BOUNDARIES,
                BUCKET_BOUNDARIES.length);
        differentBucketBoundaries[differentBucketBoundaries.length - 1] += 100f;
        AmbientBrightnessDayStats differentBoundariesDayStats = new AmbientBrightnessDayStats(
                LOCAL_DATE, differentBucketBoundaries, STATS);
        assertNotEquals(dayStats, differentBoundariesDayStats);
        assertNotEquals(dayStats.hashCode(), differentBoundariesDayStats.hashCode());
    }

    private interface ExceptionRunnable {
        void run() throws Exception;
    }

    private static void assertThrows(Class<? extends Throwable> exceptionClass,
            ExceptionRunnable r) {
        try {
            r.run();
        } catch (Throwable e) {
            assertTrue("Expected exception type " + exceptionClass.getName() + " but got "
                    + e.getClass().getName(), exceptionClass.isAssignableFrom(e.getClass()));
            return;
        }
        fail("Expected exception type " + exceptionClass.getName()
                + ", but no exception was thrown");
    }

}