1 /* 2 * Copyright (C) 2022 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 17 package android.server.wm.animations; 18 19 import static android.view.Display.DEFAULT_DISPLAY; 20 import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT; 21 import static android.view.RoundedCorner.POSITION_TOP_LEFT; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertNotNull; 26 import static org.junit.Assert.assertTrue; 27 import static org.junit.Assume.assumeNotNull; 28 import static org.junit.Assume.assumeTrue; 29 30 import android.graphics.Path; 31 import android.graphics.RectF; 32 import android.hardware.display.DisplayManager; 33 import android.os.Build; 34 import android.platform.test.annotations.Presubmit; 35 import android.server.wm.MultiDisplayTestBase; 36 import android.server.wm.WindowManagerState; 37 import android.server.wm.WindowManagerTestBase; 38 import android.view.Display; 39 import android.view.DisplayShape; 40 import android.view.RoundedCorner; 41 import android.view.View; 42 43 import com.android.compatibility.common.util.PropertyUtil; 44 45 import org.junit.Before; 46 import org.junit.Test; 47 48 /** 49 * Build/Install/Run: 50 * atest CtsWindowManagerDeviceAnimations:DisplayShapeTests 51 */ 52 @Presubmit 53 @android.server.wm.annotation.Group3 54 public class DisplayShapeTests extends WindowManagerTestBase { 55 56 private Display mDisplay; 57 58 @Before setUp()59 public void setUp() throws Exception { 60 mDisplay = mDm.getDisplay(DEFAULT_DISPLAY); 61 assumeNotNull(mDisplay); 62 } 63 64 @Test testNonNull()65 public void testNonNull() { 66 final DisplayShape shape = mDisplay.getShape(); 67 assertNotNull(shape); 68 69 final Path path = shape.getPath(); 70 assertNotNull(path); 71 assertFalse(path.isEmpty()); 72 } 73 74 @Test testDisplayShapeConfig()75 public void testDisplayShapeConfig() { 76 // Skip the mix build case when the base build < U (e.x. U GSI on T base build) and only 77 // test for U+ base builds. 78 assumeTrue("Test does not apply for vendor image with API level lower than U", 79 PropertyUtil.isVendorApiLevelNewerThan(Build.VERSION_CODES.TIRAMISU)); 80 81 boolean hasRoundedCorner = false; 82 for (int i = POSITION_TOP_LEFT; i <= POSITION_BOTTOM_LEFT; i++) { 83 final RoundedCorner r = mDisplay.getRoundedCorner(i); 84 if (r != null && r.getRadius() > 0) { 85 hasRoundedCorner = true; 86 break; 87 } 88 } 89 90 if (hasRoundedCorner) { 91 // If the display shape is not configured, the returned path will be rectangular if the 92 // display is not round. The config must be set if the display is not round or 93 // rectangular. 94 assertFalse("The display has a rounded corner but the shape specifies a rectangle." 95 + " Please set the config (config_mainDisplayShape) for the display shape.", 96 mDisplay.getShape().getPath().isRect(null)); 97 } 98 } 99 100 @Test testDisplayShapeFromWindowInsets()101 public void testDisplayShapeFromWindowInsets() { 102 DisplayShapeTests.TestActivity activity = 103 startActivity(DisplayShapeTests.TestActivity.class, DEFAULT_DISPLAY); 104 105 final DisplayShape fromDisplay = mDisplay.getShape(); 106 final View decorView = activity.getWindow().getDecorView(); 107 final DisplayShape fromInsets = decorView.getRootWindowInsets().getDisplayShape(); 108 109 final int[] location = new int[2]; 110 decorView.getLocationOnScreen(location); 111 final RectF boundsFromDisplay = getBoundsFromPath(fromDisplay.getPath()); 112 boundsFromDisplay.offset(-location[0], -location[1]); 113 final RectF boundsFromView = getBoundsFromPath(fromInsets.getPath()); 114 assertEquals(boundsFromView, boundsFromDisplay); 115 } 116 117 @Test testDisplayShapeOnVirtualDisplay()118 public void testDisplayShapeOnVirtualDisplay() { 119 try (MultiDisplayTestBase.VirtualDisplaySession session = 120 new MultiDisplayTestBase.VirtualDisplaySession()) { 121 // Setup a simulated display. 122 WindowManagerState.DisplayContent dc = session.setSimulateDisplay(true).createDisplay(); 123 Display simulatedDisplay = mContext.getSystemService(DisplayManager.class) 124 .getDisplay(dc.mId); 125 final DisplayShape shape = simulatedDisplay.getShape(); 126 assertNotNull(shape); 127 assertTrue(shape.getPath().isRect(null)); 128 129 final int displayWidth = dc.getDisplayRect().width(); 130 final int displayHeight = dc.getDisplayRect().height(); 131 final RectF expectRect = new RectF(0, 0, displayWidth, displayHeight); 132 final RectF actualRect = getBoundsFromPath(shape.getPath()); 133 assertEquals(expectRect, actualRect); 134 } 135 } 136 getBoundsFromPath(Path path)137 private static RectF getBoundsFromPath(Path path) { 138 final RectF rect = new RectF(); 139 path.computeBounds(rect, false); 140 return rect; 141 } 142 143 public static class TestActivity extends FocusableActivity { 144 } 145 } 146