blob: 7c47e50244341db13e3caec243115eb4d0a1b829 [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
Winson Chung268eccb2020-03-26 13:43:44 -070043import java.io.PrintWriter;
Robert Carr8a2f9132019-11-11 15:03:15 -080044import 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";
Evan Roskyb8540a02020-03-25 16:30:24 -070056 private static final LinkedList<IBinder> 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 {
Robert Carr8a2f9132019-11-11 15:03:15 -080068 ITaskOrganizer mTaskOrganizer;
69
Evan Roskyb8540a02020-03-25 16:30:24 -070070 DeathRecipient(ITaskOrganizer organizer) {
Robert Carr8a2f9132019-11-11 15:03:15 -080071 mTaskOrganizer = organizer;
Robert Carr8a2f9132019-11-11 15:03:15 -080072 }
73
74 @Override
75 public void binderDied() {
76 synchronized (mGlobalLock) {
Winson Chungaff506b2020-03-21 22:56:31 -070077 final TaskOrganizerState state = mTaskOrganizerStates.remove(
78 mTaskOrganizer.asBinder());
79 state.dispose();
Robert Carr8a2f9132019-11-11 15:03:15 -080080 }
81 }
82 };
83
Winson Chungaff506b2020-03-21 22:56:31 -070084 private class TaskOrganizerState {
85 private final ITaskOrganizer mOrganizer;
86 private final DeathRecipient mDeathRecipient;
Winson Chungaff506b2020-03-21 22:56:31 -070087 private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
Winson Chung268eccb2020-03-26 13:43:44 -070088 private final int mUid;
Winson Chunga1f869d2020-03-21 23:02:48 -070089 private boolean mInterceptBackPressedOnTaskRoot;
Robert Carr8a2f9132019-11-11 15:03:15 -080090
Winson Chung268eccb2020-03-26 13:43:44 -070091 TaskOrganizerState(ITaskOrganizer organizer, int uid) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -080092 mOrganizer = organizer;
Evan Roskyb8540a02020-03-25 16:30:24 -070093 mDeathRecipient = new DeathRecipient(organizer);
Robert Carr7d7c8ab2020-01-28 15:57:23 -080094 try {
95 organizer.asBinder().linkToDeath(mDeathRecipient, 0);
96 } catch (RemoteException e) {
97 Slog.e(TAG, "TaskOrganizer failed to register death recipient");
98 }
Winson Chung268eccb2020-03-26 13:43:44 -070099 mUid = uid;
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800100 }
101
Winson Chunga1f869d2020-03-21 23:02:48 -0700102 void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) {
103 mInterceptBackPressedOnTaskRoot = interceptBackPressed;
104 }
105
Robert Carr8a2f9132019-11-11 15:03:15 -0800106 void addTask(Task t) {
107 mOrganizedTasks.add(t);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800108 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700109 mOrganizer.onTaskAppeared(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800110 } catch (Exception e) {
111 Slog.e(TAG, "Exception sending taskAppeared callback" + e);
112 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800113 }
114
115 void removeTask(Task t) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800116 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700117 mOrganizer.onTaskVanished(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800118 } catch (Exception e) {
119 Slog.e(TAG, "Exception sending taskVanished callback" + e);
120 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800121 mOrganizedTasks.remove(t);
122 }
123
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800124 void dispose() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800125 releaseTasks();
Evan Roskyb8540a02020-03-25 16:30:24 -0700126 for (int i = mTaskOrganizersForWindowingMode.size() - 1; i >= 0; --i) {
127 mTaskOrganizersForWindowingMode.valueAt(i).remove(mOrganizer.asBinder());
128 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800129 }
130
Winson Chungaff506b2020-03-21 22:56:31 -0700131 private void releaseTasks() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800132 for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) {
133 final Task t = mOrganizedTasks.get(i);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800134 removeTask(t);
Winson Chungaff506b2020-03-21 22:56:31 -0700135 t.taskOrganizerUnregistered();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800136 }
137 }
138
139 void unlinkDeath() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800140 mOrganizer.asBinder().unlinkToDeath(mDeathRecipient, 0);
Robert Carr8a2f9132019-11-11 15:03:15 -0800141 }
Winson Chungaff506b2020-03-21 22:56:31 -0700142 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800143
Evan Roskyb8540a02020-03-25 16:30:24 -0700144 private final SparseArray<LinkedList<IBinder>> mTaskOrganizersForWindowingMode =
Winson Chungaff506b2020-03-21 22:56:31 -0700145 new SparseArray<>();
146 private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800147 private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
148 private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
149
Robert Carr8a2f9132019-11-11 15:03:15 -0800150 final ActivityTaskManagerService mService;
151
Evan Rosky0037e5f2019-11-05 10:26:24 -0800152 RunningTaskInfo mTmpTaskInfo;
153
154 TaskOrganizerController(ActivityTaskManagerService atm) {
Robert Carr8a2f9132019-11-11 15:03:15 -0800155 mService = atm;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800156 mGlobalLock = atm.mGlobalLock;
157 }
158
159 private void enforceStackPermission(String func) {
160 mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
Robert Carr8a2f9132019-11-11 15:03:15 -0800161 }
162
Robert Carr8a2f9132019-11-11 15:03:15 -0800163 /**
164 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
165 * If there was already a TaskOrganizer for this windowing mode it will be evicted
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800166 * but will continue to organize it's existing tasks.
Robert Carr8a2f9132019-11-11 15:03:15 -0800167 */
Evan Rosky0037e5f2019-11-05 10:26:24 -0800168 @Override
169 public void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700170 if (windowingMode == WINDOWING_MODE_PINNED) {
171 if (!mService.mSupportsPictureInPicture) {
172 throw new UnsupportedOperationException("Picture in picture is not supported on "
173 + "this device");
174 }
175 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
176 if (!mService.mSupportsSplitScreenMultiWindow) {
177 throw new UnsupportedOperationException("Split-screen is not supported on this "
178 + "device");
179 }
180 } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
181 if (!mService.mSupportsMultiWindow) {
182 throw new UnsupportedOperationException("Multi-window is not supported on this "
183 + "device");
184 }
185 } else {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800186 throw new UnsupportedOperationException("As of now only Pinned/Split/Multiwindow"
187 + " windowing modes are supported for registerTaskOrganizer");
Robert Carr8a2f9132019-11-11 15:03:15 -0800188 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800189 enforceStackPermission("registerTaskOrganizer()");
Winson Chung268eccb2020-03-26 13:43:44 -0700190 final int uid = Binder.getCallingUid();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800191 final long origId = Binder.clearCallingIdentity();
Robert Carr8a2f9132019-11-11 15:03:15 -0800192 try {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800193 synchronized (mGlobalLock) {
Winson Chung77338ab2020-03-09 16:32:34 -0700194 if (getTaskOrganizer(windowingMode) != null) {
195 Slog.w(TAG, "Task organizer already exists for windowing mode: "
196 + windowingMode);
197 }
Winson Chungaff506b2020-03-21 22:56:31 -0700198
Evan Roskyb8540a02020-03-25 16:30:24 -0700199 LinkedList<IBinder> orgs = mTaskOrganizersForWindowingMode.get(windowingMode);
200 if (orgs == null) {
201 orgs = new LinkedList<>();
202 mTaskOrganizersForWindowingMode.put(windowingMode, orgs);
Winson Chungaff506b2020-03-21 22:56:31 -0700203 }
Evan Roskyb8540a02020-03-25 16:30:24 -0700204 orgs.add(organizer.asBinder());
205 if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
206 mTaskOrganizerStates.put(organizer.asBinder(),
Winson Chung268eccb2020-03-26 13:43:44 -0700207 new TaskOrganizerState(organizer, uid));
Evan Roskyb8540a02020-03-25 16:30:24 -0700208 }
Winson Chung77338ab2020-03-09 16:32:34 -0700209
Evan Roskyb8540a02020-03-25 16:30:24 -0700210 if (orgs.size() == 1) {
Winson Chung77338ab2020-03-09 16:32:34 -0700211 // Only in the case where this is the root task organizer for the given
212 // windowing mode, we add report all existing tasks in that mode to the new
213 // task organizer.
214 mService.mRootWindowContainer.forAllTasks((task) -> {
215 if (task.getWindowingMode() == windowingMode) {
216 task.updateTaskOrganizerState(true /* forceUpdate */);
217 }
218 });
219 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800220 }
221 } finally {
222 Binder.restoreCallingIdentity(origId);
Robert Carr8a2f9132019-11-11 15:03:15 -0800223 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800224 }
225
Winson Chung8a168902020-03-12 22:39:22 -0700226 @Override
227 public void unregisterTaskOrganizer(ITaskOrganizer organizer) {
Winson Chungaff506b2020-03-21 22:56:31 -0700228 final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800229 state.unlinkDeath();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800230 state.dispose();
231 }
232
Robert Carr8a2f9132019-11-11 15:03:15 -0800233 ITaskOrganizer getTaskOrganizer(int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700234 final IBinder organizer =
235 mTaskOrganizersForWindowingMode.get(windowingMode, EMPTY_LIST).peekLast();
236 if (organizer == null) {
237 return null;
238 }
239 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer);
Robert Carr8a2f9132019-11-11 15:03:15 -0800240 if (state == null) {
241 return null;
242 }
243 return state.mOrganizer;
244 }
245
Robert Carr8a2f9132019-11-11 15:03:15 -0800246 void onTaskAppeared(ITaskOrganizer organizer, Task task) {
Robert Carre10ee3d2019-11-11 15:03:15 -0800247 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800248 state.addTask(task);
Robert Carr8a2f9132019-11-11 15:03:15 -0800249 }
250
251 void onTaskVanished(ITaskOrganizer organizer, Task task) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800252 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800253 state.removeTask(task);
254 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800255
256 @Override
257 public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
258 enforceStackPermission("createRootTask()");
259 final long origId = Binder.clearCallingIdentity();
260 try {
261 synchronized (mGlobalLock) {
262 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
263 if (display == null) {
264 return null;
265 }
Louis Changa009c762020-02-26 11:21:31 +0800266
Andrii Kulian9ea12da2020-03-27 17:16:38 -0700267 final Task task = display.mTaskContainers.getOrCreateStack(windowingMode,
268 ACTIVITY_TYPE_UNDEFINED, false /* onTop */, new Intent(),
269 null /* candidateTask */, true /* createdByOrganizer */);
Louis Changa009c762020-02-26 11:21:31 +0800270 RunningTaskInfo out = task.getTaskInfo();
271 mLastSentTaskInfos.put(task, out);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800272 return out;
273 }
274 } finally {
275 Binder.restoreCallingIdentity(origId);
276 }
277 }
278
279 @Override
280 public boolean deleteRootTask(IWindowContainer token) {
281 enforceStackPermission("deleteRootTask()");
282 final long origId = Binder.clearCallingIdentity();
283 try {
284 synchronized (mGlobalLock) {
Louis Changa009c762020-02-26 11:21:31 +0800285 final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
286 if (task == null) return false;
287 if (!task.mCreatedByOrganizer) {
288 throw new IllegalArgumentException(
289 "Attempt to delete task not created by organizer task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800290 }
Louis Changa009c762020-02-26 11:21:31 +0800291 task.removeImmediately();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800292 return true;
293 }
294 } finally {
295 Binder.restoreCallingIdentity(origId);
296 }
297 }
298
299 void dispatchPendingTaskInfoChanges() {
300 if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
301 return;
302 }
303 for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
304 dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
305 }
306 mPendingTaskInfoChanges.clear();
307 }
308
309 void dispatchTaskInfoChanged(Task task, boolean force) {
310 if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
311 // Defer task info reporting while layout is deferred. This is because layout defer
312 // blocks tend to do lots of re-ordering which can mess up animations in receivers.
313 mPendingTaskInfoChanges.remove(task);
314 mPendingTaskInfoChanges.add(task);
315 return;
316 }
317 RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
318 if (mTmpTaskInfo == null) {
319 mTmpTaskInfo = new RunningTaskInfo();
320 }
Evan Roskyf64f5da2020-03-16 13:47:48 -0700321 mTmpTaskInfo.configuration.unset();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800322 task.fillTaskInfo(mTmpTaskInfo);
323 boolean changed = lastInfo == null
324 || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800325 || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
326 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
Evan Roskyf64f5da2020-03-16 13:47:48 -0700327 if (!changed) {
328 int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
329 final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
330 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff(
331 lastInfo.configuration.windowConfiguration,
332 true /* compareUndefined */) : 0;
333 if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) {
334 cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
335 }
336 changed = (cfgChanges & REPORT_CONFIGS) != 0;
337 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800338 if (!(changed || force)) {
339 return;
340 }
341 final RunningTaskInfo newInfo = mTmpTaskInfo;
342 mLastSentTaskInfos.put(task, mTmpTaskInfo);
343 // Since we've stored this, clean up the reference so a new one will be created next time.
344 // Transferring it this way means we only have to construct new RunningTaskInfos when they
345 // change.
346 mTmpTaskInfo = null;
347
348 if (task.mTaskOrganizer != null) {
349 try {
350 task.mTaskOrganizer.onTaskInfoChanged(newInfo);
351 } catch (RemoteException e) {
352 }
353 }
354 }
355
356 @Override
357 public IWindowContainer getImeTarget(int displayId) {
358 enforceStackPermission("getImeTarget()");
359 final long origId = Binder.clearCallingIdentity();
360 try {
361 synchronized (mGlobalLock) {
362 DisplayContent dc = mService.mWindowManager.mRoot
363 .getDisplayContent(displayId);
364 if (dc == null || dc.mInputMethodTarget == null) {
365 return null;
366 }
367 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
368 final Task task = dc.mInputMethodTarget.getTask();
369 if (task == null) {
370 return null;
371 }
Louis Changa009c762020-02-26 11:21:31 +0800372 return task.getRootTask().mRemoteToken;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800373 }
374 } finally {
375 Binder.restoreCallingIdentity(origId);
376 }
377 }
378
379 @Override
Louis Changa009c762020-02-26 11:21:31 +0800380 public void setLaunchRoot(int displayId, @Nullable IWindowContainer token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800381 enforceStackPermission("setLaunchRoot()");
382 final long origId = Binder.clearCallingIdentity();
383 try {
384 synchronized (mGlobalLock) {
385 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
386 if (display == null) {
387 return;
388 }
Louis Changa009c762020-02-26 11:21:31 +0800389 Task task = token == null
390 ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
391 if (task == null) {
392 display.mLaunchRootTask = null;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800393 return;
394 }
Louis Changa009c762020-02-26 11:21:31 +0800395 if (!task.mCreatedByOrganizer) {
396 throw new IllegalArgumentException("Attempt to set task not created by "
397 + "organizer as launch root task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800398 }
Louis Changa009c762020-02-26 11:21:31 +0800399 if (task.getDisplayContent() != display) {
400 throw new RuntimeException("Can't set launch root for display " + displayId
401 + " to task on display " + task.getDisplayContent().getDisplayId());
402 }
403 display.mLaunchRootTask = task;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800404 }
405 } finally {
406 Binder.restoreCallingIdentity(origId);
407 }
408 }
409
Evan Roskya8fde152020-01-07 19:09:13 -0800410 @Override
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800411 public List<RunningTaskInfo> getChildTasks(IWindowContainer parent,
412 @Nullable int[] activityTypes) {
Evan Roskya8fde152020-01-07 19:09:13 -0800413 enforceStackPermission("getChildTasks()");
414 final long ident = Binder.clearCallingIdentity();
415 try {
416 synchronized (mGlobalLock) {
417 if (parent == null) {
418 throw new IllegalArgumentException("Can't get children of null parent");
419 }
420 final WindowContainer container = WindowContainer.fromBinder(parent.asBinder());
421 if (container == null) {
422 Slog.e(TAG, "Can't get children of " + parent + " because it is not valid.");
423 return null;
424 }
Louis Changa009c762020-02-26 11:21:31 +0800425 final Task task = container.asTask();
426 if (task == null) {
427 Slog.e(TAG, container + " is not a task...");
428 return null;
429 }
430 // For now, only support returning children of tasks created by the organizer.
431 if (!task.mCreatedByOrganizer) {
Evan Roskya8fde152020-01-07 19:09:13 -0800432 Slog.w(TAG, "Can only get children of root tasks created via createRootTask");
433 return null;
434 }
435 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Louis Changa009c762020-02-26 11:21:31 +0800436 for (int i = task.getChildCount() - 1; i >= 0; --i) {
437 final Task child = task.getChildAt(i).asTask();
438 if (child == null) continue;
439 if (activityTypes != null
440 && !ArrayUtils.contains(activityTypes, child.getActivityType())) {
441 continue;
Evan Roskya8fde152020-01-07 19:09:13 -0800442 }
Louis Changa009c762020-02-26 11:21:31 +0800443 out.add(child.getTaskInfo());
Evan Roskya8fde152020-01-07 19:09:13 -0800444 }
445 return out;
446 }
447 } finally {
448 Binder.restoreCallingIdentity(ident);
449 }
450 }
451
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800452 @Override
453 public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) {
454 enforceStackPermission("getRootTasks()");
455 final long ident = Binder.clearCallingIdentity();
456 try {
457 synchronized (mGlobalLock) {
458 final DisplayContent dc =
459 mService.mRootWindowContainer.getDisplayContent(displayId);
460 if (dc == null) {
461 throw new IllegalArgumentException("Display " + displayId + " doesn't exist");
462 }
463 ArrayList<RunningTaskInfo> out = new ArrayList<>();
464 for (int i = dc.getStackCount() - 1; i >= 0; --i) {
Louis Changa009c762020-02-26 11:21:31 +0800465 final Task task = dc.getStackAt(i);
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800466 if (activityTypes != null
467 && !ArrayUtils.contains(activityTypes, task.getActivityType())) {
468 continue;
469 }
Winson Chung66b08f02020-03-03 14:32:35 -0800470 out.add(task.getTaskInfo());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800471 }
472 return out;
473 }
474 } finally {
475 Binder.restoreCallingIdentity(ident);
476 }
477 }
Winson Chung268eccb2020-03-26 13:43:44 -0700478
Winson Chunga1f869d2020-03-21 23:02:48 -0700479 @Override
480 public void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer,
481 boolean interceptBackPressed) {
482 enforceStackPermission("setInterceptBackPressedOnTaskRoot()");
483 final long origId = Binder.clearCallingIdentity();
484 try {
485 synchronized (mGlobalLock) {
486 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
487 if (state != null) {
488 state.setInterceptBackPressedOnTaskRoot(interceptBackPressed);
489 }
490 }
491 } finally {
492 Binder.restoreCallingIdentity(origId);
493 }
494 }
495
496 public boolean handleInterceptBackPressedOnTaskRoot(Task task) {
497 if (task == null || !task.isOrganized()) {
498 return false;
499 }
500
501 final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder());
502 if (!state.mInterceptBackPressedOnTaskRoot) {
503 return false;
504 }
505
506 try {
507 state.mOrganizer.onBackPressedOnTaskRoot(task.getTaskInfo());
508 } catch (Exception e) {
509 Slog.e(TAG, "Exception sending interceptBackPressedOnTaskRoot callback" + e);
510 }
511 return true;
512 }
513
Winson Chung268eccb2020-03-26 13:43:44 -0700514 public void dump(PrintWriter pw, String prefix) {
515 final String innerPrefix = prefix + " ";
516 pw.print(prefix); pw.println("TaskOrganizerController:");
517 pw.print(innerPrefix); pw.println("Per windowing mode:");
518 for (int i = 0; i < mTaskOrganizersForWindowingMode.size(); i++) {
519 final int windowingMode = mTaskOrganizersForWindowingMode.keyAt(i);
520 final List<IBinder> taskOrgs = mTaskOrganizersForWindowingMode.valueAt(i);
521 pw.println(innerPrefix + " "
522 + WindowConfiguration.windowingModeToString(windowingMode) + ":");
523 for (int j = 0; j < taskOrgs.size(); j++) {
524 final TaskOrganizerState state = mTaskOrganizerStates.get(taskOrgs.get(j));
525 final ArrayList<Task> tasks = state.mOrganizedTasks;
526 pw.print(innerPrefix + " ");
527 pw.println(state.mOrganizer + " uid=" + state.mUid + ":");
528 for (int k = 0; k < tasks.size(); k++) {
529 pw.println(innerPrefix + " " + tasks.get(k));
530 }
531 }
532
533 }
534 pw.println();
535 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800536}