1 /* 2 * Copyright 2019 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 package android.view.surfacecontrol.cts; 17 18 import static android.server.wm.ActivityManagerTestBase.createFullscreenActivityScenarioRule; 19 import static android.server.wm.BuildUtils.HW_TIMEOUT_MULTIPLIER; 20 21 import android.content.Context; 22 import android.graphics.Color; 23 import android.os.Binder; 24 import android.view.Gravity; 25 import android.view.SurfaceControlViewHost; 26 import android.view.SurfaceView; 27 import android.view.View; 28 import android.view.cts.surfacevalidator.CapturedActivity; 29 import android.view.cts.surfacevalidator.ISurfaceValidatorTestCase; 30 import android.view.cts.surfacevalidator.PixelChecker; 31 import android.widget.FrameLayout; 32 33 import androidx.test.ext.junit.rules.ActivityScenarioRule; 34 35 import org.junit.Before; 36 import org.junit.Rule; 37 import org.junit.Test; 38 import org.junit.rules.TestName; 39 40 import java.util.concurrent.CountDownLatch; 41 import java.util.concurrent.TimeUnit; 42 43 public class SurfacePackageFlickerTest { 44 private static final int DEFAULT_LAYOUT_WIDTH = 100; 45 private static final int DEFAULT_LAYOUT_HEIGHT = 100; 46 47 @Rule 48 public final ActivityScenarioRule<CapturedActivity> mActivityRule = 49 createFullscreenActivityScenarioRule(CapturedActivity.class); 50 51 @Rule 52 public TestName mName = new TestName(); 53 private CapturedActivity mActivity; 54 55 @Before setup()56 public void setup() { 57 mActivityRule.getScenario().onActivity(activity -> mActivity = activity); 58 } 59 60 class SurfacePackageTestCase implements ISurfaceValidatorTestCase { 61 private final FrameLayout.LayoutParams mLayoutParams; 62 private final PixelChecker mPixelChecker; 63 private SurfaceView mSurfaceView; 64 private SurfaceControlViewHost mSurfaceControlViewHost; 65 private FrameLayout mParent; 66 private final CountDownLatch mFirstDrawLatch = new CountDownLatch(1); 67 68 69 private final Runnable mRecreateSurfaceViewCallback = new Runnable() { 70 public void run() { 71 if (mSurfaceControlViewHost == null) { 72 return; 73 } 74 mParent.removeView(mSurfaceView); 75 mSurfaceView = new SurfaceView(mActivity); 76 mSurfaceView.setZOrderOnTop(true); 77 mParent.addView(mSurfaceView, mLayoutParams); 78 mSurfaceView.setChildSurfacePackage(mSurfaceControlViewHost.getSurfacePackage()); 79 mParent.post(mRecreateSurfaceViewCallback); 80 } 81 }; 82 SurfacePackageTestCase(PixelChecker pixelChecker, int layoutWidth, int layoutHeight)83 public SurfacePackageTestCase(PixelChecker pixelChecker, 84 int layoutWidth, int layoutHeight) { 85 mLayoutParams = new FrameLayout.LayoutParams(layoutWidth, layoutHeight, 86 Gravity.LEFT | Gravity.TOP); 87 mPixelChecker = pixelChecker; 88 } 89 90 @Override start(Context context, FrameLayout parent)91 public void start(Context context, FrameLayout parent) { 92 mParent = parent; 93 mSurfaceView = new SurfaceView(context); 94 mSurfaceView.setZOrderOnTop(true); 95 mParent.addView(mSurfaceView, mLayoutParams); 96 97 final View v = new View(mActivity); 98 v.setBackgroundColor(Color.GREEN); 99 100 mSurfaceControlViewHost = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(), 101 new Binder()); 102 mSurfaceControlViewHost.setView(v, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT); 103 mSurfaceView.setChildSurfacePackage(mSurfaceControlViewHost.getSurfacePackage()); 104 105 v.getViewTreeObserver().registerFrameCommitCallback(() -> { 106 parent.post(mRecreateSurfaceViewCallback); 107 mFirstDrawLatch.countDown(); 108 }); 109 } 110 waitForReady()111 public boolean waitForReady() { 112 try { 113 return mFirstDrawLatch.await(5L * HW_TIMEOUT_MULTIPLIER, TimeUnit.SECONDS); 114 } catch (Exception e) { 115 return false; 116 // Oh well 117 } 118 } 119 120 @Override end()121 public void end() { 122 mSurfaceControlViewHost.release(); 123 mParent.removeAllViews(); 124 mSurfaceControlViewHost = null; 125 } 126 127 @Override getChecker()128 public PixelChecker getChecker() { 129 return mPixelChecker; 130 } 131 } 132 133 @Test testSurfacePackageNoFlicker()134 public void testSurfacePackageNoFlicker() throws Throwable { 135 // The basic operation of this test is to continually recreate 136 // SurfaceViews hosting a single green SurfacePackage. 137 // We verify that removing the old SurfaceView at the 138 // "same time" as reparenting the SurfacePackage to the new one 139 // results in a flicker free process. 140 PixelChecker pixelChecker = new PixelChecker(Color.GREEN) { 141 @Override 142 public boolean checkPixels(int pixelCount, int width, int height) { 143 return pixelCount == DEFAULT_LAYOUT_WIDTH*DEFAULT_LAYOUT_HEIGHT; 144 } 145 }; 146 SurfacePackageTestCase t = new SurfacePackageTestCase( 147 pixelChecker, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT); 148 mActivity.verifyTest(t, mName); 149 } 150 } 151