blob: 2bbf8dbb274cea07b44f39a6071b73de25282f17 [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 Ogunwaleadf116e2020-03-27 16:36:01 -070039import android.window.WindowContainerToken;
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());
Riddle Hsu3c290512020-03-30 22:12:52 +080079 if (state != null) {
80 state.dispose();
81 }
Robert Carr8a2f9132019-11-11 15:03:15 -080082 }
83 }
84 };
85
Winson Chungaff506b2020-03-21 22:56:31 -070086 private class TaskOrganizerState {
87 private final ITaskOrganizer mOrganizer;
88 private final DeathRecipient mDeathRecipient;
Winson Chungaff506b2020-03-21 22:56:31 -070089 private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
Winson Chung268eccb2020-03-26 13:43:44 -070090 private final int mUid;
Winson Chunga1f869d2020-03-21 23:02:48 -070091 private boolean mInterceptBackPressedOnTaskRoot;
Robert Carr8a2f9132019-11-11 15:03:15 -080092
Winson Chung268eccb2020-03-26 13:43:44 -070093 TaskOrganizerState(ITaskOrganizer organizer, int uid) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -080094 mOrganizer = organizer;
Evan Roskyb8540a02020-03-25 16:30:24 -070095 mDeathRecipient = new DeathRecipient(organizer);
Robert Carr7d7c8ab2020-01-28 15:57:23 -080096 try {
97 organizer.asBinder().linkToDeath(mDeathRecipient, 0);
98 } catch (RemoteException e) {
99 Slog.e(TAG, "TaskOrganizer failed to register death recipient");
100 }
Winson Chung268eccb2020-03-26 13:43:44 -0700101 mUid = uid;
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800102 }
103
Winson Chunga1f869d2020-03-21 23:02:48 -0700104 void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) {
105 mInterceptBackPressedOnTaskRoot = interceptBackPressed;
106 }
107
Robert Carr8a2f9132019-11-11 15:03:15 -0800108 void addTask(Task t) {
109 mOrganizedTasks.add(t);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800110 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700111 mOrganizer.onTaskAppeared(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800112 } catch (Exception e) {
113 Slog.e(TAG, "Exception sending taskAppeared callback" + e);
114 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800115 }
116
117 void removeTask(Task t) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800118 try {
Wale Ogunwaledec34082020-03-22 09:45:00 -0700119 mOrganizer.onTaskVanished(t.getTaskInfo());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800120 } catch (Exception e) {
121 Slog.e(TAG, "Exception sending taskVanished callback" + e);
122 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800123 mOrganizedTasks.remove(t);
124 }
125
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800126 void dispose() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800127 releaseTasks();
Evan Roskyb8540a02020-03-25 16:30:24 -0700128 for (int i = mTaskOrganizersForWindowingMode.size() - 1; i >= 0; --i) {
129 mTaskOrganizersForWindowingMode.valueAt(i).remove(mOrganizer.asBinder());
130 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800131 }
132
Winson Chungaff506b2020-03-21 22:56:31 -0700133 private void releaseTasks() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800134 for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) {
135 final Task t = mOrganizedTasks.get(i);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800136 removeTask(t);
Winson Chungaff506b2020-03-21 22:56:31 -0700137 t.taskOrganizerUnregistered();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800138 }
139 }
140
141 void unlinkDeath() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800142 mOrganizer.asBinder().unlinkToDeath(mDeathRecipient, 0);
Robert Carr8a2f9132019-11-11 15:03:15 -0800143 }
Winson Chungaff506b2020-03-21 22:56:31 -0700144 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800145
Evan Roskyb8540a02020-03-25 16:30:24 -0700146 private final SparseArray<LinkedList<IBinder>> mTaskOrganizersForWindowingMode =
Winson Chungaff506b2020-03-21 22:56:31 -0700147 new SparseArray<>();
148 private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800149 private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
150 private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
151
Robert Carr8a2f9132019-11-11 15:03:15 -0800152 final ActivityTaskManagerService mService;
153
Evan Rosky0037e5f2019-11-05 10:26:24 -0800154 RunningTaskInfo mTmpTaskInfo;
155
156 TaskOrganizerController(ActivityTaskManagerService atm) {
Robert Carr8a2f9132019-11-11 15:03:15 -0800157 mService = atm;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800158 mGlobalLock = atm.mGlobalLock;
159 }
160
161 private void enforceStackPermission(String func) {
162 mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
Robert Carr8a2f9132019-11-11 15:03:15 -0800163 }
164
Robert Carr8a2f9132019-11-11 15:03:15 -0800165 /**
166 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
167 * If there was already a TaskOrganizer for this windowing mode it will be evicted
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800168 * but will continue to organize it's existing tasks.
Robert Carr8a2f9132019-11-11 15:03:15 -0800169 */
Evan Rosky0037e5f2019-11-05 10:26:24 -0800170 @Override
171 public void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700172 if (windowingMode == WINDOWING_MODE_PINNED) {
173 if (!mService.mSupportsPictureInPicture) {
174 throw new UnsupportedOperationException("Picture in picture is not supported on "
175 + "this device");
176 }
177 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
178 if (!mService.mSupportsSplitScreenMultiWindow) {
179 throw new UnsupportedOperationException("Split-screen is not supported on this "
180 + "device");
181 }
182 } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
183 if (!mService.mSupportsMultiWindow) {
184 throw new UnsupportedOperationException("Multi-window is not supported on this "
185 + "device");
186 }
187 } else {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800188 throw new UnsupportedOperationException("As of now only Pinned/Split/Multiwindow"
189 + " windowing modes are supported for registerTaskOrganizer");
Robert Carr8a2f9132019-11-11 15:03:15 -0800190 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800191 enforceStackPermission("registerTaskOrganizer()");
Winson Chung268eccb2020-03-26 13:43:44 -0700192 final int uid = Binder.getCallingUid();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800193 final long origId = Binder.clearCallingIdentity();
Robert Carr8a2f9132019-11-11 15:03:15 -0800194 try {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800195 synchronized (mGlobalLock) {
Winson Chung77338ab2020-03-09 16:32:34 -0700196 if (getTaskOrganizer(windowingMode) != null) {
197 Slog.w(TAG, "Task organizer already exists for windowing mode: "
198 + windowingMode);
199 }
Winson Chungaff506b2020-03-21 22:56:31 -0700200
Evan Roskyb8540a02020-03-25 16:30:24 -0700201 LinkedList<IBinder> orgs = mTaskOrganizersForWindowingMode.get(windowingMode);
202 if (orgs == null) {
203 orgs = new LinkedList<>();
204 mTaskOrganizersForWindowingMode.put(windowingMode, orgs);
Winson Chungaff506b2020-03-21 22:56:31 -0700205 }
Evan Roskyb8540a02020-03-25 16:30:24 -0700206 orgs.add(organizer.asBinder());
207 if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
208 mTaskOrganizerStates.put(organizer.asBinder(),
Winson Chung268eccb2020-03-26 13:43:44 -0700209 new TaskOrganizerState(organizer, uid));
Evan Roskyb8540a02020-03-25 16:30:24 -0700210 }
Winson Chung77338ab2020-03-09 16:32:34 -0700211
Evan Roskyb8540a02020-03-25 16:30:24 -0700212 if (orgs.size() == 1) {
Winson Chung77338ab2020-03-09 16:32:34 -0700213 // Only in the case where this is the root task organizer for the given
214 // windowing mode, we add report all existing tasks in that mode to the new
215 // task organizer.
216 mService.mRootWindowContainer.forAllTasks((task) -> {
217 if (task.getWindowingMode() == windowingMode) {
218 task.updateTaskOrganizerState(true /* forceUpdate */);
219 }
220 });
221 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800222 }
223 } finally {
224 Binder.restoreCallingIdentity(origId);
Robert Carr8a2f9132019-11-11 15:03:15 -0800225 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800226 }
227
Winson Chung8a168902020-03-12 22:39:22 -0700228 @Override
229 public void unregisterTaskOrganizer(ITaskOrganizer organizer) {
Riddle Hsu3c290512020-03-30 22:12:52 +0800230 enforceStackPermission("unregisterTaskOrganizer()");
231 final long origId = Binder.clearCallingIdentity();
232 try {
233 synchronized (mGlobalLock) {
234 final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder());
235 if (state == null) {
236 return;
237 }
238 state.unlinkDeath();
239 state.dispose();
240 }
241 } finally {
242 Binder.restoreCallingIdentity(origId);
243 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800244 }
245
Robert Carr8a2f9132019-11-11 15:03:15 -0800246 ITaskOrganizer getTaskOrganizer(int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700247 final IBinder organizer =
248 mTaskOrganizersForWindowingMode.get(windowingMode, EMPTY_LIST).peekLast();
249 if (organizer == null) {
250 return null;
251 }
252 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer);
Robert Carr8a2f9132019-11-11 15:03:15 -0800253 if (state == null) {
254 return null;
255 }
256 return state.mOrganizer;
257 }
258
Robert Carr8a2f9132019-11-11 15:03:15 -0800259 void onTaskAppeared(ITaskOrganizer organizer, Task task) {
Robert Carre10ee3d2019-11-11 15:03:15 -0800260 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800261 state.addTask(task);
Robert Carr8a2f9132019-11-11 15:03:15 -0800262 }
263
264 void onTaskVanished(ITaskOrganizer organizer, Task task) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800265 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800266 state.removeTask(task);
267 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800268
269 @Override
270 public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
271 enforceStackPermission("createRootTask()");
272 final long origId = Binder.clearCallingIdentity();
273 try {
274 synchronized (mGlobalLock) {
275 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
276 if (display == null) {
277 return null;
278 }
Louis Changa009c762020-02-26 11:21:31 +0800279
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700280 final Task task = display.getDefaultTaskDisplayArea().createStack(windowingMode,
Wale Ogunwalec27e1ac2020-03-31 13:18:47 -0700281 ACTIVITY_TYPE_UNDEFINED, false /* onTop */, null /* info */, new Intent(),
282 true /* createdByOrganizer */);
Louis Changa009c762020-02-26 11:21:31 +0800283 RunningTaskInfo out = task.getTaskInfo();
284 mLastSentTaskInfos.put(task, out);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800285 return out;
286 }
287 } finally {
288 Binder.restoreCallingIdentity(origId);
289 }
290 }
291
292 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700293 public boolean deleteRootTask(WindowContainerToken token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800294 enforceStackPermission("deleteRootTask()");
295 final long origId = Binder.clearCallingIdentity();
296 try {
297 synchronized (mGlobalLock) {
Louis Changa009c762020-02-26 11:21:31 +0800298 final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
299 if (task == null) return false;
300 if (!task.mCreatedByOrganizer) {
301 throw new IllegalArgumentException(
302 "Attempt to delete task not created by organizer task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800303 }
Louis Changa009c762020-02-26 11:21:31 +0800304 task.removeImmediately();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800305 return true;
306 }
307 } finally {
308 Binder.restoreCallingIdentity(origId);
309 }
310 }
311
312 void dispatchPendingTaskInfoChanges() {
313 if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
314 return;
315 }
316 for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
317 dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
318 }
319 mPendingTaskInfoChanges.clear();
320 }
321
322 void dispatchTaskInfoChanged(Task task, boolean force) {
323 if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
324 // Defer task info reporting while layout is deferred. This is because layout defer
325 // blocks tend to do lots of re-ordering which can mess up animations in receivers.
326 mPendingTaskInfoChanges.remove(task);
327 mPendingTaskInfoChanges.add(task);
328 return;
329 }
330 RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
331 if (mTmpTaskInfo == null) {
332 mTmpTaskInfo = new RunningTaskInfo();
333 }
Evan Roskyf64f5da2020-03-16 13:47:48 -0700334 mTmpTaskInfo.configuration.unset();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800335 task.fillTaskInfo(mTmpTaskInfo);
336 boolean changed = lastInfo == null
337 || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800338 || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
339 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
Evan Roskyf64f5da2020-03-16 13:47:48 -0700340 if (!changed) {
341 int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
342 final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
343 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff(
344 lastInfo.configuration.windowConfiguration,
345 true /* compareUndefined */) : 0;
346 if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) {
347 cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
348 }
349 changed = (cfgChanges & REPORT_CONFIGS) != 0;
350 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800351 if (!(changed || force)) {
352 return;
353 }
354 final RunningTaskInfo newInfo = mTmpTaskInfo;
355 mLastSentTaskInfos.put(task, mTmpTaskInfo);
356 // Since we've stored this, clean up the reference so a new one will be created next time.
357 // Transferring it this way means we only have to construct new RunningTaskInfos when they
358 // change.
359 mTmpTaskInfo = null;
360
361 if (task.mTaskOrganizer != null) {
362 try {
363 task.mTaskOrganizer.onTaskInfoChanged(newInfo);
364 } catch (RemoteException e) {
365 }
366 }
367 }
368
369 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700370 public WindowContainerToken getImeTarget(int displayId) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800371 enforceStackPermission("getImeTarget()");
372 final long origId = Binder.clearCallingIdentity();
373 try {
374 synchronized (mGlobalLock) {
375 DisplayContent dc = mService.mWindowManager.mRoot
376 .getDisplayContent(displayId);
377 if (dc == null || dc.mInputMethodTarget == null) {
378 return null;
379 }
380 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
381 final Task task = dc.mInputMethodTarget.getTask();
382 if (task == null) {
383 return null;
384 }
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700385 return task.getRootTask().mRemoteToken.toWindowContainerToken();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800386 }
387 } finally {
388 Binder.restoreCallingIdentity(origId);
389 }
390 }
391
392 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700393 public void setLaunchRoot(int displayId, @Nullable WindowContainerToken token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800394 enforceStackPermission("setLaunchRoot()");
395 final long origId = Binder.clearCallingIdentity();
396 try {
397 synchronized (mGlobalLock) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700398 TaskDisplayArea defaultTaskDisplayArea = mService.mRootWindowContainer
399 .getDisplayContent(displayId).getDefaultTaskDisplayArea();
400 if (defaultTaskDisplayArea == null) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800401 return;
402 }
Louis Changa009c762020-02-26 11:21:31 +0800403 Task task = token == null
404 ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
405 if (task == null) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700406 defaultTaskDisplayArea.mLaunchRootTask = null;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800407 return;
408 }
Louis Changa009c762020-02-26 11:21:31 +0800409 if (!task.mCreatedByOrganizer) {
410 throw new IllegalArgumentException("Attempt to set task not created by "
411 + "organizer as launch root task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800412 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700413 if (task.getDisplayArea() == null
414 || task.getDisplayArea().getDisplayId() != displayId) {
Louis Changa009c762020-02-26 11:21:31 +0800415 throw new RuntimeException("Can't set launch root for display " + displayId
416 + " to task on display " + task.getDisplayContent().getDisplayId());
417 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700418 task.getDisplayArea().mLaunchRootTask = task;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800419 }
420 } finally {
421 Binder.restoreCallingIdentity(origId);
422 }
423 }
424
Evan Roskya8fde152020-01-07 19:09:13 -0800425 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700426 public List<RunningTaskInfo> getChildTasks(WindowContainerToken parent,
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800427 @Nullable int[] activityTypes) {
Evan Roskya8fde152020-01-07 19:09:13 -0800428 enforceStackPermission("getChildTasks()");
429 final long ident = Binder.clearCallingIdentity();
430 try {
431 synchronized (mGlobalLock) {
432 if (parent == null) {
433 throw new IllegalArgumentException("Can't get children of null parent");
434 }
435 final WindowContainer container = WindowContainer.fromBinder(parent.asBinder());
436 if (container == null) {
437 Slog.e(TAG, "Can't get children of " + parent + " because it is not valid.");
438 return null;
439 }
Louis Changa009c762020-02-26 11:21:31 +0800440 final Task task = container.asTask();
441 if (task == null) {
442 Slog.e(TAG, container + " is not a task...");
443 return null;
444 }
445 // For now, only support returning children of tasks created by the organizer.
446 if (!task.mCreatedByOrganizer) {
Evan Roskya8fde152020-01-07 19:09:13 -0800447 Slog.w(TAG, "Can only get children of root tasks created via createRootTask");
448 return null;
449 }
450 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Louis Changa009c762020-02-26 11:21:31 +0800451 for (int i = task.getChildCount() - 1; i >= 0; --i) {
452 final Task child = task.getChildAt(i).asTask();
453 if (child == null) continue;
454 if (activityTypes != null
455 && !ArrayUtils.contains(activityTypes, child.getActivityType())) {
456 continue;
Evan Roskya8fde152020-01-07 19:09:13 -0800457 }
Louis Changa009c762020-02-26 11:21:31 +0800458 out.add(child.getTaskInfo());
Evan Roskya8fde152020-01-07 19:09:13 -0800459 }
460 return out;
461 }
462 } finally {
463 Binder.restoreCallingIdentity(ident);
464 }
465 }
466
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800467 @Override
468 public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) {
469 enforceStackPermission("getRootTasks()");
470 final long ident = Binder.clearCallingIdentity();
471 try {
472 synchronized (mGlobalLock) {
473 final DisplayContent dc =
474 mService.mRootWindowContainer.getDisplayContent(displayId);
475 if (dc == null) {
476 throw new IllegalArgumentException("Display " + displayId + " doesn't exist");
477 }
478 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700479 for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
480 final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx);
481 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
482 final Task task = taskDisplayArea.getStackAt(sNdx);
483 if (activityTypes != null
484 && !ArrayUtils.contains(activityTypes, task.getActivityType())) {
485 continue;
486 }
487 out.add(task.getTaskInfo());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800488 }
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800489 }
490 return out;
491 }
492 } finally {
493 Binder.restoreCallingIdentity(ident);
494 }
495 }
Winson Chung268eccb2020-03-26 13:43:44 -0700496
Winson Chunga1f869d2020-03-21 23:02:48 -0700497 @Override
498 public void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer,
499 boolean interceptBackPressed) {
500 enforceStackPermission("setInterceptBackPressedOnTaskRoot()");
501 final long origId = Binder.clearCallingIdentity();
502 try {
503 synchronized (mGlobalLock) {
504 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
505 if (state != null) {
506 state.setInterceptBackPressedOnTaskRoot(interceptBackPressed);
507 }
508 }
509 } finally {
510 Binder.restoreCallingIdentity(origId);
511 }
512 }
513
514 public boolean handleInterceptBackPressedOnTaskRoot(Task task) {
515 if (task == null || !task.isOrganized()) {
516 return false;
517 }
518
519 final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder());
520 if (!state.mInterceptBackPressedOnTaskRoot) {
521 return false;
522 }
523
524 try {
525 state.mOrganizer.onBackPressedOnTaskRoot(task.getTaskInfo());
526 } catch (Exception e) {
527 Slog.e(TAG, "Exception sending interceptBackPressedOnTaskRoot callback" + e);
528 }
529 return true;
530 }
531
Winson Chung268eccb2020-03-26 13:43:44 -0700532 public void dump(PrintWriter pw, String prefix) {
533 final String innerPrefix = prefix + " ";
534 pw.print(prefix); pw.println("TaskOrganizerController:");
535 pw.print(innerPrefix); pw.println("Per windowing mode:");
536 for (int i = 0; i < mTaskOrganizersForWindowingMode.size(); i++) {
537 final int windowingMode = mTaskOrganizersForWindowingMode.keyAt(i);
538 final List<IBinder> taskOrgs = mTaskOrganizersForWindowingMode.valueAt(i);
539 pw.println(innerPrefix + " "
540 + WindowConfiguration.windowingModeToString(windowingMode) + ":");
541 for (int j = 0; j < taskOrgs.size(); j++) {
542 final TaskOrganizerState state = mTaskOrganizerStates.get(taskOrgs.get(j));
543 final ArrayList<Task> tasks = state.mOrganizedTasks;
544 pw.print(innerPrefix + " ");
545 pw.println(state.mOrganizer + " uid=" + state.mUid + ":");
546 for (int k = 0; k < tasks.size(); k++) {
547 pw.println(innerPrefix + " " + tasks.get(k));
548 }
549 }
550
551 }
552 pw.println();
553 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800554}