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