blob: f4f826222576f86de77b443ed1a9612b2c15ff3f [file] [log] [blame]
Robert Carr8a2f9132019-11-11 15:03:15 -08001/*
2 * Copyright (C) 2019 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
Evan Rosky0037e5f2019-11-05 10:26:24 -080019import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Louis Changa009c762020-02-26 11:21:31 +080020import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Robert Carr00c0dbe2020-01-24 15:30:24 -080021import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
Evan Rosky0037e5f2019-11-05 10:26:24 -080022import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Robert Carr8a2f9132019-11-11 15:03:15 -080023
Wale Ogunwale568f9f412020-03-21 22:27:35 -070024import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS;
25import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDOW_CONFIGS;
Evan Rosky0037e5f2019-11-05 10:26:24 -080026
27import android.annotation.Nullable;
28import android.app.ActivityManager.RunningTaskInfo;
Evan Roskyb8540a02020-03-25 16:30:24 -070029import android.app.WindowConfiguration;
Louis Changa009c762020-02-26 11:21:31 +080030import android.content.Intent;
Evan Rosky0037e5f2019-11-05 10:26:24 -080031import android.content.pm.ActivityInfo;
Evan Rosky0037e5f2019-11-05 10:26:24 -080032import android.os.Binder;
Robert Carr8a2f9132019-11-11 15:03:15 -080033import android.os.IBinder;
34import android.os.RemoteException;
Winson Chung268eccb2020-03-26 13:43:44 -070035import android.os.UserHandle;
Robert Carr8a2f9132019-11-11 15:03:15 -080036import android.util.Slog;
Winson Chungaff506b2020-03-21 22:56:31 -070037import android.util.SparseArray;
Wale Ogunwale57946582020-03-21 14:29:07 -070038import android.window.ITaskOrganizer;
Louis Changa009c762020-02-26 11:21:31 +080039import android.window.ITaskOrganizerController;
Wale Ogunwale57946582020-03-21 14:29:07 -070040import android.window.IWindowContainer;
Evan Rosky0037e5f2019-11-05 10:26:24 -080041
Evan Rosky29d4a0a2020-02-04 16:40:44 -080042import com.android.internal.util.ArrayUtils;
Robert Carr8a2f9132019-11-11 15:03:15 -080043
Winson Chung268eccb2020-03-26 13:43:44 -070044import java.io.PrintWriter;
Robert Carr8a2f9132019-11-11 15:03:15 -080045import java.util.ArrayList;
46import java.util.HashMap;
Winson Chungaff506b2020-03-21 22:56:31 -070047import java.util.LinkedList;
Evan Roskya8fde152020-01-07 19:09:13 -080048import java.util.List;
Winson Chung268eccb2020-03-26 13:43:44 -070049import java.util.Set;
Evan Rosky0037e5f2019-11-05 10:26:24 -080050import java.util.WeakHashMap;
Robert Carr8a2f9132019-11-11 15:03:15 -080051
52/**
53 * Stores the TaskOrganizers associated with a given windowing mode and
54 * their associated state.
55 */
Wale Ogunwale568f9f412020-03-21 22:27:35 -070056class TaskOrganizerController extends ITaskOrganizerController.Stub {
Robert Carr8a2f9132019-11-11 15:03:15 -080057 private static final String TAG = "TaskOrganizerController";
Evan Roskyb8540a02020-03-25 16:30:24 -070058 private static final LinkedList<IBinder> EMPTY_LIST = new LinkedList<>();
Robert Carr8a2f9132019-11-11 15:03:15 -080059
Evan Roskyf64f5da2020-03-16 13:47:48 -070060 /**
61 * Masks specifying which configurations are important to report back to an organizer when
62 * changed.
63 */
64 private static final int REPORT_CONFIGS = CONTROLLABLE_CONFIGS;
65 private static final int REPORT_WINDOW_CONFIGS = CONTROLLABLE_WINDOW_CONFIGS;
66
Evan Rosky0037e5f2019-11-05 10:26:24 -080067 private final WindowManagerGlobalLock mGlobalLock;
Robert Carr8a2f9132019-11-11 15:03:15 -080068
69 private class DeathRecipient implements IBinder.DeathRecipient {
Robert Carr8a2f9132019-11-11 15:03:15 -080070 ITaskOrganizer mTaskOrganizer;
71
Evan Roskyb8540a02020-03-25 16:30:24 -070072 DeathRecipient(ITaskOrganizer organizer) {
Robert Carr8a2f9132019-11-11 15:03:15 -080073 mTaskOrganizer = organizer;
Robert Carr8a2f9132019-11-11 15:03:15 -080074 }
75
76 @Override
77 public void binderDied() {
78 synchronized (mGlobalLock) {
Winson Chungaff506b2020-03-21 22:56:31 -070079 final TaskOrganizerState state = mTaskOrganizerStates.remove(
80 mTaskOrganizer.asBinder());
81 state.dispose();
Robert Carr8a2f9132019-11-11 15:03:15 -080082 }
83 }
84 };
85
Winson Chungaff506b2020-03-21 22:56:31 -070086 private class TaskOrganizerState {
87 private final ITaskOrganizer mOrganizer;
88 private final DeathRecipient mDeathRecipient;
Winson Chungaff506b2020-03-21 22:56:31 -070089 private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
Winson Chung268eccb2020-03-26 13:43:44 -070090 private final int mUid;
Robert Carr8a2f9132019-11-11 15:03:15 -080091
Winson Chung268eccb2020-03-26 13:43:44 -070092 TaskOrganizerState(ITaskOrganizer organizer, int uid) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -080093 mOrganizer = organizer;
Evan Roskyb8540a02020-03-25 16:30:24 -070094 mDeathRecipient = new DeathRecipient(organizer);
Robert Carr7d7c8ab2020-01-28 15:57:23 -080095 try {
96 organizer.asBinder().linkToDeath(mDeathRecipient, 0);
97 } catch (RemoteException e) {
98 Slog.e(TAG, "TaskOrganizer failed to register death recipient");
99 }
Winson Chung268eccb2020-03-26 13:43:44 -0700100 mUid = uid;
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800101 }
102
Robert Carr8a2f9132019-11-11 15:03:15 -0800103 void addTask(Task t) {
104 mOrganizedTasks.add(t);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800105 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700106 mOrganizer.onTaskAppeared(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800107 } catch (Exception e) {
108 Slog.e(TAG, "Exception sending taskAppeared callback" + e);
109 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800110 }
111
112 void removeTask(Task t) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800113 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700114 mOrganizer.onTaskVanished(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800115 } catch (Exception e) {
116 Slog.e(TAG, "Exception sending taskVanished callback" + e);
117 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800118 mOrganizedTasks.remove(t);
119 }
120
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800121 void dispose() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800122 releaseTasks();
Evan Roskyb8540a02020-03-25 16:30:24 -0700123 for (int i = mTaskOrganizersForWindowingMode.size() - 1; i >= 0; --i) {
124 mTaskOrganizersForWindowingMode.valueAt(i).remove(mOrganizer.asBinder());
125 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800126 }
127
Winson Chungaff506b2020-03-21 22:56:31 -0700128 private void releaseTasks() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800129 for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) {
130 final Task t = mOrganizedTasks.get(i);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800131 removeTask(t);
Winson Chungaff506b2020-03-21 22:56:31 -0700132 t.taskOrganizerUnregistered();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800133 }
134 }
135
136 void unlinkDeath() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800137 mOrganizer.asBinder().unlinkToDeath(mDeathRecipient, 0);
Robert Carr8a2f9132019-11-11 15:03:15 -0800138 }
Winson Chungaff506b2020-03-21 22:56:31 -0700139 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800140
Evan Roskyb8540a02020-03-25 16:30:24 -0700141 private final SparseArray<LinkedList<IBinder>> mTaskOrganizersForWindowingMode =
Winson Chungaff506b2020-03-21 22:56:31 -0700142 new SparseArray<>();
143 private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800144 private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
145 private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
146
Robert Carr8a2f9132019-11-11 15:03:15 -0800147 final ActivityTaskManagerService mService;
148
Evan Rosky0037e5f2019-11-05 10:26:24 -0800149 RunningTaskInfo mTmpTaskInfo;
150
151 TaskOrganizerController(ActivityTaskManagerService atm) {
Robert Carr8a2f9132019-11-11 15:03:15 -0800152 mService = atm;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800153 mGlobalLock = atm.mGlobalLock;
154 }
155
156 private void enforceStackPermission(String func) {
157 mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
Robert Carr8a2f9132019-11-11 15:03:15 -0800158 }
159
Robert Carr8a2f9132019-11-11 15:03:15 -0800160 /**
161 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
162 * If there was already a TaskOrganizer for this windowing mode it will be evicted
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800163 * but will continue to organize it's existing tasks.
Robert Carr8a2f9132019-11-11 15:03:15 -0800164 */
Evan Rosky0037e5f2019-11-05 10:26:24 -0800165 @Override
166 public void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700167 if (windowingMode == WINDOWING_MODE_PINNED) {
168 if (!mService.mSupportsPictureInPicture) {
169 throw new UnsupportedOperationException("Picture in picture is not supported on "
170 + "this device");
171 }
172 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
173 if (!mService.mSupportsSplitScreenMultiWindow) {
174 throw new UnsupportedOperationException("Split-screen is not supported on this "
175 + "device");
176 }
177 } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
178 if (!mService.mSupportsMultiWindow) {
179 throw new UnsupportedOperationException("Multi-window is not supported on this "
180 + "device");
181 }
182 } else {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800183 throw new UnsupportedOperationException("As of now only Pinned/Split/Multiwindow"
184 + " windowing modes are supported for registerTaskOrganizer");
Robert Carr8a2f9132019-11-11 15:03:15 -0800185 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800186 enforceStackPermission("registerTaskOrganizer()");
Winson Chung268eccb2020-03-26 13:43:44 -0700187 final int uid = Binder.getCallingUid();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800188 final long origId = Binder.clearCallingIdentity();
Robert Carr8a2f9132019-11-11 15:03:15 -0800189 try {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800190 synchronized (mGlobalLock) {
Winson Chung77338ab2020-03-09 16:32:34 -0700191 if (getTaskOrganizer(windowingMode) != null) {
192 Slog.w(TAG, "Task organizer already exists for windowing mode: "
193 + windowingMode);
194 }
Winson Chungaff506b2020-03-21 22:56:31 -0700195
Evan Roskyb8540a02020-03-25 16:30:24 -0700196 LinkedList<IBinder> orgs = mTaskOrganizersForWindowingMode.get(windowingMode);
197 if (orgs == null) {
198 orgs = new LinkedList<>();
199 mTaskOrganizersForWindowingMode.put(windowingMode, orgs);
Winson Chungaff506b2020-03-21 22:56:31 -0700200 }
Evan Roskyb8540a02020-03-25 16:30:24 -0700201 orgs.add(organizer.asBinder());
202 if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
203 mTaskOrganizerStates.put(organizer.asBinder(),
Winson Chung268eccb2020-03-26 13:43:44 -0700204 new TaskOrganizerState(organizer, uid));
Evan Roskyb8540a02020-03-25 16:30:24 -0700205 }
Winson Chung77338ab2020-03-09 16:32:34 -0700206
Evan Roskyb8540a02020-03-25 16:30:24 -0700207 if (orgs.size() == 1) {
Winson Chung77338ab2020-03-09 16:32:34 -0700208 // Only in the case where this is the root task organizer for the given
209 // windowing mode, we add report all existing tasks in that mode to the new
210 // task organizer.
211 mService.mRootWindowContainer.forAllTasks((task) -> {
212 if (task.getWindowingMode() == windowingMode) {
213 task.updateTaskOrganizerState(true /* forceUpdate */);
214 }
215 });
216 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800217 }
218 } finally {
219 Binder.restoreCallingIdentity(origId);
Robert Carr8a2f9132019-11-11 15:03:15 -0800220 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800221 }
222
Winson Chung8a168902020-03-12 22:39:22 -0700223 @Override
224 public void unregisterTaskOrganizer(ITaskOrganizer organizer) {
Winson Chungaff506b2020-03-21 22:56:31 -0700225 final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800226 state.unlinkDeath();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800227 state.dispose();
228 }
229
Robert Carr8a2f9132019-11-11 15:03:15 -0800230 ITaskOrganizer getTaskOrganizer(int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700231 final IBinder organizer =
232 mTaskOrganizersForWindowingMode.get(windowingMode, EMPTY_LIST).peekLast();
233 if (organizer == null) {
234 return null;
235 }
236 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer);
Robert Carr8a2f9132019-11-11 15:03:15 -0800237 if (state == null) {
238 return null;
239 }
240 return state.mOrganizer;
241 }
242
Robert Carr8a2f9132019-11-11 15:03:15 -0800243 void onTaskAppeared(ITaskOrganizer organizer, Task task) {
Robert Carre10ee3d2019-11-11 15:03:15 -0800244 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800245 state.addTask(task);
Robert Carr8a2f9132019-11-11 15:03:15 -0800246 }
247
248 void onTaskVanished(ITaskOrganizer organizer, Task task) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800249 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800250 state.removeTask(task);
251 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800252
253 @Override
254 public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
255 enforceStackPermission("createRootTask()");
256 final long origId = Binder.clearCallingIdentity();
257 try {
258 synchronized (mGlobalLock) {
259 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
260 if (display == null) {
261 return null;
262 }
Louis Changa009c762020-02-26 11:21:31 +0800263
264 final Task task = display.getOrCreateStack(windowingMode, ACTIVITY_TYPE_UNDEFINED,
265 false /* onTop */, new Intent(), null /* candidateTask */,
266 true /* createdByOrganizer */);
267 RunningTaskInfo out = task.getTaskInfo();
268 mLastSentTaskInfos.put(task, out);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800269 return out;
270 }
271 } finally {
272 Binder.restoreCallingIdentity(origId);
273 }
274 }
275
276 @Override
277 public boolean deleteRootTask(IWindowContainer token) {
278 enforceStackPermission("deleteRootTask()");
279 final long origId = Binder.clearCallingIdentity();
280 try {
281 synchronized (mGlobalLock) {
Louis Changa009c762020-02-26 11:21:31 +0800282 final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
283 if (task == null) return false;
284 if (!task.mCreatedByOrganizer) {
285 throw new IllegalArgumentException(
286 "Attempt to delete task not created by organizer task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800287 }
Louis Changa009c762020-02-26 11:21:31 +0800288 task.removeImmediately();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800289 return true;
290 }
291 } finally {
292 Binder.restoreCallingIdentity(origId);
293 }
294 }
295
296 void dispatchPendingTaskInfoChanges() {
297 if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
298 return;
299 }
300 for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
301 dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
302 }
303 mPendingTaskInfoChanges.clear();
304 }
305
306 void dispatchTaskInfoChanged(Task task, boolean force) {
307 if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
308 // Defer task info reporting while layout is deferred. This is because layout defer
309 // blocks tend to do lots of re-ordering which can mess up animations in receivers.
310 mPendingTaskInfoChanges.remove(task);
311 mPendingTaskInfoChanges.add(task);
312 return;
313 }
314 RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
315 if (mTmpTaskInfo == null) {
316 mTmpTaskInfo = new RunningTaskInfo();
317 }
Evan Roskyf64f5da2020-03-16 13:47:48 -0700318 mTmpTaskInfo.configuration.unset();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800319 task.fillTaskInfo(mTmpTaskInfo);
320 boolean changed = lastInfo == null
321 || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800322 || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
323 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
Evan Roskyf64f5da2020-03-16 13:47:48 -0700324 if (!changed) {
325 int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
326 final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
327 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff(
328 lastInfo.configuration.windowConfiguration,
329 true /* compareUndefined */) : 0;
330 if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) {
331 cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
332 }
333 changed = (cfgChanges & REPORT_CONFIGS) != 0;
334 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800335 if (!(changed || force)) {
336 return;
337 }
338 final RunningTaskInfo newInfo = mTmpTaskInfo;
339 mLastSentTaskInfos.put(task, mTmpTaskInfo);
340 // Since we've stored this, clean up the reference so a new one will be created next time.
341 // Transferring it this way means we only have to construct new RunningTaskInfos when they
342 // change.
343 mTmpTaskInfo = null;
344
345 if (task.mTaskOrganizer != null) {
346 try {
347 task.mTaskOrganizer.onTaskInfoChanged(newInfo);
348 } catch (RemoteException e) {
349 }
350 }
351 }
352
353 @Override
354 public IWindowContainer getImeTarget(int displayId) {
355 enforceStackPermission("getImeTarget()");
356 final long origId = Binder.clearCallingIdentity();
357 try {
358 synchronized (mGlobalLock) {
359 DisplayContent dc = mService.mWindowManager.mRoot
360 .getDisplayContent(displayId);
361 if (dc == null || dc.mInputMethodTarget == null) {
362 return null;
363 }
364 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
365 final Task task = dc.mInputMethodTarget.getTask();
366 if (task == null) {
367 return null;
368 }
Louis Changa009c762020-02-26 11:21:31 +0800369 return task.getRootTask().mRemoteToken;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800370 }
371 } finally {
372 Binder.restoreCallingIdentity(origId);
373 }
374 }
375
376 @Override
Louis Changa009c762020-02-26 11:21:31 +0800377 public void setLaunchRoot(int displayId, @Nullable IWindowContainer token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800378 enforceStackPermission("setLaunchRoot()");
379 final long origId = Binder.clearCallingIdentity();
380 try {
381 synchronized (mGlobalLock) {
382 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
383 if (display == null) {
384 return;
385 }
Louis Changa009c762020-02-26 11:21:31 +0800386 Task task = token == null
387 ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
388 if (task == null) {
389 display.mLaunchRootTask = null;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800390 return;
391 }
Louis Changa009c762020-02-26 11:21:31 +0800392 if (!task.mCreatedByOrganizer) {
393 throw new IllegalArgumentException("Attempt to set task not created by "
394 + "organizer as launch root task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800395 }
Louis Changa009c762020-02-26 11:21:31 +0800396 if (task.getDisplayContent() != display) {
397 throw new RuntimeException("Can't set launch root for display " + displayId
398 + " to task on display " + task.getDisplayContent().getDisplayId());
399 }
400 display.mLaunchRootTask = task;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800401 }
402 } finally {
403 Binder.restoreCallingIdentity(origId);
404 }
405 }
406
Evan Roskya8fde152020-01-07 19:09:13 -0800407 @Override
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800408 public List<RunningTaskInfo> getChildTasks(IWindowContainer parent,
409 @Nullable int[] activityTypes) {
Evan Roskya8fde152020-01-07 19:09:13 -0800410 enforceStackPermission("getChildTasks()");
411 final long ident = Binder.clearCallingIdentity();
412 try {
413 synchronized (mGlobalLock) {
414 if (parent == null) {
415 throw new IllegalArgumentException("Can't get children of null parent");
416 }
417 final WindowContainer container = WindowContainer.fromBinder(parent.asBinder());
418 if (container == null) {
419 Slog.e(TAG, "Can't get children of " + parent + " because it is not valid.");
420 return null;
421 }
Louis Changa009c762020-02-26 11:21:31 +0800422 final Task task = container.asTask();
423 if (task == null) {
424 Slog.e(TAG, container + " is not a task...");
425 return null;
426 }
427 // For now, only support returning children of tasks created by the organizer.
428 if (!task.mCreatedByOrganizer) {
Evan Roskya8fde152020-01-07 19:09:13 -0800429 Slog.w(TAG, "Can only get children of root tasks created via createRootTask");
430 return null;
431 }
432 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Louis Changa009c762020-02-26 11:21:31 +0800433 for (int i = task.getChildCount() - 1; i >= 0; --i) {
434 final Task child = task.getChildAt(i).asTask();
435 if (child == null) continue;
436 if (activityTypes != null
437 && !ArrayUtils.contains(activityTypes, child.getActivityType())) {
438 continue;
Evan Roskya8fde152020-01-07 19:09:13 -0800439 }
Louis Changa009c762020-02-26 11:21:31 +0800440 out.add(child.getTaskInfo());
Evan Roskya8fde152020-01-07 19:09:13 -0800441 }
442 return out;
443 }
444 } finally {
445 Binder.restoreCallingIdentity(ident);
446 }
447 }
448
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800449 @Override
450 public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) {
451 enforceStackPermission("getRootTasks()");
452 final long ident = Binder.clearCallingIdentity();
453 try {
454 synchronized (mGlobalLock) {
455 final DisplayContent dc =
456 mService.mRootWindowContainer.getDisplayContent(displayId);
457 if (dc == null) {
458 throw new IllegalArgumentException("Display " + displayId + " doesn't exist");
459 }
460 ArrayList<RunningTaskInfo> out = new ArrayList<>();
461 for (int i = dc.getStackCount() - 1; i >= 0; --i) {
Louis Changa009c762020-02-26 11:21:31 +0800462 final Task task = dc.getStackAt(i);
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800463 if (activityTypes != null
464 && !ArrayUtils.contains(activityTypes, task.getActivityType())) {
465 continue;
466 }
Winson Chung66b08f02020-03-03 14:32:35 -0800467 out.add(task.getTaskInfo());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800468 }
469 return out;
470 }
471 } finally {
472 Binder.restoreCallingIdentity(ident);
473 }
474 }
Winson Chung268eccb2020-03-26 13:43:44 -0700475
476 public void dump(PrintWriter pw, String prefix) {
477 final String innerPrefix = prefix + " ";
478 pw.print(prefix); pw.println("TaskOrganizerController:");
479 pw.print(innerPrefix); pw.println("Per windowing mode:");
480 for (int i = 0; i < mTaskOrganizersForWindowingMode.size(); i++) {
481 final int windowingMode = mTaskOrganizersForWindowingMode.keyAt(i);
482 final List<IBinder> taskOrgs = mTaskOrganizersForWindowingMode.valueAt(i);
483 pw.println(innerPrefix + " "
484 + WindowConfiguration.windowingModeToString(windowingMode) + ":");
485 for (int j = 0; j < taskOrgs.size(); j++) {
486 final TaskOrganizerState state = mTaskOrganizerStates.get(taskOrgs.get(j));
487 final ArrayList<Task> tasks = state.mOrganizedTasks;
488 pw.print(innerPrefix + " ");
489 pw.println(state.mOrganizer + " uid=" + state.mUid + ":");
490 for (int k = 0; k < tasks.size(); k++) {
491 pw.println(innerPrefix + " " + tasks.get(k));
492 }
493 }
494
495 }
496 pw.println();
497 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800498}