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

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

Add Ambient Brightness tracker API

Test: atest com.android.server.display.AmbientBrightnessStatsTrackerTest
&& atest android.hardware.display.AmbientBrightnessDayStatsTest
Bug: 69406079
Change-Id: I4b13c6bdd3e9fdded8086371f46dba0fd3102b98
parent 150cca87
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.display;

parcelable AmbientBrightnessDayStats;
+196 −0
Original line number Diff line number Diff line
/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.display;

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

import com.android.internal.util.Preconditions;

import java.time.LocalDate;
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 {

    /** The localdate for which brightness stats are being tracked */
    private final LocalDate mLocalDate;

    /** Ambient brightness values for creating bucket boundaries from */
    private final float[] mBucketBoundaries;

    /** Stats of how much time (in seconds) was spent in each of the buckets */
    private final float[] mStats;

    /**
     * @hide
     */
    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];
    }

    /**
     * @hide
     */
    public AmbientBrightnessDayStats(@NonNull LocalDate localDate,
            @NonNull float[] bucketBoundaries, @NonNull float[] stats) {
        Preconditions.checkNotNull(localDate);
        Preconditions.checkNotNull(bucketBoundaries);
        Preconditions.checkNotNull(stats);
        if (bucketBoundaries.length < 1) {
            throw new IllegalArgumentException("Bucket boundaries must contain at least 1 value");
        }
        if (bucketBoundaries.length != stats.length) {
            throw new IllegalArgumentException("Bucket boundaries and stats must be of same size.");
        }
        mLocalDate = localDate;
        mBucketBoundaries = bucketBoundaries;
        mStats = stats;
    }

    public LocalDate getLocalDate() {
        return mLocalDate;
    }

    public float[] getStats() {
        return mStats;
    }

    public float[] getBucketBoundaries() {
        return mBucketBoundaries;
    }

    private AmbientBrightnessDayStats(Parcel source) {
        mLocalDate = LocalDate.parse(source.readString());
        mBucketBoundaries = source.createFloatArray();
        mStats = source.createFloatArray();
    }

    public static final Creator<AmbientBrightnessDayStats> CREATOR =
            new Creator<AmbientBrightnessDayStats>() {

                @Override
                public AmbientBrightnessDayStats createFromParcel(Parcel source) {
                    return new AmbientBrightnessDayStats(source);
                }

                @Override
                public AmbientBrightnessDayStats[] newArray(int size) {
                    return new AmbientBrightnessDayStats[size];
                }
            };

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        AmbientBrightnessDayStats other = (AmbientBrightnessDayStats) obj;
        return mLocalDate.equals(other.mLocalDate) && Arrays.equals(mBucketBoundaries,
                other.mBucketBoundaries) && Arrays.equals(mStats, other.mStats);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = result * prime + mLocalDate.hashCode();
        result = result * prime + Arrays.hashCode(mBucketBoundaries);
        result = result * prime + Arrays.hashCode(mStats);
        return result;
    }

    @Override
    public String toString() {
        StringBuilder bucketBoundariesString = new StringBuilder();
        StringBuilder statsString = new StringBuilder();
        for (int i = 0; i < mBucketBoundaries.length; i++) {
            if (i != 0) {
                bucketBoundariesString.append(", ");
                statsString.append(", ");
            }
            bucketBoundariesString.append(mBucketBoundaries[i]);
            statsString.append(mStats[i]);
        }
        return new StringBuilder()
                .append(mLocalDate).append(" ")
                .append("{").append(bucketBoundariesString).append("} ")
                .append("{").append(statsString).append("}").toString();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mLocalDate.toString());
        dest.writeFloatArray(mBucketBoundaries);
        dest.writeFloatArray(mStats);
    }

    /** @hide */
    public void log(float ambientBrightness, float durationSec) {
        int bucketIndex = getBucketIndex(ambientBrightness);
        if (bucketIndex >= 0) {
            mStats[bucketIndex] += durationSec;
        }
    }

    private int getBucketIndex(float ambientBrightness) {
        if (ambientBrightness < mBucketBoundaries[0]) {
            return -1;
        }
        int low = 0;
        int high = mBucketBoundaries.length - 1;
        while (low < high) {
            int mid = (low + high) / 2;
            if (mBucketBoundaries[mid] <= ambientBrightness
                    && ambientBrightness < mBucketBoundaries[mid + 1]) {
                return mid;
            } else if (mBucketBoundaries[mid] < ambientBrightness) {
                low = mid + 1;
            } else if (mBucketBoundaries[mid] > ambientBrightness) {
                high = mid - 1;
            }
        }
        return low;
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -630,6 +630,16 @@ public final class DisplayManager {
        return mGlobal.getBrightnessEvents(mContext.getOpPackageName());
    }

    /**
     * Fetch {@link AmbientBrightnessDayStats}s.
     *
     * @hide until we make it a system api
     */
    @RequiresPermission(Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS)
    public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
        return mGlobal.getAmbientBrightnessStats();
    }

    /**
     * Sets the global display brightness configuration.
     *
+15 −0
Original line number Diff line number Diff line
@@ -525,6 +525,21 @@ public final class DisplayManagerGlobal {
        }
    }

    /**
     * Retrieves ambient brightness stats.
     */
    public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
        try {
            ParceledListSlice<AmbientBrightnessDayStats> stats = mDm.getAmbientBrightnessStats();
            if (stats == null) {
                return Collections.emptyList();
            }
            return stats.getList();
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
        @Override
        public void onDisplayEvent(int displayId, int event) {
+2 −2
Original line number Diff line number Diff line
@@ -174,9 +174,9 @@ public abstract class DisplayManagerInternal {
    public abstract boolean isUidPresentOnDisplay(int uid, int displayId);

    /**
     * Persist brightness slider events.
     * Persist brightness slider events and ambient brightness stats.
     */
    public abstract void persistBrightnessSliderEvents();
    public abstract void persistBrightnessTrackerState();

    /**
     * Notifies the display manager that resource overlays have changed.
Loading