blob: 4382e9d578ad6e159eec44bc3d0d5022a76bd138 [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;
23import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
24import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Robert Carr8a2f9132019-11-11 15:03:15 -080025
Wale Ogunwale568f9f412020-03-21 22:27:35 -070026import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS;
27import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDOW_CONFIGS;
Evan Rosky0037e5f2019-11-05 10:26:24 -080028
29import android.annotation.Nullable;
30import android.app.ActivityManager.RunningTaskInfo;
Louis Changa009c762020-02-26 11:21:31 +080031import android.content.Intent;
Evan Rosky0037e5f2019-11-05 10:26:24 -080032import android.content.pm.ActivityInfo;
Evan Rosky0037e5f2019-11-05 10:26:24 -080033import android.os.Binder;
Robert Carr8a2f9132019-11-11 15:03:15 -080034import android.os.IBinder;
35import android.os.RemoteException;
36import 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
44import java.util.ArrayList;
45import java.util.HashMap;
Winson Chungaff506b2020-03-21 22:56:31 -070046import java.util.LinkedList;
Evan Roskya8fde152020-01-07 19:09:13 -080047import java.util.List;
Evan Rosky0037e5f2019-11-05 10:26:24 -080048import java.util.WeakHashMap;
Robert Carr8a2f9132019-11-11 15:03:15 -080049
50/**
51 * Stores the TaskOrganizers associated with a given windowing mode and
52 * their associated state.
53 */
Wale Ogunwale568f9f412020-03-21 22:27:35 -070054class TaskOrganizerController extends ITaskOrganizerController.Stub {
Robert Carr8a2f9132019-11-11 15:03:15 -080055 private static final String TAG = "TaskOrganizerController";
Winson Chungaff506b2020-03-21 22:56:31 -070056 private static final LinkedList<TaskOrganizerState> EMPTY_LIST = new LinkedList<>();
Robert Carr8a2f9132019-11-11 15:03:15 -080057
Evan Roskyf64f5da2020-03-16 13:47:48 -070058 /**
59 * Masks specifying which configurations are important to report back to an organizer when
60 * changed.
61 */
62 private static final int REPORT_CONFIGS = CONTROLLABLE_CONFIGS;
63 private static final int REPORT_WINDOW_CONFIGS = CONTROLLABLE_WINDOW_CONFIGS;
64
Evan Rosky0037e5f2019-11-05 10:26:24 -080065 private final WindowManagerGlobalLock mGlobalLock;
Robert Carr8a2f9132019-11-11 15:03:15 -080066
67 private class DeathRecipient implements IBinder.DeathRecipient {
68 int mWindowingMode;
69 ITaskOrganizer mTaskOrganizer;
70
71 DeathRecipient(ITaskOrganizer organizer, int windowingMode) {
72 mTaskOrganizer = organizer;
73 mWindowingMode = windowingMode;
74 }
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;
89 private final int mWindowingMode;
90 private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
Robert Carr8a2f9132019-11-11 15:03:15 -080091
Winson Chungaff506b2020-03-21 22:56:31 -070092 TaskOrganizerState(ITaskOrganizer organizer, int windowingMode) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -080093 mOrganizer = organizer;
94 mDeathRecipient = new DeathRecipient(organizer, windowingMode);
95 try {
96 organizer.asBinder().linkToDeath(mDeathRecipient, 0);
97 } catch (RemoteException e) {
98 Slog.e(TAG, "TaskOrganizer failed to register death recipient");
99 }
100 mWindowingMode = windowingMode;
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();
Winson Chungaff506b2020-03-21 22:56:31 -0700123 mTaskOrganizersForWindowingMode.get(mWindowingMode).remove(this);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800124 }
125
Winson Chungaff506b2020-03-21 22:56:31 -0700126 private void releaseTasks() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800127 for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) {
128 final Task t = mOrganizedTasks.get(i);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800129 removeTask(t);
Winson Chungaff506b2020-03-21 22:56:31 -0700130 t.taskOrganizerUnregistered();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800131 }
132 }
133
134 void unlinkDeath() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800135 mOrganizer.asBinder().unlinkToDeath(mDeathRecipient, 0);
Robert Carr8a2f9132019-11-11 15:03:15 -0800136 }
Winson Chungaff506b2020-03-21 22:56:31 -0700137 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800138
Winson Chungaff506b2020-03-21 22:56:31 -0700139 private final SparseArray<LinkedList<TaskOrganizerState>> mTaskOrganizersForWindowingMode =
140 new SparseArray<>();
141 private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800142 private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
143 private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
144
Robert Carr8a2f9132019-11-11 15:03:15 -0800145 final ActivityTaskManagerService mService;
146
Evan Rosky0037e5f2019-11-05 10:26:24 -0800147 RunningTaskInfo mTmpTaskInfo;
148
149 TaskOrganizerController(ActivityTaskManagerService atm) {
Robert Carr8a2f9132019-11-11 15:03:15 -0800150 mService = atm;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800151 mGlobalLock = atm.mGlobalLock;
152 }
153
154 private void enforceStackPermission(String func) {
155 mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
Robert Carr8a2f9132019-11-11 15:03:15 -0800156 }
157
Robert Carr8a2f9132019-11-11 15:03:15 -0800158 /**
159 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
160 * If there was already a TaskOrganizer for this windowing mode it will be evicted
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800161 * but will continue to organize it's existing tasks.
Robert Carr8a2f9132019-11-11 15:03:15 -0800162 */
Evan Rosky0037e5f2019-11-05 10:26:24 -0800163 @Override
164 public void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) {
165 if (windowingMode != WINDOWING_MODE_PINNED
166 && windowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
167 && windowingMode != WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
168 && windowingMode != WINDOWING_MODE_MULTI_WINDOW) {
169 throw new UnsupportedOperationException("As of now only Pinned/Split/Multiwindow"
170 + " windowing modes are supported for registerTaskOrganizer");
Robert Carr8a2f9132019-11-11 15:03:15 -0800171 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800172 enforceStackPermission("registerTaskOrganizer()");
173 final long origId = Binder.clearCallingIdentity();
Robert Carr8a2f9132019-11-11 15:03:15 -0800174 try {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800175 synchronized (mGlobalLock) {
Winson Chung77338ab2020-03-09 16:32:34 -0700176 if (getTaskOrganizer(windowingMode) != null) {
177 Slog.w(TAG, "Task organizer already exists for windowing mode: "
178 + windowingMode);
179 }
Winson Chungaff506b2020-03-21 22:56:31 -0700180
181 LinkedList<TaskOrganizerState> states;
182 if (mTaskOrganizersForWindowingMode.contains(windowingMode)) {
183 states = mTaskOrganizersForWindowingMode.get(windowingMode);
184 } else {
185 states = new LinkedList<>();
186 mTaskOrganizersForWindowingMode.put(windowingMode, states);
187 }
188 final TaskOrganizerState previousState = states.peekLast();
189 final TaskOrganizerState state = new TaskOrganizerState(organizer, windowingMode);
190 states.add(state);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800191 mTaskOrganizerStates.put(organizer.asBinder(), state);
Winson Chung77338ab2020-03-09 16:32:34 -0700192
193 if (previousState == null) {
194 // Only in the case where this is the root task organizer for the given
195 // windowing mode, we add report all existing tasks in that mode to the new
196 // task organizer.
197 mService.mRootWindowContainer.forAllTasks((task) -> {
198 if (task.getWindowingMode() == windowingMode) {
199 task.updateTaskOrganizerState(true /* forceUpdate */);
200 }
201 });
202 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800203 }
204 } finally {
205 Binder.restoreCallingIdentity(origId);
Robert Carr8a2f9132019-11-11 15:03:15 -0800206 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800207 }
208
Winson Chung8a168902020-03-12 22:39:22 -0700209 @Override
210 public void unregisterTaskOrganizer(ITaskOrganizer organizer) {
Winson Chungaff506b2020-03-21 22:56:31 -0700211 final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800212 state.unlinkDeath();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800213 state.dispose();
214 }
215
Robert Carr8a2f9132019-11-11 15:03:15 -0800216 ITaskOrganizer getTaskOrganizer(int windowingMode) {
Winson Chungaff506b2020-03-21 22:56:31 -0700217 final TaskOrganizerState state = mTaskOrganizersForWindowingMode.get(windowingMode,
218 EMPTY_LIST).peekLast();
Robert Carr8a2f9132019-11-11 15:03:15 -0800219 if (state == null) {
220 return null;
221 }
222 return state.mOrganizer;
223 }
224
Robert Carr8a2f9132019-11-11 15:03:15 -0800225 void onTaskAppeared(ITaskOrganizer organizer, Task task) {
Robert Carre10ee3d2019-11-11 15:03:15 -0800226 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800227 state.addTask(task);
Robert Carr8a2f9132019-11-11 15:03:15 -0800228 }
229
230 void onTaskVanished(ITaskOrganizer organizer, Task task) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800231 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800232 state.removeTask(task);
233 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800234
235 @Override
236 public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
237 enforceStackPermission("createRootTask()");
238 final long origId = Binder.clearCallingIdentity();
239 try {
240 synchronized (mGlobalLock) {
241 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
242 if (display == null) {
243 return null;
244 }
Louis Changa009c762020-02-26 11:21:31 +0800245
246 final Task task = display.getOrCreateStack(windowingMode, ACTIVITY_TYPE_UNDEFINED,
247 false /* onTop */, new Intent(), null /* candidateTask */,
248 true /* createdByOrganizer */);
249 RunningTaskInfo out = task.getTaskInfo();
250 mLastSentTaskInfos.put(task, out);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800251 return out;
252 }
253 } finally {
254 Binder.restoreCallingIdentity(origId);
255 }
256 }
257
258 @Override
259 public boolean deleteRootTask(IWindowContainer token) {
260 enforceStackPermission("deleteRootTask()");
261 final long origId = Binder.clearCallingIdentity();
262 try {
263 synchronized (mGlobalLock) {
Louis Changa009c762020-02-26 11:21:31 +0800264 final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
265 if (task == null) return false;
266 if (!task.mCreatedByOrganizer) {
267 throw new IllegalArgumentException(
268 "Attempt to delete task not created by organizer task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800269 }
Louis Changa009c762020-02-26 11:21:31 +0800270 task.removeImmediately();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800271 return true;
272 }
273 } finally {
274 Binder.restoreCallingIdentity(origId);
275 }
276 }
277
278 void dispatchPendingTaskInfoChanges() {
279 if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
280 return;
281 }
282 for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
283 dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
284 }
285 mPendingTaskInfoChanges.clear();
286 }
287
288 void dispatchTaskInfoChanged(Task task, boolean force) {
289 if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
290 // Defer task info reporting while layout is deferred. This is because layout defer
291 // blocks tend to do lots of re-ordering which can mess up animations in receivers.
292 mPendingTaskInfoChanges.remove(task);
293 mPendingTaskInfoChanges.add(task);
294 return;
295 }
296 RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
297 if (mTmpTaskInfo == null) {
298 mTmpTaskInfo = new RunningTaskInfo();
299 }
Evan Roskyf64f5da2020-03-16 13:47:48 -0700300 mTmpTaskInfo.configuration.unset();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800301 task.fillTaskInfo(mTmpTaskInfo);
302 boolean changed = lastInfo == null
303 || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800304 || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
305 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
Evan Roskyf64f5da2020-03-16 13:47:48 -0700306 if (!changed) {
307 int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
308 final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
309 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff(
310 lastInfo.configuration.windowConfiguration,
311 true /* compareUndefined */) : 0;
312 if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) {
313 cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
314 }
315 changed = (cfgChanges & REPORT_CONFIGS) != 0;
316 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800317 if (!(changed || force)) {
318 return;
319 }
320 final RunningTaskInfo newInfo = mTmpTaskInfo;
321 mLastSentTaskInfos.put(task, mTmpTaskInfo);
322 // Since we've stored this, clean up the reference so a new one will be created next time.
323 // Transferring it this way means we only have to construct new RunningTaskInfos when they
324 // change.
325 mTmpTaskInfo = null;
326
327 if (task.mTaskOrganizer != null) {
328 try {
329 task.mTaskOrganizer.onTaskInfoChanged(newInfo);
330 } catch (RemoteException e) {
331 }
332 }
333 }
334
335 @Override
336 public IWindowContainer getImeTarget(int displayId) {
337 enforceStackPermission("getImeTarget()");
338 final long origId = Binder.clearCallingIdentity();
339 try {
340 synchronized (mGlobalLock) {
341 DisplayContent dc = mService.mWindowManager.mRoot
342 .getDisplayContent(displayId);
343 if (dc == null || dc.mInputMethodTarget == null) {
344 return null;
345 }
346 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
347 final Task task = dc.mInputMethodTarget.getTask();
348 if (task == null) {
349 return null;
350 }
Louis Changa009c762020-02-26 11:21:31 +0800351 return task.getRootTask().mRemoteToken;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800352 }
353 } finally {
354 Binder.restoreCallingIdentity(origId);
355 }
356 }
357
358 @Override
Louis Changa009c762020-02-26 11:21:31 +0800359 public void setLaunchRoot(int displayId, @Nullable IWindowContainer token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800360 enforceStackPermission("setLaunchRoot()");
361 final long origId = Binder.clearCallingIdentity();
362 try {
363 synchronized (mGlobalLock) {
364 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
365 if (display == null) {
366 return;
367 }
Louis Changa009c762020-02-26 11:21:31 +0800368 Task task = token == null
369 ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
370 if (task == null) {
371 display.mLaunchRootTask = null;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800372 return;
373 }
Louis Changa009c762020-02-26 11:21:31 +0800374 if (!task.mCreatedByOrganizer) {
375 throw new IllegalArgumentException("Attempt to set task not created by "
376 + "organizer as launch root task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800377 }
Louis Changa009c762020-02-26 11:21:31 +0800378 if (task.getDisplayContent() != display) {
379 throw new RuntimeException("Can't set launch root for display " + displayId
380 + " to task on display " + task.getDisplayContent().getDisplayId());
381 }
382 display.mLaunchRootTask = task;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800383 }
384 } finally {
385 Binder.restoreCallingIdentity(origId);
386 }
387 }
388
Evan Roskya8fde152020-01-07 19:09:13 -0800389 @Override
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800390 public List<RunningTaskInfo> getChildTasks(IWindowContainer parent,
391 @Nullable int[] activityTypes) {
Evan Roskya8fde152020-01-07 19:09:13 -0800392 enforceStackPermission("getChildTasks()");
393 final long ident = Binder.clearCallingIdentity();
394 try {
395 synchronized (mGlobalLock) {
396 if (parent == null) {
397 throw new IllegalArgumentException("Can't get children of null parent");
398 }
399 final WindowContainer container = WindowContainer.fromBinder(parent.asBinder());
400 if (container == null) {
401 Slog.e(TAG, "Can't get children of " + parent + " because it is not valid.");
402 return null;
403 }
Louis Changa009c762020-02-26 11:21:31 +0800404 final Task task = container.asTask();
405 if (task == null) {
406 Slog.e(TAG, container + " is not a task...");
407 return null;
408 }
409 // For now, only support returning children of tasks created by the organizer.
410 if (!task.mCreatedByOrganizer) {
Evan Roskya8fde152020-01-07 19:09:13 -0800411 Slog.w(TAG, "Can only get children of root tasks created via createRootTask");
412 return null;
413 }
414 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Louis Changa009c762020-02-26 11:21:31 +0800415 for (int i = task.getChildCount() - 1; i >= 0; --i) {
416 final Task child = task.getChildAt(i).asTask();
417 if (child == null) continue;
418 if (activityTypes != null
419 && !ArrayUtils.contains(activityTypes, child.getActivityType())) {
420 continue;
Evan Roskya8fde152020-01-07 19:09:13 -0800421 }
Louis Changa009c762020-02-26 11:21:31 +0800422 out.add(child.getTaskInfo());
Evan Roskya8fde152020-01-07 19:09:13 -0800423 }
424 return out;
425 }
426 } finally {
427 Binder.restoreCallingIdentity(ident);
428 }
429 }
430
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800431 @Override
432 public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) {
433 enforceStackPermission("getRootTasks()");
434 final long ident = Binder.clearCallingIdentity();
435 try {
436 synchronized (mGlobalLock) {
437 final DisplayContent dc =
438 mService.mRootWindowContainer.getDisplayContent(displayId);
439 if (dc == null) {
440 throw new IllegalArgumentException("Display " + displayId + " doesn't exist");
441 }
442 ArrayList<RunningTaskInfo> out = new ArrayList<>();
443 for (int i = dc.getStackCount() - 1; i >= 0; --i) {
Louis Changa009c762020-02-26 11:21:31 +0800444 final Task task = dc.getStackAt(i);
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800445 if (activityTypes != null
446 && !ArrayUtils.contains(activityTypes, task.getActivityType())) {
447 continue;
448 }
Winson Chung66b08f02020-03-03 14:32:35 -0800449 out.add(task.getTaskInfo());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800450 }
451 return out;
452 }
453 } finally {
454 Binder.restoreCallingIdentity(ident);
455 }
456 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800457}