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