1/* 2 * Copyright (C) 2017 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 17package com.android.server.wm; 18 19import org.junit.Test; 20 21import android.app.WindowConfiguration; 22import android.content.res.Configuration; 23import android.graphics.Rect; 24import android.platform.test.annotations.Presubmit; 25import android.support.test.filters.FlakyTest; 26import android.support.test.filters.SmallTest; 27import android.support.test.runner.AndroidJUnit4; 28import android.view.DisplayInfo; 29 30import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 31import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 32import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 33import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 34import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS; 35import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE; 36import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION; 37import static org.junit.Assert.assertEquals; 38import static org.junit.Assert.assertNotEquals; 39import static org.junit.Assert.assertTrue; 40 41/** 42 * Test class to for {@link android.app.WindowConfiguration}. 43 * 44 * Build/Install/Run: 45 * bit FrameworksServicesTests:com.android.server.wm.WindowConfigurationTests 46 */ 47@SmallTest 48@FlakyTest(bugId = 74078662) 49@Presubmit 50@org.junit.runner.RunWith(AndroidJUnit4.class) 51public class WindowConfigurationTests extends WindowTestsBase { 52 private Rect mParentBounds; 53 54 @Override 55 public void setUp() throws Exception { 56 super.setUp(); 57 mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/); 58 } 59 60 /** Tests {@link android.app.WindowConfiguration#diff(WindowConfiguration, boolean)}. */ 61 @Test 62 public void testDiff() { 63 final Configuration config1 = new Configuration(); 64 final WindowConfiguration winConfig1 = config1.windowConfiguration; 65 final Configuration config2 = new Configuration(); 66 final WindowConfiguration winConfig2 = config2.windowConfiguration; 67 final Configuration config3 = new Configuration(); 68 final WindowConfiguration winConfig3 = config3.windowConfiguration; 69 70 winConfig1.setAppBounds(0, 1, 1, 0); 71 winConfig2.setAppBounds(1, 2, 2, 1); 72 winConfig3.setAppBounds(winConfig1.getAppBounds()); 73 74 75 assertEquals(CONFIG_WINDOW_CONFIGURATION, config1.diff(config2)); 76 assertEquals(0, config1.diffPublicOnly(config2)); 77 assertEquals(WINDOW_CONFIG_APP_BOUNDS, 78 winConfig1.diff(winConfig2, false /* compareUndefined */)); 79 80 winConfig2.setWindowingMode(WINDOWING_MODE_FREEFORM); 81 assertEquals(WINDOW_CONFIG_APP_BOUNDS | WINDOW_CONFIG_WINDOWING_MODE, 82 winConfig1.diff(winConfig2, false /* compareUndefined */)); 83 84 assertEquals(0, config1.diff(config3)); 85 assertEquals(0, config1.diffPublicOnly(config3)); 86 assertEquals(0, winConfig1.diff(winConfig3, false /* compareUndefined */)); 87 } 88 89 /** Tests {@link android.app.WindowConfiguration#compareTo(WindowConfiguration)}. */ 90 @Test 91 public void testConfigurationCompareTo() throws Exception { 92 final Configuration blankConfig = new Configuration(); 93 final WindowConfiguration blankWinConfig = new WindowConfiguration(); 94 95 final Configuration config1 = new Configuration(); 96 final WindowConfiguration winConfig1 = config1.windowConfiguration; 97 winConfig1.setAppBounds(1, 2, 3, 4); 98 99 final Configuration config2 = new Configuration(config1); 100 final WindowConfiguration winConfig2 = config2.windowConfiguration; 101 102 assertEquals(config1.compareTo(config2), 0); 103 assertEquals(winConfig1.compareTo(winConfig2), 0); 104 105 // Different windowing mode 106 winConfig2.setWindowingMode(WINDOWING_MODE_FREEFORM); 107 assertNotEquals(config1.compareTo(config2), 0); 108 assertNotEquals(winConfig1.compareTo(winConfig2), 0); 109 winConfig2.setWindowingMode(winConfig1.getWindowingMode()); 110 111 // Different bounds 112 winConfig2.setAppBounds(0, 2, 3, 4); 113 assertNotEquals(config1.compareTo(config2), 0); 114 assertNotEquals(winConfig1.compareTo(winConfig2), 0); 115 116 // No bounds 117 assertEquals(config1.compareTo(blankConfig), -1); 118 assertEquals(winConfig1.compareTo(blankWinConfig), -1); 119 120 assertEquals(blankConfig.compareTo(config1), 1); 121 assertEquals(blankWinConfig.compareTo(winConfig1), 1); 122 } 123 124 @Test 125 public void testSetActivityType() throws Exception { 126 final WindowConfiguration config = new WindowConfiguration(); 127 config.setActivityType(ACTIVITY_TYPE_HOME); 128 assertEquals(ACTIVITY_TYPE_HOME, config.getActivityType()); 129 130 // Allowed to change from app process. 131 config.setActivityType(ACTIVITY_TYPE_STANDARD); 132 assertEquals(ACTIVITY_TYPE_STANDARD, config.getActivityType()); 133 } 134 135 /** Ensures the configuration app bounds at the root level match the app dimensions. */ 136 @Test 137 public void testAppBounds_RootConfigurationBounds() throws Exception { 138 final DisplayInfo info = mDisplayContent.getDisplayInfo(); 139 info.appWidth = 1024; 140 info.appHeight = 768; 141 142 final Rect appBounds = sWm.computeNewConfiguration( 143 mDisplayContent.getDisplayId()).windowConfiguration.getAppBounds(); 144 // The bounds should always be positioned in the top left. 145 assertEquals(appBounds.left, 0); 146 assertEquals(appBounds.top, 0); 147 148 // The bounds should equal the defined app width and height 149 assertEquals(appBounds.width(), info.appWidth); 150 assertEquals(appBounds.height(), info.appHeight); 151 } 152 153 /** Ensures that bounds are clipped to their parent. */ 154 @Test 155 public void testAppBounds_BoundsClipping() throws Exception { 156 final Rect shiftedBounds = new Rect(mParentBounds); 157 shiftedBounds.offset(10, 10); 158 final Rect expectedBounds = new Rect(mParentBounds); 159 expectedBounds.intersect(shiftedBounds); 160 testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, shiftedBounds, 161 expectedBounds); 162 } 163 164 /** Ensures that empty bounds are not propagated to the configuration. */ 165 @Test 166 public void testAppBounds_EmptyBounds() throws Exception { 167 final Rect emptyBounds = new Rect(); 168 testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, emptyBounds, 169 null /*ExpectedBounds*/); 170 } 171 172 /** Ensures that bounds on freeform stacks are not clipped. */ 173 @Test 174 public void testAppBounds_FreeFormBounds() throws Exception { 175 final Rect freeFormBounds = new Rect(mParentBounds); 176 freeFormBounds.offset(10, 10); 177 testStackBoundsConfiguration(WINDOWING_MODE_FREEFORM, mParentBounds, freeFormBounds, 178 freeFormBounds); 179 } 180 181 /** Ensures that fully contained bounds are not clipped. */ 182 @Test 183 public void testAppBounds_ContainedBounds() throws Exception { 184 final Rect insetBounds = new Rect(mParentBounds); 185 insetBounds.inset(5, 5, 5, 5); 186 testStackBoundsConfiguration( 187 WINDOWING_MODE_FULLSCREEN, mParentBounds, insetBounds, insetBounds); 188 } 189 190 /** Ensures that full screen free form bounds are clipped */ 191 @Test 192 public void testAppBounds_FullScreenFreeFormBounds() throws Exception { 193 final Rect fullScreenBounds = new Rect(0, 0, mDisplayInfo.logicalWidth, 194 mDisplayInfo.logicalHeight); 195 testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, fullScreenBounds, 196 mParentBounds); 197 } 198 199 private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds, 200 Rect expectedConfigBounds) { 201 final StackWindowController stackController = createStackControllerOnStackOnDisplay( 202 windowingMode, ACTIVITY_TYPE_STANDARD, mDisplayContent); 203 204 final Configuration parentConfig = mDisplayContent.getConfiguration(); 205 parentConfig.windowConfiguration.setAppBounds(parentBounds); 206 207 final Configuration config = new Configuration(); 208 final WindowConfiguration winConfig = config.windowConfiguration; 209 stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/, 210 new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/, 211 false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig, 212 windowingMode); 213 // Assert that both expected and actual are null or are equal to each other 214 215 assertEquals(expectedConfigBounds, winConfig.getAppBounds()); 216 } 217 218} 219