1/*
2 * Copyright (C) 2015 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.uirendering.cts.testclasses;
18
19import static org.junit.Assert.assertFalse;
20import static org.junit.Assert.assertTrue;
21
22import android.graphics.Bitmap;
23import android.graphics.Canvas;
24import android.graphics.Color;
25import android.graphics.Path;
26import android.graphics.RectF;
27import android.graphics.Region;
28import android.support.test.filters.MediumTest;
29import android.support.test.runner.AndroidJUnit4;
30import android.uirendering.cts.bitmapverifiers.ColorVerifier;
31import android.uirendering.cts.testinfrastructure.ActivityTestBase;
32import android.util.DisplayMetrics;
33
34import org.junit.Test;
35import org.junit.runner.RunWith;
36
37/**
38 * Tests of state query-able from canvas at draw time.
39 *
40 * Although these tests don't verify drawing content, they still make use of ActivityTestBase's
41 * capability to test the hardware accelerated Canvas in the way that it is used by Views.
42 */
43@MediumTest
44@RunWith(AndroidJUnit4.class)
45public class CanvasStateTests extends ActivityTestBase {
46    @Test
47    public void testClipRectReturnValues() {
48        createTest()
49                .addCanvasClient((canvas, width, height) -> {
50                    canvas.save();
51                    boolean isNonEmpty = canvas.clipRect(0, 0, 20, 20);
52                    assertTrue("clip state should be non empty", isNonEmpty);
53
54                    isNonEmpty = canvas.clipRect(0, 40, 20, 60);
55                    assertFalse("clip state should be empty", isNonEmpty);
56                    canvas.restore();
57                })
58                .runWithoutVerification();
59    }
60
61    @Test
62    public void testClipPathReturnValues() {
63        createTest()
64                .addCanvasClient((canvas, width, height) -> {
65                    canvas.save();
66                    Path rectPath = new Path();
67                    rectPath.addRect(0, 0, 20, 20, Path.Direction.CW);
68
69                    boolean isNonEmpty = canvas.clipPath(rectPath);
70                    assertTrue("clip state should be non empty", isNonEmpty);
71
72                    rectPath.offset(0, 40);
73                    isNonEmpty = canvas.clipPath(rectPath);
74                    assertFalse("clip state should be empty", isNonEmpty);
75                    canvas.restore();
76                })
77                .runWithoutVerification();
78    }
79    @Test
80    public void testQuickReject() {
81        createTest()
82                .addCanvasClient((canvas, width, height) -> {
83                    canvas.save();
84                    canvas.clipRect(0, 0, 20, 20);
85
86                    // not rejected!
87                    assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
88
89                    // rejected!
90                    assertTrue(canvas.quickReject(0, 40, 20, 60, Canvas.EdgeType.BW));
91                    canvas.restore();
92                })
93                .runWithoutVerification();
94    }
95
96    private void testFailureOnBitmapDraw(Bitmap bitmap) {
97        createTest()
98                .addCanvasClient((canvas, width, height) -> {
99                    boolean sawException = false;
100                    try {
101                        canvas.drawBitmap(bitmap, 0, 0, null);
102                    } catch (RuntimeException e) {
103                        sawException = true;
104                    }
105                    assertTrue(sawException);
106                })
107                .runWithoutVerification();
108    }
109
110    @Test
111    public void testFailureOnDrawRecycledBitmap() {
112        Bitmap recycledBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
113        recycledBitmap.recycle();
114        testFailureOnBitmapDraw(recycledBitmap);
115    }
116
117    @Test
118    public void testFailureOnNonPremultipliedBitmap() {
119        Bitmap nonPremultipliedBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
120        nonPremultipliedBitmap.setPremultiplied(false);
121        nonPremultipliedBitmap.setHasAlpha(true);
122        testFailureOnBitmapDraw(nonPremultipliedBitmap);
123    }
124
125    @Test
126    public void testDrawScreenWideBitmap() {
127        createTest()
128                .addCanvasClient((canvas, width, height) -> {
129                    DisplayMetrics displayMetrics =
130                            getActivity().getResources().getDisplayMetrics();
131                    assertTrue(displayMetrics.widthPixels <= canvas.getMaximumBitmapWidth());
132                    assertTrue(displayMetrics.heightPixels <= canvas.getMaximumBitmapHeight());
133                    Bitmap bitmap = Bitmap.createBitmap(displayMetrics.widthPixels,
134                            displayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
135                    bitmap.eraseColor(Color.RED);
136                    canvas.drawBitmap(bitmap, 0, 0, null);
137                })
138                .runWithVerifier(new ColorVerifier(Color.RED, 0));
139    }
140
141    @Test
142    public void testDrawLargeBitmap() {
143        // verify that HW and SW pipelines can both draw screen-and-a-half sized bitmap
144        createTest()
145                .addCanvasClient((canvas, width, height) -> {
146                    DisplayMetrics displayMetrics =
147                            getActivity().getResources().getDisplayMetrics();
148
149                    int bWidth = displayMetrics.widthPixels * 3 / 2;
150                    int bHeight = displayMetrics.heightPixels * 3 / 2;
151                    bWidth = Math.min(bWidth, canvas.getMaximumBitmapWidth());
152                    bHeight = Math.min(bHeight, canvas.getMaximumBitmapHeight());
153                    Bitmap bitmap = Bitmap.createBitmap(bWidth, bHeight, Bitmap.Config.ARGB_8888);
154                    bitmap.eraseColor(Color.RED);
155                    canvas.drawBitmap(bitmap, 0, 0, null);
156                })
157                .runWithVerifier(new ColorVerifier(Color.RED, 0));
158    }
159}
160