• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.app;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.RequiresPermission;
22 import android.annotation.SystemService;
23 import android.annotation.TestApi;
24 import android.compat.annotation.UnsupportedAppUsage;
25 import android.content.Context;
26 import android.content.pm.PackageManager;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.graphics.Rect;
30 import android.os.Build;
31 import android.os.IBinder;
32 import android.os.Parcel;
33 import android.os.Parcelable;
34 import android.os.RemoteException;
35 import android.os.ServiceManager;
36 import android.util.DisplayMetrics;
37 import android.util.Singleton;
38 import android.view.RemoteAnimationDefinition;
39 import android.window.SplashScreenView.SplashScreenViewParcelable;
40 
41 import java.util.List;
42 
43 /**
44  * This class gives information about, and interacts with activities and their containers like task,
45  * stacks, and displays.
46  *
47  * @hide
48  */
49 @TestApi
50 @SystemService(Context.ACTIVITY_TASK_SERVICE)
51 public class ActivityTaskManager {
52 
53     /** Invalid stack ID. */
54     public static final int INVALID_STACK_ID = -1;
55 
56     /**
57      * Invalid task ID.
58      * @hide
59      */
60     public static final int INVALID_TASK_ID = -1;
61 
62     /**
63      * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
64      * that the resize doesn't need to preserve the window, and can be skipped if bounds
65      * is unchanged. This mode is used by window manager in most cases.
66      * @hide
67      */
68     public static final int RESIZE_MODE_SYSTEM = 0;
69 
70     /**
71      * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
72      * that the resize should preserve the window if possible.
73      * @hide
74      */
75     public static final int RESIZE_MODE_PRESERVE_WINDOW   = (0x1 << 0);
76 
77     /**
78      * Input parameter to {@link IActivityTaskManager#resizeTask} used when the
79      * resize is due to a drag action.
80      * @hide
81      */
82     public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW;
83 
84     /**
85      * Input parameter to {@link IActivityTaskManager#resizeTask} used by window
86      * manager during a screen rotation.
87      * @hide
88      */
89     public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW;
90 
91     /**
92      * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
93      * that the resize should be performed even if the bounds appears unchanged.
94      * @hide
95      */
96     public static final int RESIZE_MODE_FORCED = (0x1 << 1);
97 
98     /**
99      * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
100      * that the resize should preserve the window if possible, and should not be skipped
101      * even if the bounds is unchanged. Usually used to force a resizing when a drag action
102      * is ending.
103      * @hide
104      */
105     public static final int RESIZE_MODE_USER_FORCED =
106             RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED;
107 
108     /**
109      * Extra included on intents that are delegating the call to
110      * ActivityManager#startActivityAsCaller to another app.  This token is necessary for that call
111      * to succeed.  Type is IBinder.
112      * @hide
113      */
114     public static final String EXTRA_PERMISSION_TOKEN = "android.app.extra.PERMISSION_TOKEN";
115 
116     /**
117      * Extra included on intents that contain an EXTRA_INTENT, with options that the contained
118      * intent may want to be started with.  Type is Bundle.
119      * TODO: remove once the ChooserActivity moves to systemui
120      * @hide
121      */
122     public static final String EXTRA_OPTIONS = "android.app.extra.OPTIONS";
123 
124     /**
125      * Extra included on intents that contain an EXTRA_INTENT, use this boolean value for the
126      * parameter of the same name when starting the contained intent.
127      * TODO: remove once the ChooserActivity moves to systemui
128      * @hide
129      */
130     public static final String EXTRA_IGNORE_TARGET_SECURITY =
131             "android.app.extra.EXTRA_IGNORE_TARGET_SECURITY";
132 
133     /** The minimal size of a display's long-edge needed to support split-screen multi-window. */
134     public static final int DEFAULT_MINIMAL_SPLIT_SCREEN_DISPLAY_SIZE_DP = 440;
135 
136     private static int sMaxRecentTasks = -1;
137 
138     private static final Singleton<ActivityTaskManager> sInstance =
139             new Singleton<ActivityTaskManager>() {
140                 @Override
141                 protected ActivityTaskManager create() {
142                     return new ActivityTaskManager();
143                 }
144             };
145 
ActivityTaskManager()146     private ActivityTaskManager() {
147     }
148 
149     /** @hide */
getInstance()150     public static ActivityTaskManager getInstance() {
151         return sInstance.get();
152     }
153 
154     /** @hide */
getService()155     public static IActivityTaskManager getService() {
156         return IActivityTaskManagerSingleton.get();
157     }
158 
159     @UnsupportedAppUsage(trackingBug = 129726065)
160     private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
161             new Singleton<IActivityTaskManager>() {
162                 @Override
163                 protected IActivityTaskManager create() {
164                     final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
165                     return IActivityTaskManager.Stub.asInterface(b);
166                 }
167             };
168 
169     /**
170      * Removes root tasks in the windowing modes from the system if they are of activity type
171      * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
172      */
173     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
removeRootTasksInWindowingModes(@onNull int[] windowingModes)174     public void removeRootTasksInWindowingModes(@NonNull int[] windowingModes) {
175         try {
176             getService().removeRootTasksInWindowingModes(windowingModes);
177         } catch (RemoteException e) {
178             throw e.rethrowFromSystemServer();
179         }
180     }
181 
182     /** Removes root tasks of the activity types from the system. */
183     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
removeRootTasksWithActivityTypes(@onNull int[] activityTypes)184     public void removeRootTasksWithActivityTypes(@NonNull int[] activityTypes) {
185         try {
186             getService().removeRootTasksWithActivityTypes(activityTypes);
187         } catch (RemoteException e) {
188             throw e.rethrowFromSystemServer();
189         }
190     }
191 
192     /**
193      * Removes all visible recent tasks from the system.
194      * @hide
195      */
196     @RequiresPermission(android.Manifest.permission.REMOVE_TASKS)
removeAllVisibleRecentTasks()197     public void removeAllVisibleRecentTasks() {
198         try {
199             getService().removeAllVisibleRecentTasks();
200         } catch (RemoteException e) {
201             throw e.rethrowFromSystemServer();
202         }
203     }
204 
205     /**
206      * Return the maximum number of recents entries that we will maintain and show.
207      * @hide
208      */
getMaxRecentTasksStatic()209     public static int getMaxRecentTasksStatic() {
210         if (sMaxRecentTasks < 0) {
211             return sMaxRecentTasks = ActivityManager.isLowRamDeviceStatic() ? 36 : 48;
212         }
213         return sMaxRecentTasks;
214     }
215 
216     /**
217      * Notify the server that splash screen of the given task has been copied"
218      *
219      * @param taskId Id of task to handle the material to reconstruct the splash screen view.
220      * @param parcelable Used to reconstruct the view, null means the surface is un-copyable.
221      * @hide
222      */
onSplashScreenViewCopyFinished(int taskId, @Nullable SplashScreenViewParcelable parcelable)223     public void onSplashScreenViewCopyFinished(int taskId,
224             @Nullable SplashScreenViewParcelable parcelable) {
225         try {
226             getService().onSplashScreenViewCopyFinished(taskId, parcelable);
227         } catch (RemoteException e) {
228             throw e.rethrowFromSystemServer();
229         }
230     }
231 
232     /**
233      * Return the default limit on the number of recents that an app can make.
234      * @hide
235      */
getDefaultAppRecentsLimitStatic()236     public static int getDefaultAppRecentsLimitStatic() {
237         return getMaxRecentTasksStatic() / 6;
238     }
239 
240     /**
241      * Return the maximum limit on the number of recents that an app can make.
242      * @hide
243      */
getMaxAppRecentsLimitStatic()244     public static int getMaxAppRecentsLimitStatic() {
245         return getMaxRecentTasksStatic() / 2;
246     }
247 
248     /**
249      * Returns true if the system supports at least one form of multi-window.
250      * E.g. freeform, split-screen, picture-in-picture.
251      */
supportsMultiWindow(Context context)252     public static boolean supportsMultiWindow(Context context) {
253         // On watches, multi-window is used to present essential system UI, and thus it must be
254         // supported regardless of device memory characteristics.
255         boolean isWatch = context.getPackageManager().hasSystemFeature(
256                 PackageManager.FEATURE_WATCH);
257         return (!ActivityManager.isLowRamDeviceStatic() || isWatch)
258                 && Resources.getSystem().getBoolean(
259                 com.android.internal.R.bool.config_supportsMultiWindow);
260     }
261 
262     /**
263      * Returns {@code true} if the display the context is associated with supports split screen
264      * multi-window.
265      *
266      * @throws UnsupportedOperationException if the supplied {@link Context} is not associated with
267      * a display.
268      */
supportsSplitScreenMultiWindow(Context context)269     public static boolean supportsSplitScreenMultiWindow(Context context) {
270         DisplayMetrics dm = new DisplayMetrics();
271         context.getDisplay().getRealMetrics(dm);
272 
273         int widthDp = (int) (dm.widthPixels / dm.density);
274         int heightDp = (int) (dm.heightPixels / dm.density);
275         if (Math.max(widthDp, heightDp) < DEFAULT_MINIMAL_SPLIT_SCREEN_DISPLAY_SIZE_DP) {
276             return false;
277         }
278 
279         return supportsMultiWindow(context)
280                 && Resources.getSystem().getBoolean(
281                 com.android.internal.R.bool.config_supportsSplitScreenMultiWindow);
282     }
283 
284     /**
285      * Start to enter lock task mode for given task by system(UI).
286      * @param taskId Id of task to lock.
287      */
288     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
startSystemLockTaskMode(int taskId)289     public void startSystemLockTaskMode(int taskId) {
290         try {
291             getService().startSystemLockTaskMode(taskId);
292         } catch (RemoteException e) {
293             throw e.rethrowFromSystemServer();
294         }
295     }
296 
297     /**
298      * Stop lock task mode by system(UI).
299      */
300     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
stopSystemLockTaskMode()301     public void stopSystemLockTaskMode() {
302         try {
303             getService().stopSystemLockTaskMode();
304         } catch (RemoteException e) {
305             throw e.rethrowFromSystemServer();
306         }
307     }
308 
309     /**
310      * Move task to root task with given id.
311      * @param taskId Id of the task to move.
312      * @param rootTaskId Id of the rootTask for task moving.
313      * @param toTop Whether the given task should shown to top of stack.
314      */
315     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop)316     public void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop) {
317         try {
318             getService().moveTaskToRootTask(taskId, rootTaskId, toTop);
319         } catch (RemoteException e) {
320             throw e.rethrowFromSystemServer();
321         }
322     }
323 
324     /**
325      * Resize task to given bounds.
326      * @param taskId Id of task to resize.
327      * @param bounds Bounds to resize task.
328      */
329     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
resizeTask(int taskId, Rect bounds)330     public void resizeTask(int taskId, Rect bounds) {
331         try {
332             getService().resizeTask(taskId, bounds, RESIZE_MODE_SYSTEM);
333         } catch (RemoteException e) {
334             throw e.rethrowFromSystemServer();
335         }
336     }
337 
338     /**
339      * Clears launch params for the given package.
340      * @param packageNames the names of the packages of which the launch params are to be cleared
341      */
342     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
clearLaunchParamsForPackages(List<String> packageNames)343     public void clearLaunchParamsForPackages(List<String> packageNames) {
344         try {
345             getService().clearLaunchParamsForPackages(packageNames);
346         } catch (RemoteException e) {
347             e.rethrowFromSystemServer();
348         }
349     }
350 
351     /**
352      * @return whether the UI mode of the given config supports error dialogs (ANR, crash, etc).
353      * @hide
354      */
currentUiModeSupportsErrorDialogs(@onNull Configuration config)355     public static boolean currentUiModeSupportsErrorDialogs(@NonNull Configuration config) {
356         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
357         return (modeType != Configuration.UI_MODE_TYPE_CAR
358                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
359                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
360                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
361     }
362 
363     /** @return whether the current UI mode supports error dialogs (ANR, crash, etc). */
currentUiModeSupportsErrorDialogs(@onNull Context context)364     public static boolean currentUiModeSupportsErrorDialogs(@NonNull Context context) {
365         final Configuration config = context.getResources().getConfiguration();
366         return currentUiModeSupportsErrorDialogs(config);
367     }
368 
369     /** @return max allowed number of actions in picture-in-picture mode. */
getMaxNumPictureInPictureActions(@onNull Context context)370     public static int getMaxNumPictureInPictureActions(@NonNull Context context) {
371         return context.getResources().getInteger(
372                 com.android.internal.R.integer.config_pictureInPictureMaxNumberOfActions);
373     }
374 
375     /**
376      * @return List of running tasks.
377      * @hide
378      */
getTasks(int maxNum)379     public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
380         return getTasks(maxNum, false /* filterForVisibleRecents */);
381     }
382 
383     /**
384      * @return List of running tasks that can be filtered by visibility in recents.
385      * @hide
386      */
getTasks( int maxNum, boolean filterOnlyVisibleRecents)387     public List<ActivityManager.RunningTaskInfo> getTasks(
388             int maxNum, boolean filterOnlyVisibleRecents) {
389         return getTasks(maxNum, filterOnlyVisibleRecents, false /* keepIntentExtra */);
390     }
391 
392     /**
393      * @return List of running tasks that can be filtered by visibility in recents and keep intent
394      * extra.
395      * @hide
396      */
getTasks( int maxNum, boolean filterOnlyVisibleRecents, boolean keepIntentExtra)397     public List<ActivityManager.RunningTaskInfo> getTasks(
398             int maxNum, boolean filterOnlyVisibleRecents, boolean keepIntentExtra) {
399         try {
400             return getService().getTasks(maxNum, filterOnlyVisibleRecents, keepIntentExtra);
401         } catch (RemoteException e) {
402             throw e.rethrowFromSystemServer();
403         }
404     }
405 
406     /**
407      * @return List of recent tasks.
408      * @hide
409      */
getRecentTasks( int maxNum, int flags, int userId)410     public List<ActivityManager.RecentTaskInfo> getRecentTasks(
411             int maxNum, int flags, int userId) {
412         try {
413             return getService().getRecentTasks(maxNum, flags, userId).getList();
414         } catch (RemoteException e) {
415             throw e.rethrowFromSystemServer();
416         }
417     }
418 
419     /** @hide */
registerTaskStackListener(TaskStackListener listener)420     public void registerTaskStackListener(TaskStackListener listener) {
421         try {
422             getService().registerTaskStackListener(listener);
423         } catch (RemoteException e) {
424             throw e.rethrowFromSystemServer();
425         }
426     }
427 
428     /** @hide */
unregisterTaskStackListener(TaskStackListener listener)429     public void unregisterTaskStackListener(TaskStackListener listener) {
430         try {
431             getService().unregisterTaskStackListener(listener);
432         } catch (RemoteException e) {
433             throw e.rethrowFromSystemServer();
434         }
435     }
436 
437     /** @hide */
getTaskBounds(int taskId)438     public Rect getTaskBounds(int taskId) {
439         try {
440             return getService().getTaskBounds(taskId);
441         } catch (RemoteException e) {
442             throw e.rethrowFromSystemServer();
443         }
444     }
445 
446     /**
447      * Registers remote animations for a display.
448      * @hide
449      */
registerRemoteAnimationsForDisplay( int displayId, RemoteAnimationDefinition definition)450     public void registerRemoteAnimationsForDisplay(
451             int displayId, RemoteAnimationDefinition definition) {
452         try {
453             getService().registerRemoteAnimationsForDisplay(displayId, definition);
454         } catch (RemoteException e) {
455             throw e.rethrowFromSystemServer();
456         }
457     }
458 
459     /** @hide */
isInLockTaskMode()460     public boolean isInLockTaskMode() {
461         try {
462             return getService().isInLockTaskMode();
463         } catch (RemoteException e) {
464             throw e.rethrowFromSystemServer();
465         }
466     }
467 
468     /** Removes task by a given taskId */
469     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
removeTask(int taskId)470     public boolean removeTask(int taskId) {
471         try {
472             return getService().removeTask(taskId);
473         } catch (RemoteException e) {
474             throw e.rethrowFromSystemServer();
475         }
476     }
477 
478     /**
479      * Information you can retrieve about a root task in the system.
480      * @hide
481      */
482     public static class RootTaskInfo extends TaskInfo implements Parcelable {
483         // TODO(b/148895075): Move some of the fields to TaskInfo.
484         public Rect bounds = new Rect();
485         public int[] childTaskIds;
486         public String[] childTaskNames;
487         public Rect[] childTaskBounds;
488         public int[] childTaskUserIds;
489         public boolean visible;
490         // Index of the stack in the display's stack list, can be used for comparison of stack order
491         public int position;
492 
493         @Override
describeContents()494         public int describeContents() {
495             return 0;
496         }
497 
498         @Override
writeToParcel(Parcel dest, int flags)499         public void writeToParcel(Parcel dest, int flags) {
500             dest.writeTypedObject(bounds, flags);
501             dest.writeIntArray(childTaskIds);
502             dest.writeStringArray(childTaskNames);
503             dest.writeTypedArray(childTaskBounds, flags);
504             dest.writeIntArray(childTaskUserIds);
505             dest.writeInt(visible ? 1 : 0);
506             dest.writeInt(position);
507             super.writeToParcel(dest, flags);
508         }
509 
510         @Override
readFromParcel(Parcel source)511         void readFromParcel(Parcel source) {
512             bounds = source.readTypedObject(Rect.CREATOR);
513             childTaskIds = source.createIntArray();
514             childTaskNames = source.createStringArray();
515             childTaskBounds = source.createTypedArray(Rect.CREATOR);
516             childTaskUserIds = source.createIntArray();
517             visible = source.readInt() > 0;
518             position = source.readInt();
519             super.readFromParcel(source);
520         }
521 
522         public static final @NonNull Creator<RootTaskInfo> CREATOR = new Creator<>() {
523             @Override
524             public RootTaskInfo createFromParcel(Parcel source) {
525                 return new RootTaskInfo(source);
526             }
527 
528             @Override
529             public RootTaskInfo[] newArray(int size) {
530                 return new RootTaskInfo[size];
531             }
532         };
533 
RootTaskInfo()534         public RootTaskInfo() {
535         }
536 
RootTaskInfo(Parcel source)537         private RootTaskInfo(Parcel source) {
538             readFromParcel(source);
539         }
540 
541         @Override
toString()542         public String toString() {
543             StringBuilder sb = new StringBuilder(256);
544             sb.append("RootTask id="); sb.append(taskId);
545             sb.append(" bounds="); sb.append(bounds.toShortString());
546             sb.append(" displayId="); sb.append(displayId);
547             sb.append(" userId="); sb.append(userId);
548             sb.append("\n");
549 
550             sb.append(" configuration="); sb.append(configuration);
551             sb.append("\n");
552 
553             for (int i = 0; i < childTaskIds.length; ++i) {
554                 sb.append("  taskId="); sb.append(childTaskIds[i]);
555                 sb.append(": "); sb.append(childTaskNames[i]);
556                 if (childTaskBounds != null) {
557                     sb.append(" bounds="); sb.append(childTaskBounds[i].toShortString());
558                 }
559                 sb.append(" userId=").append(childTaskUserIds[i]);
560                 sb.append(" visible=").append(visible);
561                 if (topActivity != null) {
562                     sb.append(" topActivity=").append(topActivity);
563                 }
564                 sb.append("\n");
565             }
566             return sb.toString();
567         }
568     }
569 }
570