blob: b225b1684fc710e076fbc48ad3189f0ecaf69355 [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.server.wm;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static android.server.wm.UiDeviceUtils.pressHomeButton;
import static android.server.wm.UiDeviceUtils.pressUnlockButton;
import static android.server.wm.UiDeviceUtils.pressWakeupButton;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.cts.surfacevalidator.CapturedActivity;
import android.view.cts.surfacevalidator.PixelChecker;
import android.view.cts.surfacevalidator.PixelColor;
import android.view.cts.surfacevalidator.RectChecker;
import android.view.cts.surfacevalidator.SurfaceControlTestCase;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
@LargeTest
@Presubmit
public class SurfaceControlTest {
private static final int DEFAULT_LAYOUT_WIDTH = 640;
private static final int DEFAULT_LAYOUT_HEIGHT = 480;
private static final int DEFAULT_BUFFER_WIDTH = 640;
private static final int DEFAULT_BUFFER_HEIGHT = 480;
private static final int DEFAULT_SURFACE_SIZE = 100;
@Rule
public ActivityTestRule<CapturedActivity> mActivityRule =
new ActivityTestRule<>(CapturedActivity.class);
@Rule
public TestName mName = new TestName();
private CapturedActivity mActivity;
private void verifyTest(SurfaceControlTestCase.ParentSurfaceConsumer psc,
PixelChecker pixelChecker) throws Throwable {
mActivity.verifyTest(new SurfaceControlTestCase(psc, null,
pixelChecker, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT),
mName);
}
@Before
public void setup() {
pressWakeupButton();
pressUnlockButton();
mActivity = mActivityRule.getActivity();
mActivity.dismissPermissionDialog();
}
/**
* Want to be especially sure we don't leave up the permission dialog, so try and dismiss
* after test.
*/
@After
public void tearDown() throws UiObjectNotFoundException {
mActivity.dismissPermissionDialog();
}
@Test
public void testLifecycle() {
final SurfaceControl.Builder b = new SurfaceControl.Builder();
final SurfaceControl sc = b.setName("CTS").build();
assertTrue("Failed to build SurfaceControl", sc != null);
assertTrue(sc.isValid());
sc.release();
assertFalse(sc.isValid());
}
private SurfaceControl buildDefaultSurface(SurfaceControl parent) {
return new SurfaceControl.Builder()
.setBufferSize(DEFAULT_SURFACE_SIZE, DEFAULT_SURFACE_SIZE)
.setName("CTS surface")
.setParent(parent)
.build();
}
void fillWithColor(SurfaceControl sc, int color) {
Surface s = new Surface(sc);
Canvas c = s.lockHardwareCanvas();
c.drawColor(color);
s.unlockCanvasAndPost(c);
}
private SurfaceControl buildDefaultSurface(SurfaceControl parent, int color) {
final SurfaceControl sc = buildDefaultSurface(parent);
fillWithColor(sc, color);
return sc;
}
private SurfaceControl buildDefaultRedSurface(SurfaceControl parent) {
return buildDefaultSurface(parent, Color.RED);
}
/**
* Verify that showing a 100x100 surface filled with RED produces roughly 10,000 red pixels.
*/
@Test
public void testShow() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(parent);
new SurfaceControl.Transaction().setVisibility(sc, true).apply();
sc.release();
}
},
new RectChecker(new Rect(0, 0, 100, 100), PixelColor.RED));
}
/**
* The same setup as testShow, however we hide the surface and verify that we don't see Red.
*/
@Test
public void testHide() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(parent);
new SurfaceControl.Transaction().setVisibility(sc, false).apply();
sc.release();
}
},
new RectChecker(new Rect(0, 0, 100, 100), PixelColor.WHITE));
}
/**
* Like testHide but we reparent the surface off-screen instead.
*/
@Test
public void testReparentOff() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(parent);
new SurfaceControl.Transaction().reparent(sc, null).apply();
sc.release();
}
},
new RectChecker(new Rect(0, 0, 100, 100), PixelColor.WHITE));
}
/**
* Here we use the same red-surface set up but construct it off-screen and then re-parent it.
*/
@Test
public void testReparentOn() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(null);
new SurfaceControl.Transaction().setVisibility(sc, true)
.reparent(sc, parent)
.apply();
sc.release();
}
},
new RectChecker(new Rect(0, 0, 100, 100), PixelColor.RED));
}
/**
* Test that a surface with Layer "2" appears over a surface with Layer "1".
*/
@Test
public void testSetLayer() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(parent);
final SurfaceControl sc2 = buildDefaultSurface(parent, Color.GREEN);
new SurfaceControl.Transaction().setVisibility(sc, true)
.setVisibility(sc2, true)
.setLayer(sc, 1)
.setLayer(sc2, 2)
.apply();
sc.release();
}
},
new RectChecker(new Rect(0, 0, 100, 100), PixelColor.GREEN));
}
/**
* Try setting the position of a surface with the top-left corner off-screen.
*/
@Test
public void testSetGeometry_dstBoundsOffScreen() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(parent);
new SurfaceControl.Transaction().setVisibility(sc, true)
.setGeometry(sc, null, new Rect(-50, -50, 50, 50), Surface.ROTATION_0)
.apply();
sc.release();
}
},
// The rect should be offset by -50 pixels
new RectChecker(
new RectChecker.Target(new Rect(0, 0, 50, 50), PixelColor.RED),
new RectChecker.Target(new Rect(50, 50, 150, 150), PixelColor.WHITE)));
}
/**
* Try setting the position of a surface with the top-left corner on-screen.
*/
@Test
public void testSetGeometry_dstBoundsOnScreen() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(parent);
new SurfaceControl.Transaction().setVisibility(sc, true)
.setGeometry(sc, null, new Rect(50, 50, 150, 150), Surface.ROTATION_0)
.apply();
sc.release();
}
},
// The rect should be offset by 50 pixels
new RectChecker(
new RectChecker.Target(new Rect(50, 50, 150, 150), PixelColor.RED)));
}
/**
* Try scaling a surface
*/
@Test
public void testSetGeometry_dstBoundsScaled() throws Throwable {
verifyTest(
new SurfaceControlTestCase.ParentSurfaceConsumer () {
@Override
public void addChildren(SurfaceControl parent) {
final SurfaceControl sc = buildDefaultRedSurface(parent);
new SurfaceControl.Transaction().setVisibility(sc, true)
.setGeometry(sc, new Rect(0, 0, DEFAULT_SURFACE_SIZE, DEFAULT_SURFACE_SIZE),
new Rect(0, 0, DEFAULT_SURFACE_SIZE * 2, DEFAULT_SURFACE_SIZE*2),
Surface.ROTATION_0)
.apply();
sc.release();
}
},
new RectChecker(
new RectChecker.Target(new Rect(0, 0, 200, 200), PixelColor.RED)));
}
}