summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Robert Carr <racarr@google.com> 2016-10-28 11:45:22 -0700
committer Robert Carr <racarr@google.com> 2016-10-28 13:13:50 -0700
commit16a4e3cbf7068504e4628ed6e81e7700a6f8edbc (patch)
tree966cf141735b1e0bac7100286e5e738e86373556
parent4452e751d41e19ec153acee01518e5a70b49e57e (diff)
Begin series of computeFrame unit tests
Start with a fixture and some simple unit tests for WindowState.computeFrame. Test: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests Change-Id: I3176837ee60dbd474f22a3b1857f19b4e82afee7
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java189
1 files changed, 189 insertions, 0 deletions
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
new file mode 100644
index 000000000000..15cd55f37fb3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -0,0 +1,189 @@
+/*
+ * 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 com.android.server.wm;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Gravity;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
+import static android.view.WindowManager.LayoutParams.FILL_PARENT;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
+ *
+ * Build/Install/Run: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowFrameTests {
+
+ private static WindowManagerService sWm = null;
+ private WindowToken mWindowToken;
+ private final IWindow mIWindow = new TestIWindow();
+
+ class WindowStateWithTask extends WindowState {
+ final Task mTask;
+ WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
+ super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0);
+ mTask = t;
+ }
+
+ @Override
+ Task getTask() {
+ return mTask;
+ }
+ };
+
+ class TaskWithBounds extends Task {
+ final Rect mBounds;
+ TaskWithBounds(Rect bounds) {
+ super(0, mStubStack, 0, sWm, null, null, false);
+ mBounds = bounds;
+ }
+ @Override
+ void getBounds(Rect outBounds) {
+ outBounds.set(mBounds);
+ }
+ @Override
+ void getTempInsetBounds(Rect outBounds) {
+ outBounds.setEmpty();
+ }
+ @Override
+ boolean isFullscreen() {
+ return true;
+ }
+ }
+
+ TaskStack mStubStack;
+
+ @Before
+ public void setUp() throws Exception {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+ mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
+ sWm.getDefaultDisplayContentLocked());
+ mStubStack = new TaskStack(sWm, 0);
+ }
+
+ public void assertRect(Rect rect, int left, int top, int right, int bottom) {
+ assertEquals(left, rect.left);
+ assertEquals(top, rect.top);
+ assertEquals(right, rect.right);
+ assertEquals(bottom, rect.bottom);
+ }
+
+ @Test
+ public void testLayoutInFullscreenTaskNoInsets() throws Exception {
+ Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
+ WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+ w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+ // With no insets or system decor all the frames incoming from PhoneWindowManager
+ // are identical.
+ final Rect pf = new Rect(0, 0, 1000, 1000);
+
+ // Here the window has FILL_PARENT, FILL_PARENT
+ // so we expect it to fill the entire available frame.
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+ // It can select various widths and heights within the bounds.
+ // Strangely the window attribute width is ignored for normal windows
+ // and we use mRequestedWidth/mRequestedHeight
+ w.mAttrs.width = 300;
+ w.mAttrs.height = 300;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ // Explicit width and height without requested width/height
+ // gets us nothing.
+ assertRect(w.mFrame, 0, 0, 0, 0);
+
+ w.mRequestedWidth = 300;
+ w.mRequestedHeight = 300;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ // With requestedWidth/Height we can freely choose our size within the
+ // parent bounds.
+ assertRect(w.mFrame, 0, 0, 300, 300);
+
+ // With FLAG_SCALED though, requestedWidth/height is used to control
+ // the unscaled surface size, and mAttrs.width/height becomes the
+ // layout controller.
+ w.mAttrs.flags = WindowManager.LayoutParams.FLAG_SCALED;
+ w.mRequestedHeight = -1;
+ w.mRequestedWidth = -1;
+ w.mAttrs.width = 100;
+ w.mAttrs.height = 100;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ assertRect(w.mFrame, 0, 0, 100, 100);
+ w.mAttrs.flags = 0;
+
+ // But sizes too large will be clipped to the containing frame
+ w.mRequestedWidth = 1200;
+ w.mRequestedHeight = 1200;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+ // Before they are clipped though windows will be shifted
+ w.mAttrs.x = 300;
+ w.mAttrs.y = 300;
+ w.mRequestedWidth = 1000;
+ w.mRequestedHeight = 1000;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+ // If there is room to move around in the parent frame the window will be shifted according
+ // to gravity.
+ w.mAttrs.x = 0;
+ w.mAttrs.y = 0;
+ w.mRequestedWidth = 300;
+ w.mRequestedHeight = 300;
+ w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ assertRect(w.mFrame, 700, 0, 1000, 300);
+ w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ assertRect(w.mFrame, 700, 700, 1000, 1000);
+ // Window specified x and y are interpreted as offsets in the opposite
+ // direction of gravity
+ w.mAttrs.x = 100;
+ w.mAttrs.y = 100;
+ w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+ assertRect(w.mFrame, 600, 600, 900, 900);
+ }
+
+ private WindowState createWindow(Task task, int width, int height) {
+ final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
+ attrs.width = width;
+ attrs.height = height;
+
+ return new WindowStateWithTask(attrs, task);
+ }
+}