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 */ 16 17package android.uirendering.cts.testclasses; 18 19import static org.mockito.Matchers.any; 20import static org.mockito.Mockito.mock; 21import static org.mockito.Mockito.times; 22import static org.mockito.Mockito.verify; 23import static org.mockito.Mockito.when; 24 25import android.graphics.Canvas; 26import android.graphics.Color; 27import android.graphics.SurfaceTexture; 28import android.support.annotation.ColorInt; 29import android.support.test.filters.MediumTest; 30import android.support.test.runner.AndroidJUnit4; 31import android.uirendering.cts.R; 32import android.uirendering.cts.bitmapverifiers.ColorVerifier; 33import android.uirendering.cts.testinfrastructure.ActivityTestBase; 34import android.uirendering.cts.testinfrastructure.ViewInitializer; 35import android.uirendering.cts.util.DrawCountDown; 36import android.view.Surface; 37import android.view.TextureView; 38import android.view.TextureView.SurfaceTextureListener; 39import android.view.ViewGroup; 40 41import org.junit.After; 42import org.junit.AfterClass; 43import org.junit.Assert; 44import org.junit.BeforeClass; 45import org.junit.Test; 46import org.junit.runner.RunWith; 47 48import java.util.concurrent.CountDownLatch; 49 50@MediumTest 51@RunWith(AndroidJUnit4.class) 52public class TextureViewTests extends ActivityTestBase { 53 54 private static SurfaceTexture sRedTexture; 55 56 @BeforeClass 57 public static void setupClass() { 58 sRedTexture = createSurfaceTexture(true, Color.RED); 59 } 60 61 @AfterClass 62 public static void teardownClass() { 63 sRedTexture.release(); 64 sRedTexture = null; 65 } 66 67 @After 68 public void tearDown() { 69 // TODO: Workaround for b/34231066 70 DrawCountDown.cancelPending(); 71 } 72 73 @Test 74 public void testConstructDetachedSingleBuffered() { 75 testConstructDetached(true); 76 } 77 @Test 78 public void testConstructDetachedMultiBuffered() { 79 testConstructDetached(false); 80 } 81 82 private void testConstructDetached(boolean singleBuffered) { 83 final SurfaceTexture texture = createSurfaceTexture(singleBuffered, Color.RED); 84 createTest() 85 .addLayout(R.layout.textureview, (ViewInitializer) view -> { 86 TextureView textureview = (TextureView) view; 87 textureview.setSurfaceTexture(texture); 88 }, true) 89 .runWithVerifier(new ColorVerifier(Color.RED)); 90 Assert.assertTrue(texture.isReleased()); 91 } 92 93 private static SurfaceTexture createSurfaceTexture(boolean singleBuffered, 94 @ColorInt int fillColor) { 95 SurfaceTexture texture = new SurfaceTexture(singleBuffered); 96 texture.setDefaultBufferSize(TEST_WIDTH, TEST_HEIGHT); 97 Surface producer = new Surface(texture); 98 Canvas canvas = producer.lockCanvas(null); 99 canvas.drawColor(fillColor); 100 producer.unlockCanvasAndPost(canvas); 101 return texture; 102 } 103 104 @Test 105 public void testReuseSurfaceTexture() { 106 final CountDownLatch fence = new CountDownLatch(1); 107 SurfaceTextureListener stlistener = mock(SurfaceTextureListener.class); 108 when(stlistener.onSurfaceTextureDestroyed(any(SurfaceTexture.class))) 109 .thenReturn(false); 110 createTest() 111 .addLayout(R.layout.textureview, (ViewInitializer) view -> { 112 final TextureView textureview = (TextureView) view; 113 final ViewGroup parent = (ViewGroup) textureview.getParent(); 114 textureview.setSurfaceTextureListener(stlistener); 115 textureview.setSurfaceTexture(sRedTexture); 116 DrawCountDown.countDownDraws(parent, 1, () -> { 117 parent.removeView(textureview); 118 }); 119 DrawCountDown.countDownDraws(parent, 2, () -> { 120 parent.addView(textureview); 121 textureview.setSurfaceTexture(sRedTexture); 122 textureview.post(fence::countDown); 123 }); 124 }, true, fence) 125 .runWithVerifier(new ColorVerifier(Color.RED)); 126 verify(stlistener, times(2)).onSurfaceTextureDestroyed(any(SurfaceTexture.class)); 127 } 128 129 @Test 130 public void testLockCanvas() { 131 final CountDownLatch fence = new CountDownLatch(1); 132 createTest() 133 .addLayout(R.layout.textureview, (ViewInitializer) view -> { 134 final TextureView textureview = (TextureView) view; 135 textureview.setSurfaceTextureListener(new SurfaceTextureListener() { 136 @Override 137 public void onSurfaceTextureUpdated(SurfaceTexture surface) { 138 textureview.post(fence::countDown); 139 } 140 @Override 141 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, 142 int width, int height) {} 143 @Override 144 public void onSurfaceTextureAvailable(SurfaceTexture surface, 145 int width, int height) { 146 Canvas canvas = textureview.lockCanvas(); 147 canvas.drawColor(Color.BLUE); 148 textureview.unlockCanvasAndPost(canvas); 149 } 150 @Override 151 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 152 return true; 153 } 154 }); 155 }, true, fence) 156 .runWithVerifier(new ColorVerifier(Color.BLUE)); 157 } 158} 159