blob: 094622154ca03588864d902c33eb25076f89b5d5 [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.wm;
import static android.server.am.ComponentNameUtils.getWindowName;
import static android.server.wm.DialogFrameTestActivity.DIALOG_WINDOW_NAME;
import static android.server.wm.DialogFrameTestActivity.TEST_EXPLICIT_POSITION_MATCH_PARENT;
import static android.server.wm.DialogFrameTestActivity.TEST_EXPLICIT_POSITION_MATCH_PARENT_NO_LIMITS;
import static android.server.wm.DialogFrameTestActivity.TEST_EXPLICIT_SIZE;
import static android.server.wm.DialogFrameTestActivity.TEST_EXPLICIT_SIZE_BOTTOM_RIGHT_GRAVITY;
import static android.server.wm.DialogFrameTestActivity.TEST_EXPLICIT_SIZE_TOP_LEFT_GRAVITY;
import static android.server.wm.DialogFrameTestActivity.TEST_MATCH_PARENT;
import static android.server.wm.DialogFrameTestActivity.TEST_MATCH_PARENT_LAYOUT_IN_OVERSCAN;
import static android.server.wm.DialogFrameTestActivity.TEST_NO_FOCUS;
import static android.server.wm.DialogFrameTestActivity.TEST_OVER_SIZED_DIMENSIONS;
import static android.server.wm.DialogFrameTestActivity.TEST_OVER_SIZED_DIMENSIONS_NO_LIMITS;
import static android.server.wm.DialogFrameTestActivity.TEST_WITH_MARGINS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import android.content.ComponentName;
import android.graphics.Rect;
import android.platform.test.annotations.AppModeFull;
import android.server.am.WaitForValidActivityState;
import android.server.am.WindowManagerState;
import android.server.am.WindowManagerState.WindowState;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import java.util.List;
/**
* Build/Install/Run:
* atest CtsWindowManagerDeviceTestCases:DialogFrameTests
*
* TODO: Consolidate this class with {@link ParentChildTestBase}.
*/
@AppModeFull(reason = "Requires android.permission.MANAGE_ACTIVITY_STACKS")
public class DialogFrameTests extends ParentChildTestBase<DialogFrameTestActivity> {
private static final ComponentName DIALOG_FRAME_TEST_ACTIVITY = new ComponentName(
InstrumentationRegistry.getContext(), DialogFrameTestActivity.class);
@Rule
public final ActivityTestRule<DialogFrameTestActivity> mDialogTestActivity =
new ActivityTestRule<>(DialogFrameTestActivity.class, false /* initialTOuchMode */,
false /* launchActivity */);
@Override
ComponentName activityName() {
return DIALOG_FRAME_TEST_ACTIVITY;
}
@Override
ActivityTestRule<DialogFrameTestActivity> activityRule() {
return mDialogTestActivity;
}
private WindowState getSingleWindow(final String windowName) {
final List<WindowState> windowList =
mAmWmState.getWmState().getMatchingVisibleWindowState(windowName);
assertThat(windowList.size(), greaterThan(0));
return windowList.get(0);
}
@Override
void doSingleTest(ParentChildTest t) throws Exception {
mAmWmState.computeState(WaitForValidActivityState.forWindow(DIALOG_WINDOW_NAME));
WindowState dialog = getSingleWindow(DIALOG_WINDOW_NAME);
WindowState parent = getSingleWindow(getWindowName(activityName()));
t.doTest(parent, dialog);
}
// With Width and Height as MATCH_PARENT we should fill
// the same content frame as the main activity window
@Test
public void testMatchParentDialog() throws Exception {
doParentChildTest(TEST_MATCH_PARENT, (parent, dialog) ->
assertEquals(parent.getContentFrame(), dialog.getFrame())
);
}
// If we have LAYOUT_IN_SCREEN and LAYOUT_IN_OVERSCAN with MATCH_PARENT,
// we will not be constrained to the insets and so we will be the same size
// as the main window main frame.
// TODO: b/80262496
// LAYOUT_IN_OVERSCAN isn't allowing windows to extend in to cutouts. We will have
// to revisit whether to modify the behavior, or this test.
@Ignore
@Test
public void testMatchParentDialogLayoutInOverscan() throws Exception {
doParentChildTest(TEST_MATCH_PARENT_LAYOUT_IN_OVERSCAN, (parent, dialog) ->
assertEquals(parent.getFrame(), dialog.getFrame())
);
}
private static final int explicitDimension = 200;
// The default gravity for dialogs should center them.
@Test
public void testExplicitSizeDefaultGravity() throws Exception {
doParentChildTest(TEST_EXPLICIT_SIZE, (parent, dialog) -> {
Rect contentFrame = parent.getContentFrame();
Rect expectedFrame = new Rect(
contentFrame.left + (contentFrame.width() - explicitDimension) / 2,
contentFrame.top + (contentFrame.height() - explicitDimension) / 2,
contentFrame.left + (contentFrame.width() + explicitDimension) / 2,
contentFrame.top + (contentFrame.height() + explicitDimension) / 2);
assertEquals(expectedFrame, dialog.getFrame());
});
}
@Test
public void testExplicitSizeTopLeftGravity() throws Exception {
doParentChildTest(TEST_EXPLICIT_SIZE_TOP_LEFT_GRAVITY, (parent, dialog) -> {
Rect contentFrame = parent.getContentFrame();
Rect expectedFrame = new Rect(
contentFrame.left,
contentFrame.top,
contentFrame.left + explicitDimension,
contentFrame.top + explicitDimension);
assertEquals(expectedFrame, dialog.getFrame());
});
}
@Test
public void testExplicitSizeBottomRightGravity() throws Exception {
doParentChildTest(TEST_EXPLICIT_SIZE_BOTTOM_RIGHT_GRAVITY, (parent, dialog) -> {
Rect contentFrame = parent.getContentFrame();
Rect expectedFrame = new Rect(
contentFrame.left + contentFrame.width() - explicitDimension,
contentFrame.top + contentFrame.height() - explicitDimension,
contentFrame.left + contentFrame.width(),
contentFrame.top + contentFrame.height());
assertEquals(expectedFrame, dialog.getFrame());
});
}
// TODO(b/30127373): Commented out for now because it doesn't work. We end up insetting the
// decor on the bottom. I think this is a bug probably in the default dialog flags:
@Ignore
@Test
public void testOversizedDimensions() throws Exception {
doParentChildTest(TEST_OVER_SIZED_DIMENSIONS, (parent, dialog) ->
// With the default flags oversize should result in clipping to
// parent frame.
assertEquals(parent.getContentFrame(), dialog.getFrame())
);
}
// TODO(b/63993863) : Disabled pending public API to fetch maximum surface size.
static final int oversizedDimension = 5000;
// With FLAG_LAYOUT_NO_LIMITS we should get the size we request, even if its much larger than
// the screen.
@Ignore
@Test
public void testOversizedDimensionsNoLimits() throws Exception {
// TODO(b/36890978): We only run this in fullscreen because of the
// unclear status of NO_LIMITS for non-child surfaces in MW modes
doFullscreenTest(TEST_OVER_SIZED_DIMENSIONS_NO_LIMITS, (parent, dialog) -> {
Rect contentFrame = parent.getContentFrame();
Rect expectedFrame = new Rect(contentFrame.left, contentFrame.top,
contentFrame.left + oversizedDimension,
contentFrame.top + oversizedDimension);
assertEquals(expectedFrame, dialog.getFrame());
});
}
// If we request the MATCH_PARENT and a non-zero position, we wouldn't be
// able to fit all of our content, so we should be adjusted to just fit the
// content frame.
@Test
public void testExplicitPositionMatchParent() throws Exception {
doParentChildTest(TEST_EXPLICIT_POSITION_MATCH_PARENT, (parent, dialog) ->
assertEquals(parent.getContentFrame(), dialog.getFrame())
);
}
// Unless we pass NO_LIMITS in which case our requested position should
// be honored.
@Test
public void testExplicitPositionMatchParentNoLimits() throws Exception {
final int explicitPosition = 100;
doParentChildTest(TEST_EXPLICIT_POSITION_MATCH_PARENT_NO_LIMITS, (parent, dialog) -> {
Rect contentFrame = parent.getContentFrame();
Rect expectedFrame = new Rect(contentFrame);
expectedFrame.offset(explicitPosition, explicitPosition);
assertEquals(expectedFrame, dialog.getFrame());
});
}
// We run the two focus tests fullscreen only because switching to the
// docked stack will strip away focus from the task anyway.
@Test
public void testDialogReceivesFocus() throws Exception {
doFullscreenTest(TEST_MATCH_PARENT, (parent, dialog) ->
assertEquals(dialog.getName(), mAmWmState.getWmState().getFocusedWindow())
);
}
@Test
public void testNoFocusDialog() throws Exception {
doFullscreenTest(TEST_NO_FOCUS, (parent, dialog) ->
assertEquals(parent.getName(), mAmWmState.getWmState().getFocusedWindow())
);
}
@Test
public void testMarginsArePercentagesOfContentFrame() throws Exception {
float horizontalMargin = .25f;
float verticalMargin = .35f;
doParentChildTest(TEST_WITH_MARGINS, (parent, dialog) -> {
Rect frame = parent.getContentFrame();
Rect expectedFrame = new Rect(
(int) (horizontalMargin * frame.width() + frame.left),
(int) (verticalMargin * frame.height() + frame.top),
(int) (horizontalMargin * frame.width() + frame.left) + explicitDimension,
(int) (verticalMargin * frame.height() + frame.top) + explicitDimension);
assertEquals(expectedFrame, dialog.getFrame());
});
}
@Test
public void testDialogPlacedAboveParent() throws Exception {
final WindowManagerState wmState = mAmWmState.getWmState();
doParentChildTest(TEST_MATCH_PARENT, (parent, dialog) ->
// Not only should the dialog be higher, but it should be leave multiple layers of
// space in between for DimLayers, etc...
assertThat(wmState.getZOrder(dialog), greaterThan(wmState.getZOrder(parent)))
);
}
}