1/*
2 * Copyright (C) 2016 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 */
16package android.uirendering.cts.testclasses;
17
18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertFalse;
20import static org.junit.Assert.assertTrue;
21import static org.junit.Assert.fail;
22import static org.mockito.Matchers.anyFloat;
23import static org.mockito.Mockito.mock;
24import static org.mockito.Mockito.verify;
25
26import android.app.Activity;
27import android.graphics.Bitmap;
28import android.graphics.Canvas;
29import android.graphics.Color;
30import android.graphics.Paint;
31import android.support.test.filters.LargeTest;
32import android.support.test.filters.MediumTest;
33import android.support.test.rule.ActivityTestRule;
34import android.support.test.runner.AndroidJUnit4;
35import android.uirendering.cts.R;
36import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
37import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
38import android.uirendering.cts.testinfrastructure.MaterialActivity;
39import android.uirendering.cts.util.BitmapAsserter;
40import android.widget.EdgeEffect;
41
42import org.junit.Before;
43import org.junit.Rule;
44import org.junit.Test;
45import org.junit.rules.TestName;
46import org.junit.runner.RunWith;
47import org.mockito.ArgumentCaptor;
48
49@MediumTest
50@RunWith(AndroidJUnit4.class)
51public class EdgeEffectTests {
52
53    private static final int WIDTH = 90;
54    private static final int HEIGHT = 90;
55
56    @Rule
57    public TestName name = new TestName();
58
59    @Rule
60    public ActivityTestRule<MaterialActivity> mActivityRule = new ActivityTestRule<>(
61            MaterialActivity.class);
62
63    private BitmapAsserter mBitmapAsserter = new BitmapAsserter(this.getClass().getSimpleName(),
64            name.getMethodName());
65
66    interface EdgeEffectInitializer {
67        void initialize(EdgeEffect edgeEffect);
68    }
69
70    private Activity getActivity() {
71        return mActivityRule.getActivity();
72    }
73
74    @Before
75    public void setUp() {
76        mBitmapAsserter.setUp(getActivity());
77    }
78
79    private void assertEdgeEffect(EdgeEffectInitializer initializer, int goldenId) {
80        Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
81        Canvas canvas = new Canvas(bitmap);
82        canvas.drawColor(Color.WHITE);
83        EdgeEffect edgeEffect = new EdgeEffect(getActivity());
84        edgeEffect.setSize(WIDTH, HEIGHT);
85        edgeEffect.setColor(Color.RED);
86        initializer.initialize(edgeEffect);
87        edgeEffect.draw(canvas);
88
89        GoldenImageVerifier verifier = new GoldenImageVerifier(getActivity(), goldenId,
90                new MSSIMComparer(0.99));
91        mBitmapAsserter.assertBitmapIsVerified(bitmap, verifier,
92                name.getMethodName(), "EdgeEffect doesn't match expected");
93    }
94
95    @Test
96    public void testOnPull() {
97        assertEdgeEffect(edgeEffect -> {
98            edgeEffect.onPull(1);
99        }, R.drawable.edge_effect_red);
100    }
101
102    @Test
103    public void testSetSize() {
104        assertEdgeEffect(edgeEffect -> {
105            edgeEffect.setSize(70, 70);
106            edgeEffect.onPull(1);
107        }, R.drawable.edge_effect_size);
108    }
109
110    @Test
111    public void testSetColor() {
112        assertEdgeEffect(edgeEffect -> {
113            edgeEffect.setColor(Color.GREEN);
114            edgeEffect.onPull(1);
115        }, R.drawable.edge_effect_green);
116    }
117
118    @Test
119    public void testOnPullWithDisplacement() {
120        assertEdgeEffect(edgeEffect -> {
121            edgeEffect.onPull(1, 0);
122        }, R.drawable.edge_effect_displacement_0);
123
124        assertEdgeEffect(edgeEffect -> {
125            edgeEffect.onPull(1, 1);
126        }, R.drawable.edge_effect_displacement_1);
127    }
128
129    @Test
130    public void testIsFinished() {
131        EdgeEffect effect = new EdgeEffect(getActivity());
132        assertTrue(effect.isFinished());
133        effect.onPull(0.5f);
134        assertFalse(effect.isFinished());
135    }
136
137    @Test
138    public void testFinish() {
139        EdgeEffect effect = new EdgeEffect(getActivity());
140        effect.onPull(1);
141        effect.finish();
142        assertTrue(effect.isFinished());
143
144        effect.onAbsorb(1000);
145        effect.finish();
146        assertFalse(effect.draw(new Canvas()));
147    }
148
149    @Test
150    public void testGetColor() {
151        EdgeEffect effect = new EdgeEffect(getActivity());
152        effect.setColor(Color.GREEN);
153        assertEquals(Color.GREEN, effect.getColor());
154    }
155
156    @Test
157    public void testGetMaxHeight() {
158        EdgeEffect edgeEffect = new EdgeEffect(getActivity());
159        edgeEffect.setSize(200, 200);
160        assertTrue(edgeEffect.getMaxHeight() <= 200 * 2 + 1);
161        edgeEffect.setSize(200, 0);
162        assertEquals(0, edgeEffect.getMaxHeight());
163    }
164
165    private interface AlphaVerifier {
166        void verify(int oldAlpha, int newAlpha);
167    }
168
169    // validates changes to the alpha of draw commands produced by EdgeEffect
170    // over the course of an animation
171    private void verifyAlpha(EdgeEffectInitializer initializer, AlphaVerifier alphaVerifier) {
172        Canvas canvas = mock(Canvas.class);
173        ArgumentCaptor<Paint> captor = ArgumentCaptor.forClass(Paint.class);
174        EdgeEffect edgeEffect = new EdgeEffect(getActivity());
175        edgeEffect.setSize(200, 200);
176        initializer.initialize(edgeEffect);
177        edgeEffect.draw(canvas);
178        verify(canvas).drawCircle(anyFloat(), anyFloat(), anyFloat(), captor.capture());
179        int oldAlpha = captor.getValue().getAlpha();
180        for (int i = 0; i < 3; i++) {
181            try {
182                Thread.sleep(20);
183            } catch (InterruptedException e) {
184                fail();
185            }
186            canvas = mock(Canvas.class);
187            edgeEffect.draw(canvas);
188            verify(canvas).drawCircle(anyFloat(), anyFloat(), anyFloat(), captor.capture());
189            int newAlpha = captor.getValue().getAlpha();
190            alphaVerifier.verify(oldAlpha, newAlpha);
191            oldAlpha = newAlpha;
192        }
193    }
194
195    @LargeTest
196    @Test
197    public void testOnAbsorb() {
198        verifyAlpha(edgeEffect -> {
199            edgeEffect.onAbsorb(10000);
200        }, ((oldAlpha, newAlpha) -> {
201            assertTrue("Alpha should grow", oldAlpha < newAlpha);
202        }));
203    }
204
205    @Test
206    public void testOnRelease() {
207        verifyAlpha(edgeEffect -> {
208            edgeEffect.onPull(1);
209            edgeEffect.onRelease();
210        }, ((oldAlpha, newAlpha) -> {
211            assertTrue("Alpha should decrease", oldAlpha > newAlpha);
212        }));
213    }
214
215}
216