WindowTestsBase.java revision 6ce0fb8ddbdc726d55c81a4bf797f028e441e448
1/*
2 * Copyright (C) 2016 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.Assert;
20import org.junit.Before;
21
22import android.content.Context;
23import android.os.IBinder;
24import android.support.test.InstrumentationRegistry;
25import android.view.IWindow;
26import android.view.WindowManager;
27
28import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
29import static android.app.AppOpsManager.OP_NONE;
30import static android.content.res.Configuration.EMPTY;
31import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
32import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
33import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
34import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
35import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
36import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
37import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
38import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
39import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
40import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
41import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
42import static org.mockito.Mockito.mock;
43
44/**
45 * Common base class for window manager unit test classes.
46 */
47public class WindowTestsBase {
48    static WindowManagerService sWm = null;
49    private final IWindow mIWindow = new TestIWindow();
50    private final Session mMockSession = mock(Session.class);
51    private static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
52    private static int sNextTaskId = 0;
53
54    private static boolean sOneTimeSetupDone = false;
55    protected static DisplayContent sDisplayContent;
56    protected static WindowLayersController sLayersController;
57    protected static WindowState sWallpaperWindow;
58    protected static WindowState sImeWindow;
59    protected static WindowState sImeDialogWindow;
60    protected static WindowState sStatusBarWindow;
61    protected static WindowState sDockedDividerWindow;
62    protected static WindowState sNavBarWindow;
63    protected static WindowState sAppWindow;
64    protected static WindowState sChildAppWindowAbove;
65    protected static WindowState sChildAppWindowBelow;
66
67    @Before
68    public void setUp() throws Exception {
69        if (sOneTimeSetupDone) {
70            return;
71        }
72        sOneTimeSetupDone = true;
73        final Context context = InstrumentationRegistry.getTargetContext();
74        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
75        sLayersController = new WindowLayersController(sWm);
76        sDisplayContent = new DisplayContent(context.getDisplay(), sWm, sLayersController,
77                new WallpaperController(sWm));
78
79        // Set-up some common windows.
80        sWallpaperWindow = createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow");
81        sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow");
82        sImeDialogWindow =
83                createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow");
84        sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow");
85        sNavBarWindow =
86                createWindow(null, TYPE_NAVIGATION_BAR, sDisplayContent, "sNavBarWindow");
87        sDockedDividerWindow =
88                createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow");
89        sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow");
90        sChildAppWindowAbove = createWindow(sAppWindow,
91                TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindowAbove");
92        sChildAppWindowBelow = createWindow(sAppWindow,
93                TYPE_APPLICATION_MEDIA_OVERLAY, sAppWindow.mToken, "sChildAppWindowBelow");
94    }
95
96    /** Asserts that the first entry is greater than the second entry. */
97    void assertGreaterThan(int first, int second) throws Exception {
98        Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second);
99    }
100
101    private WindowToken createWindowToken(DisplayContent dc, int type) {
102        if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
103            return new TestWindowToken(type, dc);
104        }
105
106        final int stackId = sNextStackId++;
107        dc.addStackToDisplay(stackId, true);
108        final TaskStack stack = sWm.mStackIdToStack.get(stackId);
109        final Task task = new Task(sNextTaskId++, stack, 0, sWm, null, EMPTY, false, 0, false);
110        stack.addTask(task, true);
111        final TestAppWindowToken token = new TestAppWindowToken(dc);
112        task.addChild(token, 0);
113        return token;
114    }
115
116    WindowState createWindow(WindowState parent, int type, String name) {
117        return (parent == null)
118                ? createWindow(parent, type, sDisplayContent, name)
119                : createWindow(parent, type, parent.mToken, name);
120    }
121
122    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
123        final WindowToken token = createWindowToken(dc, type);
124        return createWindow(parent, type, token, name);
125    }
126
127    WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
128        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
129        attrs.setTitle(name);
130
131        final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
132                0, attrs, 0, 0);
133        // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
134        // adding it to the token...
135        token.addWindow(w);
136        return w;
137    }
138
139    /* Used so we can gain access to some protected members of the {@link WindowToken} class */
140    class TestWindowToken extends WindowToken {
141
142        TestWindowToken(int type, DisplayContent dc) {
143            this(type, dc, false /* persistOnEmpty */);
144        }
145
146        TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
147            super(sWm, mock(IBinder.class), type, persistOnEmpty, dc);
148        }
149
150        int getWindowsCount() {
151            return mChildren.size();
152        }
153
154        boolean hasWindow(WindowState w) {
155            return mChildren.contains(w);
156        }
157    }
158
159    /* Used so we can gain access to some protected members of the {@link AppWindowToken} class */
160    class TestAppWindowToken extends AppWindowToken {
161
162        TestAppWindowToken(DisplayContent dc) {
163            super(sWm, null, false, dc);
164        }
165
166        int getWindowsCount() {
167            return mChildren.size();
168        }
169
170        boolean hasWindow(WindowState w) {
171            return mChildren.contains(w);
172        }
173
174        WindowState getFirstChild() {
175            return mChildren.getFirst();
176        }
177
178        WindowState getLastChild() {
179            return mChildren.getLast();
180        }
181    }
182}
183