blob: 0e4d048ee15eaf4894e19f90b4ab4567832bab64 [file] [log] [blame]
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08001/*
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
Jorim Jaggie2c77f92016-12-29 14:57:22 +010019import android.app.ActivityManager.TaskSnapshot;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080020import android.content.res.Configuration;
Jorim Jaggi02886a82016-12-06 09:10:06 -080021import android.graphics.GraphicBuffer;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080022import android.graphics.Rect;
23import android.util.EventLog;
24import android.util.Slog;
25
26import static com.android.server.EventLogTags.WM_TASK_CREATED;
27import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
28import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
29import static com.android.server.wm.WindowContainer.POSITION_TOP;
30import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
31import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
32
33/**
34 * Controller for the task container. This is created by activity manager to link task records to
35 * the task container they use in window manager.
36 *
37 * Test class: {@link TaskWindowContainerControllerTests}
38 */
39public class TaskWindowContainerController
40 extends WindowContainerController<Task, WindowContainerListener> {
41
42 private final int mTaskId;
43
44 public TaskWindowContainerController(int taskId, int stackId, int userId, Rect bounds,
45 Configuration overrideConfig, int resizeMode, boolean homeTask, boolean isOnTopLauncher,
46 boolean toTop, boolean showForAllUsers) {
47 super(null, WindowManagerService.getInstance());
48 mTaskId = taskId;
49
50 synchronized(mWindowMap) {
51 if (DEBUG_STACK) Slog.i(TAG_WM, "TaskWindowContainerController: taskId=" + taskId
52 + " stackId=" + stackId + " bounds=" + bounds);
53
54 // TODO: Pass controller for the stack to get the container object when stack is
55 // switched to use controller.
56 final TaskStack stack = mService.mStackIdToStack.get(stackId);
57 if (stack == null) {
58 throw new IllegalArgumentException("TaskWindowContainerController: invalid stackId="
59 + stackId);
60 }
61 EventLog.writeEvent(WM_TASK_CREATED, taskId, stackId);
62 final Task task = new Task(taskId, stack, userId, mService, bounds, overrideConfig,
63 isOnTopLauncher, resizeMode, homeTask, this);
64 final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
65 stack.addTask(task, position, showForAllUsers, true /* moveParents */);
66 }
67 }
68
69 @Override
70 public void removeContainer() {
71 synchronized(mWindowMap) {
72 if (mContainer == null) {
73 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + mTaskId);
74 return;
75 }
76 mContainer.removeIfPossible();
77 super.removeContainer();
78 }
79 }
80
81 public void positionChildAt(AppWindowContainerController childController, int index) {
82 synchronized(mService.mWindowMap) {
83 final AppWindowToken aToken = childController.mContainer;
84 if (aToken == null) {
85 Slog.w(TAG_WM,
86 "Attempted to position of non-existing app : " + childController);
87 return;
88 }
89
90 final Task task = mContainer;
91 if (task == null) {
92 throw new IllegalArgumentException("positionChildAt: invalid task=" + this);
93 }
94 task.addChild(aToken, index);
95 }
96 }
97
98 public void reparent(int stackId, int position) {
99 synchronized (mWindowMap) {
100 if (DEBUG_STACK) Slog.i(TAG_WM, "reparent: moving taskId=" + mTaskId
101 + " to stackId=" + stackId + " at " + position);
102 if (mContainer == null) {
103 if (DEBUG_STACK) Slog.i(TAG_WM,
104 "reparent: could not find taskId=" + mTaskId);
105 return;
106 }
107 final TaskStack stack = mService.mStackIdToStack.get(stackId);
108 if (stack == null) {
109 if (DEBUG_STACK) Slog.i(TAG_WM,
110 "reparent: could not find stackId=" + stackId);
111 return;
112 }
113 mContainer.reparent(stack, position);
114 final DisplayContent displayContent = stack.getDisplayContent();
115 displayContent.setLayoutNeeded();
116 mService.mWindowPlacerLocked.performSurfacePlacement();
117 }
118 }
119
120 public void setResizeable(int resizeMode) {
121 synchronized (mWindowMap) {
122 if (mContainer != null) {
123 mContainer.setResizeable(resizeMode);
124 }
125 }
126 }
127
128 public void resize(Rect bounds, Configuration overrideConfig, boolean relayout,
129 boolean forced) {
130 synchronized (mWindowMap) {
131 if (mContainer == null) {
132 throw new IllegalArgumentException("resizeTask: taskId " + mTaskId + " not found.");
133 }
134
135 if (mContainer.resizeLocked(bounds, overrideConfig, forced) && relayout) {
136 mContainer.getDisplayContent().setLayoutNeeded();
137 mService.mWindowPlacerLocked.performSurfacePlacement();
138 }
139 }
140 }
141
142 // TODO: Move to positionChildAt() in stack controller once we have a stack controller.
143 public void positionAt(int stackId, int index, Rect bounds, Configuration overrideConfig) {
144 synchronized (mWindowMap) {
145 if (DEBUG_STACK) Slog.i(TAG_WM, "positionChildAt: positioning taskId=" + mTaskId
146 + " in stackId=" + stackId + " at " + index);
147 if (mContainer == null) {
148 if (DEBUG_STACK) Slog.i(TAG_WM,
149 "positionTaskInStack: could not find taskId=" + mTaskId);
150 return;
151 }
152 final TaskStack stack = mService.mStackIdToStack.get(stackId);
153 if (stack == null) {
154 if (DEBUG_STACK) Slog.i(TAG_WM,
155 "positionTaskInStack: could not find stackId=" + stackId);
156 return;
157 }
158 mContainer.positionTaskInStack(stack, index, bounds, overrideConfig);
159 final DisplayContent displayContent = stack.getDisplayContent();
160 displayContent.setLayoutNeeded();
161 mService.mWindowPlacerLocked.performSurfacePlacement();
162 }
163 }
164
165 // TODO: Replace with moveChildToTop in stack controller?
166 public void moveToTop(boolean includingParents) {
167 synchronized(mWindowMap) {
168 if (mContainer == null) {
169 Slog.e(TAG_WM, "moveToTop: taskId=" + mTaskId + " not found");
170 return;
171 }
172 final TaskStack stack = mContainer.mStack;
173 stack.positionChildAt(POSITION_TOP, mContainer, includingParents);
174
175 if (mService.mAppTransition.isTransitionSet()) {
176 mContainer.setSendingToBottom(false);
177 }
178 stack.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
179 }
180 }
181
182 // TODO: Replace with moveChildToBottom in stack controller?
183 public void moveToBottom() {
184 synchronized(mWindowMap) {
185 if (mContainer == null) {
186 Slog.e(TAG_WM, "moveTaskToBottom: taskId=" + mTaskId + " not found");
187 return;
188 }
189 final TaskStack stack = mContainer.mStack;
190 stack.positionChildAt(POSITION_BOTTOM, mContainer, false /* includingParents */);
191 if (mService.mAppTransition.isTransitionSet()) {
192 mContainer.setSendingToBottom(true);
193 }
194 stack.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
195 }
196 }
197
198 public void getBounds(Rect bounds) {
199 synchronized (mWindowMap) {
200 if (mContainer != null) {
201 mContainer.getBounds(bounds);
202 return;
203 }
204 bounds.setEmpty();
205 }
206 }
207
208 /**
209 * Puts this task into docked drag resizing mode. See {@link DragResizeMode}.
210 *
211 * @param resizing Whether to put the task into drag resize mode.
212 */
213 public void setTaskDockedResizing(boolean resizing) {
214 synchronized (mWindowMap) {
215 if (mContainer == null) {
216 Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + mTaskId + " not found.");
217 return;
218 }
219 mContainer.setDragResizing(resizing, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
220 }
221 }
222
223 public void cancelWindowTransition() {
224 synchronized (mWindowMap) {
225 if (mContainer == null) {
226 Slog.w(TAG_WM, "cancelWindowTransition: taskId " + mTaskId + " not found.");
227 return;
228 }
229 mContainer.cancelTaskWindowTransition();
230 }
231 }
232
233 public void cancelThumbnailTransition() {
234 synchronized (mWindowMap) {
235 if (mContainer == null) {
236 Slog.w(TAG_WM, "cancelThumbnailTransition: taskId " + mTaskId + " not found.");
237 return;
238 }
239 mContainer.cancelTaskThumbnailTransition();
240 }
241 }
242
Jorim Jaggi02886a82016-12-06 09:10:06 -0800243 /**
244 * @return a graphic buffer representing a screenshot of a task
245 */
Jorim Jaggie2c77f92016-12-29 14:57:22 +0100246 public TaskSnapshot getSnapshot() {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800247 synchronized (mWindowMap) {
248 if (mContainer == null) {
249 Slog.w(TAG_WM, "getSnapshot: taskId " + mTaskId + " not found.");
250 return null;
251 }
252 return mService.mTaskSnapshotController.getSnapshot(mContainer);
253 }
254 }
255
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800256 @Override
257 public String toString() {
258 return "{TaskWindowContainerController taskId=" + mTaskId + "}";
259 }
260}