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 17 package android.server.wm; 18 19 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 20 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; 21 import static android.server.wm.ActivityAndWindowManagersState.dpToPx; 22 import static android.server.wm.ComponentNameUtils.getWindowName; 23 import static android.server.wm.app.Components.BOTTOM_LEFT_LAYOUT_ACTIVITY; 24 import static android.server.wm.app.Components.BOTTOM_RIGHT_LAYOUT_ACTIVITY; 25 import static android.server.wm.app.Components.TEST_ACTIVITY; 26 import static android.server.wm.app.Components.TOP_LEFT_LAYOUT_ACTIVITY; 27 import static android.server.wm.app.Components.TOP_RIGHT_LAYOUT_ACTIVITY; 28 29 import static org.junit.Assert.assertEquals; 30 import static org.junit.Assert.assertNotNull; 31 import static org.junit.Assume.assumeTrue; 32 33 import android.content.ComponentName; 34 import android.graphics.Rect; 35 import android.platform.test.annotations.Presubmit; 36 import android.server.wm.WindowManagerState.Display; 37 import android.server.wm.WindowManagerState.WindowState; 38 39 import org.junit.Test; 40 41 import java.util.List; 42 43 /** 44 * Build/Install/Run: 45 * atest CtsWindowManagerDeviceTestCases:ManifestLayoutTests 46 */ 47 @Presubmit 48 public class ManifestLayoutTests extends ActivityManagerTestBase { 49 50 // Test parameters 51 private static final int DEFAULT_WIDTH_DP = 240; 52 private static final int DEFAULT_HEIGHT_DP = 160; 53 private static final float DEFAULT_WIDTH_FRACTION = 0.50f; 54 private static final float DEFAULT_HEIGHT_FRACTION = 0.70f; 55 private static final int MIN_WIDTH_DP = 100; 56 private static final int MIN_HEIGHT_DP = 80; 57 58 private static final int GRAVITY_VER_CENTER = 0x01; 59 private static final int GRAVITY_VER_TOP = 0x02; 60 private static final int GRAVITY_VER_BOTTOM = 0x04; 61 private static final int GRAVITY_HOR_CENTER = 0x10; 62 private static final int GRAVITY_HOR_LEFT = 0x20; 63 private static final int GRAVITY_HOR_RIGHT = 0x40; 64 65 private Display mDisplay; 66 private WindowState mWindowState; 67 68 @Test testGravityAndDefaultSizeTopLeft()69 public void testGravityAndDefaultSizeTopLeft() throws Exception { 70 testLayout(GRAVITY_VER_TOP, GRAVITY_HOR_LEFT, false /*fraction*/); 71 } 72 73 @Test testGravityAndDefaultSizeTopRight()74 public void testGravityAndDefaultSizeTopRight() throws Exception { 75 testLayout(GRAVITY_VER_TOP, GRAVITY_HOR_RIGHT, true /*fraction*/); 76 } 77 78 @Test testGravityAndDefaultSizeBottomLeft()79 public void testGravityAndDefaultSizeBottomLeft() throws Exception { 80 testLayout(GRAVITY_VER_BOTTOM, GRAVITY_HOR_LEFT, true /*fraction*/); 81 } 82 83 @Test testGravityAndDefaultSizeBottomRight()84 public void testGravityAndDefaultSizeBottomRight() throws Exception { 85 testLayout(GRAVITY_VER_BOTTOM, GRAVITY_HOR_RIGHT, false /*fraction*/); 86 } 87 88 @Test testMinimalSizeFreeform()89 public void testMinimalSizeFreeform() throws Exception { 90 assumeTrue("Skipping test: no freeform support", supportsFreeform()); 91 92 testMinimalSize(WINDOWING_MODE_FREEFORM); 93 } 94 95 @Test 96 @Presubmit testMinimalSizeDocked()97 public void testMinimalSizeDocked() throws Exception { 98 assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow()); 99 100 testMinimalSize(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); 101 } 102 testMinimalSize(int windowingMode)103 private void testMinimalSize(int windowingMode) throws Exception { 104 // Issue command to resize to <0,0,1,1>. We expect the size to be floored at 105 // MIN_WIDTH_DPxMIN_HEIGHT_DP. 106 if (windowingMode == WINDOWING_MODE_FREEFORM) { 107 launchActivity(BOTTOM_RIGHT_LAYOUT_ACTIVITY, WINDOWING_MODE_FREEFORM); 108 resizeActivityTask(BOTTOM_RIGHT_LAYOUT_ACTIVITY, 0, 0, 1, 1); 109 } else { // stackId == DOCKED_STACK_ID 110 launchActivitiesInSplitScreen( 111 getLaunchActivityBuilder().setTargetActivity(BOTTOM_RIGHT_LAYOUT_ACTIVITY), 112 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY)); 113 resizeDockedStack(1, 1, 1, 1); 114 } 115 getDisplayAndWindowState(BOTTOM_RIGHT_LAYOUT_ACTIVITY, false); 116 117 final int minWidth = dpToPx(MIN_WIDTH_DP, mDisplay.getDpi()); 118 final int minHeight = dpToPx(MIN_HEIGHT_DP, mDisplay.getDpi()); 119 final Rect containingRect = mWindowState.getContainingFrame(); 120 121 assertEquals("Min width is incorrect", minWidth, containingRect.width()); 122 assertEquals("Min height is incorrect", minHeight, containingRect.height()); 123 } 124 testLayout( int vGravity, int hGravity, boolean fraction)125 private void testLayout( 126 int vGravity, int hGravity, boolean fraction) throws Exception { 127 assumeTrue("Skipping test: no freeform support", supportsFreeform()); 128 129 final ComponentName activityName; 130 if (vGravity == GRAVITY_VER_TOP) { 131 activityName = (hGravity == GRAVITY_HOR_LEFT) ? TOP_LEFT_LAYOUT_ACTIVITY 132 : TOP_RIGHT_LAYOUT_ACTIVITY; 133 } else { 134 activityName = (hGravity == GRAVITY_HOR_LEFT) ? BOTTOM_LEFT_LAYOUT_ACTIVITY 135 : BOTTOM_RIGHT_LAYOUT_ACTIVITY; 136 } 137 138 // Launch in freeform stack 139 launchActivity(activityName, WINDOWING_MODE_FREEFORM); 140 141 getDisplayAndWindowState(activityName, true); 142 143 final Rect containingRect = mWindowState.getContainingFrame(); 144 final Rect appRect = mDisplay.getAppRect(); 145 final int expectedWidthPx, expectedHeightPx; 146 // Evaluate the expected window size in px. If we're using fraction dimensions, 147 // calculate the size based on the app rect size. Otherwise, convert the expected 148 // size in dp to px. 149 if (fraction) { 150 expectedWidthPx = (int) (appRect.width() * DEFAULT_WIDTH_FRACTION); 151 expectedHeightPx = (int) (appRect.height() * DEFAULT_HEIGHT_FRACTION); 152 } else { 153 final int densityDpi = mDisplay.getDpi(); 154 expectedWidthPx = dpToPx(DEFAULT_WIDTH_DP, densityDpi); 155 expectedHeightPx = dpToPx(DEFAULT_HEIGHT_DP, densityDpi); 156 } 157 158 verifyFrameSizeAndPosition( 159 vGravity, hGravity, expectedWidthPx, expectedHeightPx, containingRect, appRect); 160 } 161 getDisplayAndWindowState(ComponentName activityName, boolean checkFocus)162 private void getDisplayAndWindowState(ComponentName activityName, boolean checkFocus) 163 throws Exception { 164 final String windowName = getWindowName(activityName); 165 166 mAmWmState.computeState(activityName); 167 168 if (checkFocus) { 169 mAmWmState.assertFocusedWindow("Test window must be the front window.", windowName); 170 } else { 171 mAmWmState.assertVisibility(activityName, true); 172 } 173 174 final List<WindowState> windowList = 175 mAmWmState.getWmState().getMatchingVisibleWindowState(windowName); 176 177 assertEquals("Should have exactly one window state for the activity.", 178 1, windowList.size()); 179 180 mWindowState = windowList.get(0); 181 assertNotNull("Should have a valid window", mWindowState); 182 183 mDisplay = mAmWmState.getWmState().getDisplay(mWindowState.getDisplayId()); 184 assertNotNull("Should be on a display", mDisplay); 185 } 186 verifyFrameSizeAndPosition( int vGravity, int hGravity, int expectedWidthPx, int expectedHeightPx, Rect containingFrame, Rect parentFrame)187 private void verifyFrameSizeAndPosition( 188 int vGravity, int hGravity, int expectedWidthPx, int expectedHeightPx, 189 Rect containingFrame, Rect parentFrame) { 190 assertEquals("Width is incorrect", expectedWidthPx, containingFrame.width()); 191 assertEquals("Height is incorrect", expectedHeightPx, containingFrame.height()); 192 193 if (vGravity == GRAVITY_VER_TOP) { 194 assertEquals("Should be on the top", parentFrame.top, containingFrame.top); 195 } else if (vGravity == GRAVITY_VER_BOTTOM) { 196 assertEquals("Should be on the bottom", parentFrame.bottom, containingFrame.bottom); 197 } 198 199 if (hGravity == GRAVITY_HOR_LEFT) { 200 assertEquals("Should be on the left", parentFrame.left, containingFrame.left); 201 } else if (hGravity == GRAVITY_HOR_RIGHT){ 202 assertEquals("Should be on the right", parentFrame.right, containingFrame.right); 203 } 204 } 205 } 206