blob: c9673f59183af1764868dce5c294b5a3428e5548 [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 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 android.app;
18
jorgegil@google.com06bc3232019-10-31 14:51:22 -070019import android.annotation.NonNull;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070020import android.annotation.RequiresPermission;
21import android.annotation.SystemService;
22import android.annotation.TestApi;
Artur Satayevc895b1b2019-12-10 17:47:51 +000023import android.compat.annotation.UnsupportedAppUsage;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070024import android.content.Context;
25import android.content.pm.PackageManager;
26import android.content.res.Resources;
27import android.graphics.Rect;
28import android.os.Handler;
29import android.os.IBinder;
30import android.os.RemoteException;
31import android.os.ServiceManager;
32import android.util.Singleton;
Wale Ogunwale57946582020-03-21 14:29:07 -070033import android.window.ITaskOrganizerController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034
lumark793e0562018-07-09 22:14:33 +080035import java.util.List;
36
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037/**
38 * This class gives information about, and interacts with activities and their containers like task,
39 * stacks, and displays.
40 *
41 * @hide
42 */
43@TestApi
44@SystemService(Context.ACTIVITY_TASK_SERVICE)
45public class ActivityTaskManager {
46
47 /** Invalid stack ID. */
48 public static final int INVALID_STACK_ID = -1;
49
50 /**
Wale Ogunwale98875612018-10-12 07:53:02 -070051 * Invalid task ID.
52 * @hide
53 */
54 public static final int INVALID_TASK_ID = -1;
55
56 /**
Wale Ogunwale65ebd952018-04-25 15:41:44 -070057 * Parameter to {@link IActivityTaskManager#setTaskWindowingModeSplitScreenPrimary} which
58 * specifies the position of the created docked stack at the top half of the screen if
59 * in portrait mode or at the left half of the screen if in landscape mode.
60 */
61 public static final int SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT = 0;
62
63 /**
64 * Parameter to {@link IActivityTaskManager#setTaskWindowingModeSplitScreenPrimary} which
65 * specifies the position of the created docked stack at the bottom half of the screen if
66 * in portrait mode or at the right half of the screen if in landscape mode.
67 */
68 public static final int SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT = 1;
69
70 /**
71 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
72 * that the resize doesn't need to preserve the window, and can be skipped if bounds
73 * is unchanged. This mode is used by window manager in most cases.
74 * @hide
75 */
76 public static final int RESIZE_MODE_SYSTEM = 0;
77
78 /**
79 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
80 * that the resize should preserve the window if possible.
81 * @hide
82 */
83 public static final int RESIZE_MODE_PRESERVE_WINDOW = (0x1 << 0);
84
85 /**
86 * Input parameter to {@link IActivityTaskManager#resizeTask} used when the
87 * resize is due to a drag action.
88 * @hide
89 */
90 public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW;
91
92 /**
93 * Input parameter to {@link IActivityTaskManager#resizeTask} used by window
94 * manager during a screen rotation.
95 * @hide
96 */
97 public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW;
98
99 /**
100 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
101 * that the resize should be performed even if the bounds appears unchanged.
102 * @hide
103 */
104 public static final int RESIZE_MODE_FORCED = (0x1 << 1);
105
106 /**
107 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
108 * that the resize should preserve the window if possible, and should not be skipped
109 * even if the bounds is unchanged. Usually used to force a resizing when a drag action
110 * is ending.
111 * @hide
112 */
113 public static final int RESIZE_MODE_USER_FORCED =
114 RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED;
115
Alison Cichowlas3e340502018-08-07 17:15:01 -0400116 /**
117 * Extra included on intents that are delegating the call to
118 * ActivityManager#startActivityAsCaller to another app. This token is necessary for that call
119 * to succeed. Type is IBinder.
120 * @hide
121 */
122 public static final String EXTRA_PERMISSION_TOKEN = "android.app.extra.PERMISSION_TOKEN";
123
124 /**
125 * Extra included on intents that contain an EXTRA_INTENT, with options that the contained
126 * intent may want to be started with. Type is Bundle.
127 * TODO: remove once the ChooserActivity moves to systemui
128 * @hide
129 */
130 public static final String EXTRA_OPTIONS = "android.app.extra.OPTIONS";
131
132 /**
133 * Extra included on intents that contain an EXTRA_INTENT, use this boolean value for the
134 * parameter of the same name when starting the contained intent.
135 * TODO: remove once the ChooserActivity moves to systemui
136 * @hide
137 */
138 public static final String EXTRA_IGNORE_TARGET_SECURITY =
139 "android.app.extra.EXTRA_IGNORE_TARGET_SECURITY";
140
141
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700142 private static int sMaxRecentTasks = -1;
143
144 ActivityTaskManager(Context context, Handler handler) {
145 }
146
147 /** @hide */
148 public static IActivityTaskManager getService() {
149 return IActivityTaskManagerSingleton.get();
150 }
151
Mathew Inwood7fb5aca2019-04-03 09:49:04 +0100152 @UnsupportedAppUsage(trackingBug = 129726065)
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700153 private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
154 new Singleton<IActivityTaskManager>() {
155 @Override
156 protected IActivityTaskManager create() {
157 final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
158 return IActivityTaskManager.Stub.asInterface(b);
159 }
160 };
161
Evan Rosky0037e5f2019-11-05 10:26:24 -0800162 /** @hide */
163 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
164 public static ITaskOrganizerController getTaskOrganizerController() {
165 return ITaskOrganizerControllerSingleton.get();
166 }
167
168 private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton =
169 new Singleton<ITaskOrganizerController>() {
170 @Override
171 protected ITaskOrganizerController create() {
172 try {
173 return getService().getTaskOrganizerController();
174 } catch (RemoteException e) {
175 return null;
176 }
177 }
178 };
179
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700180 /**
181 * Sets the windowing mode for a specific task. Only works on tasks of type
182 * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}
183 * @param taskId The id of the task to set the windowing mode for.
184 * @param windowingMode The windowing mode to set for the task.
185 * @param toTop If the task should be moved to the top once the windowing mode changes.
Winson Chung7ccc6812020-01-23 16:15:10 -0800186 * @return Whether the task was successfully put into the specified windowing mode.
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700187 */
188 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
Winson Chung7ccc6812020-01-23 16:15:10 -0800189 public boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700190 throws SecurityException {
191 try {
Winson Chung7ccc6812020-01-23 16:15:10 -0800192 return getService().setTaskWindowingMode(taskId, windowingMode, toTop);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700193 } catch (RemoteException e) {
194 throw e.rethrowFromSystemServer();
195 }
196 }
197
198 /**
199 * Moves the input task to the primary-split-screen stack.
200 * @param taskId Id of task to move.
201 * @param createMode The mode the primary split screen stack should be created in if it doesn't
202 * exist already. See
203 * {@link ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
204 * and
205 * {@link android.app.ActivityManager
206 * #SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
207 * @param toTop If the task and stack should be moved to the top.
208 * @param animate Whether we should play an animation for the moving the task
209 * @param initialBounds If the primary stack gets created, it will use these bounds for the
210 * docked stack. Pass {@code null} to use default bounds.
211 * @param showRecents If the recents activity should be shown on the other side of the task
212 * going into split-screen mode.
Winson Chung7ccc6812020-01-23 16:15:10 -0800213 * @return Whether the task was successfully put into splitscreen.
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700214 */
215 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
Winson Chung7ccc6812020-01-23 16:15:10 -0800216 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700217 boolean animate, Rect initialBounds, boolean showRecents) throws SecurityException {
218 try {
Evan Rosky73a7fe92019-11-18 18:28:01 -0800219 return getService().setTaskWindowingModeSplitScreenPrimary(taskId, toTop);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700220 } catch (RemoteException e) {
221 throw e.rethrowFromSystemServer();
222 }
223 }
224
225 /**
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700226 * Removes stacks in the windowing modes from the system if they are of activity type
227 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
228 */
229 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
230 public void removeStacksInWindowingModes(int[] windowingModes) throws SecurityException {
231 try {
232 getService().removeStacksInWindowingModes(windowingModes);
233 } catch (RemoteException e) {
234 throw e.rethrowFromSystemServer();
235 }
236 }
237
238 /** Removes stack of the activity types from the system. */
239 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
240 public void removeStacksWithActivityTypes(int[] activityTypes) throws SecurityException {
241 try {
242 getService().removeStacksWithActivityTypes(activityTypes);
243 } catch (RemoteException e) {
244 throw e.rethrowFromSystemServer();
245 }
246 }
247
248 /**
Winson Chunge6439102018-07-30 15:48:01 -0700249 * Removes all visible recent tasks from the system.
250 * @hide
251 */
252 @RequiresPermission(android.Manifest.permission.REMOVE_TASKS)
253 public void removeAllVisibleRecentTasks() {
254 try {
255 getService().removeAllVisibleRecentTasks();
256 } catch (RemoteException e) {
257 throw e.rethrowFromSystemServer();
258 }
259 }
260
261 /**
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700262 * Return the maximum number of recents entries that we will maintain and show.
263 * @hide
264 */
265 public static int getMaxRecentTasksStatic() {
266 if (sMaxRecentTasks < 0) {
267 return sMaxRecentTasks = ActivityManager.isLowRamDeviceStatic() ? 36 : 48;
268 }
269 return sMaxRecentTasks;
270 }
271
272 /**
273 * Return the default limit on the number of recents that an app can make.
274 * @hide
275 */
276 public static int getDefaultAppRecentsLimitStatic() {
277 return getMaxRecentTasksStatic() / 6;
278 }
279
280 /**
281 * Return the maximum limit on the number of recents that an app can make.
282 * @hide
283 */
284 public static int getMaxAppRecentsLimitStatic() {
285 return getMaxRecentTasksStatic() / 2;
286 }
287
288 /**
289 * Returns true if the system supports at least one form of multi-window.
290 * E.g. freeform, split-screen, picture-in-picture.
291 */
292 public static boolean supportsMultiWindow(Context context) {
293 // On watches, multi-window is used to present essential system UI, and thus it must be
294 // supported regardless of device memory characteristics.
295 boolean isWatch = context.getPackageManager().hasSystemFeature(
296 PackageManager.FEATURE_WATCH);
297 return (!ActivityManager.isLowRamDeviceStatic() || isWatch)
298 && Resources.getSystem().getBoolean(
299 com.android.internal.R.bool.config_supportsMultiWindow);
300 }
301
302 /** Returns true if the system supports split screen multi-window. */
303 public static boolean supportsSplitScreenMultiWindow(Context context) {
304 return supportsMultiWindow(context)
305 && Resources.getSystem().getBoolean(
306 com.android.internal.R.bool.config_supportsSplitScreenMultiWindow);
307 }
lumark793e0562018-07-09 22:14:33 +0800308
309 /**
310 * Moves the top activity in the input stackId to the pinned stack.
311 * @param stackId Id of stack to move the top activity to pinned stack.
312 * @param bounds Bounds to use for pinned stack.
313 * @return True if the top activity of stack was successfully moved to the pinned stack.
lumark793e0562018-07-09 22:14:33 +0800314 */
lumark793e0562018-07-09 22:14:33 +0800315 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
316 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
317 try {
318 return getService().moveTopActivityToPinnedStack(stackId, bounds);
319 } catch (RemoteException e) {
320 throw e.rethrowFromSystemServer();
321 }
322 }
323
324 /**
325 * Start to enter lock task mode for given task by system(UI).
326 * @param taskId Id of task to lock.
lumark793e0562018-07-09 22:14:33 +0800327 */
lumark793e0562018-07-09 22:14:33 +0800328 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
329 public void startSystemLockTaskMode(int taskId) {
330 try {
331 getService().startSystemLockTaskMode(taskId);
332 } catch (RemoteException e) {
333 throw e.rethrowFromSystemServer();
334 }
335 }
336
337 /**
338 * Stop lock task mode by system(UI).
lumark793e0562018-07-09 22:14:33 +0800339 */
lumark793e0562018-07-09 22:14:33 +0800340 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
341 public void stopSystemLockTaskMode() {
342 try {
343 getService().stopSystemLockTaskMode();
344 } catch (RemoteException e) {
345 throw e.rethrowFromSystemServer();
346 }
347 }
348
349 /**
350 * Move task to stack with given id.
351 * @param taskId Id of the task to move.
352 * @param stackId Id of the stack for task moving.
353 * @param toTop Whether the given task should shown to top of stack.
lumark793e0562018-07-09 22:14:33 +0800354 */
lumark793e0562018-07-09 22:14:33 +0800355 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
356 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
357 try {
358 getService().moveTaskToStack(taskId, stackId, toTop);
359 } catch (RemoteException e) {
360 throw e.rethrowFromSystemServer();
361 }
362 }
363
364 /**
lumark793e0562018-07-09 22:14:33 +0800365 * Resize task to given bounds.
366 * @param taskId Id of task to resize.
367 * @param bounds Bounds to resize task.
lumark793e0562018-07-09 22:14:33 +0800368 */
lumark793e0562018-07-09 22:14:33 +0800369 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
370 public void resizeTask(int taskId, Rect bounds) {
371 try {
372 getService().resizeTask(taskId, bounds, RESIZE_MODE_SYSTEM);
373 } catch (RemoteException e) {
374 throw e.rethrowFromSystemServer();
375 }
376 }
377
378 /**
379 * Resize docked stack & its task to given stack & task bounds.
380 * @param stackBounds Bounds to resize stack.
381 * @param taskBounds Bounds to resize task.
lumark793e0562018-07-09 22:14:33 +0800382 */
lumark793e0562018-07-09 22:14:33 +0800383 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
384 public void resizeDockedStack(Rect stackBounds, Rect taskBounds) {
385 try {
386 getService().resizeDockedStack(stackBounds, taskBounds, null, null, null);
387 } catch (RemoteException e) {
388 throw e.rethrowFromSystemServer();
389 }
390 }
391
392 /**
393 * List all activity stacks information.
lumark793e0562018-07-09 22:14:33 +0800394 */
lumark793e0562018-07-09 22:14:33 +0800395 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
396 public String listAllStacks() {
397 final List<ActivityManager.StackInfo> stacks;
398 try {
399 stacks = getService().getAllStackInfos();
400 } catch (RemoteException e) {
401 throw e.rethrowFromSystemServer();
402 }
403
404 final StringBuilder sb = new StringBuilder();
405 if (stacks != null) {
406 for (ActivityManager.StackInfo info : stacks) {
407 sb.append(info).append("\n");
408 }
409 }
410 return sb.toString();
411 }
Garfield Tan01548632018-11-27 10:15:48 -0800412
413 /**
414 * Clears launch params for the given package.
415 * @param packageNames the names of the packages of which the launch params are to be cleared
416 */
Garfield Tan01548632018-11-27 10:15:48 -0800417 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
418 public void clearLaunchParamsForPackages(List<String> packageNames) {
419 try {
420 getService().clearLaunchParamsForPackages(packageNames);
421 } catch (RemoteException e) {
422 e.rethrowFromSystemServer();
423 }
424 }
Wale Ogunwale9e737db2018-12-17 15:42:37 -0800425
426 /**
427 * Makes the display with the given id a single task instance display. I.e the display can only
428 * contain one task.
429 */
430 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
431 public void setDisplayToSingleTaskInstance(int displayId) {
432 try {
433 getService().setDisplayToSingleTaskInstance(displayId);
434 } catch (RemoteException e) {
435 throw e.rethrowFromSystemServer();
436 }
437 }
jorgegil@google.com06bc3232019-10-31 14:51:22 -0700438
439 /**
440 * Requests that an activity should enter picture-in-picture mode if possible.
441 * @hide
442 */
443 @TestApi
444 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
445 public void requestPictureInPictureMode(@NonNull IBinder token) {
446 try {
447 getService().requestPictureInPictureMode(token);
448 } catch (RemoteException e) {
449 throw e.rethrowFromSystemServer();
450 }
451 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700452}