blob: 5b21ee90934fdf90f68c16e215b3cddd013fb1f8 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package android.server.cts;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
public class ActivityManagerAppConfigurationTests extends ActivityManagerTestBase {
private static final String RESIZEABLE_ACTIVITY_NAME = "ResizeableActivity";
private static final String TEST_ACTIVITY_NAME = "TestActivity";
/**
* Tests that the WindowManager#getDefaultDisplay() and the Configuration of the Activity
* has an updated size when the Activity is resized from fullscreen to docked state.
*
* The Activity handles configuration changes, so it will not be restarted between resizes.
* On Configuration changes, the Activity logs the Display size and Configuration width
* and heights. The values reported in fullscreen should be larger than those reported in
* docked state.
*/
public void testConfigurationUpdatesWhenResizedFromFullscreen() throws Exception {
launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
final ReportedSizes fullscreenSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
FULLSCREEN_WORKSPACE_STACK_ID);
moveActivityToStack(RESIZEABLE_ACTIVITY_NAME, DOCKED_STACK_ID);
final ReportedSizes dockedSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
DOCKED_STACK_ID);
assertSizesAreSane(fullscreenSizes, dockedSizes);
}
/**
* Same as {@link #testConfigurationUpdatesWhenResizedFromFullscreen()} but resizing
* from docked state to fullscreen (reverse).
*/
public void testConfigurationUpdatesWhenResizedFromDockedStack() throws Exception {
launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, DOCKED_STACK_ID);
final ReportedSizes dockedSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
DOCKED_STACK_ID);
moveActivityToStack(RESIZEABLE_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
final ReportedSizes fullscreenSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
FULLSCREEN_WORKSPACE_STACK_ID);
assertSizesAreSane(fullscreenSizes, dockedSizes);
}
/**
* Tests whether the Display sizes change when rotating the device.
*/
public void testConfigurationUpdatesWhenRotatingWhileFullscreen() throws Exception {
setDeviceRotation(0);
launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, FULLSCREEN_WORKSPACE_STACK_ID);
final ReportedSizes orientationASizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
FULLSCREEN_WORKSPACE_STACK_ID);
setDeviceRotation(1);
final ReportedSizes orientationBSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
FULLSCREEN_WORKSPACE_STACK_ID);
assertSizesRotate(orientationASizes, orientationBSizes);
}
/**
* Same as {@link #testConfigurationUpdatesWhenRotatingWhileFullscreen()} but when the Activity
* is in the docked stack.
*/
public void testConfigurationUpdatesWhenRotatingWhileDocked() throws Exception {
setDeviceRotation(0);
launchActivityInStack(RESIZEABLE_ACTIVITY_NAME, DOCKED_STACK_ID);
final ReportedSizes orientationASizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
DOCKED_STACK_ID);
setDeviceRotation(1);
final ReportedSizes orientationBSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
DOCKED_STACK_ID);
assertSizesRotate(orientationASizes, orientationBSizes);
}
/**
* Tests when activity moved from fullscreen stack to docked and back. Activity will be
* relaunched twice and it should have same config as initial one.
*/
public void testSameConfigurationFullSplitFullRelaunch() throws Exception {
moveActivityFullSplitFull(TEST_ACTIVITY_NAME);
}
/**
* Same as {@link #testSameConfigurationFullSplitFullRelaunch} but without relaunch.
*/
public void testSameConfigurationFullSplitFullNoRelaunch() throws Exception {
moveActivityFullSplitFull(RESIZEABLE_ACTIVITY_NAME);
}
/**
* Launches activity in fullscreen stack, moves to docked stack and back to fullscreen stack.
* Last operation is done in a way which simulates split-screen divider movement maximizing
* docked stack size and then moving task to fullscreen stack - the same way it is done when
* user long-presses overview/recents button to exit split-screen.
* Asserts that initial and final reported sizes in fullscreen stack are the same.
*/
private void moveActivityFullSplitFull(String activityName) throws Exception {
// Launch to fullscreen stack and record size.
launchActivityInStack(activityName, FULLSCREEN_WORKSPACE_STACK_ID);
final ReportedSizes initialFullscreenSizes = getActivityDisplaySize(activityName,
FULLSCREEN_WORKSPACE_STACK_ID);
final Rectangle displayRect = getDisplayRect(activityName);
// Move to docked stack.
moveActivityToStack(activityName, DOCKED_STACK_ID);
final ReportedSizes dockedSizes = getActivityDisplaySize(activityName, DOCKED_STACK_ID);
assertSizesAreSane(initialFullscreenSizes, dockedSizes);
// Make sure docked stack is focused. This way when we dismiss it later fullscreen stack
// will come up.
launchActivityInStack(activityName, DOCKED_STACK_ID);
mAmWmState.computeState(mDevice, new String[] { activityName },
false /* compareTaskAndStackBounds */);
// Resize docked stack to fullscreen size. This will trigger activity relaunch with
// non-empty override configuration corresponding to fullscreen size.
runCommandAndPrintOutput("am stack resize " + DOCKED_STACK_ID + " 0 0 "
+ displayRect.width + " " + displayRect.height);
// Move activity back to fullscreen stack.
moveActivityToStack(activityName, FULLSCREEN_WORKSPACE_STACK_ID);
final ReportedSizes finalFullscreenSizes = getActivityDisplaySize(activityName,
FULLSCREEN_WORKSPACE_STACK_ID);
// After activity configuration was changed twice it must report same size as original one.
assertSizesAreSame(initialFullscreenSizes, finalFullscreenSizes);
}
/**
* Tests when activity moved from docked stack to fullscreen and back. Activity will be
* relaunched twice and it should have same config as initial one.
*/
public void testSameConfigurationSplitFullSplitRelaunch() throws Exception {
moveActivitySplitFullSplit(TEST_ACTIVITY_NAME);
}
/**
* Same as {@link #testSameConfigurationSplitFullSplitRelaunch} but without relaunch.
*/
public void testSameConfigurationSplitFullSplitNoRelaunch() throws Exception {
moveActivitySplitFullSplit(RESIZEABLE_ACTIVITY_NAME);
}
/**
* Launches activity in docked stack, moves to fullscreen stack and back to docked stack.
* Asserts that initial and final reported sizes in docked stack are the same.
*/
private void moveActivitySplitFullSplit(String activityName) throws Exception {
// Launch to docked stack and record size.
launchActivityInStack(activityName, DOCKED_STACK_ID);
final ReportedSizes initialDockedSizes = getActivityDisplaySize(activityName,
DOCKED_STACK_ID);
// Make sure docked stack is focused. This way when we dismiss it later fullscreen stack
// will come up.
launchActivityInStack(activityName, DOCKED_STACK_ID);
mAmWmState.computeState(mDevice, new String[] { activityName },
false /* compareTaskAndStackBounds */);
// Move to fullscreen stack.
moveActivityToStack(activityName, FULLSCREEN_WORKSPACE_STACK_ID);
final ReportedSizes fullscreenSizes = getActivityDisplaySize(activityName,
FULLSCREEN_WORKSPACE_STACK_ID);
assertSizesAreSane(fullscreenSizes, initialDockedSizes);
// Move activity back to docked stack.
moveActivityToStack(activityName, DOCKED_STACK_ID);
final ReportedSizes finalDockedSizes = getActivityDisplaySize(activityName,
DOCKED_STACK_ID);
// After activity configuration was changed twice it must report same size as original one.
assertSizesAreSame(initialDockedSizes, finalDockedSizes);
}
/**
* Asserts that after rotation, the aspect ratios of display size, metrics, and configuration
* have flipped.
*/
private static void assertSizesRotate(ReportedSizes rotationA, ReportedSizes rotationB)
throws Exception {
assertEquals(rotationA.displayWidth, rotationA.metricsWidth);
assertEquals(rotationA.displayHeight, rotationA.metricsHeight);
assertEquals(rotationB.displayWidth, rotationB.metricsWidth);
assertEquals(rotationB.displayHeight, rotationB.metricsHeight);
final boolean beforePortrait = rotationA.displayWidth < rotationA.displayHeight;
final boolean afterPortrait = rotationB.displayWidth < rotationB.displayHeight;
assertFalse(beforePortrait == afterPortrait);
final boolean beforeConfigPortrait = rotationA.widthDp < rotationA.heightDp;
final boolean afterConfigPortrait = rotationB.widthDp < rotationB.heightDp;
assertEquals(beforePortrait, beforeConfigPortrait);
assertEquals(afterPortrait, afterConfigPortrait);
}
/**
* Throws an AssertionError if fullscreenSizes has widths/heights (depending on aspect ratio)
* that are smaller than the dockedSizes.
*/
private static void assertSizesAreSane(ReportedSizes fullscreenSizes, ReportedSizes dockedSizes)
throws Exception {
final boolean portrait = fullscreenSizes.displayWidth < fullscreenSizes.displayHeight;
if (portrait) {
assertTrue(dockedSizes.displayHeight < fullscreenSizes.displayHeight);
assertTrue(dockedSizes.heightDp < fullscreenSizes.heightDp);
assertTrue(dockedSizes.metricsHeight < fullscreenSizes.metricsHeight);
} else {
assertTrue(dockedSizes.displayWidth < fullscreenSizes.displayWidth);
assertTrue(dockedSizes.widthDp < fullscreenSizes.widthDp);
assertTrue(dockedSizes.metricsWidth < fullscreenSizes.metricsWidth);
}
}
/**
* Throws an AssertionError if sizes are different.
*/
private static void assertSizesAreSame(ReportedSizes firstSize, ReportedSizes secondSize)
throws Exception {
assertEquals(firstSize.widthDp, secondSize.widthDp);
assertEquals(firstSize.heightDp, secondSize.heightDp);
assertEquals(firstSize.displayWidth, secondSize.displayWidth);
assertEquals(firstSize.displayHeight, secondSize.displayHeight);
assertEquals(firstSize.metricsWidth, secondSize.metricsWidth);
assertEquals(firstSize.metricsHeight, secondSize.metricsHeight);
}
private ReportedSizes getActivityDisplaySize(String activityName, int stackId)
throws Exception {
mAmWmState.computeState(mDevice, new String[] { activityName },
false /* compareTaskAndStackBounds */);
mAmWmState.assertContainsStack("Must contain stack " + stackId, stackId);
final ReportedSizes details = getLastReportedSizesForActivity(activityName);
assertNotNull(details);
return details;
}
private Rectangle getDisplayRect(String activityName)
throws Exception {
final String windowName = getWindowName(activityName);
mAmWmState.computeState(mDevice, true /* visibleOnly */, new String[] {activityName});
mAmWmState.assertFocusedWindow("Test window must be the front window.", windowName);
final List<WindowManagerState.WindowState> tempWindowList = new ArrayList<>();
mAmWmState.getWmState().getMatchingWindowState(windowName, tempWindowList);
assertEquals("Should have exactly one window state for the activity.", 1,
tempWindowList.size());
WindowManagerState.WindowState windowState = tempWindowList.get(0);
assertNotNull("Should have a valid window", windowState);
WindowManagerState.Display display = mAmWmState.getWmState()
.getDisplay(windowState.getDisplayId());
assertNotNull("Should be on a display", display);
return display.getDisplayRect();
}
}