Home | History | Annotate | Download | only in display
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.hardware.display;
     18 
     19 import android.annotation.Nullable;
     20 import android.annotation.SystemApi;
     21 import android.annotation.TestApi;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 import android.util.Pair;
     25 
     26 import com.android.internal.util.Preconditions;
     27 
     28 import java.util.Arrays;
     29 import java.util.Objects;
     30 
     31 /** @hide */
     32 @SystemApi
     33 @TestApi
     34 public final class BrightnessConfiguration implements Parcelable {
     35     private final float[] mLux;
     36     private final float[] mNits;
     37     private final String mDescription;
     38 
     39     private BrightnessConfiguration(float[] lux, float[] nits, String description) {
     40         mLux = lux;
     41         mNits = nits;
     42         mDescription = description;
     43     }
     44 
     45     /**
     46      * Gets the base brightness as curve.
     47      *
     48      * The curve is returned as a pair of float arrays, the first representing all of the lux
     49      * points of the brightness curve and the second representing all of the nits values of the
     50      * brightness curve.
     51      *
     52      * @return the control points for the brightness curve.
     53      */
     54     public Pair<float[], float[]> getCurve() {
     55         return Pair.create(Arrays.copyOf(mLux, mLux.length), Arrays.copyOf(mNits, mNits.length));
     56     }
     57 
     58     /**
     59      * Returns description string.
     60      * @hide
     61      */
     62     public String getDescription() {
     63         return mDescription;
     64     }
     65 
     66     @Override
     67     public void writeToParcel(Parcel dest, int flags) {
     68         dest.writeFloatArray(mLux);
     69         dest.writeFloatArray(mNits);
     70         dest.writeString(mDescription);
     71     }
     72 
     73     @Override
     74     public int describeContents() {
     75         return 0;
     76     }
     77 
     78     @Override
     79     public String toString() {
     80         StringBuilder sb = new StringBuilder("BrightnessConfiguration{[");
     81         final int size = mLux.length;
     82         for (int i = 0; i < size; i++) {
     83             if (i != 0) {
     84                 sb.append(", ");
     85             }
     86             sb.append("(").append(mLux[i]).append(", ").append(mNits[i]).append(")");
     87         }
     88         sb.append("], '");
     89         if (mDescription != null) {
     90             sb.append(mDescription);
     91         }
     92         sb.append("'}");
     93         return sb.toString();
     94     }
     95 
     96     @Override
     97     public int hashCode() {
     98         int result = 1;
     99         result = result * 31 + Arrays.hashCode(mLux);
    100         result = result * 31 + Arrays.hashCode(mNits);
    101         if (mDescription != null) {
    102             result = result * 31 + mDescription.hashCode();
    103         }
    104         return result;
    105     }
    106 
    107     @Override
    108     public boolean equals(Object o) {
    109         if (o == this) {
    110             return true;
    111         }
    112         if (!(o instanceof BrightnessConfiguration)) {
    113             return false;
    114         }
    115         final BrightnessConfiguration other = (BrightnessConfiguration) o;
    116         return Arrays.equals(mLux, other.mLux) && Arrays.equals(mNits, other.mNits)
    117                 && Objects.equals(mDescription, other.mDescription);
    118     }
    119 
    120     public static final Creator<BrightnessConfiguration> CREATOR =
    121             new Creator<BrightnessConfiguration>() {
    122         public BrightnessConfiguration createFromParcel(Parcel in) {
    123             float[] lux = in.createFloatArray();
    124             float[] nits = in.createFloatArray();
    125             Builder builder = new Builder(lux, nits);
    126             builder.setDescription(in.readString());
    127             return builder.build();
    128         }
    129 
    130         public BrightnessConfiguration[] newArray(int size) {
    131             return new BrightnessConfiguration[size];
    132         }
    133     };
    134 
    135     /**
    136      * A builder class for {@link BrightnessConfiguration}s.
    137      */
    138     public static class Builder {
    139         private float[] mCurveLux;
    140         private float[] mCurveNits;
    141         private String mDescription;
    142 
    143         /**
    144          * STOPSHIP remove when app has stopped using this.
    145          * @hide
    146          */
    147         public Builder() {
    148         }
    149 
    150         /**
    151          * Constructs the builder with the control points for the brightness curve.
    152          *
    153          * Brightness curves must have strictly increasing ambient brightness values in lux and
    154          * monotonically increasing display brightness values in nits. In addition, the initial
    155          * control point must be 0 lux.
    156          *
    157          * @throws IllegalArgumentException if the initial control point is not at 0 lux.
    158          * @throws IllegalArgumentException if the lux levels are not strictly increasing.
    159          * @throws IllegalArgumentException if the nit levels are not monotonically increasing.
    160          */
    161         public Builder(float[] lux, float[] nits) {
    162             setCurve(lux, nits);
    163         }
    164 
    165         /**
    166          * Sets the control points for the brightness curve.
    167          *
    168          * Brightness curves must have strictly increasing ambient brightness values in lux and
    169          * monotonically increasing display brightness values in nits. In addition, the initial
    170          * control point must be 0 lux.
    171          *
    172          * @throws IllegalArgumentException if the initial control point is not at 0 lux.
    173          * @throws IllegalArgumentException if the lux levels are not strictly increasing.
    174          * @throws IllegalArgumentException if the nit levels are not monotonically increasing.
    175          *
    176          * STOPSHIP remove when app has stopped using this.
    177          * @hide
    178          */
    179         public Builder setCurve(float[] lux, float[] nits) {
    180             Preconditions.checkNotNull(lux);
    181             Preconditions.checkNotNull(nits);
    182             if (lux.length == 0 || nits.length == 0) {
    183                 throw new IllegalArgumentException("Lux and nits arrays must not be empty");
    184             }
    185             if (lux.length != nits.length) {
    186                 throw new IllegalArgumentException("Lux and nits arrays must be the same length");
    187             }
    188             if (lux[0] != 0) {
    189                 throw new IllegalArgumentException("Initial control point must be for 0 lux");
    190             }
    191             Preconditions.checkArrayElementsInRange(lux, 0, Float.MAX_VALUE, "lux");
    192             Preconditions.checkArrayElementsInRange(nits, 0, Float.MAX_VALUE, "nits");
    193             checkMonotonic(lux, true/*strictly increasing*/, "lux");
    194             checkMonotonic(nits, false /*strictly increasing*/, "nits");
    195             mCurveLux = lux;
    196             mCurveNits = nits;
    197             return this;
    198         }
    199 
    200         /**
    201          * Set description of the brightness curve.
    202          *
    203          * @param description brief text describing the curve pushed. It maybe truncated
    204          *                    and will not be displayed in the UI
    205          */
    206         public Builder setDescription(@Nullable String description) {
    207             mDescription = description;
    208             return this;
    209         }
    210 
    211         /**
    212          * Builds the {@link BrightnessConfiguration}.
    213          *
    214          * A brightness curve <b>must</b> be set before calling this.
    215          */
    216         public BrightnessConfiguration build() {
    217             if (mCurveLux == null || mCurveNits == null) {
    218                 throw new IllegalStateException("A curve must be set!");
    219             }
    220             return new BrightnessConfiguration(mCurveLux, mCurveNits, mDescription);
    221         }
    222 
    223         private static void checkMonotonic(float[] vals, boolean strictlyIncreasing, String name) {
    224             if (vals.length <= 1) {
    225                 return;
    226             }
    227             float prev = vals[0];
    228             for (int i = 1; i < vals.length; i++) {
    229                 if (prev > vals[i] || prev == vals[i] && strictlyIncreasing) {
    230                     String condition = strictlyIncreasing ? "strictly increasing" : "monotonic";
    231                     throw new IllegalArgumentException(name + " values must be " + condition);
    232                 }
    233                 prev = vals[i];
    234             }
    235         }
    236     }
    237 }
    238