1 /*
2  * Copyright (C) 2008 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.graphics.cts;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 
24 import android.graphics.Interpolator;
25 import android.graphics.Interpolator.Result;
26 import android.os.SystemClock;
27 
28 import androidx.test.filters.SmallTest;
29 import androidx.test.runner.AndroidJUnit4;
30 
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 
34 @SmallTest
35 @RunWith(AndroidJUnit4.class)
36 public class InterpolatorTest {
37     private static final int DEFAULT_KEYFRAME_COUNT = 2;
38     private static final float TOLERANCE = 0.1f;
39 
40     @Test
testConstructor()41     public void testConstructor() {
42         Interpolator interpolator = new Interpolator(10);
43         assertEquals(10, interpolator.getValueCount());
44         assertEquals(DEFAULT_KEYFRAME_COUNT, interpolator.getKeyFrameCount());
45 
46         interpolator = new Interpolator(15, 20);
47         assertEquals(15, interpolator.getValueCount());
48         assertEquals(20, interpolator.getKeyFrameCount());
49     }
50 
51     @Test
testReset1()52     public void testReset1() {
53         final int expected = 100;
54         Interpolator interpolator = new Interpolator(10);
55         assertEquals(DEFAULT_KEYFRAME_COUNT, interpolator.getKeyFrameCount());
56         interpolator.reset(expected);
57         assertEquals(expected, interpolator.getValueCount());
58         assertEquals(DEFAULT_KEYFRAME_COUNT, interpolator.getKeyFrameCount());
59     }
60 
61     @Test
testReset2()62     public void testReset2() {
63         int expected1 = 100;
64         int expected2 = 200;
65         // new the Interpolator instance
66         Interpolator interpolator = new Interpolator(10);
67         interpolator.reset(expected1, expected2);
68         assertEquals(expected1, interpolator.getValueCount());
69         assertEquals(expected2, interpolator.getKeyFrameCount());
70     }
71 
72     @Test
testTimeToValues1()73     public void testTimeToValues1() throws InterruptedException {
74         Interpolator interpolator = new Interpolator(1);
75         assertEquals(1, interpolator.getValueCount());
76 
77         // NORMAL
78         long time = SystemClock.uptimeMillis();
79         // set key frames far enough apart so that processing time will not cause result to
80         // deviate more than TOLERANCE
81         interpolator.setKeyFrame(0, (int)(time - 10000), new float[] {1.0f});
82         interpolator.setKeyFrame(1, (int)(time + 10000), new float[] {2.0f});
83         verifyValue(1.5f, Result.NORMAL, interpolator);
84 
85         // FREEZE_START
86         interpolator.reset(1);
87         time = SystemClock.uptimeMillis();
88         interpolator.setKeyFrame(0, (int)(time + 1000), new float[] {2.0f});
89         interpolator.setKeyFrame(1, (int)(time + 2000), new float[] {3.0f});
90         verifyValue(2.0f, Result.FREEZE_START, interpolator);
91 
92         // FREEZE_END
93         interpolator.reset(1);
94         time = SystemClock.uptimeMillis();
95         interpolator.setKeyFrame(0, (int)(time - 2000), new float[] {2.0f});
96         interpolator.setKeyFrame(1, (int)(time - 1000), new float[] {3.0f});
97         verifyValue(3.0f, Result.FREEZE_END, interpolator);
98 
99         final int valueCount = 2;
100         interpolator.reset(valueCount);
101         assertEquals(valueCount, interpolator.getValueCount());
102 
103         try {
104             // value array too short
105             interpolator.timeToValues(new float[valueCount - 1]);
106             fail("should throw ArrayStoreException");
107         } catch (ArrayStoreException e) {
108             // expected
109         }
110     }
111 
112     @Test
testTimeToValues2()113     public void testTimeToValues2() {
114         Interpolator interpolator = new Interpolator(1);
115         interpolator.setKeyFrame(0, 2000, new float[] {1.0f});
116         interpolator.setKeyFrame(1, 4000, new float[] {2.0f});
117         verifyValue(1000, 1.0f, Result.FREEZE_START, interpolator);
118         verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
119         verifyValue(6000, 2.0f, Result.FREEZE_END, interpolator);
120 
121         // known bug: time argument is unsigned 32bit in graphics library
122         verifyValue(-1000, 2.0f, Result.FREEZE_END, interpolator);
123 
124         interpolator.reset(1, 3);
125         interpolator.setKeyFrame(0, 2000, new float[] {1.0f});
126         interpolator.setKeyFrame(1, 4000, new float[] {2.0f});
127         interpolator.setKeyFrame(2, 6000, new float[] {4.0f});
128         verifyValue(0, 1.0f, Result.FREEZE_START, interpolator);
129         verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
130         verifyValue(5000, 3.0f, Result.NORMAL, interpolator);
131         verifyValue(8000, 4.0f, Result.FREEZE_END, interpolator);
132 
133 
134         final int valueCount = 2;
135         final int validTime = 0;
136         interpolator.reset(valueCount);
137         assertEquals(valueCount, interpolator.getValueCount());
138         try {
139             // value array too short
140             interpolator.timeToValues(validTime, new float[valueCount - 1]);
141             fail("should throw out ArrayStoreException");
142         } catch (ArrayStoreException e) {
143             // expected
144         }
145 
146         interpolator.reset(2, 2);
147         interpolator.setKeyFrame(0, 4000, new float[] {1.0f, 1.0f});
148         interpolator.setKeyFrame(1, 6000, new float[] {2.0f, 4.0f});
149         verifyValues(2000, new float[] {1.0f, 1.0f}, Result.FREEZE_START, interpolator);
150         verifyValues(5000, new float[] {1.5f, 2.5f}, Result.NORMAL, interpolator);
151         verifyValues(8000, new float[] {2.0f, 4.0f}, Result.FREEZE_END, interpolator);
152     }
153 
154     @Test
testSetRepeatMirror()155     public void testSetRepeatMirror() {
156         Interpolator interpolator = new Interpolator(1, 3);
157         interpolator.setKeyFrame(0, 2000, new float[] {1.0f});
158         interpolator.setKeyFrame(1, 4000, new float[] {2.0f});
159         interpolator.setKeyFrame(2, 6000, new float[] {4.0f});
160 
161         verifyValue(1000, 1.0f, Result.FREEZE_START, interpolator);
162         verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
163         verifyValue(5000, 3.0f, Result.NORMAL, interpolator);
164         verifyValue(7000, 4.0f, Result.FREEZE_END, interpolator);
165 
166         // repeat once, no mirror
167         interpolator.setRepeatMirror(2, false);
168         verifyValue( 1000, 4.0f, Result.FREEZE_END, interpolator); // known bug
169         verifyValue( 3000, 1.5f, Result.NORMAL, interpolator);
170         verifyValue( 5000, 3.0f, Result.NORMAL, interpolator);
171         verifyValue( 7000, 1.5f, Result.NORMAL, interpolator);
172         verifyValue( 9000, 3.0f, Result.NORMAL, interpolator);
173         verifyValue(11000, 4.0f, Result.FREEZE_END, interpolator);
174 
175         // repeat once, mirror
176         interpolator.setRepeatMirror(2, true);
177         verifyValue( 1000, 4.0f, Result.FREEZE_END, interpolator); // known bug
178         verifyValue( 3000, 1.5f, Result.NORMAL, interpolator);
179         verifyValue( 5000, 3.0f, Result.NORMAL, interpolator);
180         verifyValue( 7000, 3.0f, Result.NORMAL, interpolator);
181         verifyValue( 9000, 1.5f, Result.NORMAL, interpolator);
182         verifyValue(11000, 4.0f, Result.FREEZE_END, interpolator);
183     }
184 
185     @Test
testSetKeyFrame()186     public void testSetKeyFrame() {
187         final float[] aZero = new float[] {0.0f};
188         final float[] aOne = new float[] {1.0f};
189 
190         Interpolator interpolator = new Interpolator(1);
191         interpolator.setKeyFrame(0, 2000, aZero);
192         interpolator.setKeyFrame(1, 4000, aOne);
193         verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
194         verifyValue(3000, 0.5f, Result.NORMAL, interpolator);
195         verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
196 
197         final float[] linearBlend = new float[] {
198                 0.0f, 0.0f, 1.0f, 1.0f
199         };
200         final float[] accelerateBlend = new float[] {
201                 // approximate circle at PI/6 and PI/3
202                 0.5f, 1.0f - 0.866f, 0.866f, 0.5f
203         };
204         final float[] decelerateBlend = new float[] {
205                 // approximate circle at PI/6 and PI/3
206                 1.0f - 0.866f, 0.5f, 0.5f, 0.866f
207         };
208 
209         // explicit linear blend should yield the same values
210         interpolator.setKeyFrame(0, 2000, aZero, linearBlend);
211         interpolator.setKeyFrame(1, 4000, aOne, linearBlend);
212         verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
213         verifyValue(3000, 0.5f, Result.NORMAL, interpolator);
214         verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
215 
216         // blend of end key frame is not used
217         interpolator.setKeyFrame(0, 2000, aZero);
218         interpolator.setKeyFrame(1, 4000, aOne, accelerateBlend);
219         verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
220         verifyValue(3000, 0.5f, Result.NORMAL, interpolator);
221         verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
222 
223         final float[] result = new float[1];
224 
225         interpolator.setKeyFrame(0, 2000, aZero, accelerateBlend);
226         interpolator.setKeyFrame(1, 4000, aOne);
227         verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
228         assertEquals(Result.NORMAL, interpolator.timeToValues(3000, result));
229         assertTrue(result[0] < 0.5f); // exact blend algorithm not known
230         verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
231 
232         interpolator.setKeyFrame(0, 2000, aZero, decelerateBlend);
233         interpolator.setKeyFrame(1, 4000, aOne);
234         verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
235         assertEquals(Result.NORMAL, interpolator.timeToValues(3000, result));
236         assertTrue(result[0] > 0.5f); // exact blend algorithm not known
237         verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
238 
239         final int validTime = 0;
240         final int valueCount = 2;
241         interpolator.reset(valueCount);
242         assertEquals(valueCount, interpolator.getValueCount());
243         try {
244             // value array too short
245             interpolator.setKeyFrame(0, validTime, new float[valueCount - 1]);
246             fail("should throw ArrayStoreException");
247         } catch (ArrayStoreException e) {
248             // expected
249         }
250 
251         try {
252             // index too small
253             interpolator.setKeyFrame(-1, validTime, new float[valueCount]);
254             fail("should throw IndexOutOfBoundsException");
255         } catch (IndexOutOfBoundsException e) {
256             // expected
257         }
258 
259         try {
260             // index too large
261             interpolator.setKeyFrame(2, validTime, new float[valueCount]);
262             fail("should throw IndexOutOfBoundsException");
263         } catch (IndexOutOfBoundsException e) {
264             // expected
265         }
266 
267         try {
268             // blend array too short
269             interpolator.setKeyFrame(0, validTime, new float[valueCount], new float[3]);
270             fail("should throw ArrayStoreException");
271         } catch (ArrayStoreException e) {
272             // expected
273         }
274 
275     }
276 
verifyValue(int time, float expected, Result expectedResult, Interpolator interpolator)277     private void verifyValue(int time, float expected, Result expectedResult,
278             Interpolator interpolator) {
279         float[] values = new float[1];
280         assertEquals(expectedResult, interpolator.timeToValues(time, values));
281         assertEquals(expected, values[0], TOLERANCE);
282     }
283 
verifyValues(int time, float[] expected, Result expectedResult, Interpolator interpolator)284     private void verifyValues(int time, float[] expected, Result expectedResult,
285             Interpolator interpolator) {
286         float[] values = new float[expected.length];
287         assertEquals(expectedResult, interpolator.timeToValues(time, values));
288         assertArrayEquals(expected, values, TOLERANCE);
289     }
290 
verifyValue(float expected, Result expectedResult, Interpolator interpolator)291     private void verifyValue(float expected, Result expectedResult, Interpolator interpolator) {
292         float[] values = new float[1];
293         assertEquals(expectedResult, interpolator.timeToValues(values));
294         assertEquals(expected, values[0], TOLERANCE);
295     }
296 }
297