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