blob: 22702dd6b5661d3c006fe9bff8f2667c2a93d943 [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 }
Winson Chungd2fb07e2020-04-06 18:17:21 +000084 };
Robert Carr8a2f9132019-11-11 15:03:15 -080085
Winson Chungaff506b2020-03-21 22:56:31 -070086 private class TaskOrganizerState {
Winson Chungd2fb07e2020-04-06 18:17:21 +000087 private final ITaskOrganizer mOrganizer;
Winson Chungaff506b2020-03-21 22:56:31 -070088 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) {
Winson Chungd2fb07e2020-04-06 18:17:21 +000094 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) {
Louis Chang9d35a3a2020-04-06 17:23:02 +0800109 if (t.mTaskAppearedSent) return;
110
111 if (!mOrganizedTasks.contains(t)) {
112 mOrganizedTasks.add(t);
113 }
114 if (t.taskAppearedReady()) {
115 try {
116 t.mTaskAppearedSent = true;
117 mOrganizer.onTaskAppeared(t.getTaskInfo());
118 } catch (Exception e) {
119 Slog.e(TAG, "Exception sending taskAppeared callback" + e);
120 }
Winson Chungd2fb07e2020-04-06 18:17:21 +0000121 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800122 }
123
124 void removeTask(Task t) {
Louis Chang9d35a3a2020-04-06 17:23:02 +0800125 if (t.mTaskAppearedSent) {
126 try {
127 t.mTaskAppearedSent = false;
128 mOrganizer.onTaskVanished(t.getTaskInfo());
129 } catch (Exception e) {
130 Slog.e(TAG, "Exception sending taskVanished callback" + e);
131 }
Winson Chungd2fb07e2020-04-06 18:17:21 +0000132 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800133 mOrganizedTasks.remove(t);
134 }
135
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800136 void dispose() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800137 releaseTasks();
Evan Roskyb8540a02020-03-25 16:30:24 -0700138 for (int i = mTaskOrganizersForWindowingMode.size() - 1; i >= 0; --i) {
Winson Chungd2fb07e2020-04-06 18:17:21 +0000139 mTaskOrganizersForWindowingMode.valueAt(i).remove(mOrganizer.asBinder());
Evan Roskyb8540a02020-03-25 16:30:24 -0700140 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800141 }
142
Winson Chungaff506b2020-03-21 22:56:31 -0700143 private void releaseTasks() {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800144 for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) {
145 final Task t = mOrganizedTasks.get(i);
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800146 removeTask(t);
Winson Chungaff506b2020-03-21 22:56:31 -0700147 t.taskOrganizerUnregistered();
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800148 }
149 }
150
151 void unlinkDeath() {
Winson Chungd2fb07e2020-04-06 18:17:21 +0000152 mOrganizer.asBinder().unlinkToDeath(mDeathRecipient, 0);
Robert Carr8a2f9132019-11-11 15:03:15 -0800153 }
Winson Chungaff506b2020-03-21 22:56:31 -0700154 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800155
Evan Roskyb8540a02020-03-25 16:30:24 -0700156 private final SparseArray<LinkedList<IBinder>> mTaskOrganizersForWindowingMode =
Winson Chungaff506b2020-03-21 22:56:31 -0700157 new SparseArray<>();
158 private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800159 private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
160 private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
161
Winson Chungd2fb07e2020-04-06 18:17:21 +0000162 final ActivityTaskManagerService mService;
Robert Carr8a2f9132019-11-11 15:03:15 -0800163
Winson Chungd2fb07e2020-04-06 18:17:21 +0000164 RunningTaskInfo mTmpTaskInfo;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800165
166 TaskOrganizerController(ActivityTaskManagerService atm) {
Robert Carr8a2f9132019-11-11 15:03:15 -0800167 mService = atm;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800168 mGlobalLock = atm.mGlobalLock;
169 }
170
171 private void enforceStackPermission(String func) {
172 mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
Robert Carr8a2f9132019-11-11 15:03:15 -0800173 }
174
Robert Carr8a2f9132019-11-11 15:03:15 -0800175 /**
176 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
177 * If there was already a TaskOrganizer for this windowing mode it will be evicted
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800178 * but will continue to organize it's existing tasks.
Robert Carr8a2f9132019-11-11 15:03:15 -0800179 */
Evan Rosky0037e5f2019-11-05 10:26:24 -0800180 @Override
181 public void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700182 if (windowingMode == WINDOWING_MODE_PINNED) {
183 if (!mService.mSupportsPictureInPicture) {
184 throw new UnsupportedOperationException("Picture in picture is not supported on "
185 + "this device");
186 }
187 } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
188 if (!mService.mSupportsSplitScreenMultiWindow) {
189 throw new UnsupportedOperationException("Split-screen is not supported on this "
190 + "device");
191 }
192 } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
193 if (!mService.mSupportsMultiWindow) {
194 throw new UnsupportedOperationException("Multi-window is not supported on this "
195 + "device");
196 }
197 } else {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800198 throw new UnsupportedOperationException("As of now only Pinned/Split/Multiwindow"
199 + " windowing modes are supported for registerTaskOrganizer");
Robert Carr8a2f9132019-11-11 15:03:15 -0800200 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800201 enforceStackPermission("registerTaskOrganizer()");
Winson Chung268eccb2020-03-26 13:43:44 -0700202 final int uid = Binder.getCallingUid();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800203 final long origId = Binder.clearCallingIdentity();
Robert Carr8a2f9132019-11-11 15:03:15 -0800204 try {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800205 synchronized (mGlobalLock) {
Winson Chung77338ab2020-03-09 16:32:34 -0700206 if (getTaskOrganizer(windowingMode) != null) {
207 Slog.w(TAG, "Task organizer already exists for windowing mode: "
208 + windowingMode);
209 }
Winson Chungaff506b2020-03-21 22:56:31 -0700210
Evan Roskyb8540a02020-03-25 16:30:24 -0700211 LinkedList<IBinder> orgs = mTaskOrganizersForWindowingMode.get(windowingMode);
212 if (orgs == null) {
213 orgs = new LinkedList<>();
214 mTaskOrganizersForWindowingMode.put(windowingMode, orgs);
Winson Chungaff506b2020-03-21 22:56:31 -0700215 }
Evan Roskyb8540a02020-03-25 16:30:24 -0700216 orgs.add(organizer.asBinder());
217 if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
218 mTaskOrganizerStates.put(organizer.asBinder(),
Winson Chung268eccb2020-03-26 13:43:44 -0700219 new TaskOrganizerState(organizer, uid));
Evan Roskyb8540a02020-03-25 16:30:24 -0700220 }
Winson Chung77338ab2020-03-09 16:32:34 -0700221
Evan Roskyb8540a02020-03-25 16:30:24 -0700222 if (orgs.size() == 1) {
Winson Chung77338ab2020-03-09 16:32:34 -0700223 // Only in the case where this is the root task organizer for the given
224 // windowing mode, we add report all existing tasks in that mode to the new
225 // task organizer.
226 mService.mRootWindowContainer.forAllTasks((task) -> {
227 if (task.getWindowingMode() == windowingMode) {
228 task.updateTaskOrganizerState(true /* forceUpdate */);
229 }
230 });
231 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800232 }
233 } finally {
234 Binder.restoreCallingIdentity(origId);
Robert Carr8a2f9132019-11-11 15:03:15 -0800235 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800236 }
237
Winson Chung8a168902020-03-12 22:39:22 -0700238 @Override
239 public void unregisterTaskOrganizer(ITaskOrganizer organizer) {
Riddle Hsu3c290512020-03-30 22:12:52 +0800240 enforceStackPermission("unregisterTaskOrganizer()");
241 final long origId = Binder.clearCallingIdentity();
242 try {
243 synchronized (mGlobalLock) {
244 final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder());
245 if (state == null) {
246 return;
247 }
248 state.unlinkDeath();
249 state.dispose();
250 }
251 } finally {
252 Binder.restoreCallingIdentity(origId);
253 }
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800254 }
255
Robert Carr8a2f9132019-11-11 15:03:15 -0800256 ITaskOrganizer getTaskOrganizer(int windowingMode) {
Evan Roskyb8540a02020-03-25 16:30:24 -0700257 final IBinder organizer =
258 mTaskOrganizersForWindowingMode.get(windowingMode, EMPTY_LIST).peekLast();
259 if (organizer == null) {
260 return null;
261 }
262 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer);
Robert Carr8a2f9132019-11-11 15:03:15 -0800263 if (state == null) {
264 return null;
265 }
Winson Chungd2fb07e2020-04-06 18:17:21 +0000266 return state.mOrganizer;
Robert Carr8a2f9132019-11-11 15:03:15 -0800267 }
268
Robert Carr8a2f9132019-11-11 15:03:15 -0800269 void onTaskAppeared(ITaskOrganizer organizer, Task task) {
Robert Carre10ee3d2019-11-11 15:03:15 -0800270 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800271 state.addTask(task);
Robert Carr8a2f9132019-11-11 15:03:15 -0800272 }
273
274 void onTaskVanished(ITaskOrganizer organizer, Task task) {
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800275 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
Robert Carr8a2f9132019-11-11 15:03:15 -0800276 state.removeTask(task);
277 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800278
279 @Override
280 public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
281 enforceStackPermission("createRootTask()");
282 final long origId = Binder.clearCallingIdentity();
283 try {
284 synchronized (mGlobalLock) {
285 DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
286 if (display == null) {
287 return null;
288 }
Louis Changa009c762020-02-26 11:21:31 +0800289
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700290 final Task task = display.getDefaultTaskDisplayArea().createStack(windowingMode,
Wale Ogunwalec27e1ac2020-03-31 13:18:47 -0700291 ACTIVITY_TYPE_UNDEFINED, false /* onTop */, null /* info */, new Intent(),
292 true /* createdByOrganizer */);
Louis Changa009c762020-02-26 11:21:31 +0800293 RunningTaskInfo out = task.getTaskInfo();
294 mLastSentTaskInfos.put(task, out);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800295 return out;
296 }
297 } finally {
298 Binder.restoreCallingIdentity(origId);
299 }
300 }
301
302 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700303 public boolean deleteRootTask(WindowContainerToken token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800304 enforceStackPermission("deleteRootTask()");
305 final long origId = Binder.clearCallingIdentity();
306 try {
307 synchronized (mGlobalLock) {
Louis Changa009c762020-02-26 11:21:31 +0800308 final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
309 if (task == null) return false;
310 if (!task.mCreatedByOrganizer) {
311 throw new IllegalArgumentException(
312 "Attempt to delete task not created by organizer task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800313 }
Louis Changa009c762020-02-26 11:21:31 +0800314 task.removeImmediately();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800315 return true;
316 }
317 } finally {
318 Binder.restoreCallingIdentity(origId);
319 }
320 }
321
322 void dispatchPendingTaskInfoChanges() {
323 if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
324 return;
325 }
326 for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
327 dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
328 }
329 mPendingTaskInfoChanges.clear();
330 }
331
332 void dispatchTaskInfoChanged(Task task, boolean force) {
333 if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
334 // Defer task info reporting while layout is deferred. This is because layout defer
335 // blocks tend to do lots of re-ordering which can mess up animations in receivers.
336 mPendingTaskInfoChanges.remove(task);
337 mPendingTaskInfoChanges.add(task);
338 return;
339 }
340 RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
341 if (mTmpTaskInfo == null) {
342 mTmpTaskInfo = new RunningTaskInfo();
343 }
Evan Roskyf64f5da2020-03-16 13:47:48 -0700344 mTmpTaskInfo.configuration.unset();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800345 task.fillTaskInfo(mTmpTaskInfo);
346 boolean changed = lastInfo == null
347 || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800348 || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
349 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
Evan Roskyf64f5da2020-03-16 13:47:48 -0700350 if (!changed) {
351 int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
352 final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
353 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff(
354 lastInfo.configuration.windowConfiguration,
355 true /* compareUndefined */) : 0;
356 if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) {
357 cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
358 }
359 changed = (cfgChanges & REPORT_CONFIGS) != 0;
360 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800361 if (!(changed || force)) {
362 return;
363 }
364 final RunningTaskInfo newInfo = mTmpTaskInfo;
365 mLastSentTaskInfos.put(task, mTmpTaskInfo);
366 // Since we've stored this, clean up the reference so a new one will be created next time.
367 // Transferring it this way means we only have to construct new RunningTaskInfos when they
368 // change.
369 mTmpTaskInfo = null;
370
Winson Chungd2fb07e2020-04-06 18:17:21 +0000371 if (task.mTaskOrganizer != null) {
372 try {
373 task.mTaskOrganizer.onTaskInfoChanged(newInfo);
374 } catch (RemoteException e) {
375 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800376 }
377 }
378
379 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700380 public WindowContainerToken getImeTarget(int displayId) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800381 enforceStackPermission("getImeTarget()");
382 final long origId = Binder.clearCallingIdentity();
383 try {
384 synchronized (mGlobalLock) {
385 DisplayContent dc = mService.mWindowManager.mRoot
386 .getDisplayContent(displayId);
387 if (dc == null || dc.mInputMethodTarget == null) {
388 return null;
389 }
390 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
391 final Task task = dc.mInputMethodTarget.getTask();
392 if (task == null) {
393 return null;
394 }
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700395 return task.getRootTask().mRemoteToken.toWindowContainerToken();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800396 }
397 } finally {
398 Binder.restoreCallingIdentity(origId);
399 }
400 }
401
402 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700403 public void setLaunchRoot(int displayId, @Nullable WindowContainerToken token) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800404 enforceStackPermission("setLaunchRoot()");
405 final long origId = Binder.clearCallingIdentity();
406 try {
407 synchronized (mGlobalLock) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700408 TaskDisplayArea defaultTaskDisplayArea = mService.mRootWindowContainer
409 .getDisplayContent(displayId).getDefaultTaskDisplayArea();
410 if (defaultTaskDisplayArea == null) {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800411 return;
412 }
Louis Changa009c762020-02-26 11:21:31 +0800413 Task task = token == null
414 ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
415 if (task == null) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700416 defaultTaskDisplayArea.mLaunchRootTask = null;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800417 return;
418 }
Louis Changa009c762020-02-26 11:21:31 +0800419 if (!task.mCreatedByOrganizer) {
420 throw new IllegalArgumentException("Attempt to set task not created by "
421 + "organizer as launch root task=" + task);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800422 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700423 if (task.getDisplayArea() == null
424 || task.getDisplayArea().getDisplayId() != displayId) {
Louis Changa009c762020-02-26 11:21:31 +0800425 throw new RuntimeException("Can't set launch root for display " + displayId
426 + " to task on display " + task.getDisplayContent().getDisplayId());
427 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700428 task.getDisplayArea().mLaunchRootTask = task;
Evan Rosky0037e5f2019-11-05 10:26:24 -0800429 }
430 } finally {
431 Binder.restoreCallingIdentity(origId);
432 }
433 }
434
Evan Roskya8fde152020-01-07 19:09:13 -0800435 @Override
Wale Ogunwaleadf116e2020-03-27 16:36:01 -0700436 public List<RunningTaskInfo> getChildTasks(WindowContainerToken parent,
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800437 @Nullable int[] activityTypes) {
Evan Roskya8fde152020-01-07 19:09:13 -0800438 enforceStackPermission("getChildTasks()");
439 final long ident = Binder.clearCallingIdentity();
440 try {
441 synchronized (mGlobalLock) {
442 if (parent == null) {
443 throw new IllegalArgumentException("Can't get children of null parent");
444 }
445 final WindowContainer container = WindowContainer.fromBinder(parent.asBinder());
446 if (container == null) {
447 Slog.e(TAG, "Can't get children of " + parent + " because it is not valid.");
448 return null;
449 }
Louis Changa009c762020-02-26 11:21:31 +0800450 final Task task = container.asTask();
451 if (task == null) {
452 Slog.e(TAG, container + " is not a task...");
453 return null;
454 }
455 // For now, only support returning children of tasks created by the organizer.
456 if (!task.mCreatedByOrganizer) {
Evan Roskya8fde152020-01-07 19:09:13 -0800457 Slog.w(TAG, "Can only get children of root tasks created via createRootTask");
458 return null;
459 }
460 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Louis Changa009c762020-02-26 11:21:31 +0800461 for (int i = task.getChildCount() - 1; i >= 0; --i) {
462 final Task child = task.getChildAt(i).asTask();
463 if (child == null) continue;
464 if (activityTypes != null
465 && !ArrayUtils.contains(activityTypes, child.getActivityType())) {
466 continue;
Evan Roskya8fde152020-01-07 19:09:13 -0800467 }
Louis Changa009c762020-02-26 11:21:31 +0800468 out.add(child.getTaskInfo());
Evan Roskya8fde152020-01-07 19:09:13 -0800469 }
470 return out;
471 }
472 } finally {
473 Binder.restoreCallingIdentity(ident);
474 }
475 }
476
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800477 @Override
478 public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) {
479 enforceStackPermission("getRootTasks()");
480 final long ident = Binder.clearCallingIdentity();
481 try {
482 synchronized (mGlobalLock) {
483 final DisplayContent dc =
484 mService.mRootWindowContainer.getDisplayContent(displayId);
485 if (dc == null) {
486 throw new IllegalArgumentException("Display " + displayId + " doesn't exist");
487 }
488 ArrayList<RunningTaskInfo> out = new ArrayList<>();
Andrii Kulianf9df4a82020-03-31 12:09:27 -0700489 for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
490 final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx);
491 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
492 final Task task = taskDisplayArea.getStackAt(sNdx);
493 if (activityTypes != null
494 && !ArrayUtils.contains(activityTypes, task.getActivityType())) {
495 continue;
496 }
497 out.add(task.getTaskInfo());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800498 }
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800499 }
500 return out;
501 }
502 } finally {
503 Binder.restoreCallingIdentity(ident);
504 }
505 }
Winson Chung268eccb2020-03-26 13:43:44 -0700506
Winson Chunga1f869d2020-03-21 23:02:48 -0700507 @Override
508 public void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer,
509 boolean interceptBackPressed) {
510 enforceStackPermission("setInterceptBackPressedOnTaskRoot()");
511 final long origId = Binder.clearCallingIdentity();
512 try {
513 synchronized (mGlobalLock) {
514 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
515 if (state != null) {
516 state.setInterceptBackPressedOnTaskRoot(interceptBackPressed);
517 }
518 }
519 } finally {
520 Binder.restoreCallingIdentity(origId);
521 }
522 }
523
524 public boolean handleInterceptBackPressedOnTaskRoot(Task task) {
525 if (task == null || !task.isOrganized()) {
526 return false;
527 }
528
529 final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder());
530 if (!state.mInterceptBackPressedOnTaskRoot) {
531 return false;
532 }
533
Winson Chungd2fb07e2020-04-06 18:17:21 +0000534 try {
535 state.mOrganizer.onBackPressedOnTaskRoot(task.getTaskInfo());
536 } catch (Exception e) {
537 Slog.e(TAG, "Exception sending interceptBackPressedOnTaskRoot callback" + e);
538 }
Winson Chunga1f869d2020-03-21 23:02:48 -0700539 return true;
540 }
541
Winson Chung268eccb2020-03-26 13:43:44 -0700542 public void dump(PrintWriter pw, String prefix) {
543 final String innerPrefix = prefix + " ";
544 pw.print(prefix); pw.println("TaskOrganizerController:");
545 pw.print(innerPrefix); pw.println("Per windowing mode:");
546 for (int i = 0; i < mTaskOrganizersForWindowingMode.size(); i++) {
547 final int windowingMode = mTaskOrganizersForWindowingMode.keyAt(i);
548 final List<IBinder> taskOrgs = mTaskOrganizersForWindowingMode.valueAt(i);
549 pw.println(innerPrefix + " "
550 + WindowConfiguration.windowingModeToString(windowingMode) + ":");
551 for (int j = 0; j < taskOrgs.size(); j++) {
552 final TaskOrganizerState state = mTaskOrganizerStates.get(taskOrgs.get(j));
553 final ArrayList<Task> tasks = state.mOrganizedTasks;
554 pw.print(innerPrefix + " ");
Winson Chungd2fb07e2020-04-06 18:17:21 +0000555 pw.println(state.mOrganizer + " uid=" + state.mUid + ":");
Winson Chung268eccb2020-03-26 13:43:44 -0700556 for (int k = 0; k < tasks.size(); k++) {
557 pw.println(innerPrefix + " " + tasks.get(k));
558 }
559 }
560
561 }
562 pw.println();
563 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800564}