1package android.uirendering.cts.testclasses; 2 3import static org.junit.Assert.assertFalse; 4 5import android.graphics.Color; 6import android.graphics.Outline; 7import android.graphics.Path; 8import android.graphics.Rect; 9import android.support.test.filters.MediumTest; 10import android.support.test.runner.AndroidJUnit4; 11import android.uirendering.cts.R; 12import android.uirendering.cts.bitmapverifiers.BitmapVerifier; 13import android.uirendering.cts.bitmapverifiers.RectVerifier; 14import android.uirendering.cts.testclasses.view.UnclippedBlueView; 15import android.uirendering.cts.testinfrastructure.ActivityTestBase; 16import android.uirendering.cts.testinfrastructure.ViewInitializer; 17import android.view.View; 18import android.view.ViewGroup; 19import android.view.ViewOutlineProvider; 20 21import org.junit.Test; 22import org.junit.runner.RunWith; 23 24/** 25 * This tests view clipping by modifying properties of blue_padded_layout, and validating 26 * the resulting rect of content. 27 * 28 * Since the layout is blue on a white background, this is always done with a RectVerifier. 29 */ 30@MediumTest 31@RunWith(AndroidJUnit4.class) 32public class ViewClippingTests extends ActivityTestBase { 33 static final Rect FULL_RECT = new Rect(0, 0, 90, 90); 34 static final Rect BOUNDS_RECT = new Rect(0, 0, 80, 80); 35 static final Rect PADDED_RECT = new Rect(15, 16, 63, 62); 36 static final Rect OUTLINE_RECT = new Rect(1, 2, 78, 79); 37 static final Rect CLIP_BOUNDS_RECT = new Rect(10, 20, 50, 60); 38 39 static final ViewInitializer BOUNDS_CLIP_INIT = 40 rootView -> ((ViewGroup)rootView).setClipChildren(true); 41 42 static final ViewInitializer PADDING_CLIP_INIT = rootView -> { 43 ViewGroup child = (ViewGroup) rootView.findViewById(R.id.child); 44 child.setClipToPadding(true); 45 child.setWillNotDraw(true); 46 child.addView(new UnclippedBlueView(rootView.getContext())); 47 }; 48 49 static final ViewInitializer OUTLINE_CLIP_INIT = rootView -> { 50 View child = rootView.findViewById(R.id.child); 51 child.setOutlineProvider(new ViewOutlineProvider() { 52 @Override 53 public void getOutline(View view, Outline outline) { 54 outline.setRect(OUTLINE_RECT); 55 } 56 }); 57 child.setClipToOutline(true); 58 }; 59 60 static final ViewInitializer CLIP_BOUNDS_CLIP_INIT = 61 view -> view.setClipBounds(CLIP_BOUNDS_RECT); 62 63 static BitmapVerifier makeClipVerifier(Rect blueBoundsRect) { 64 // very high error tolerance, since all these tests care about is clip alignment 65 return new RectVerifier(Color.WHITE, Color.BLUE, blueBoundsRect, 75); 66 } 67 68 @Test 69 public void testSimpleUnclipped() { 70 createTest() 71 .addLayout(R.layout.blue_padded_layout, null) 72 .runWithVerifier(makeClipVerifier(FULL_RECT)); 73 } 74 75 @Test 76 public void testSimpleBoundsClip() { 77 createTest() 78 .addLayout(R.layout.blue_padded_layout, BOUNDS_CLIP_INIT) 79 .runWithVerifier(makeClipVerifier(BOUNDS_RECT)); 80 } 81 82 @Test 83 public void testSimpleClipBoundsClip() { 84 createTest() 85 .addLayout(R.layout.blue_padded_layout, CLIP_BOUNDS_CLIP_INIT) 86 .runWithVerifier(makeClipVerifier(CLIP_BOUNDS_RECT)); 87 } 88 89 @Test 90 public void testSimplePaddingClip() { 91 createTest() 92 .addLayout(R.layout.blue_padded_layout, PADDING_CLIP_INIT) 93 .runWithVerifier(makeClipVerifier(PADDED_RECT)); 94 } 95 // TODO: add tests with clip + scroll, and with interesting combinations of the above 96 97 @Test 98 public void testSimpleOutlineClip() { 99 // NOTE: Only HW is supported 100 createTest() 101 .addLayout(R.layout.blue_padded_layout, OUTLINE_CLIP_INIT, true) 102 .runWithVerifier(makeClipVerifier(OUTLINE_RECT)); 103 104 // SW ignores the outline clip 105 createTest() 106 .addLayout(R.layout.blue_padded_layout, OUTLINE_CLIP_INIT, false) 107 .runWithVerifier(makeClipVerifier(FULL_RECT)); 108 } 109 110 @Test 111 public void testOvalOutlineClip() { 112 // In hw this works because clipping to a non-round rect isn't supported, and is no-op'd. 113 // In sw this works because Outline clipping isn't supported. 114 createTest() 115 .addLayout(R.layout.blue_padded_layout, view -> { 116 view.setOutlineProvider(new ViewOutlineProvider() { 117 Path mPath = new Path(); 118 @Override 119 public void getOutline(View view, Outline outline) { 120 mPath.reset(); 121 mPath.addOval(0, 0, view.getWidth(), view.getHeight(), 122 Path.Direction.CW); 123 outline.setConvexPath(mPath); 124 assertFalse(outline.canClip()); // NOTE: non-round-rect, so can't clip 125 } 126 }); 127 view.setClipToOutline(true); // should do nothing, since non-rect clip 128 }) 129 .runWithVerifier(makeClipVerifier(FULL_RECT)); 130 } 131} 132