blob: 11667c0b6ac75a842e1163f465e3f88ff5ee0187 [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 Jaggi829b9cd2017-01-23 16:20:53 +010019import android.app.ActivityManager.TaskDescription;
Jorim Jaggie2c77f92016-12-29 14:57:22 +010020import android.app.ActivityManager.TaskSnapshot;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080021import android.content.res.Configuration;
22import android.graphics.Rect;
Jorim Jaggifb9d78a2017-01-05 18:57:12 +010023import android.os.Handler;
24import android.os.Looper;
25import android.os.Message;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080026import android.util.EventLog;
27import android.util.Slog;
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080028import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080029
Wale Ogunwale1666e312016-12-16 11:27:18 -080030import java.lang.ref.WeakReference;
31
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080032import static com.android.server.EventLogTags.WM_TASK_CREATED;
33import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
34import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
35import static com.android.server.wm.WindowContainer.POSITION_TOP;
36import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
37import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
38
39/**
40 * Controller for the task container. This is created by activity manager to link task records to
41 * the task container they use in window manager.
42 *
43 * Test class: {@link TaskWindowContainerControllerTests}
44 */
45public class TaskWindowContainerController
Jorim Jaggifb9d78a2017-01-05 18:57:12 +010046 extends WindowContainerController<Task, TaskWindowContainerListener> {
47
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080048 private final int mTaskId;
Wale Ogunwale1666e312016-12-16 11:27:18 -080049 private final H mHandler;
Jorim Jaggifb9d78a2017-01-05 18:57:12 +010050
51 public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
Wale Ogunwale1666e312016-12-16 11:27:18 -080052 StackWindowController stackController, int userId, Rect bounds,
53 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
54 boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers,
55 TaskDescription taskDescription) {
56 this(taskId, listener, stackController, userId, bounds, overrideConfig, resizeMode,
57 supportsPictureInPicture, homeTask, isOnTopLauncher, toTop, showForAllUsers,
58 taskDescription, WindowManagerService.getInstance());
59 }
60
61 public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
62 StackWindowController stackController, int userId, Rect bounds,
63 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
64 boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers,
65 TaskDescription taskDescription, WindowManagerService service) {
66 super(listener, service);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080067 mTaskId = taskId;
Wale Ogunwale1666e312016-12-16 11:27:18 -080068 mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080069
70 synchronized(mWindowMap) {
71 if (DEBUG_STACK) Slog.i(TAG_WM, "TaskWindowContainerController: taskId=" + taskId
Wale Ogunwale1666e312016-12-16 11:27:18 -080072 + " stack=" + stackController + " bounds=" + bounds);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080073
Wale Ogunwale1666e312016-12-16 11:27:18 -080074 final TaskStack stack = stackController.mContainer;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080075 if (stack == null) {
Wale Ogunwale1666e312016-12-16 11:27:18 -080076 throw new IllegalArgumentException("TaskWindowContainerController: invalid stack="
77 + stackController);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080078 }
Wale Ogunwale1666e312016-12-16 11:27:18 -080079 EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080080 final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
Winson Chungd3395382016-12-13 11:49:09 -080081 supportsPictureInPicture, homeTask, isOnTopLauncher, taskDescription);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080082 final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
83 stack.addTask(task, position, showForAllUsers, true /* moveParents */);
84 }
85 }
86
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080087 @VisibleForTesting
88 Task createTask(int taskId, TaskStack stack, int userId, Rect bounds,
Winson Chungd3395382016-12-13 11:49:09 -080089 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
90 boolean homeTask, boolean isOnTopLauncher, TaskDescription taskDescription) {
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080091 return new Task(taskId, stack, userId, mService, bounds, overrideConfig, isOnTopLauncher,
Winson Chungd3395382016-12-13 11:49:09 -080092 resizeMode, supportsPictureInPicture, homeTask, taskDescription, this);
Wale Ogunwalec5cc3012017-01-13 13:26:16 -080093 }
94
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -080095 @Override
96 public void removeContainer() {
97 synchronized(mWindowMap) {
98 if (mContainer == null) {
99 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + mTaskId);
100 return;
101 }
102 mContainer.removeIfPossible();
103 super.removeContainer();
104 }
105 }
106
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800107 public void positionChildAt(AppWindowContainerController childController, int position) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800108 synchronized(mService.mWindowMap) {
109 final AppWindowToken aToken = childController.mContainer;
110 if (aToken == null) {
111 Slog.w(TAG_WM,
112 "Attempted to position of non-existing app : " + childController);
113 return;
114 }
115
116 final Task task = mContainer;
117 if (task == null) {
118 throw new IllegalArgumentException("positionChildAt: invalid task=" + this);
119 }
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800120 task.positionChildAt(position, aToken, false /* includeParents */);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800121 }
122 }
123
Wale Ogunwale1666e312016-12-16 11:27:18 -0800124 public void reparent(StackWindowController stackController, int position) {
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800125 synchronized (mWindowMap) {
126 if (DEBUG_STACK) Slog.i(TAG_WM, "reparent: moving taskId=" + mTaskId
Wale Ogunwale1666e312016-12-16 11:27:18 -0800127 + " to stack=" + stackController + " at " + position);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800128 if (mContainer == null) {
129 if (DEBUG_STACK) Slog.i(TAG_WM,
130 "reparent: could not find taskId=" + mTaskId);
131 return;
132 }
Wale Ogunwale1666e312016-12-16 11:27:18 -0800133 final TaskStack stack = stackController.mContainer;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800134 if (stack == null) {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800135 throw new IllegalArgumentException("reparent: could not find stack="
136 + stackController);
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800137 }
138 mContainer.reparent(stack, position);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800139 mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800140 }
141 }
142
143 public void setResizeable(int resizeMode) {
144 synchronized (mWindowMap) {
145 if (mContainer != null) {
146 mContainer.setResizeable(resizeMode);
147 }
148 }
149 }
150
151 public void resize(Rect bounds, Configuration overrideConfig, boolean relayout,
152 boolean forced) {
153 synchronized (mWindowMap) {
154 if (mContainer == null) {
155 throw new IllegalArgumentException("resizeTask: taskId " + mTaskId + " not found.");
156 }
157
158 if (mContainer.resizeLocked(bounds, overrideConfig, forced) && relayout) {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800159 mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800160 }
161 }
162 }
163
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800164 public void getBounds(Rect bounds) {
165 synchronized (mWindowMap) {
166 if (mContainer != null) {
167 mContainer.getBounds(bounds);
168 return;
169 }
170 bounds.setEmpty();
171 }
172 }
173
174 /**
175 * Puts this task into docked drag resizing mode. See {@link DragResizeMode}.
176 *
177 * @param resizing Whether to put the task into drag resize mode.
178 */
179 public void setTaskDockedResizing(boolean resizing) {
180 synchronized (mWindowMap) {
181 if (mContainer == null) {
182 Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + mTaskId + " not found.");
183 return;
184 }
185 mContainer.setDragResizing(resizing, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
186 }
187 }
188
189 public void cancelWindowTransition() {
190 synchronized (mWindowMap) {
191 if (mContainer == null) {
192 Slog.w(TAG_WM, "cancelWindowTransition: taskId " + mTaskId + " not found.");
193 return;
194 }
195 mContainer.cancelTaskWindowTransition();
196 }
197 }
198
199 public void cancelThumbnailTransition() {
200 synchronized (mWindowMap) {
201 if (mContainer == null) {
202 Slog.w(TAG_WM, "cancelThumbnailTransition: taskId " + mTaskId + " not found.");
203 return;
204 }
205 mContainer.cancelTaskThumbnailTransition();
206 }
207 }
208
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100209 public void setTaskDescription(TaskDescription taskDescription) {
210 synchronized (mWindowMap) {
211 if (mContainer == null) {
212 Slog.w(TAG_WM, "setTaskDescription: taskId " + mTaskId + " not found.");
213 return;
214 }
215 mContainer.setTaskDescription(taskDescription);
216 }
217 }
218
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100219 void reportSnapshotChanged(TaskSnapshot snapshot) {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800220 mHandler.obtainMessage(H.REPORT_SNAPSHOT_CHANGED, snapshot).sendToTarget();
221 }
222
223 void requestResize(Rect bounds, int resizeMode) {
224 mHandler.obtainMessage(H.REQUEST_RESIZE, resizeMode, 0, bounds).sendToTarget();
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100225 }
226
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800227 @Override
228 public String toString() {
229 return "{TaskWindowContainerController taskId=" + mTaskId + "}";
230 }
Wale Ogunwale1666e312016-12-16 11:27:18 -0800231
232 private static final class H extends Handler {
233
234 static final int REPORT_SNAPSHOT_CHANGED = 0;
235 static final int REQUEST_RESIZE = 1;
236
237 private final WeakReference<TaskWindowContainerController> mController;
238
239 H(WeakReference<TaskWindowContainerController> controller, Looper looper) {
240 super(looper);
241 mController = controller;
242 }
243
244 @Override
245 public void handleMessage(Message msg) {
246 final TaskWindowContainerController controller = mController.get();
247 final TaskWindowContainerListener listener = (controller != null)
248 ? controller.mListener : null;
249 if (listener == null) {
250 return;
251 }
252 switch (msg.what) {
253 case REPORT_SNAPSHOT_CHANGED:
254 listener.onSnapshotChanged((TaskSnapshot) msg.obj);
255 break;
256 case REQUEST_RESIZE:
257 listener.requestResize((Rect) msg.obj, msg.arg1);
258 break;
259 }
260 }
261 }
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800262}