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
This commit is contained in:
Robert Carr
2016-10-28 11:45:22 -07:00
parent 4452e751d4
commit 16a4e3cbf7

View File

@@ -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);
}
}