blob: 8a896f52eea7ae91f63c0cd58bbed06f62ba8b0c [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());
78 state.dispose();
Robert Carr8a2f9132019-11-11 15:03:15 -080079 }
80 }
81 };
82
Winson Chungaff506b2020-03-21 22:56:31 -070083 private class TaskOrganizerState {
84 private final ITaskOrganizer mOrganizer;
85 private final DeathRecipient mDeathRecipient;
Winson Chungaff506b2020-03-21 22:56:31 -070086 private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
Robert Carr8a2f9132019-11-11 15:03:15 -080087
Evan Roskyb8540a02020-03-25 16:30:24 -070088 TaskOrganizerState(ITaskOrganizer organizer) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -080089 mOrganizer = organizer;
Evan Roskyb8540a02020-03-25 16:30:24 -070090 mDeathRecipient = new DeathRecipient(organizer);
Robert Carr7d7c8ab2020-01-28 15:57:23 -080091 try {
92 organizer.asBinder().linkToDeath(mDeathRecipient, 0);
93 } catch (RemoteException e) {
94 Slog.e(TAG, "TaskOrganizer failed to register death recipient");
95 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -080096 }
97
Robert Carr8a2f9132019-11-11 15:03:15 -080098 void addTask(Task t) {
99 mOrganizedTasks.add(t);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800100 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700101 mOrganizer.onTaskAppeared(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800102 } catch (Exception e) {
103 Slog.e(TAG, "Exception sending taskAppeared callback" + e);
104 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800105 }
106
107 void removeTask(Task t) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800108 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700109 mOrganizer.onTaskVanished(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800110 } catch (Exception e) {
111 Slog.e(TAG, "Exception sending taskVanished callback" + e);
112 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800113 mOrganizedTasks.remove(t);
114 }
115
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800116 void dispose() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800117 releaseTasks();
Evan Roskyb8540a02020-03-25 16:30:24 -0700118 for (int i = mTaskOrganizersForWindowingMode.size() - 1; i >= 0; --i) {
119 mTaskOrganizersForWindowingMode.valueAt(i).remove(mOrganizer.asBinder());
120 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800121 }
122
Winson Chungaff506b2020-03-21 22:56:31 -0700123 private void releaseTasks() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800124 for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) {
125 final Task t = mOrganizedTasks.get(i);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800126 removeTask(t);
Winson Chungaff506b2020-03-21 22:56:31 -0700127 t.taskOrganizerUnregistered();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800128 }
129 }
130
131 void unlinkDeath() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800132 mOrganizer.asBinder().unlinkToDeath(mDeathRecipient, 0);
Robert Carr8a2f9132019-11-11 15:03:15 -0800133 }
Winson Chungaff506b2020-03-21 22:56:31 -0700134 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800135
Evan Roskyb8540a02020-03-25 16:30:24 -0700136 private final SparseArray<LinkedList<IBinder>> mTaskOrganizersForWindowingMode =
Winson Chungaff506b2020-03-21 22:56:31 -0700137 new SparseArray<>();
138 private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800139 private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
140 private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
141
Robert Carr8a2f9132019-11-11 15:03:15 -0800142 final ActivityTaskManagerService mService;
143
Evan Rosky0037e5f2019-11-05 10:26:24 -0800144 RunningTaskInfo mTmpTaskInfo;
145
146 TaskOrganizerController(ActivityTaskManagerService atm) {
Robert Carr8a2f9132019-11-11 15:03:15 -0800147 mService = atm;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800148 mGlobalLock = atm.mGlobalLock;
149 }
150
151 private void enforceStackPermission(String func) {
152 mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
Robert Carr8a2f9132019-11-11 15:03:15 -0800153 }
154
Robert Carr8a2f9132019-11-11 15:03:15 -0800155 /**
156 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
157 * If there was already a TaskOrganizer for this windowing mode it will be evicted
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800158 * but will continue to organize it's existing tasks.
Robert Carr8a2f9132019-11-11 15:03:15 -0800159 */
Evan Rosky0037e5f2019-11-05 10:26:24 -0800160 @Override
161 public void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700162 if (windowingMode == WINDOWING_MODE_PINNED) {
163 if (!mService.mSupportsPictureInPicture) {
164 throw new UnsupportedOperationException("Picture in picture is not supported on "
165 + "this device");
166 }
167 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
168 if (!mService.mSupportsSplitScreenMultiWindow) {
169 throw new UnsupportedOperationException("Split-screen is not supported on this "
170 + "device");
171 }
172 } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
173 if (!mService.mSupportsMultiWindow) {
174 throw new UnsupportedOperationException("Multi-window is not supported on this "
175 + "device");
176 }
177 } else {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800178 throw new UnsupportedOperationException("As of now only Pinned/Split/Multiwindow"
179 + " windowing modes are supported for registerTaskOrganizer");
Robert Carr8a2f9132019-11-11 15:03:15 -0800180 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800181 enforceStackPermission("registerTaskOrganizer()");
182 final long origId = Binder.clearCallingIdentity();
Robert Carr8a2f9132019-11-11 15:03:15 -0800183 try {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800184 synchronized (mGlobalLock) {
Winson Chung77338ab2020-03-09 16:32:34 -0700185 if (getTaskOrganizer(windowingMode) != null) {
186 Slog.w(TAG, "Task organizer already exists for windowing mode: "
187 + windowingMode);
188 }
Winson Chungaff506b2020-03-21 22:56:31 -0700189
Evan Roskyb8540a02020-03-25 16:30:24 -0700190 LinkedList<IBinder> orgs = mTaskOrganizersForWindowingMode.get(windowingMode);
191 if (orgs == null) {
192 orgs = new LinkedList<>();
193 mTaskOrganizersForWindowingMode.put(windowingMode, orgs);
Winson Chungaff506b2020-03-21 22:56:31 -0700194 }
Evan Roskyb8540a02020-03-25 16:30:24 -0700195 orgs.add(organizer.asBinder());
196 if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
197 mTaskOrganizerStates.put(organizer.asBinder(),
198 new TaskOrganizerState(organizer));
199 }
Winson Chung77338ab2020-03-09 16:32:34 -0700200
Evan Roskyb8540a02020-03-25 16:30:24 -0700201 if (orgs.size() == 1) {
Winson Chung77338ab2020-03-09 16:32:34 -0700202 // Only in the case where this is the root task organizer for the given
203 // windowing mode, we add report all existing tasks in that mode to the new
204 // task organizer.
205 mService.mRootWindowContainer.forAllTasks((task) -> {
206 if (task.getWindowingMode() == windowingMode) {
207 task.updateTaskOrganizerState(true /* forceUpdate */);
208 }
209 });
210 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800211 }
212 } finally {
213 Binder.restoreCallingIdentity(origId);
Robert Carr8a2f9132019-11-11 15:03:15 -0800214 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800215 }
216
Winson Chung8a168902020-03-12 22:39:22 -0700217 @Override
218 public void unregisterTaskOrganizer(ITaskOrganizer organizer) {
Winson Chungaff506b2020-03-21 22:56:31 -0700219 final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800220 state.unlinkDeath();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800221 state.dispose();
222 }
223
Robert Carr8a2f9132019-11-11 15:03:15 -0800224 ITaskOrganizer getTaskOrganizer(int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700225 final IBinder organizer =
226 mTaskOrganizersForWindowingMode.get(windowingMode, EMPTY_LIST).peekLast();
227 if (organizer == null) {
228 return null;
229 }
230 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer);
Robert Carr8a2f9132019-11-11 15:03:15 -0800231 if (state == null) {
232 return null;
233 }
234 return state.mOrganizer;
235 }
236
Robert Carr8a2f9132019-11-11 15:03:15 -0800237 void onTaskAppeared(ITaskOrganizer organizer, Task task) {
Robert Carre10ee3d2019-11-11 15:03:15 -0800238 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800239 state.addTask(task);
Robert Carr8a2f9132019-11-11 15:03:15 -0800240 }
241
242 void onTaskVanished(ITaskOrganizer organizer, Task task) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800243 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800244 state.removeTask(task);
245 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800246
247 @Override
248 public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
249 enforceStackPermission("createRootTask()");
250 final long origId = Binder.clearCallingIdentity();
251 try {
252 synchronized (mGlobalLock) {
253 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
254 if (display == null) {
255 return null;
256 }
Louis Changa009c762020-02-26 11:21:31 +0800257
258 final Task task = display.getOrCreateStack(windowingMode, ACTIVITY_TYPE_UNDEFINED,
259 false /* onTop */, new Intent(), null /* candidateTask */,
260 true /* createdByOrganizer */);
261 RunningTaskInfo out = task.getTaskInfo();
262 mLastSentTaskInfos.put(task, out);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800263 return out;
264 }
265 } finally {
266 Binder.restoreCallingIdentity(origId);
267 }
268 }
269
270 @Override
271 public boolean deleteRootTask(IWindowContainer token) {
272 enforceStackPermission("deleteRootTask()");
273 final long origId = Binder.clearCallingIdentity();
274 try {
275 synchronized (mGlobalLock) {
Louis Changa009c762020-02-26 11:21:31 +0800276 final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
277 if (task == null) return false;
278 if (!task.mCreatedByOrganizer) {
279 throw new IllegalArgumentException(
280 "Attempt to delete task not created by organizer task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800281 }
Louis Changa009c762020-02-26 11:21:31 +0800282 task.removeImmediately();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800283 return true;
284 }
285 } finally {
286 Binder.restoreCallingIdentity(origId);
287 }
288 }
289
290 void dispatchPendingTaskInfoChanges() {
291 if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
292 return;
293 }
294 for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
295 dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
296 }
297 mPendingTaskInfoChanges.clear();
298 }
299
300 void dispatchTaskInfoChanged(Task task, boolean force) {
301 if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
302 // Defer task info reporting while layout is deferred. This is because layout defer
303 // blocks tend to do lots of re-ordering which can mess up animations in receivers.
304 mPendingTaskInfoChanges.remove(task);
305 mPendingTaskInfoChanges.add(task);
306 return;
307 }
308 RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
309 if (mTmpTaskInfo == null) {
310 mTmpTaskInfo = new RunningTaskInfo();
311 }
Evan Roskyf64f5da2020-03-16 13:47:48 -0700312 mTmpTaskInfo.configuration.unset();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800313 task.fillTaskInfo(mTmpTaskInfo);
314 boolean changed = lastInfo == null
315 || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800316 || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
317 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
Evan Roskyf64f5da2020-03-16 13:47:48 -0700318 if (!changed) {
319 int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
320 final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
321 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff(
322 lastInfo.configuration.windowConfiguration,
323 true /* compareUndefined */) : 0;
324 if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) {
325 cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
326 }
327 changed = (cfgChanges & REPORT_CONFIGS) != 0;
328 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800329 if (!(changed || force)) {
330 return;
331 }
332 final RunningTaskInfo newInfo = mTmpTaskInfo;
333 mLastSentTaskInfos.put(task, mTmpTaskInfo);
334 // Since we've stored this, clean up the reference so a new one will be created next time.
335 // Transferring it this way means we only have to construct new RunningTaskInfos when they
336 // change.
337 mTmpTaskInfo = null;
338
339 if (task.mTaskOrganizer != null) {
340 try {
341 task.mTaskOrganizer.onTaskInfoChanged(newInfo);
342 } catch (RemoteException e) {
343 }
344 }
345 }
346
347 @Override
348 public IWindowContainer getImeTarget(int displayId) {
349 enforceStackPermission("getImeTarget()");
350 final long origId = Binder.clearCallingIdentity();
351 try {
352 synchronized (mGlobalLock) {
353 DisplayContent dc = mService.mWindowManager.mRoot
354 .getDisplayContent(displayId);
355 if (dc == null || dc.mInputMethodTarget == null) {
356 return null;
357 }
358 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
359 final Task task = dc.mInputMethodTarget.getTask();
360 if (task == null) {
361 return null;
362 }
Louis Changa009c762020-02-26 11:21:31 +0800363 return task.getRootTask().mRemoteToken;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800364 }
365 } finally {
366 Binder.restoreCallingIdentity(origId);
367 }
368 }
369
370 @Override
Louis Changa009c762020-02-26 11:21:31 +0800371 public void setLaunchRoot(int displayId, @Nullable IWindowContainer token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800372 enforceStackPermission("setLaunchRoot()");
373 final long origId = Binder.clearCallingIdentity();
374 try {
375 synchronized (mGlobalLock) {
376 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
377 if (display == null) {
378 return;
379 }
Louis Changa009c762020-02-26 11:21:31 +0800380 Task task = token == null
381 ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
382 if (task == null) {
383 display.mLaunchRootTask = null;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800384 return;
385 }
Louis Changa009c762020-02-26 11:21:31 +0800386 if (!task.mCreatedByOrganizer) {
387 throw new IllegalArgumentException("Attempt to set task not created by "
388 + "organizer as launch root task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800389 }
Louis Changa009c762020-02-26 11:21:31 +0800390 if (task.getDisplayContent() != display) {
391 throw new RuntimeException("Can't set launch root for display " + displayId
392 + " to task on display " + task.getDisplayContent().getDisplayId());
393 }
394 display.mLaunchRootTask = task;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800395 }
396 } finally {
397 Binder.restoreCallingIdentity(origId);
398 }
399 }
400
Evan Roskya8fde152020-01-07 19:09:13 -0800401 @Override
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800402 public List<RunningTaskInfo> getChildTasks(IWindowContainer parent,
403 @Nullable int[] activityTypes) {
Evan Roskya8fde152020-01-07 19:09:13 -0800404 enforceStackPermission("getChildTasks()");
405 final long ident = Binder.clearCallingIdentity();
406 try {
407 synchronized (mGlobalLock) {
408 if (parent == null) {
409 throw new IllegalArgumentException("Can't get children of null parent");
410 }
411 final WindowContainer container = WindowContainer.fromBinder(parent.asBinder());
412 if (container == null) {
413 Slog.e(TAG, "Can't get children of " + parent + " because it is not valid.");
414 return null;
415 }
Louis Changa009c762020-02-26 11:21:31 +0800416 final Task task = container.asTask();
417 if (task == null) {
418 Slog.e(TAG, container + " is not a task...");
419 return null;
420 }
421 // For now, only support returning children of tasks created by the organizer.
422 if (!task.mCreatedByOrganizer) {
Evan Roskya8fde152020-01-07 19:09:13 -0800423 Slog.w(TAG, "Can only get children of root tasks created via createRootTask");
424 return null;
425 }
426 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Louis Changa009c762020-02-26 11:21:31 +0800427 for (int i = task.getChildCount() - 1; i >= 0; --i) {
428 final Task child = task.getChildAt(i).asTask();
429 if (child == null) continue;
430 if (activityTypes != null
431 && !ArrayUtils.contains(activityTypes, child.getActivityType())) {
432 continue;
Evan Roskya8fde152020-01-07 19:09:13 -0800433 }
Louis Changa009c762020-02-26 11:21:31 +0800434 out.add(child.getTaskInfo());
Evan Roskya8fde152020-01-07 19:09:13 -0800435 }
436 return out;
437 }
438 } finally {
439 Binder.restoreCallingIdentity(ident);
440 }
441 }
442
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800443 @Override
444 public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) {
445 enforceStackPermission("getRootTasks()");
446 final long ident = Binder.clearCallingIdentity();
447 try {
448 synchronized (mGlobalLock) {
449 final DisplayContent dc =
450 mService.mRootWindowContainer.getDisplayContent(displayId);
451 if (dc == null) {
452 throw new IllegalArgumentException("Display " + displayId + " doesn't exist");
453 }
454 ArrayList<RunningTaskInfo> out = new ArrayList<>();
455 for (int i = dc.getStackCount() - 1; i >= 0; --i) {
Louis Changa009c762020-02-26 11:21:31 +0800456 final Task task = dc.getStackAt(i);
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800457 if (activityTypes != null
458 && !ArrayUtils.contains(activityTypes, task.getActivityType())) {
459 continue;
460 }
Winson Chung66b08f02020-03-03 14:32:35 -0800461 out.add(task.getTaskInfo());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800462 }
463 return out;
464 }
465 } finally {
466 Binder.restoreCallingIdentity(ident);
467 }
468 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800469}