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