WindowTestsBase.java revision d276563b38907647ce70940e1e90603826df6ab4
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        sWm.mRoot.addChild(sDisplayContent, 0);
79
80        // Set-up some common windows.
81        sWallpaperWindow = createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow");
82        sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow");
83        sImeDialogWindow =
84                createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow");
85        sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow");
86        sNavBarWindow =
87                createWindow(null, TYPE_NAVIGATION_BAR, sDisplayContent, "sNavBarWindow");
88        sDockedDividerWindow =
89                createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow");
90        sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow");
91        sChildAppWindowAbove = createWindow(sAppWindow,
92                TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindowAbove");
93        sChildAppWindowBelow = createWindow(sAppWindow,
94                TYPE_APPLICATION_MEDIA_OVERLAY, sAppWindow.mToken, "sChildAppWindowBelow");
95    }
96
97    /** Asserts that the first entry is greater than the second entry. */
98    void assertGreaterThan(int first, int second) throws Exception {
99        Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second);
100    }
101
102    private WindowToken createWindowToken(DisplayContent dc, int type) {
103        if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
104            return new TestWindowToken(type, dc);
105        }
106
107        final TaskStack stack = createTaskStackOnDisplay(dc);
108        final Task task = createTaskInStack(stack, 0 /* userId */);
109        final TestAppWindowToken token = new TestAppWindowToken(dc);
110        task.addChild(token, 0);
111        return token;
112    }
113
114    WindowState createWindow(WindowState parent, int type, String name) {
115        return (parent == null)
116                ? createWindow(parent, type, sDisplayContent, name)
117                : createWindow(parent, type, parent.mToken, name);
118    }
119
120    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
121        final WindowToken token = createWindowToken(dc, type);
122        return createWindow(parent, type, token, name);
123    }
124
125    WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
126        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
127        attrs.setTitle(name);
128
129        final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
130                0, attrs, 0, 0);
131        // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
132        // adding it to the token...
133        token.addWindow(w);
134        return w;
135    }
136
137    /** Creates a {@link TaskStack} and adds it to the specified {@link DisplayContent}. */
138    TaskStack createTaskStackOnDisplay(DisplayContent dc) {
139        final int stackId = sNextStackId++;
140        dc.addStackToDisplay(stackId, true);
141        return sWm.mStackIdToStack.get(stackId);
142    }
143
144    /**Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
145    Task createTaskInStack(TaskStack stack, int userId) {
146        final Task newTask = new Task(sNextTaskId++, stack, userId, sWm, null, EMPTY, false, 0,
147                false);
148        stack.addTask(newTask, true);
149        return newTask;
150    }
151
152    /* Used so we can gain access to some protected members of the {@link WindowToken} class */
153    class TestWindowToken extends WindowToken {
154
155        TestWindowToken(int type, DisplayContent dc) {
156            this(type, dc, false /* persistOnEmpty */);
157        }
158
159        TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
160            super(sWm, mock(IBinder.class), type, persistOnEmpty, dc);
161        }
162
163        int getWindowsCount() {
164            return mChildren.size();
165        }
166
167        boolean hasWindow(WindowState w) {
168            return mChildren.contains(w);
169        }
170    }
171
172    /* Used so we can gain access to some protected members of the {@link AppWindowToken} class */
173    class TestAppWindowToken extends AppWindowToken {
174
175        TestAppWindowToken(DisplayContent dc) {
176            super(sWm, null, false, dc);
177        }
178
179        int getWindowsCount() {
180            return mChildren.size();
181        }
182
183        boolean hasWindow(WindowState w) {
184            return mChildren.contains(w);
185        }
186
187        WindowState getFirstChild() {
188            return mChildren.getFirst();
189        }
190
191        WindowState getLastChild() {
192            return mChildren.getLast();
193        }
194    }
195}
196