blob: 0533efc6d862770dde689491311bdb8ddfec78c6 [file] [log] [blame]
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001/*
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.Before;
20import org.junit.Test;
21import org.junit.runner.RunWith;
22
23import android.content.Context;
24import android.content.res.Configuration;
25import android.os.IBinder;
26import android.platform.test.annotations.Presubmit;
27import android.support.test.InstrumentationRegistry;
28import android.support.test.filters.SmallTest;
29import android.support.test.runner.AndroidJUnit4;
30import android.view.Display;
31import android.view.IWindow;
32import android.view.WindowManager;
33
34import java.util.ArrayList;
35
36import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
37import static android.app.AppOpsManager.OP_NONE;
38import static android.content.res.Configuration.EMPTY;
39import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
40import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
41import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
42import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
43import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
44import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
45import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
46import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
47import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
48import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
49import static org.junit.Assert.assertEquals;
50import static org.mockito.Mockito.mock;
51
52/**
53 * Tests for the {@link DisplayContent} class.
54 *
55 * Build/Install/Run:
56 * bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests
57 */
58@SmallTest
59@Presubmit
60@RunWith(AndroidJUnit4.class)
61public class DisplayContentTests {
62
63 private static WindowManagerService sWm = null;
64 private final IWindow mIWindow = new TestIWindow();
65 private final Session mMockSession = mock(Session.class);
66 private Display mDisplay;
67 private int mNextStackId = FIRST_DYNAMIC_STACK_ID;
68 private int mNextTaskId = 0;
69
70 @Before
71 public void setUp() throws Exception {
72 final Context context = InstrumentationRegistry.getTargetContext();
73 sWm = TestWindowManagerPolicy.getWindowManagerService(context);
74 mDisplay = context.getDisplay();
75 }
76
77 @Test
78 public void testForAllWindows() throws Exception {
79 final DisplayContent dc = new DisplayContent(mDisplay, sWm, null, null);
80 final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, dc, "wallpaper");
81 final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, dc, "ime");
82 final WindowState imeDialogWindow = createWindow(null, TYPE_INPUT_METHOD_DIALOG, dc,
83 "ime dialog");
84 final WindowState statusBarWindow = createWindow(null, TYPE_STATUS_BAR, dc, "status bar");
85 final WindowState navBarWindow = createWindow(null, TYPE_NAVIGATION_BAR,
86 statusBarWindow.mToken, "nav bar");
87 final WindowState appWindow = createWindow(null, TYPE_BASE_APPLICATION, dc, "app");
88 final WindowState negChildAppWindow = createWindow(appWindow, TYPE_APPLICATION_MEDIA,
89 appWindow.mToken, "negative app child");
90 final WindowState posChildAppWindow = createWindow(appWindow,
91 TYPE_APPLICATION_ATTACHED_DIALOG, appWindow.mToken, "positive app child");
92 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION, dc,
93 "exiting app");
94 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
95 exitingAppToken.mIsExiting = true;
96 exitingAppToken.mTask.mStack.mExitingAppTokens.add(exitingAppToken);
97
98 final ArrayList<WindowState> windows = new ArrayList();
99
100 // Test forward traversal.
101 dc.forAllWindows(windows::add, false /* traverseTopToBottom */);
102
103 assertEquals(wallpaperWindow, windows.get(0));
104 assertEquals(exitingAppWindow, windows.get(1));
105 assertEquals(negChildAppWindow, windows.get(2));
106 assertEquals(appWindow, windows.get(3));
107 assertEquals(posChildAppWindow, windows.get(4));
108 assertEquals(statusBarWindow, windows.get(5));
109 assertEquals(navBarWindow, windows.get(6));
110 assertEquals(imeWindow, windows.get(7));
111 assertEquals(imeDialogWindow, windows.get(8));
112
113 // Test backward traversal.
114 windows.clear();
115 dc.forAllWindows(windows::add, true /* traverseTopToBottom */);
116
117 assertEquals(wallpaperWindow, windows.get(8));
118 assertEquals(exitingAppWindow, windows.get(7));
119 assertEquals(negChildAppWindow, windows.get(6));
120 assertEquals(appWindow, windows.get(5));
121 assertEquals(posChildAppWindow, windows.get(4));
122 assertEquals(statusBarWindow, windows.get(3));
123 assertEquals(navBarWindow, windows.get(2));
124 assertEquals(imeWindow, windows.get(1));
125 assertEquals(imeDialogWindow, windows.get(0));
126 }
127
128 private WindowToken createWindowToken(DisplayContent dc, int type) {
129 if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
130 return new WindowToken(sWm, mock(IBinder.class), type, false, dc);
131 }
132
133 final int stackId = mNextStackId++;
134 dc.addStackToDisplay(stackId, true);
135 final TaskStack stack = sWm.mStackIdToStack.get(stackId);
136 final Task task = new Task(mNextTaskId++, stack, 0, sWm, null, EMPTY, false);
137 stack.addTask(task, true);
138 final AppWindowToken token = new AppWindowToken(sWm, null, false, dc);
139 task.addAppToken(0, token, 0, false);
140 return token;
141 }
142
143 private WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
144 final WindowToken token = createWindowToken(dc, type);
145 return createWindow(parent, type, token, name);
146 }
147
148 private WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
149 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
150 attrs.setTitle(name);
151
152 final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
153 0, attrs, 0, 0);
154 // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
155 // adding it to the token...
156 token.addWindow(w);
157 return w;
158 }
159}