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
17package android.hardware.display;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertNotEquals;
21import static org.junit.Assert.assertTrue;
22import static org.junit.Assert.fail;
23
24import android.os.Parcel;
25import android.support.test.filters.SmallTest;
26import android.support.test.runner.AndroidJUnit4;
27import android.util.Pair;
28
29import org.junit.Test;
30import org.junit.runner.RunWith;
31
32import java.util.Arrays;
33
34@SmallTest
35@RunWith(AndroidJUnit4.class)
36public class BrightnessConfigurationTest {
37    private static final float[] LUX_LEVELS = {
38        0f,
39        10f,
40        100f,
41    };
42
43    private static final float[] NITS_LEVELS = {
44        1f,
45        90f,
46        100f,
47    };
48
49    @Test
50    public void testSetCurveIsUnmodified() {
51        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
52        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
53        BrightnessConfiguration config = builder.build();
54        Pair<float[], float[]> curve = config.getCurve();
55        assertArrayEquals(LUX_LEVELS, curve.first, "lux");
56        assertArrayEquals(NITS_LEVELS, curve.second, "nits");
57    }
58
59    @Test(expected = IllegalArgumentException.class)
60    public void testCurveMustHaveZeroLuxPoint() {
61        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
62        float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
63        lux[0] = 1f;
64        builder.setCurve(lux, NITS_LEVELS);
65    }
66
67    @Test(expected = IllegalStateException.class)
68    public void testCurveMustBeSet() {
69        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
70        builder.build();
71    }
72
73    @Test(expected = NullPointerException.class)
74    public void testCurveMustNotHaveNullArrays() {
75        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
76        builder.setCurve(null, null);
77    }
78
79    @Test(expected = IllegalArgumentException.class)
80    public void testCurveMustNotHaveEmptyArrays() {
81        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
82        builder.setCurve(new float[0], new float[0]);
83    }
84
85    @Test
86    public void testCurveMustNotHaveArraysOfDifferentLengths() {
87        assertThrows(IllegalArgumentException.class, () -> {
88            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
89            float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length + 1);
90            lux[lux.length - 1] = lux[lux.length - 2] + 1;
91            boolean exceptionThrown = false;
92            builder.setCurve(lux, NITS_LEVELS);
93        });
94
95        assertThrows(IllegalArgumentException.class, () -> {
96            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
97            float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length + 1);
98            nits[nits.length - 1] = nits[nits.length - 2] + 1;
99            builder.setCurve(LUX_LEVELS, nits);
100        });
101    }
102
103    @Test
104    public void testCurvesMustNotContainNaN() {
105        assertThrows(IllegalArgumentException.class, () -> {
106            float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
107            lux[lux.length - 1] = Float.NaN;
108            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
109            builder.setCurve(lux, NITS_LEVELS);
110        });
111
112        assertThrows(IllegalArgumentException.class, () -> {
113            float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
114            nits[nits.length - 1] = Float.NaN;
115            BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
116            builder.setCurve(LUX_LEVELS, nits);
117        });
118    }
119
120
121    @Test
122    public void testParceledConfigIsEquivalent() {
123        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
124        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
125        BrightnessConfiguration config = builder.build();
126        Parcel p = Parcel.obtain();
127        p.writeParcelable(config, 0 /*flags*/);
128        p.setDataPosition(0);
129        BrightnessConfiguration newConfig =
130                p.readParcelable(BrightnessConfiguration.class.getClassLoader());
131        assertEquals(config, newConfig);
132    }
133
134    @Test
135    public void testEquals() {
136        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
137        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
138        BrightnessConfiguration baseConfig = builder.build();
139
140        builder = new BrightnessConfiguration.Builder();
141        builder.setCurve(LUX_LEVELS, NITS_LEVELS);
142        BrightnessConfiguration identicalConfig = builder.build();
143        assertEquals(baseConfig, identicalConfig);
144        assertEquals("hashCodes must be equal for identical configs",
145                baseConfig.hashCode(), identicalConfig.hashCode());
146
147        float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
148        lux[lux.length - 1] = lux[lux.length - 1] * 2;
149        builder = new BrightnessConfiguration.Builder();
150        builder.setCurve(lux, NITS_LEVELS);
151        BrightnessConfiguration luxDifferConfig = builder.build();
152        assertNotEquals(baseConfig, luxDifferConfig);
153
154        float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
155        nits[nits.length - 1] = nits[nits.length - 1] * 2;
156        builder = new BrightnessConfiguration.Builder();
157        builder.setCurve(LUX_LEVELS, nits);
158        BrightnessConfiguration nitsDifferConfig = builder.build();
159        assertNotEquals(baseConfig, nitsDifferConfig);
160    }
161
162    private static void assertArrayEquals(float[] expected, float[] actual, String name) {
163        assertEquals("Expected " + name + " arrays to be the same length!",
164                expected.length, actual.length);
165        for (int i = 0; i < expected.length; i++) {
166            assertEquals("Expected " + name + " arrays to be equivalent when value " + i
167                    + "differs", expected[i], actual[i], 0.01 /*tolerance*/);
168        }
169    }
170
171    private interface ExceptionRunnable {
172        void run() throws Exception;
173    }
174
175    private static void assertThrows(Class<? extends Throwable> exceptionClass,
176            ExceptionRunnable r) {
177        try {
178            r.run();
179        } catch (Throwable e) {
180            assertTrue("Expected exception type " + exceptionClass.getName() + " but got "
181                    + e.getClass().getName(), exceptionClass.isAssignableFrom(e.getClass()));
182            return;
183        }
184        fail("Expected exception type " + exceptionClass.getName()
185                + ", but no exception was thrown");
186    }
187}
188