blob: eddb2cec1e21767ade311760f684c0c51b9da226 [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;
35import android.util.Slog;
Winson Chungaff506b2020-03-21 22:56:31 -070036import android.util.SparseArray;
Wale Ogunwale57946582020-03-21 14:29:07 -070037import android.window.ITaskOrganizer;
Louis Changa009c762020-02-26 11:21:31 +080038import android.window.ITaskOrganizerController;
Wale Ogunwale57946582020-03-21 14:29:07 -070039import android.window.IWindowContainer;
Evan Rosky0037e5f2019-11-05 10:26:24 -080040
Evan Rosky29d4a0a2020-02-04 16:40:44 -080041import com.android.internal.util.ArrayUtils;
Robert Carr8a2f9132019-11-11 15:03:15 -080042
43import java.util.ArrayList;
44import java.util.HashMap;
Winson Chungaff506b2020-03-21 22:56:31 -070045import java.util.LinkedList;
Evan Roskya8fde152020-01-07 19:09:13 -080046import java.util.List;
Evan Rosky0037e5f2019-11-05 10:26:24 -080047import java.util.WeakHashMap;
Robert Carr8a2f9132019-11-11 15:03:15 -080048
49/**
50 * Stores the TaskOrganizers associated with a given windowing mode and
51 * their associated state.
52 */
Wale Ogunwale568f9f412020-03-21 22:27:35 -070053class TaskOrganizerController extends ITaskOrganizerController.Stub {
Robert Carr8a2f9132019-11-11 15:03:15 -080054 private static final String TAG = "TaskOrganizerController";
Evan Roskyb8540a02020-03-25 16:30:24 -070055 private static final LinkedList<IBinder> EMPTY_LIST = new LinkedList<>();
Robert Carr8a2f9132019-11-11 15:03:15 -080056
Evan Roskyf64f5da2020-03-16 13:47:48 -070057 /**
58 * Masks specifying which configurations are important to report back to an organizer when
59 * changed.
60 */
61 private static final int REPORT_CONFIGS = CONTROLLABLE_CONFIGS;
62 private static final int REPORT_WINDOW_CONFIGS = CONTROLLABLE_WINDOW_CONFIGS;
63
Evan Rosky0037e5f2019-11-05 10:26:24 -080064 private final WindowManagerGlobalLock mGlobalLock;
Robert Carr8a2f9132019-11-11 15:03:15 -080065
66 private class DeathRecipient implements IBinder.DeathRecipient {
Robert Carr8a2f9132019-11-11 15:03:15 -080067 ITaskOrganizer mTaskOrganizer;
68
Evan Roskyb8540a02020-03-25 16:30:24 -070069 DeathRecipient(ITaskOrganizer organizer) {
Robert Carr8a2f9132019-11-11 15:03:15 -080070 mTaskOrganizer = organizer;
Robert Carr8a2f9132019-11-11 15:03:15 -080071 }
72
73 @Override
74 public void binderDied() {
75 synchronized (mGlobalLock) {
Winson Chungaff506b2020-03-21 22:56:31 -070076 final TaskOrganizerState state = mTaskOrganizerStates.remove(
77 mTaskOrganizer.asBinder());
Riddle Hsu3c290512020-03-30 22:12:52 +080078 if (state != null) {
79 state.dispose();
80 }
Robert Carr8a2f9132019-11-11 15:03:15 -080081 }
82 }
83 };
84
Winson Chungaff506b2020-03-21 22:56:31 -070085 private class TaskOrganizerState {
86 private final ITaskOrganizer mOrganizer;
87 private final DeathRecipient mDeathRecipient;
Winson Chungaff506b2020-03-21 22:56:31 -070088 private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
Robert Carr8a2f9132019-11-11 15:03:15 -080089
Evan Roskyb8540a02020-03-25 16:30:24 -070090 TaskOrganizerState(ITaskOrganizer organizer) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -080091 mOrganizer = organizer;
Evan Roskyb8540a02020-03-25 16:30:24 -070092 mDeathRecipient = new DeathRecipient(organizer);
Robert Carr7d7c8ab2020-01-28 15:57:23 -080093 try {
94 organizer.asBinder().linkToDeath(mDeathRecipient, 0);
95 } catch (RemoteException e) {
96 Slog.e(TAG, "TaskOrganizer failed to register death recipient");
97 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -080098 }
99
Robert Carr8a2f9132019-11-11 15:03:15 -0800100 void addTask(Task t) {
101 mOrganizedTasks.add(t);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800102 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700103 mOrganizer.onTaskAppeared(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800104 } catch (Exception e) {
105 Slog.e(TAG, "Exception sending taskAppeared callback" + e);
106 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800107 }
108
109 void removeTask(Task t) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800110 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700111 mOrganizer.onTaskVanished(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800112 } catch (Exception e) {
113 Slog.e(TAG, "Exception sending taskVanished callback" + e);
114 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800115 mOrganizedTasks.remove(t);
116 }
117
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800118 void dispose() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800119 releaseTasks();
Evan Roskyb8540a02020-03-25 16:30:24 -0700120 for (int i = mTaskOrganizersForWindowingMode.size() - 1; i >= 0; --i) {
121 mTaskOrganizersForWindowingMode.valueAt(i).remove(mOrganizer.asBinder());
122 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800123 }
124
Winson Chungaff506b2020-03-21 22:56:31 -0700125 private void releaseTasks() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800126 for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) {
127 final Task t = mOrganizedTasks.get(i);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800128 removeTask(t);
Winson Chungaff506b2020-03-21 22:56:31 -0700129 t.taskOrganizerUnregistered();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800130 }
131 }
132
133 void unlinkDeath() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800134 mOrganizer.asBinder().unlinkToDeath(mDeathRecipient, 0);
Robert Carr8a2f9132019-11-11 15:03:15 -0800135 }
Winson Chungaff506b2020-03-21 22:56:31 -0700136 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800137
Evan Roskyb8540a02020-03-25 16:30:24 -0700138 private final SparseArray<LinkedList<IBinder>> mTaskOrganizersForWindowingMode =
Winson Chungaff506b2020-03-21 22:56:31 -0700139 new SparseArray<>();
140 private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800141 private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
142 private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
143
Robert Carr8a2f9132019-11-11 15:03:15 -0800144 final ActivityTaskManagerService mService;
145
Evan Rosky0037e5f2019-11-05 10:26:24 -0800146 RunningTaskInfo mTmpTaskInfo;
147
148 TaskOrganizerController(ActivityTaskManagerService atm) {
Robert Carr8a2f9132019-11-11 15:03:15 -0800149 mService = atm;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800150 mGlobalLock = atm.mGlobalLock;
151 }
152
153 private void enforceStackPermission(String func) {
154 mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
Robert Carr8a2f9132019-11-11 15:03:15 -0800155 }
156
Robert Carr8a2f9132019-11-11 15:03:15 -0800157 /**
158 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
159 * If there was already a TaskOrganizer for this windowing mode it will be evicted
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800160 * but will continue to organize it's existing tasks.
Robert Carr8a2f9132019-11-11 15:03:15 -0800161 */
Evan Rosky0037e5f2019-11-05 10:26:24 -0800162 @Override
163 public void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700164 if (windowingMode == WINDOWING_MODE_PINNED) {
165 if (!mService.mSupportsPictureInPicture) {
166 throw new UnsupportedOperationException("Picture in picture is not supported on "
167 + "this device");
168 }
169 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
170 if (!mService.mSupportsSplitScreenMultiWindow) {
171 throw new UnsupportedOperationException("Split-screen is not supported on this "
172 + "device");
173 }
174 } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
175 if (!mService.mSupportsMultiWindow) {
176 throw new UnsupportedOperationException("Multi-window is not supported on this "
177 + "device");
178 }
179 } else {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800180 throw new UnsupportedOperationException("As of now only Pinned/Split/Multiwindow"
181 + " windowing modes are supported for registerTaskOrganizer");
Robert Carr8a2f9132019-11-11 15:03:15 -0800182 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800183 enforceStackPermission("registerTaskOrganizer()");
184 final long origId = Binder.clearCallingIdentity();
Robert Carr8a2f9132019-11-11 15:03:15 -0800185 try {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800186 synchronized (mGlobalLock) {
Winson Chung77338ab2020-03-09 16:32:34 -0700187 if (getTaskOrganizer(windowingMode) != null) {
188 Slog.w(TAG, "Task organizer already exists for windowing mode: "
189 + windowingMode);
190 }
Winson Chungaff506b2020-03-21 22:56:31 -0700191
Evan Roskyb8540a02020-03-25 16:30:24 -0700192 LinkedList<IBinder> orgs = mTaskOrganizersForWindowingMode.get(windowingMode);
193 if (orgs == null) {
194 orgs = new LinkedList<>();
195 mTaskOrganizersForWindowingMode.put(windowingMode, orgs);
Winson Chungaff506b2020-03-21 22:56:31 -0700196 }
Evan Roskyb8540a02020-03-25 16:30:24 -0700197 orgs.add(organizer.asBinder());
198 if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
199 mTaskOrganizerStates.put(organizer.asBinder(),
200 new TaskOrganizerState(organizer));
201 }
Winson Chung77338ab2020-03-09 16:32:34 -0700202
Evan Roskyb8540a02020-03-25 16:30:24 -0700203 if (orgs.size() == 1) {
Winson Chung77338ab2020-03-09 16:32:34 -0700204 // Only in the case where this is the root task organizer for the given
205 // windowing mode, we add report all existing tasks in that mode to the new
206 // task organizer.
207 mService.mRootWindowContainer.forAllTasks((task) -> {
208 if (task.getWindowingMode() == windowingMode) {
209 task.updateTaskOrganizerState(true /* forceUpdate */);
210 }
211 });
212 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800213 }
214 } finally {
215 Binder.restoreCallingIdentity(origId);
Robert Carr8a2f9132019-11-11 15:03:15 -0800216 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800217 }
218
Winson Chung8a168902020-03-12 22:39:22 -0700219 @Override
220 public void unregisterTaskOrganizer(ITaskOrganizer organizer) {
Riddle Hsu3c290512020-03-30 22:12:52 +0800221 enforceStackPermission("unregisterTaskOrganizer()");
222 final long origId = Binder.clearCallingIdentity();
223 try {
224 synchronized (mGlobalLock) {
225 final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder());
226 if (state == null) {
227 return;
228 }
229 state.unlinkDeath();
230 state.dispose();
231 }
232 } finally {
233 Binder.restoreCallingIdentity(origId);
234 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800235 }
236
Robert Carr8a2f9132019-11-11 15:03:15 -0800237 ITaskOrganizer getTaskOrganizer(int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700238 final IBinder organizer =
239 mTaskOrganizersForWindowingMode.get(windowingMode, EMPTY_LIST).peekLast();
240 if (organizer == null) {
241 return null;
242 }
243 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer);
Robert Carr8a2f9132019-11-11 15:03:15 -0800244 if (state == null) {
245 return null;
246 }
247 return state.mOrganizer;
248 }
249
Robert Carr8a2f9132019-11-11 15:03:15 -0800250 void onTaskAppeared(ITaskOrganizer organizer, Task task) {
Robert Carre10ee3d2019-11-11 15:03:15 -0800251 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800252 state.addTask(task);
Robert Carr8a2f9132019-11-11 15:03:15 -0800253 }
254
255 void onTaskVanished(ITaskOrganizer organizer, Task task) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800256 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800257 state.removeTask(task);
258 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800259
260 @Override
261 public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
262 enforceStackPermission("createRootTask()");
263 final long origId = Binder.clearCallingIdentity();
264 try {
265 synchronized (mGlobalLock) {
266 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
267 if (display == null) {
268 return null;
269 }
Louis Changa009c762020-02-26 11:21:31 +0800270
Andrii Kulian9ea12da2020-03-27 17:16:38 -0700271 final Task task = display.mTaskContainers.getOrCreateStack(windowingMode,
272 ACTIVITY_TYPE_UNDEFINED, false /* onTop */, new Intent(),
273 null /* candidateTask */, true /* createdByOrganizer */);
Louis Changa009c762020-02-26 11:21:31 +0800274 RunningTaskInfo out = task.getTaskInfo();
275 mLastSentTaskInfos.put(task, out);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800276 return out;
277 }
278 } finally {
279 Binder.restoreCallingIdentity(origId);
280 }
281 }
282
283 @Override
284 public boolean deleteRootTask(IWindowContainer token) {
285 enforceStackPermission("deleteRootTask()");
286 final long origId = Binder.clearCallingIdentity();
287 try {
288 synchronized (mGlobalLock) {
Louis Changa009c762020-02-26 11:21:31 +0800289 final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
290 if (task == null) return false;
291 if (!task.mCreatedByOrganizer) {
292 throw new IllegalArgumentException(
293 "Attempt to delete task not created by organizer task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800294 }
Louis Changa009c762020-02-26 11:21:31 +0800295 task.removeImmediately();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800296 return true;
297 }
298 } finally {
299 Binder.restoreCallingIdentity(origId);
300 }
301 }
302
303 void dispatchPendingTaskInfoChanges() {
304 if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
305 return;
306 }
307 for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
308 dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
309 }
310 mPendingTaskInfoChanges.clear();
311 }
312
313 void dispatchTaskInfoChanged(Task task, boolean force) {
314 if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
315 // Defer task info reporting while layout is deferred. This is because layout defer
316 // blocks tend to do lots of re-ordering which can mess up animations in receivers.
317 mPendingTaskInfoChanges.remove(task);
318 mPendingTaskInfoChanges.add(task);
319 return;
320 }
321 RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
322 if (mTmpTaskInfo == null) {
323 mTmpTaskInfo = new RunningTaskInfo();
324 }
Evan Roskyf64f5da2020-03-16 13:47:48 -0700325 mTmpTaskInfo.configuration.unset();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800326 task.fillTaskInfo(mTmpTaskInfo);
327 boolean changed = lastInfo == null
328 || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800329 || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
330 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
Evan Roskyf64f5da2020-03-16 13:47:48 -0700331 if (!changed) {
332 int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
333 final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
334 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff(
335 lastInfo.configuration.windowConfiguration,
336 true /* compareUndefined */) : 0;
337 if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) {
338 cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
339 }
340 changed = (cfgChanges & REPORT_CONFIGS) != 0;
341 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800342 if (!(changed || force)) {
343 return;
344 }
345 final RunningTaskInfo newInfo = mTmpTaskInfo;
346 mLastSentTaskInfos.put(task, mTmpTaskInfo);
347 // Since we've stored this, clean up the reference so a new one will be created next time.
348 // Transferring it this way means we only have to construct new RunningTaskInfos when they
349 // change.
350 mTmpTaskInfo = null;
351
352 if (task.mTaskOrganizer != null) {
353 try {
354 task.mTaskOrganizer.onTaskInfoChanged(newInfo);
355 } catch (RemoteException e) {
356 }
357 }
358 }
359
360 @Override
361 public IWindowContainer getImeTarget(int displayId) {
362 enforceStackPermission("getImeTarget()");
363 final long origId = Binder.clearCallingIdentity();
364 try {
365 synchronized (mGlobalLock) {
366 DisplayContent dc = mService.mWindowManager.mRoot
367 .getDisplayContent(displayId);
368 if (dc == null || dc.mInputMethodTarget == null) {
369 return null;
370 }
371 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
372 final Task task = dc.mInputMethodTarget.getTask();
373 if (task == null) {
374 return null;
375 }
Louis Changa009c762020-02-26 11:21:31 +0800376 return task.getRootTask().mRemoteToken;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800377 }
378 } finally {
379 Binder.restoreCallingIdentity(origId);
380 }
381 }
382
383 @Override
Louis Changa009c762020-02-26 11:21:31 +0800384 public void setLaunchRoot(int displayId, @Nullable IWindowContainer token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800385 enforceStackPermission("setLaunchRoot()");
386 final long origId = Binder.clearCallingIdentity();
387 try {
388 synchronized (mGlobalLock) {
389 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
390 if (display == null) {
391 return;
392 }
Louis Changa009c762020-02-26 11:21:31 +0800393 Task task = token == null
394 ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
395 if (task == null) {
396 display.mLaunchRootTask = null;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800397 return;
398 }
Louis Changa009c762020-02-26 11:21:31 +0800399 if (!task.mCreatedByOrganizer) {
400 throw new IllegalArgumentException("Attempt to set task not created by "
401 + "organizer as launch root task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800402 }
Louis Changa009c762020-02-26 11:21:31 +0800403 if (task.getDisplayContent() != display) {
404 throw new RuntimeException("Can't set launch root for display " + displayId
405 + " to task on display " + task.getDisplayContent().getDisplayId());
406 }
407 display.mLaunchRootTask = task;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800408 }
409 } finally {
410 Binder.restoreCallingIdentity(origId);
411 }
412 }
413
Evan Roskya8fde152020-01-07 19:09:13 -0800414 @Override
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800415 public List<RunningTaskInfo> getChildTasks(IWindowContainer parent,
416 @Nullable int[] activityTypes) {
Evan Roskya8fde152020-01-07 19:09:13 -0800417 enforceStackPermission("getChildTasks()");
418 final long ident = Binder.clearCallingIdentity();
419 try {
420 synchronized (mGlobalLock) {
421 if (parent == null) {
422 throw new IllegalArgumentException("Can't get children of null parent");
423 }
424 final WindowContainer container = WindowContainer.fromBinder(parent.asBinder());
425 if (container == null) {
426 Slog.e(TAG, "Can't get children of " + parent + " because it is not valid.");
427 return null;
428 }
Louis Changa009c762020-02-26 11:21:31 +0800429 final Task task = container.asTask();
430 if (task == null) {
431 Slog.e(TAG, container + " is not a task...");
432 return null;
433 }
434 // For now, only support returning children of tasks created by the organizer.
435 if (!task.mCreatedByOrganizer) {
Evan Roskya8fde152020-01-07 19:09:13 -0800436 Slog.w(TAG, "Can only get children of root tasks created via createRootTask");
437 return null;
438 }
439 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Louis Changa009c762020-02-26 11:21:31 +0800440 for (int i = task.getChildCount() - 1; i >= 0; --i) {
441 final Task child = task.getChildAt(i).asTask();
442 if (child == null) continue;
443 if (activityTypes != null
444 && !ArrayUtils.contains(activityTypes, child.getActivityType())) {
445 continue;
Evan Roskya8fde152020-01-07 19:09:13 -0800446 }
Louis Changa009c762020-02-26 11:21:31 +0800447 out.add(child.getTaskInfo());
Evan Roskya8fde152020-01-07 19:09:13 -0800448 }
449 return out;
450 }
451 } finally {
452 Binder.restoreCallingIdentity(ident);
453 }
454 }
455
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800456 @Override
457 public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) {
458 enforceStackPermission("getRootTasks()");
459 final long ident = Binder.clearCallingIdentity();
460 try {
461 synchronized (mGlobalLock) {
462 final DisplayContent dc =
463 mService.mRootWindowContainer.getDisplayContent(displayId);
464 if (dc == null) {
465 throw new IllegalArgumentException("Display " + displayId + " doesn't exist");
466 }
467 ArrayList<RunningTaskInfo> out = new ArrayList<>();
468 for (int i = dc.getStackCount() - 1; i >= 0; --i) {
Louis Changa009c762020-02-26 11:21:31 +0800469 final Task task = dc.getStackAt(i);
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800470 if (activityTypes != null
471 && !ArrayUtils.contains(activityTypes, task.getActivityType())) {
472 continue;
473 }
Winson Chung66b08f02020-03-03 14:32:35 -0800474 out.add(task.getTaskInfo());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800475 }
476 return out;
477 }
478 } finally {
479 Binder.restoreCallingIdentity(ident);
480 }
481 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800482}