1 /*
2  * Copyright (C) 2007 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.Manifest;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SystemApi;
25 import android.annotation.SystemService;
26 import android.annotation.TestApi;
27 import android.content.pm.ActivityInfo;
28 import android.content.res.Configuration;
29 import android.graphics.Canvas;
30 import android.graphics.GraphicBuffer;
31 import android.graphics.Matrix;
32 import android.graphics.Point;
33 import android.os.BatteryStats;
34 import android.os.Build;
35 import android.os.Build.VERSION_CODES;
36 import android.os.IBinder;
37 import android.os.ParcelFileDescriptor;
38 
39 import com.android.internal.app.procstats.ProcessStats;
40 import com.android.internal.os.RoSystemProperties;
41 import com.android.internal.os.TransferPipe;
42 import com.android.internal.util.FastPrintWriter;
43 import com.android.server.LocalServices;
44 
45 import android.content.ComponentName;
46 import android.content.Context;
47 import android.content.Intent;
48 import android.content.UriPermission;
49 import android.content.pm.ApplicationInfo;
50 import android.content.pm.ConfigurationInfo;
51 import android.content.pm.IPackageDataObserver;
52 import android.content.pm.PackageManager;
53 import android.content.pm.ParceledListSlice;
54 import android.content.pm.UserInfo;
55 import android.content.res.Resources;
56 import android.graphics.Bitmap;
57 import android.graphics.Color;
58 import android.graphics.Rect;
59 import android.os.Bundle;
60 import android.os.Debug;
61 import android.os.Handler;
62 import android.os.Parcel;
63 import android.os.Parcelable;
64 import android.os.Process;
65 import android.os.RemoteException;
66 import android.os.ServiceManager;
67 import android.os.SystemProperties;
68 import android.os.UserHandle;
69 import android.text.TextUtils;
70 import android.util.ArrayMap;
71 import android.util.DisplayMetrics;
72 import android.util.Singleton;
73 import android.util.Size;
74 
75 import org.xmlpull.v1.XmlSerializer;
76 
77 import java.io.FileDescriptor;
78 import java.io.FileOutputStream;
79 import java.io.IOException;
80 import java.io.PrintWriter;
81 import java.lang.annotation.Retention;
82 import java.lang.annotation.RetentionPolicy;
83 import java.util.ArrayList;
84 import java.util.List;
85 
86 /**
87  * <p>
88  * This class gives information about, and interacts
89  * with, activities, services, and the containing
90  * process.
91  * </p>
92  *
93  * <p>
94  * A number of the methods in this class are for
95  * debugging or informational purposes and they should
96  * not be used to affect any runtime behavior of
97  * your app. These methods are called out as such in
98  * the method level documentation.
99  * </p>
100  *
101  *<p>
102  * Most application developers should not have the need to
103  * use this class, most of whose methods are for specialized
104  * use cases. However, a few methods are more broadly applicable.
105  * For instance, {@link android.app.ActivityManager#isLowRamDevice() isLowRamDevice()}
106  * enables your app to detect whether it is running on a low-memory device,
107  * and behave accordingly.
108  * {@link android.app.ActivityManager#clearApplicationUserData() clearApplicationUserData()}
109  * is for apps with reset-data functionality.
110  * </p>
111  *
112  * <p>
113  * In some special use cases, where an app interacts with
114  * its Task stack, the app may use the
115  * {@link android.app.ActivityManager.AppTask} and
116  * {@link android.app.ActivityManager.RecentTaskInfo} inner
117  * classes. However, in general, the methods in this class should
118  * be used for testing and debugging purposes only.
119  * </p>
120  */
121 @SystemService(Context.ACTIVITY_SERVICE)
122 public class ActivityManager {
123     private static String TAG = "ActivityManager";
124 
125     private static int gMaxRecentTasks = -1;
126 
127     private final Context mContext;
128 
129     private static volatile boolean sSystemReady = false;
130 
131 
132     private static final int FIRST_START_FATAL_ERROR_CODE = -100;
133     private static final int LAST_START_FATAL_ERROR_CODE = -1;
134     private static final int FIRST_START_SUCCESS_CODE = 0;
135     private static final int LAST_START_SUCCESS_CODE = 99;
136     private static final int FIRST_START_NON_FATAL_ERROR_CODE = 100;
137     private static final int LAST_START_NON_FATAL_ERROR_CODE = 199;
138 
139     /**
140      * System property to enable task snapshots.
141      * @hide
142      */
143     public final static boolean ENABLE_TASK_SNAPSHOTS;
144 
145     static {
146         ENABLE_TASK_SNAPSHOTS = SystemProperties.getBoolean("persist.enable_task_snapshots", true);
147     }
148 
149     static final class UidObserver extends IUidObserver.Stub {
150         final OnUidImportanceListener mListener;
151         final Context mContext;
152 
UidObserver(OnUidImportanceListener listener, Context clientContext)153         UidObserver(OnUidImportanceListener listener, Context clientContext) {
154             mListener = listener;
155             mContext = clientContext;
156         }
157 
158         @Override
onUidStateChanged(int uid, int procState, long procStateSeq)159         public void onUidStateChanged(int uid, int procState, long procStateSeq) {
160             mListener.onUidImportance(uid, RunningAppProcessInfo.procStateToImportanceForClient(
161                     procState, mContext));
162         }
163 
164         @Override
onUidGone(int uid, boolean disabled)165         public void onUidGone(int uid, boolean disabled) {
166             mListener.onUidImportance(uid, RunningAppProcessInfo.IMPORTANCE_GONE);
167         }
168 
169         @Override
onUidActive(int uid)170         public void onUidActive(int uid) {
171         }
172 
173         @Override
onUidIdle(int uid, boolean disabled)174         public void onUidIdle(int uid, boolean disabled) {
175         }
176     }
177 
178     final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();
179 
180     /**
181      * Defines acceptable types of bugreports.
182      * @hide
183      */
184     @Retention(RetentionPolicy.SOURCE)
185     @IntDef({
186             BUGREPORT_OPTION_FULL,
187             BUGREPORT_OPTION_INTERACTIVE,
188             BUGREPORT_OPTION_REMOTE,
189             BUGREPORT_OPTION_WEAR,
190             BUGREPORT_OPTION_TELEPHONY
191     })
192     public @interface BugreportMode {}
193     /**
194      * Takes a bugreport without user interference (and hence causing less
195      * interference to the system), but includes all sections.
196      * @hide
197      */
198     public static final int BUGREPORT_OPTION_FULL = 0;
199     /**
200      * Allows user to monitor progress and enter additional data; might not include all
201      * sections.
202      * @hide
203      */
204     public static final int BUGREPORT_OPTION_INTERACTIVE = 1;
205     /**
206      * Takes a bugreport requested remotely by administrator of the Device Owner app,
207      * not the device's user.
208      * @hide
209      */
210     public static final int BUGREPORT_OPTION_REMOTE = 2;
211     /**
212      * Takes a bugreport on a wearable device.
213      * @hide
214      */
215     public static final int BUGREPORT_OPTION_WEAR = 3;
216 
217     /**
218      * Takes a lightweight version of bugreport that only includes a few, urgent sections
219      * used to report telephony bugs.
220      * @hide
221      */
222     public static final int BUGREPORT_OPTION_TELEPHONY = 4;
223 
224     /**
225      * <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code
226      * <meta-data>}</a> name for a 'home' Activity that declares a package that is to be
227      * uninstalled in lieu of the declaring one.  The package named here must be
228      * signed with the same certificate as the one declaring the {@code <meta-data>}.
229      */
230     public static final String META_HOME_ALTERNATE = "android.app.home.alternate";
231 
232     // NOTE: Before adding a new start result, please reference the defined ranges to ensure the
233     // result is properly categorized.
234 
235     /**
236      * Result for IActivityManager.startVoiceActivity: active session is currently hidden.
237      * @hide
238      */
239     public static final int START_VOICE_HIDDEN_SESSION = FIRST_START_FATAL_ERROR_CODE;
240 
241     /**
242      * Result for IActivityManager.startVoiceActivity: active session does not match
243      * the requesting token.
244      * @hide
245      */
246     public static final int START_VOICE_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 1;
247 
248     /**
249      * Result for IActivityManager.startActivity: trying to start a background user
250      * activity that shouldn't be displayed for all users.
251      * @hide
252      */
253     public static final int START_NOT_CURRENT_USER_ACTIVITY = FIRST_START_FATAL_ERROR_CODE + 2;
254 
255     /**
256      * Result for IActivityManager.startActivity: trying to start an activity under voice
257      * control when that activity does not support the VOICE category.
258      * @hide
259      */
260     public static final int START_NOT_VOICE_COMPATIBLE = FIRST_START_FATAL_ERROR_CODE + 3;
261 
262     /**
263      * Result for IActivityManager.startActivity: an error where the
264      * start had to be canceled.
265      * @hide
266      */
267     public static final int START_CANCELED = FIRST_START_FATAL_ERROR_CODE + 4;
268 
269     /**
270      * Result for IActivityManager.startActivity: an error where the
271      * thing being started is not an activity.
272      * @hide
273      */
274     public static final int START_NOT_ACTIVITY = FIRST_START_FATAL_ERROR_CODE + 5;
275 
276     /**
277      * Result for IActivityManager.startActivity: an error where the
278      * caller does not have permission to start the activity.
279      * @hide
280      */
281     public static final int START_PERMISSION_DENIED = FIRST_START_FATAL_ERROR_CODE + 6;
282 
283     /**
284      * Result for IActivityManager.startActivity: an error where the
285      * caller has requested both to forward a result and to receive
286      * a result.
287      * @hide
288      */
289     public static final int START_FORWARD_AND_REQUEST_CONFLICT = FIRST_START_FATAL_ERROR_CODE + 7;
290 
291     /**
292      * Result for IActivityManager.startActivity: an error where the
293      * requested class is not found.
294      * @hide
295      */
296     public static final int START_CLASS_NOT_FOUND = FIRST_START_FATAL_ERROR_CODE + 8;
297 
298     /**
299      * Result for IActivityManager.startActivity: an error where the
300      * given Intent could not be resolved to an activity.
301      * @hide
302      */
303     public static final int START_INTENT_NOT_RESOLVED = FIRST_START_FATAL_ERROR_CODE + 9;
304 
305     /**
306      * Result for IActivityManager.startAssistantActivity: active session is currently hidden.
307      * @hide
308      */
309     public static final int START_ASSISTANT_HIDDEN_SESSION = FIRST_START_FATAL_ERROR_CODE + 10;
310 
311     /**
312      * Result for IActivityManager.startAssistantActivity: active session does not match
313      * the requesting token.
314      * @hide
315      */
316     public static final int START_ASSISTANT_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 11;
317 
318     /**
319      * Result for IActivityManaqer.startActivity: the activity was started
320      * successfully as normal.
321      * @hide
322      */
323     public static final int START_SUCCESS = FIRST_START_SUCCESS_CODE;
324 
325     /**
326      * Result for IActivityManaqer.startActivity: the caller asked that the Intent not
327      * be executed if it is the recipient, and that is indeed the case.
328      * @hide
329      */
330     public static final int START_RETURN_INTENT_TO_CALLER = FIRST_START_SUCCESS_CODE + 1;
331 
332     /**
333      * Result for IActivityManaqer.startActivity: activity wasn't really started, but
334      * a task was simply brought to the foreground.
335      * @hide
336      */
337     public static final int START_TASK_TO_FRONT = FIRST_START_SUCCESS_CODE + 2;
338 
339     /**
340      * Result for IActivityManaqer.startActivity: activity wasn't really started, but
341      * the given Intent was given to the existing top activity.
342      * @hide
343      */
344     public static final int START_DELIVERED_TO_TOP = FIRST_START_SUCCESS_CODE + 3;
345 
346     /**
347      * Result for IActivityManaqer.startActivity: request was canceled because
348      * app switches are temporarily canceled to ensure the user's last request
349      * (such as pressing home) is performed.
350      * @hide
351      */
352     public static final int START_SWITCHES_CANCELED = FIRST_START_NON_FATAL_ERROR_CODE;
353 
354     /**
355      * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
356      * while in Lock Task Mode.
357      * @hide
358      */
359     public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION =
360             FIRST_START_NON_FATAL_ERROR_CODE + 1;
361 
362     /**
363      * Flag for IActivityManaqer.startActivity: do special start mode where
364      * a new activity is launched only if it is needed.
365      * @hide
366      */
367     public static final int START_FLAG_ONLY_IF_NEEDED = 1<<0;
368 
369     /**
370      * Flag for IActivityManaqer.startActivity: launch the app for
371      * debugging.
372      * @hide
373      */
374     public static final int START_FLAG_DEBUG = 1<<1;
375 
376     /**
377      * Flag for IActivityManaqer.startActivity: launch the app for
378      * allocation tracking.
379      * @hide
380      */
381     public static final int START_FLAG_TRACK_ALLOCATION = 1<<2;
382 
383     /**
384      * Flag for IActivityManaqer.startActivity: launch the app with
385      * native debugging support.
386      * @hide
387      */
388     public static final int START_FLAG_NATIVE_DEBUGGING = 1<<3;
389 
390     /**
391      * Result for IActivityManaqer.broadcastIntent: success!
392      * @hide
393      */
394     public static final int BROADCAST_SUCCESS = 0;
395 
396     /**
397      * Result for IActivityManaqer.broadcastIntent: attempt to broadcast
398      * a sticky intent without appropriate permission.
399      * @hide
400      */
401     public static final int BROADCAST_STICKY_CANT_HAVE_PERMISSION = -1;
402 
403     /**
404      * Result for IActivityManager.broadcastIntent: trying to send a broadcast
405      * to a stopped user. Fail.
406      * @hide
407      */
408     public static final int BROADCAST_FAILED_USER_STOPPED = -2;
409 
410     /**
411      * Type for IActivityManaqer.getIntentSender: this PendingIntent is
412      * for a sendBroadcast operation.
413      * @hide
414      */
415     public static final int INTENT_SENDER_BROADCAST = 1;
416 
417     /**
418      * Type for IActivityManaqer.getIntentSender: this PendingIntent is
419      * for a startActivity operation.
420      * @hide
421      */
422     public static final int INTENT_SENDER_ACTIVITY = 2;
423 
424     /**
425      * Type for IActivityManaqer.getIntentSender: this PendingIntent is
426      * for an activity result operation.
427      * @hide
428      */
429     public static final int INTENT_SENDER_ACTIVITY_RESULT = 3;
430 
431     /**
432      * Type for IActivityManaqer.getIntentSender: this PendingIntent is
433      * for a startService operation.
434      * @hide
435      */
436     public static final int INTENT_SENDER_SERVICE = 4;
437 
438     /**
439      * Type for IActivityManaqer.getIntentSender: this PendingIntent is
440      * for a startForegroundService operation.
441      * @hide
442      */
443     public static final int INTENT_SENDER_FOREGROUND_SERVICE = 5;
444 
445     /** @hide User operation call: success! */
446     public static final int USER_OP_SUCCESS = 0;
447 
448     /** @hide User operation call: given user id is not known. */
449     public static final int USER_OP_UNKNOWN_USER = -1;
450 
451     /** @hide User operation call: given user id is the current user, can't be stopped. */
452     public static final int USER_OP_IS_CURRENT = -2;
453 
454     /** @hide User operation call: system user can't be stopped. */
455     public static final int USER_OP_ERROR_IS_SYSTEM = -3;
456 
457     /** @hide User operation call: one of related users cannot be stopped. */
458     public static final int USER_OP_ERROR_RELATED_USERS_CANNOT_STOP = -4;
459 
460     /** @hide Not a real process state. */
461     public static final int PROCESS_STATE_UNKNOWN = -1;
462 
463     /** @hide Process is a persistent system process. */
464     public static final int PROCESS_STATE_PERSISTENT = 0;
465 
466     /** @hide Process is a persistent system process and is doing UI. */
467     public static final int PROCESS_STATE_PERSISTENT_UI = 1;
468 
469     /** @hide Process is hosting the current top activities.  Note that this covers
470      * all activities that are visible to the user. */
471     public static final int PROCESS_STATE_TOP = 2;
472 
473     /** @hide Process is hosting a foreground service due to a system binding. */
474     public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 3;
475 
476     /** @hide Process is hosting a foreground service. */
477     public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
478 
479     /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
480     public static final int PROCESS_STATE_TOP_SLEEPING = 5;
481 
482     /** @hide Process is important to the user, and something they are aware of. */
483     public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
484 
485     /** @hide Process is important to the user, but not something they are aware of. */
486     public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
487 
488     /** @hide Process is in the background transient so we will try to keep running. */
489     public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8;
490 
491     /** @hide Process is in the background running a backup/restore operation. */
492     public static final int PROCESS_STATE_BACKUP = 9;
493 
494     /** @hide Process is in the background, but it can't restore its state so we want
495      * to try to avoid killing it. */
496     public static final int PROCESS_STATE_HEAVY_WEIGHT = 10;
497 
498     /** @hide Process is in the background running a service.  Unlike oom_adj, this level
499      * is used for both the normal running in background state and the executing
500      * operations state. */
501     public static final int PROCESS_STATE_SERVICE = 11;
502 
503     /** @hide Process is in the background running a receiver.   Note that from the
504      * perspective of oom_adj receivers run at a higher foreground level, but for our
505      * prioritization here that is not necessary and putting them below services means
506      * many fewer changes in some process states as they receive broadcasts. */
507     public static final int PROCESS_STATE_RECEIVER = 12;
508 
509     /** @hide Process is in the background but hosts the home activity. */
510     public static final int PROCESS_STATE_HOME = 13;
511 
512     /** @hide Process is in the background but hosts the last shown activity. */
513     public static final int PROCESS_STATE_LAST_ACTIVITY = 14;
514 
515     /** @hide Process is being cached for later use and contains activities. */
516     public static final int PROCESS_STATE_CACHED_ACTIVITY = 15;
517 
518     /** @hide Process is being cached for later use and is a client of another cached
519      * process that contains activities. */
520     public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 16;
521 
522     /** @hide Process is being cached for later use and is empty. */
523     public static final int PROCESS_STATE_CACHED_EMPTY = 17;
524 
525     /** @hide Process does not exist. */
526     public static final int PROCESS_STATE_NONEXISTENT = 18;
527 
528     /** @hide The lowest process state number */
529     public static final int MIN_PROCESS_STATE = PROCESS_STATE_PERSISTENT;
530 
531     /** @hide The highest process state number */
532     public static final int MAX_PROCESS_STATE = PROCESS_STATE_NONEXISTENT;
533 
534     /** @hide Should this process state be considered a background state? */
isProcStateBackground(int procState)535     public static final boolean isProcStateBackground(int procState) {
536         return procState >= PROCESS_STATE_TRANSIENT_BACKGROUND;
537     }
538 
539     /** @hide requestType for assist context: only basic information. */
540     public static final int ASSIST_CONTEXT_BASIC = 0;
541 
542     /** @hide requestType for assist context: generate full AssistStructure. */
543     public static final int ASSIST_CONTEXT_FULL = 1;
544 
545     /** @hide requestType for assist context: generate full AssistStructure for autofill. */
546     public static final int ASSIST_CONTEXT_AUTOFILL = 2;
547 
548     /** @hide Flag for registerUidObserver: report changes in process state. */
549     public static final int UID_OBSERVER_PROCSTATE = 1<<0;
550 
551     /** @hide Flag for registerUidObserver: report uid gone. */
552     public static final int UID_OBSERVER_GONE = 1<<1;
553 
554     /** @hide Flag for registerUidObserver: report uid has become idle. */
555     public static final int UID_OBSERVER_IDLE = 1<<2;
556 
557     /** @hide Flag for registerUidObserver: report uid has become active. */
558     public static final int UID_OBSERVER_ACTIVE = 1<<3;
559 
560     /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: normal free-to-run operation. */
561     public static final int APP_START_MODE_NORMAL = 0;
562 
563     /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: delay running until later. */
564     public static final int APP_START_MODE_DELAYED = 1;
565 
566     /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: delay running until later, with
567      * rigid errors (throwing exception). */
568     public static final int APP_START_MODE_DELAYED_RIGID = 2;
569 
570     /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: disable/cancel pending
571      * launches; this is the mode for ephemeral apps. */
572     public static final int APP_START_MODE_DISABLED = 3;
573 
574     /**
575      * Lock task mode is not active.
576      */
577     public static final int LOCK_TASK_MODE_NONE = 0;
578 
579     /**
580      * Full lock task mode is active.
581      */
582     public static final int LOCK_TASK_MODE_LOCKED = 1;
583 
584     /**
585      * App pinning mode is active.
586      */
587     public static final int LOCK_TASK_MODE_PINNED = 2;
588 
589     Point mAppTaskThumbnailSize;
590 
ActivityManager(Context context, Handler handler)591     /*package*/ ActivityManager(Context context, Handler handler) {
592         mContext = context;
593     }
594 
595     /**
596      * Returns whether the launch was successful.
597      * @hide
598      */
isStartResultSuccessful(int result)599     public static final boolean isStartResultSuccessful(int result) {
600         return FIRST_START_SUCCESS_CODE <= result && result <= LAST_START_SUCCESS_CODE;
601     }
602 
603     /**
604      * Returns whether the launch result was a fatal error.
605      * @hide
606      */
isStartResultFatalError(int result)607     public static final boolean isStartResultFatalError(int result) {
608         return FIRST_START_FATAL_ERROR_CODE <= result && result <= LAST_START_FATAL_ERROR_CODE;
609     }
610 
611     /**
612      * Screen compatibility mode: the application most always run in
613      * compatibility mode.
614      * @hide
615      */
616     public static final int COMPAT_MODE_ALWAYS = -1;
617 
618     /**
619      * Screen compatibility mode: the application can never run in
620      * compatibility mode.
621      * @hide
622      */
623     public static final int COMPAT_MODE_NEVER = -2;
624 
625     /**
626      * Screen compatibility mode: unknown.
627      * @hide
628      */
629     public static final int COMPAT_MODE_UNKNOWN = -3;
630 
631     /**
632      * Screen compatibility mode: the application currently has compatibility
633      * mode disabled.
634      * @hide
635      */
636     public static final int COMPAT_MODE_DISABLED = 0;
637 
638     /**
639      * Screen compatibility mode: the application currently has compatibility
640      * mode enabled.
641      * @hide
642      */
643     public static final int COMPAT_MODE_ENABLED = 1;
644 
645     /**
646      * Screen compatibility mode: request to toggle the application's
647      * compatibility mode.
648      * @hide
649      */
650     public static final int COMPAT_MODE_TOGGLE = 2;
651 
652     /** @hide */
653     public static class StackId {
654         /** Invalid stack ID. */
655         public static final int INVALID_STACK_ID = -1;
656 
657         /** First static stack ID. */
658         public static final int FIRST_STATIC_STACK_ID = 0;
659 
660         /** Home activity stack ID. */
661         public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID;
662 
663         /** ID of stack where fullscreen activities are normally launched into. */
664         public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
665 
666         /** ID of stack where freeform/resized activities are normally launched into. */
667         public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;
668 
669         /** ID of stack that occupies a dedicated region of the screen. */
670         public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1;
671 
672         /** ID of stack that always on top (always visible) when it exist. */
673         public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
674 
675         /** ID of stack that contains the Recents activity. */
676         public static final int RECENTS_STACK_ID = PINNED_STACK_ID + 1;
677 
678         /** ID of stack that contains activities launched by the assistant. */
679         public static final int ASSISTANT_STACK_ID = RECENTS_STACK_ID + 1;
680 
681         /** Last static stack stack ID. */
682         public static final int LAST_STATIC_STACK_ID = ASSISTANT_STACK_ID;
683 
684         /** Start of ID range used by stacks that are created dynamically. */
685         public static final int FIRST_DYNAMIC_STACK_ID = LAST_STATIC_STACK_ID + 1;
686 
isStaticStack(int stackId)687         public static boolean isStaticStack(int stackId) {
688             return stackId >= FIRST_STATIC_STACK_ID && stackId <= LAST_STATIC_STACK_ID;
689         }
690 
isDynamicStack(int stackId)691         public static boolean isDynamicStack(int stackId) {
692             return stackId >= FIRST_DYNAMIC_STACK_ID;
693         }
694 
695         /**
696          * Returns true if the activities contained in the input stack display a shadow around
697          * their border.
698          */
hasWindowShadow(int stackId)699         public static boolean hasWindowShadow(int stackId) {
700             return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID;
701         }
702 
703         /**
704          * Returns true if the activities contained in the input stack display a decor view.
705          */
hasWindowDecor(int stackId)706         public static boolean hasWindowDecor(int stackId) {
707             return stackId == FREEFORM_WORKSPACE_STACK_ID;
708         }
709 
710         /**
711          * Returns true if the tasks contained in the stack can be resized independently of the
712          * stack.
713          */
isTaskResizeAllowed(int stackId)714         public static boolean isTaskResizeAllowed(int stackId) {
715             return stackId == FREEFORM_WORKSPACE_STACK_ID;
716         }
717 
718         /** Returns true if the task bounds should persist across power cycles. */
persistTaskBounds(int stackId)719         public static boolean persistTaskBounds(int stackId) {
720             return stackId == FREEFORM_WORKSPACE_STACK_ID;
721         }
722 
723         /**
724          * Returns true if dynamic stacks are allowed to be visible behind the input stack.
725          */
isDynamicStacksVisibleBehindAllowed(int stackId)726         public static boolean isDynamicStacksVisibleBehindAllowed(int stackId) {
727             return stackId == PINNED_STACK_ID || stackId == ASSISTANT_STACK_ID;
728         }
729 
730         /**
731          * Returns true if we try to maintain focus in the current stack when the top activity
732          * finishes.
733          */
keepFocusInStackIfPossible(int stackId)734         public static boolean keepFocusInStackIfPossible(int stackId) {
735             return stackId == FREEFORM_WORKSPACE_STACK_ID
736                     || stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID;
737         }
738 
739         /**
740          * Returns true if Stack size is affected by the docked stack changing size.
741          */
isResizeableByDockedStack(int stackId)742         public static boolean isResizeableByDockedStack(int stackId) {
743             return isStaticStack(stackId) && stackId != DOCKED_STACK_ID
744                     && stackId != PINNED_STACK_ID && stackId != ASSISTANT_STACK_ID;
745         }
746 
747         /**
748          * Returns true if the size of tasks in the input stack are affected by the docked stack
749          * changing size.
750          */
isTaskResizeableByDockedStack(int stackId)751         public static boolean isTaskResizeableByDockedStack(int stackId) {
752             return isStaticStack(stackId) && stackId != FREEFORM_WORKSPACE_STACK_ID
753                     && stackId != DOCKED_STACK_ID && stackId != PINNED_STACK_ID
754                     && stackId != ASSISTANT_STACK_ID;
755         }
756 
757         /**
758          * Returns true if the input stack is affected by drag resizing.
759          */
isStackAffectedByDragResizing(int stackId)760         public static boolean isStackAffectedByDragResizing(int stackId) {
761             return isStaticStack(stackId) && stackId != PINNED_STACK_ID
762                     && stackId != ASSISTANT_STACK_ID;
763         }
764 
765         /**
766          * Returns true if the windows of tasks being moved to the target stack from the source
767          * stack should be replaced, meaning that window manager will keep the old window around
768          * until the new is ready.
769          */
replaceWindowsOnTaskMove(int sourceStackId, int targetStackId)770         public static boolean replaceWindowsOnTaskMove(int sourceStackId, int targetStackId) {
771             return sourceStackId == FREEFORM_WORKSPACE_STACK_ID
772                     || targetStackId == FREEFORM_WORKSPACE_STACK_ID;
773         }
774 
775         /**
776          * Return whether a stackId is a stack containing floating windows. Floating windows
777          * are laid out differently as they are allowed to extend past the display bounds
778          * without overscan insets.
779          */
tasksAreFloating(int stackId)780         public static boolean tasksAreFloating(int stackId) {
781             return stackId == FREEFORM_WORKSPACE_STACK_ID
782                 || stackId == PINNED_STACK_ID;
783         }
784 
785         /**
786          * Return whether a stackId is a stack that be a backdrop to a translucent activity.  These
787          * are generally fullscreen stacks.
788          */
isBackdropToTranslucentActivity(int stackId)789         public static boolean isBackdropToTranslucentActivity(int stackId) {
790             return stackId == FULLSCREEN_WORKSPACE_STACK_ID
791                     || stackId == ASSISTANT_STACK_ID;
792         }
793 
794         /**
795          * Returns true if animation specs should be constructed for app transition that moves
796          * the task to the specified stack.
797          */
useAnimationSpecForAppTransition(int stackId)798         public static boolean useAnimationSpecForAppTransition(int stackId) {
799             // TODO: INVALID_STACK_ID is also animated because we don't persist stack id's across
800             // reboots.
801             return stackId == FREEFORM_WORKSPACE_STACK_ID
802                     || stackId == FULLSCREEN_WORKSPACE_STACK_ID
803                     || stackId == ASSISTANT_STACK_ID
804                     || stackId == DOCKED_STACK_ID
805                     || stackId == INVALID_STACK_ID;
806         }
807 
808         /**
809          * Returns true if the windows in the stack can receive input keys.
810          */
canReceiveKeys(int stackId)811         public static boolean canReceiveKeys(int stackId) {
812             return stackId != PINNED_STACK_ID;
813         }
814 
815         /**
816          * Returns true if the stack can be visible above lockscreen.
817          */
isAllowedOverLockscreen(int stackId)818         public static boolean isAllowedOverLockscreen(int stackId) {
819             return stackId == HOME_STACK_ID || stackId == FULLSCREEN_WORKSPACE_STACK_ID ||
820                     stackId == ASSISTANT_STACK_ID;
821         }
822 
823         /**
824          * Returns true if activities from stasks in the given {@param stackId} are allowed to
825          * enter picture-in-picture.
826          */
isAllowedToEnterPictureInPicture(int stackId)827         public static boolean isAllowedToEnterPictureInPicture(int stackId) {
828             return stackId != HOME_STACK_ID && stackId != ASSISTANT_STACK_ID &&
829                     stackId != RECENTS_STACK_ID;
830         }
831 
isAlwaysOnTop(int stackId)832         public static boolean isAlwaysOnTop(int stackId) {
833             return stackId == PINNED_STACK_ID;
834         }
835 
836         /**
837          * Returns true if the top task in the task is allowed to return home when finished and
838          * there are other tasks in the stack.
839          */
allowTopTaskToReturnHome(int stackId)840         public static boolean allowTopTaskToReturnHome(int stackId) {
841             return stackId != PINNED_STACK_ID;
842         }
843 
844         /**
845          * Returns true if the stack should be resized to match the bounds specified by
846          * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack.
847          */
resizeStackWithLaunchBounds(int stackId)848         public static boolean resizeStackWithLaunchBounds(int stackId) {
849             return stackId == PINNED_STACK_ID;
850         }
851 
852         /**
853          * Returns true if any visible windows belonging to apps in this stack should be kept on
854          * screen when the app is killed due to something like the low memory killer.
855          */
keepVisibleDeadAppWindowOnScreen(int stackId)856         public static boolean keepVisibleDeadAppWindowOnScreen(int stackId) {
857             return stackId != PINNED_STACK_ID;
858         }
859 
860         /**
861          * Returns true if the backdrop on the client side should match the frame of the window.
862          * Returns false, if the backdrop should be fullscreen.
863          */
useWindowFrameForBackdrop(int stackId)864         public static boolean useWindowFrameForBackdrop(int stackId) {
865             return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID;
866         }
867 
868         /**
869          * Returns true if a window from the specified stack with {@param stackId} are normally
870          * fullscreen, i. e. they can become the top opaque fullscreen window, meaning that it
871          * controls system bars, lockscreen occluded/dismissing state, screen rotation animation,
872          * etc.
873          */
normallyFullscreenWindows(int stackId)874         public static boolean normallyFullscreenWindows(int stackId) {
875             return stackId != PINNED_STACK_ID && stackId != FREEFORM_WORKSPACE_STACK_ID
876                     && stackId != DOCKED_STACK_ID;
877         }
878 
879         /**
880          * Returns true if the input stack id should only be present on a device that supports
881          * multi-window mode.
882          * @see android.app.ActivityManager#supportsMultiWindow
883          */
isMultiWindowStack(int stackId)884         public static boolean isMultiWindowStack(int stackId) {
885             return stackId == PINNED_STACK_ID || stackId == FREEFORM_WORKSPACE_STACK_ID
886                     || stackId == DOCKED_STACK_ID;
887         }
888 
889         /**
890          * Returns true if the input {@param stackId} is HOME_STACK_ID or RECENTS_STACK_ID
891          */
isHomeOrRecentsStack(int stackId)892         public static boolean isHomeOrRecentsStack(int stackId) {
893             return stackId == HOME_STACK_ID || stackId == RECENTS_STACK_ID;
894         }
895 
896         /**
897          * Returns true if activities contained in this stack can request visible behind by
898          * calling {@link Activity#requestVisibleBehind}.
899          *
900          * @deprecated This method's functionality is no longer supported as of
901          * {@link android.os.Build.VERSION_CODES#O} and will be removed in a future release.
902          */
903         @Deprecated
activitiesCanRequestVisibleBehind(int stackId)904         public static boolean activitiesCanRequestVisibleBehind(int stackId) {
905             return stackId == FULLSCREEN_WORKSPACE_STACK_ID ||
906                     stackId == ASSISTANT_STACK_ID;
907         }
908 
909         /**
910          * Returns true if this stack may be scaled without resizing, and windows within may need
911          * to be configured as such.
912          */
windowsAreScaleable(int stackId)913         public static boolean windowsAreScaleable(int stackId) {
914             return stackId == PINNED_STACK_ID;
915         }
916 
917         /**
918          * Returns true if windows in this stack should be given move animations by default.
919          */
hasMovementAnimations(int stackId)920         public static boolean hasMovementAnimations(int stackId) {
921             return stackId != PINNED_STACK_ID;
922         }
923 
924         /** Returns true if the input stack and its content can affect the device orientation. */
canSpecifyOrientation(int stackId)925         public static boolean canSpecifyOrientation(int stackId) {
926             return stackId == HOME_STACK_ID
927                     || stackId == RECENTS_STACK_ID
928                     || stackId == FULLSCREEN_WORKSPACE_STACK_ID
929                     || stackId == ASSISTANT_STACK_ID
930                     || isDynamicStack(stackId);
931         }
932     }
933 
934     /**
935      * Input parameter to {@link android.app.IActivityManager#moveTaskToDockedStack} which
936      * specifies the position of the created docked stack at the top half of the screen if
937      * in portrait mode or at the left half of the screen if in landscape mode.
938      * @hide
939      */
940     public static final int DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT = 0;
941 
942     /**
943      * Input parameter to {@link android.app.IActivityManager#moveTaskToDockedStack} which
944      * specifies the position of the created docked stack at the bottom half of the screen if
945      * in portrait mode or at the right half of the screen if in landscape mode.
946      * @hide
947      */
948     public static final int DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT = 1;
949 
950     /**
951      * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates
952      * that the resize doesn't need to preserve the window, and can be skipped if bounds
953      * is unchanged. This mode is used by window manager in most cases.
954      * @hide
955      */
956     public static final int RESIZE_MODE_SYSTEM = 0;
957 
958     /**
959      * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates
960      * that the resize should preserve the window if possible.
961      * @hide
962      */
963     public static final int RESIZE_MODE_PRESERVE_WINDOW   = (0x1 << 0);
964 
965     /**
966      * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates
967      * that the resize should be performed even if the bounds appears unchanged.
968      * @hide
969      */
970     public static final int RESIZE_MODE_FORCED = (0x1 << 1);
971 
972     /**
973      * Input parameter to {@link android.app.IActivityManager#resizeTask} used by window
974      * manager during a screen rotation.
975      * @hide
976      */
977     public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW;
978 
979     /**
980      * Input parameter to {@link android.app.IActivityManager#resizeTask} used when the
981      * resize is due to a drag action.
982      * @hide
983      */
984     public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW;
985 
986     /**
987      * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates
988      * that the resize should preserve the window if possible, and should not be skipped
989      * even if the bounds is unchanged. Usually used to force a resizing when a drag action
990      * is ending.
991      * @hide
992      */
993     public static final int RESIZE_MODE_USER_FORCED =
994             RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED;
995 
996     /** @hide */
getFrontActivityScreenCompatMode()997     public int getFrontActivityScreenCompatMode() {
998         try {
999             return getService().getFrontActivityScreenCompatMode();
1000         } catch (RemoteException e) {
1001             throw e.rethrowFromSystemServer();
1002         }
1003     }
1004 
1005     /** @hide */
setFrontActivityScreenCompatMode(int mode)1006     public void setFrontActivityScreenCompatMode(int mode) {
1007         try {
1008             getService().setFrontActivityScreenCompatMode(mode);
1009         } catch (RemoteException e) {
1010             throw e.rethrowFromSystemServer();
1011         }
1012     }
1013 
1014     /** @hide */
getPackageScreenCompatMode(String packageName)1015     public int getPackageScreenCompatMode(String packageName) {
1016         try {
1017             return getService().getPackageScreenCompatMode(packageName);
1018         } catch (RemoteException e) {
1019             throw e.rethrowFromSystemServer();
1020         }
1021     }
1022 
1023     /** @hide */
setPackageScreenCompatMode(String packageName, int mode)1024     public void setPackageScreenCompatMode(String packageName, int mode) {
1025         try {
1026             getService().setPackageScreenCompatMode(packageName, mode);
1027         } catch (RemoteException e) {
1028             throw e.rethrowFromSystemServer();
1029         }
1030     }
1031 
1032     /** @hide */
getPackageAskScreenCompat(String packageName)1033     public boolean getPackageAskScreenCompat(String packageName) {
1034         try {
1035             return getService().getPackageAskScreenCompat(packageName);
1036         } catch (RemoteException e) {
1037             throw e.rethrowFromSystemServer();
1038         }
1039     }
1040 
1041     /** @hide */
setPackageAskScreenCompat(String packageName, boolean ask)1042     public void setPackageAskScreenCompat(String packageName, boolean ask) {
1043         try {
1044             getService().setPackageAskScreenCompat(packageName, ask);
1045         } catch (RemoteException e) {
1046             throw e.rethrowFromSystemServer();
1047         }
1048     }
1049 
1050     /**
1051      * Return the approximate per-application memory class of the current
1052      * device.  This gives you an idea of how hard a memory limit you should
1053      * impose on your application to let the overall system work best.  The
1054      * returned value is in megabytes; the baseline Android memory class is
1055      * 16 (which happens to be the Java heap limit of those devices); some
1056      * device with more memory may return 24 or even higher numbers.
1057      */
getMemoryClass()1058     public int getMemoryClass() {
1059         return staticGetMemoryClass();
1060     }
1061 
1062     /** @hide */
staticGetMemoryClass()1063     static public int staticGetMemoryClass() {
1064         // Really brain dead right now -- just take this from the configured
1065         // vm heap size, and assume it is in megabytes and thus ends with "m".
1066         String vmHeapSize = SystemProperties.get("dalvik.vm.heapgrowthlimit", "");
1067         if (vmHeapSize != null && !"".equals(vmHeapSize)) {
1068             return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
1069         }
1070         return staticGetLargeMemoryClass();
1071     }
1072 
1073     /**
1074      * Return the approximate per-application memory class of the current
1075      * device when an application is running with a large heap.  This is the
1076      * space available for memory-intensive applications; most applications
1077      * should not need this amount of memory, and should instead stay with the
1078      * {@link #getMemoryClass()} limit.  The returned value is in megabytes.
1079      * This may be the same size as {@link #getMemoryClass()} on memory
1080      * constrained devices, or it may be significantly larger on devices with
1081      * a large amount of available RAM.
1082      *
1083      * <p>The is the size of the application's Dalvik heap if it has
1084      * specified <code>android:largeHeap="true"</code> in its manifest.
1085      */
getLargeMemoryClass()1086     public int getLargeMemoryClass() {
1087         return staticGetLargeMemoryClass();
1088     }
1089 
1090     /** @hide */
staticGetLargeMemoryClass()1091     static public int staticGetLargeMemoryClass() {
1092         // Really brain dead right now -- just take this from the configured
1093         // vm heap size, and assume it is in megabytes and thus ends with "m".
1094         String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
1095         return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1));
1096     }
1097 
1098     /**
1099      * Returns true if this is a low-RAM device.  Exactly whether a device is low-RAM
1100      * is ultimately up to the device configuration, but currently it generally means
1101      * something in the class of a 512MB device with about a 800x480 or less screen.
1102      * This is mostly intended to be used by apps to determine whether they should turn
1103      * off certain features that require more RAM.
1104      */
isLowRamDevice()1105     public boolean isLowRamDevice() {
1106         return isLowRamDeviceStatic();
1107     }
1108 
1109     /** @hide */
isLowRamDeviceStatic()1110     public static boolean isLowRamDeviceStatic() {
1111         return RoSystemProperties.CONFIG_LOW_RAM;
1112     }
1113 
1114     /**
1115      * Used by persistent processes to determine if they are running on a
1116      * higher-end device so should be okay using hardware drawing acceleration
1117      * (which tends to consume a lot more RAM).
1118      * @hide
1119      */
isHighEndGfx()1120     static public boolean isHighEndGfx() {
1121         return !isLowRamDeviceStatic() &&
1122                 !Resources.getSystem().getBoolean(com.android.internal.R.bool.config_avoidGfxAccel);
1123     }
1124 
1125     /**
1126      * Return the maximum number of recents entries that we will maintain and show.
1127      * @hide
1128      */
getMaxRecentTasksStatic()1129     static public int getMaxRecentTasksStatic() {
1130         if (gMaxRecentTasks < 0) {
1131             return gMaxRecentTasks = isLowRamDeviceStatic() ? 36 : 48;
1132         }
1133         return gMaxRecentTasks;
1134     }
1135 
1136     /**
1137      * Return the default limit on the number of recents that an app can make.
1138      * @hide
1139      */
getDefaultAppRecentsLimitStatic()1140     static public int getDefaultAppRecentsLimitStatic() {
1141         return getMaxRecentTasksStatic() / 6;
1142     }
1143 
1144     /**
1145      * Return the maximum limit on the number of recents that an app can make.
1146      * @hide
1147      */
getMaxAppRecentsLimitStatic()1148     static public int getMaxAppRecentsLimitStatic() {
1149         return getMaxRecentTasksStatic() / 2;
1150     }
1151 
1152     /**
1153      * Returns true if the system supports at least one form of multi-window.
1154      * E.g. freeform, split-screen, picture-in-picture.
1155      * @hide
1156      */
supportsMultiWindow(Context context)1157     static public boolean supportsMultiWindow(Context context) {
1158         // On watches, multi-window is used to present essential system UI, and thus it must be
1159         // supported regardless of device memory characteristics.
1160         boolean isWatch = context.getPackageManager().hasSystemFeature(
1161                 PackageManager.FEATURE_WATCH);
1162         return (!isLowRamDeviceStatic() || isWatch)
1163                 && Resources.getSystem().getBoolean(
1164                     com.android.internal.R.bool.config_supportsMultiWindow);
1165     }
1166 
1167     /**
1168      * Returns true if the system supports split screen multi-window.
1169      * @hide
1170      */
supportsSplitScreenMultiWindow(Context context)1171     static public boolean supportsSplitScreenMultiWindow(Context context) {
1172         return supportsMultiWindow(context)
1173                 && Resources.getSystem().getBoolean(
1174                     com.android.internal.R.bool.config_supportsSplitScreenMultiWindow);
1175     }
1176 
1177     /** @removed */
1178     @Deprecated
getMaxNumPictureInPictureActions()1179     public static int getMaxNumPictureInPictureActions() {
1180         return 3;
1181     }
1182 
1183     /**
1184      * Information you can set and retrieve about the current activity within the recent task list.
1185      */
1186     public static class TaskDescription implements Parcelable {
1187         /** @hide */
1188         public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_";
1189         private static final String ATTR_TASKDESCRIPTIONLABEL =
1190                 ATTR_TASKDESCRIPTION_PREFIX + "label";
1191         private static final String ATTR_TASKDESCRIPTIONCOLOR_PRIMARY =
1192                 ATTR_TASKDESCRIPTION_PREFIX + "color";
1193         private static final String ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND =
1194                 ATTR_TASKDESCRIPTION_PREFIX + "colorBackground";
1195         private static final String ATTR_TASKDESCRIPTIONICONFILENAME =
1196                 ATTR_TASKDESCRIPTION_PREFIX + "icon_filename";
1197 
1198         private String mLabel;
1199         private Bitmap mIcon;
1200         private String mIconFilename;
1201         private int mColorPrimary;
1202         private int mColorBackground;
1203         private int mStatusBarColor;
1204         private int mNavigationBarColor;
1205 
1206         /**
1207          * Creates the TaskDescription to the specified values.
1208          *
1209          * @param label A label and description of the current state of this task.
1210          * @param icon An icon that represents the current state of this task.
1211          * @param colorPrimary A color to override the theme's primary color.  This color must be
1212          *                     opaque.
1213          */
TaskDescription(String label, Bitmap icon, int colorPrimary)1214         public TaskDescription(String label, Bitmap icon, int colorPrimary) {
1215             this(label, icon, null, colorPrimary, 0, 0, 0);
1216             if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
1217                 throw new RuntimeException("A TaskDescription's primary color should be opaque");
1218             }
1219         }
1220 
1221         /**
1222          * Creates the TaskDescription to the specified values.
1223          *
1224          * @param label A label and description of the current state of this activity.
1225          * @param icon An icon that represents the current state of this activity.
1226          */
TaskDescription(String label, Bitmap icon)1227         public TaskDescription(String label, Bitmap icon) {
1228             this(label, icon, null, 0, 0, 0, 0);
1229         }
1230 
1231         /**
1232          * Creates the TaskDescription to the specified values.
1233          *
1234          * @param label A label and description of the current state of this activity.
1235          */
TaskDescription(String label)1236         public TaskDescription(String label) {
1237             this(label, null, null, 0, 0, 0, 0);
1238         }
1239 
1240         /**
1241          * Creates an empty TaskDescription.
1242          */
TaskDescription()1243         public TaskDescription() {
1244             this(null, null, null, 0, 0, 0, 0);
1245         }
1246 
1247         /** @hide */
TaskDescription(String label, Bitmap icon, String iconFilename, int colorPrimary, int colorBackground, int statusBarColor, int navigationBarColor)1248         public TaskDescription(String label, Bitmap icon, String iconFilename, int colorPrimary,
1249                 int colorBackground, int statusBarColor, int navigationBarColor) {
1250             mLabel = label;
1251             mIcon = icon;
1252             mIconFilename = iconFilename;
1253             mColorPrimary = colorPrimary;
1254             mColorBackground = colorBackground;
1255             mStatusBarColor = statusBarColor;
1256             mNavigationBarColor = navigationBarColor;
1257         }
1258 
1259         /**
1260          * Creates a copy of another TaskDescription.
1261          */
TaskDescription(TaskDescription td)1262         public TaskDescription(TaskDescription td) {
1263             copyFrom(td);
1264         }
1265 
1266         /**
1267          * Copies this the values from another TaskDescription.
1268          * @hide
1269          */
copyFrom(TaskDescription other)1270         public void copyFrom(TaskDescription other) {
1271             mLabel = other.mLabel;
1272             mIcon = other.mIcon;
1273             mIconFilename = other.mIconFilename;
1274             mColorPrimary = other.mColorPrimary;
1275             mColorBackground = other.mColorBackground;
1276             mStatusBarColor = other.mStatusBarColor;
1277             mNavigationBarColor = other.mNavigationBarColor;
1278         }
1279 
1280         /**
1281          * Copies this the values from another TaskDescription, but preserves the hidden fields
1282          * if they weren't set on {@code other}
1283          * @hide
1284          */
copyFromPreserveHiddenFields(TaskDescription other)1285         public void copyFromPreserveHiddenFields(TaskDescription other) {
1286             mLabel = other.mLabel;
1287             mIcon = other.mIcon;
1288             mIconFilename = other.mIconFilename;
1289             mColorPrimary = other.mColorPrimary;
1290             if (other.mColorBackground != 0) {
1291                 mColorBackground = other.mColorBackground;
1292             }
1293             if (other.mStatusBarColor != 0) {
1294                 mStatusBarColor = other.mStatusBarColor;
1295             }
1296             if (other.mNavigationBarColor != 0) {
1297                 mNavigationBarColor = other.mNavigationBarColor;
1298             }
1299         }
1300 
TaskDescription(Parcel source)1301         private TaskDescription(Parcel source) {
1302             readFromParcel(source);
1303         }
1304 
1305         /**
1306          * Sets the label for this task description.
1307          * @hide
1308          */
setLabel(String label)1309         public void setLabel(String label) {
1310             mLabel = label;
1311         }
1312 
1313         /**
1314          * Sets the primary color for this task description.
1315          * @hide
1316          */
setPrimaryColor(int primaryColor)1317         public void setPrimaryColor(int primaryColor) {
1318             // Ensure that the given color is valid
1319             if ((primaryColor != 0) && (Color.alpha(primaryColor) != 255)) {
1320                 throw new RuntimeException("A TaskDescription's primary color should be opaque");
1321             }
1322             mColorPrimary = primaryColor;
1323         }
1324 
1325         /**
1326          * Sets the background color for this task description.
1327          * @hide
1328          */
setBackgroundColor(int backgroundColor)1329         public void setBackgroundColor(int backgroundColor) {
1330             // Ensure that the given color is valid
1331             if ((backgroundColor != 0) && (Color.alpha(backgroundColor) != 255)) {
1332                 throw new RuntimeException("A TaskDescription's background color should be opaque");
1333             }
1334             mColorBackground = backgroundColor;
1335         }
1336 
1337         /**
1338          * @hide
1339          */
setStatusBarColor(int statusBarColor)1340         public void setStatusBarColor(int statusBarColor) {
1341             mStatusBarColor = statusBarColor;
1342         }
1343 
1344         /**
1345          * @hide
1346          */
setNavigationBarColor(int navigationBarColor)1347         public void setNavigationBarColor(int navigationBarColor) {
1348             mNavigationBarColor = navigationBarColor;
1349         }
1350 
1351         /**
1352          * Sets the icon for this task description.
1353          * @hide
1354          */
setIcon(Bitmap icon)1355         public void setIcon(Bitmap icon) {
1356             mIcon = icon;
1357         }
1358 
1359         /**
1360          * Moves the icon bitmap reference from an actual Bitmap to a file containing the
1361          * bitmap.
1362          * @hide
1363          */
setIconFilename(String iconFilename)1364         public void setIconFilename(String iconFilename) {
1365             mIconFilename = iconFilename;
1366             mIcon = null;
1367         }
1368 
1369         /**
1370          * @return The label and description of the current state of this task.
1371          */
getLabel()1372         public String getLabel() {
1373             return mLabel;
1374         }
1375 
1376         /**
1377          * @return The icon that represents the current state of this task.
1378          */
getIcon()1379         public Bitmap getIcon() {
1380             if (mIcon != null) {
1381                 return mIcon;
1382             }
1383             return loadTaskDescriptionIcon(mIconFilename, UserHandle.myUserId());
1384         }
1385 
1386         /** @hide */
getIconFilename()1387         public String getIconFilename() {
1388             return mIconFilename;
1389         }
1390 
1391         /** @hide */
getInMemoryIcon()1392         public Bitmap getInMemoryIcon() {
1393             return mIcon;
1394         }
1395 
1396         /** @hide */
loadTaskDescriptionIcon(String iconFilename, int userId)1397         public static Bitmap loadTaskDescriptionIcon(String iconFilename, int userId) {
1398             if (iconFilename != null) {
1399                 try {
1400                     return getService().getTaskDescriptionIcon(iconFilename,
1401                             userId);
1402                 } catch (RemoteException e) {
1403                     throw e.rethrowFromSystemServer();
1404                 }
1405             }
1406             return null;
1407         }
1408 
1409         /**
1410          * @return The color override on the theme's primary color.
1411          */
getPrimaryColor()1412         public int getPrimaryColor() {
1413             return mColorPrimary;
1414         }
1415 
1416         /**
1417          * @return The background color.
1418          * @hide
1419          */
getBackgroundColor()1420         public int getBackgroundColor() {
1421             return mColorBackground;
1422         }
1423 
1424         /**
1425          * @hide
1426          */
getStatusBarColor()1427         public int getStatusBarColor() {
1428             return mStatusBarColor;
1429         }
1430 
1431         /**
1432          * @hide
1433          */
getNavigationBarColor()1434         public int getNavigationBarColor() {
1435             return mNavigationBarColor;
1436         }
1437 
1438         /** @hide */
saveToXml(XmlSerializer out)1439         public void saveToXml(XmlSerializer out) throws IOException {
1440             if (mLabel != null) {
1441                 out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel);
1442             }
1443             if (mColorPrimary != 0) {
1444                 out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_PRIMARY,
1445                         Integer.toHexString(mColorPrimary));
1446             }
1447             if (mColorBackground != 0) {
1448                 out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND,
1449                         Integer.toHexString(mColorBackground));
1450             }
1451             if (mIconFilename != null) {
1452                 out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename);
1453             }
1454         }
1455 
1456         /** @hide */
restoreFromXml(String attrName, String attrValue)1457         public void restoreFromXml(String attrName, String attrValue) {
1458             if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
1459                 setLabel(attrValue);
1460             } else if (ATTR_TASKDESCRIPTIONCOLOR_PRIMARY.equals(attrName)) {
1461                 setPrimaryColor((int) Long.parseLong(attrValue, 16));
1462             } else if (ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND.equals(attrName)) {
1463                 setBackgroundColor((int) Long.parseLong(attrValue, 16));
1464             } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) {
1465                 setIconFilename(attrValue);
1466             }
1467         }
1468 
1469         @Override
describeContents()1470         public int describeContents() {
1471             return 0;
1472         }
1473 
1474         @Override
writeToParcel(Parcel dest, int flags)1475         public void writeToParcel(Parcel dest, int flags) {
1476             if (mLabel == null) {
1477                 dest.writeInt(0);
1478             } else {
1479                 dest.writeInt(1);
1480                 dest.writeString(mLabel);
1481             }
1482             if (mIcon == null) {
1483                 dest.writeInt(0);
1484             } else {
1485                 dest.writeInt(1);
1486                 mIcon.writeToParcel(dest, 0);
1487             }
1488             dest.writeInt(mColorPrimary);
1489             dest.writeInt(mColorBackground);
1490             dest.writeInt(mStatusBarColor);
1491             dest.writeInt(mNavigationBarColor);
1492             if (mIconFilename == null) {
1493                 dest.writeInt(0);
1494             } else {
1495                 dest.writeInt(1);
1496                 dest.writeString(mIconFilename);
1497             }
1498         }
1499 
readFromParcel(Parcel source)1500         public void readFromParcel(Parcel source) {
1501             mLabel = source.readInt() > 0 ? source.readString() : null;
1502             mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
1503             mColorPrimary = source.readInt();
1504             mColorBackground = source.readInt();
1505             mStatusBarColor = source.readInt();
1506             mNavigationBarColor = source.readInt();
1507             mIconFilename = source.readInt() > 0 ? source.readString() : null;
1508         }
1509 
1510         public static final Creator<TaskDescription> CREATOR
1511                 = new Creator<TaskDescription>() {
1512             public TaskDescription createFromParcel(Parcel source) {
1513                 return new TaskDescription(source);
1514             }
1515             public TaskDescription[] newArray(int size) {
1516                 return new TaskDescription[size];
1517             }
1518         };
1519 
1520         @Override
toString()1521         public String toString() {
1522             return "TaskDescription Label: " + mLabel + " Icon: " + mIcon +
1523                     " IconFilename: " + mIconFilename + " colorPrimary: " + mColorPrimary +
1524                     " colorBackground: " + mColorBackground +
1525                     " statusBarColor: " + mColorBackground +
1526                     " navigationBarColor: " + mNavigationBarColor;
1527         }
1528     }
1529 
1530     /**
1531      * Information you can retrieve about tasks that the user has most recently
1532      * started or visited.
1533      */
1534     public static class RecentTaskInfo implements Parcelable {
1535         /**
1536          * If this task is currently running, this is the identifier for it.
1537          * If it is not running, this will be -1.
1538          */
1539         public int id;
1540 
1541         /**
1542          * The true identifier of this task, valid even if it is not running.
1543          */
1544         public int persistentId;
1545 
1546         /**
1547          * The original Intent used to launch the task.  You can use this
1548          * Intent to re-launch the task (if it is no longer running) or bring
1549          * the current task to the front.
1550          */
1551         public Intent baseIntent;
1552 
1553         /**
1554          * If this task was started from an alias, this is the actual
1555          * activity component that was initially started; the component of
1556          * the baseIntent in this case is the name of the actual activity
1557          * implementation that the alias referred to.  Otherwise, this is null.
1558          */
1559         public ComponentName origActivity;
1560 
1561         /**
1562          * The actual activity component that started the task.
1563          * @hide
1564          */
1565         @Nullable
1566         public ComponentName realActivity;
1567 
1568         /**
1569          * Description of the task's last state.
1570          */
1571         public CharSequence description;
1572 
1573         /**
1574          * The id of the ActivityStack this Task was on most recently.
1575          * @hide
1576          */
1577         public int stackId;
1578 
1579         /**
1580          * The id of the user the task was running as.
1581          * @hide
1582          */
1583         public int userId;
1584 
1585         /**
1586          * The first time this task was active.
1587          * @hide
1588          */
1589         public long firstActiveTime;
1590 
1591         /**
1592          * The last time this task was active.
1593          * @hide
1594          */
1595         public long lastActiveTime;
1596 
1597         /**
1598          * The recent activity values for the highest activity in the stack to have set the values.
1599          * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.
1600          */
1601         public TaskDescription taskDescription;
1602 
1603         /**
1604          * Task affiliation for grouping with other tasks.
1605          */
1606         public int affiliatedTaskId;
1607 
1608         /**
1609          * Task affiliation color of the source task with the affiliated task id.
1610          *
1611          * @hide
1612          */
1613         public int affiliatedTaskColor;
1614 
1615         /**
1616          * The component launched as the first activity in the task.
1617          * This can be considered the "application" of this task.
1618          */
1619         public ComponentName baseActivity;
1620 
1621         /**
1622          * The activity component at the top of the history stack of the task.
1623          * This is what the user is currently doing.
1624          */
1625         public ComponentName topActivity;
1626 
1627         /**
1628          * Number of activities in this task.
1629          */
1630         public int numActivities;
1631 
1632         /**
1633          * The bounds of the task.
1634          * @hide
1635          */
1636         public Rect bounds;
1637 
1638         /**
1639          * True if the task can go in the docked stack.
1640          * @hide
1641          */
1642         public boolean supportsSplitScreenMultiWindow;
1643 
1644         /**
1645          * The resize mode of the task. See {@link ActivityInfo#resizeMode}.
1646          * @hide
1647          */
1648         public int resizeMode;
1649 
RecentTaskInfo()1650         public RecentTaskInfo() {
1651         }
1652 
1653         @Override
describeContents()1654         public int describeContents() {
1655             return 0;
1656         }
1657 
1658         @Override
writeToParcel(Parcel dest, int flags)1659         public void writeToParcel(Parcel dest, int flags) {
1660             dest.writeInt(id);
1661             dest.writeInt(persistentId);
1662             if (baseIntent != null) {
1663                 dest.writeInt(1);
1664                 baseIntent.writeToParcel(dest, 0);
1665             } else {
1666                 dest.writeInt(0);
1667             }
1668             ComponentName.writeToParcel(origActivity, dest);
1669             ComponentName.writeToParcel(realActivity, dest);
1670             TextUtils.writeToParcel(description, dest,
1671                     Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
1672             if (taskDescription != null) {
1673                 dest.writeInt(1);
1674                 taskDescription.writeToParcel(dest, 0);
1675             } else {
1676                 dest.writeInt(0);
1677             }
1678             dest.writeInt(stackId);
1679             dest.writeInt(userId);
1680             dest.writeLong(firstActiveTime);
1681             dest.writeLong(lastActiveTime);
1682             dest.writeInt(affiliatedTaskId);
1683             dest.writeInt(affiliatedTaskColor);
1684             ComponentName.writeToParcel(baseActivity, dest);
1685             ComponentName.writeToParcel(topActivity, dest);
1686             dest.writeInt(numActivities);
1687             if (bounds != null) {
1688                 dest.writeInt(1);
1689                 bounds.writeToParcel(dest, 0);
1690             } else {
1691                 dest.writeInt(0);
1692             }
1693             dest.writeInt(supportsSplitScreenMultiWindow ? 1 : 0);
1694             dest.writeInt(resizeMode);
1695         }
1696 
readFromParcel(Parcel source)1697         public void readFromParcel(Parcel source) {
1698             id = source.readInt();
1699             persistentId = source.readInt();
1700             baseIntent = source.readInt() > 0 ? Intent.CREATOR.createFromParcel(source) : null;
1701             origActivity = ComponentName.readFromParcel(source);
1702             realActivity = ComponentName.readFromParcel(source);
1703             description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
1704             taskDescription = source.readInt() > 0 ?
1705                     TaskDescription.CREATOR.createFromParcel(source) : null;
1706             stackId = source.readInt();
1707             userId = source.readInt();
1708             firstActiveTime = source.readLong();
1709             lastActiveTime = source.readLong();
1710             affiliatedTaskId = source.readInt();
1711             affiliatedTaskColor = source.readInt();
1712             baseActivity = ComponentName.readFromParcel(source);
1713             topActivity = ComponentName.readFromParcel(source);
1714             numActivities = source.readInt();
1715             bounds = source.readInt() > 0 ?
1716                     Rect.CREATOR.createFromParcel(source) : null;
1717             supportsSplitScreenMultiWindow = source.readInt() == 1;
1718             resizeMode = source.readInt();
1719         }
1720 
1721         public static final Creator<RecentTaskInfo> CREATOR
1722                 = new Creator<RecentTaskInfo>() {
1723             public RecentTaskInfo createFromParcel(Parcel source) {
1724                 return new RecentTaskInfo(source);
1725             }
1726             public RecentTaskInfo[] newArray(int size) {
1727                 return new RecentTaskInfo[size];
1728             }
1729         };
1730 
RecentTaskInfo(Parcel source)1731         private RecentTaskInfo(Parcel source) {
1732             readFromParcel(source);
1733         }
1734     }
1735 
1736     /**
1737      * Flag for use with {@link #getRecentTasks}: return all tasks, even those
1738      * that have set their
1739      * {@link android.content.Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag.
1740      */
1741     public static final int RECENT_WITH_EXCLUDED = 0x0001;
1742 
1743     /**
1744      * Provides a list that does not contain any
1745      * recent tasks that currently are not available to the user.
1746      */
1747     public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
1748 
1749     /**
1750      * Provides a list that contains recent tasks for all
1751      * profiles of a user.
1752      * @hide
1753      */
1754     public static final int RECENT_INCLUDE_PROFILES = 0x0004;
1755 
1756     /**
1757      * Ignores all tasks that are on the home stack.
1758      * @hide
1759      */
1760     public static final int RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS = 0x0008;
1761 
1762     /**
1763      * Ignores the top task in the docked stack.
1764      * @hide
1765      */
1766     public static final int RECENT_INGORE_DOCKED_STACK_TOP_TASK = 0x0010;
1767 
1768     /**
1769      * Ignores all tasks that are on the pinned stack.
1770      * @hide
1771      */
1772     public static final int RECENT_INGORE_PINNED_STACK_TASKS = 0x0020;
1773 
1774     /**
1775      * <p></p>Return a list of the tasks that the user has recently launched, with
1776      * the most recent being first and older ones after in order.
1777      *
1778      * <p><b>Note: this method is only intended for debugging and presenting
1779      * task management user interfaces</b>.  This should never be used for
1780      * core logic in an application, such as deciding between different
1781      * behaviors based on the information found here.  Such uses are
1782      * <em>not</em> supported, and will likely break in the future.  For
1783      * example, if multiple applications can be actively running at the
1784      * same time, assumptions made about the meaning of the data here for
1785      * purposes of control flow will be incorrect.</p>
1786      *
1787      * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method is
1788      * no longer available to third party applications: the introduction of
1789      * document-centric recents means
1790      * it can leak personal information to the caller.  For backwards compatibility,
1791      * it will still return a small subset of its data: at least the caller's
1792      * own tasks (though see {@link #getAppTasks()} for the correct supported
1793      * way to retrieve that information), and possibly some other tasks
1794      * such as home that are known to not be sensitive.
1795      *
1796      * @param maxNum The maximum number of entries to return in the list.  The
1797      * actual number returned may be smaller, depending on how many tasks the
1798      * user has started and the maximum number the system can remember.
1799      * @param flags Information about what to return.  May be any combination
1800      * of {@link #RECENT_WITH_EXCLUDED} and {@link #RECENT_IGNORE_UNAVAILABLE}.
1801      *
1802      * @return Returns a list of RecentTaskInfo records describing each of
1803      * the recent tasks.
1804      */
1805     @Deprecated
getRecentTasks(int maxNum, int flags)1806     public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
1807             throws SecurityException {
1808         try {
1809             return getService().getRecentTasks(maxNum,
1810                     flags, UserHandle.myUserId()).getList();
1811         } catch (RemoteException e) {
1812             throw e.rethrowFromSystemServer();
1813         }
1814     }
1815 
1816     /**
1817      * Same as {@link #getRecentTasks(int, int)} but returns the recent tasks for a
1818      * specific user. It requires holding
1819      * the {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission.
1820      * @param maxNum The maximum number of entries to return in the list.  The
1821      * actual number returned may be smaller, depending on how many tasks the
1822      * user has started and the maximum number the system can remember.
1823      * @param flags Information about what to return.  May be any combination
1824      * of {@link #RECENT_WITH_EXCLUDED} and {@link #RECENT_IGNORE_UNAVAILABLE}.
1825      *
1826      * @return Returns a list of RecentTaskInfo records describing each of
1827      * the recent tasks. Most recently activated tasks go first.
1828      *
1829      * @hide
1830      */
getRecentTasksForUser(int maxNum, int flags, int userId)1831     public List<RecentTaskInfo> getRecentTasksForUser(int maxNum, int flags, int userId)
1832             throws SecurityException {
1833         try {
1834             return getService().getRecentTasks(maxNum,
1835                     flags, userId).getList();
1836         } catch (RemoteException e) {
1837             throw e.rethrowFromSystemServer();
1838         }
1839     }
1840 
1841     /**
1842      * Information you can retrieve about a particular task that is currently
1843      * "running" in the system.  Note that a running task does not mean the
1844      * given task actually has a process it is actively running in; it simply
1845      * means that the user has gone to it and never closed it, but currently
1846      * the system may have killed its process and is only holding on to its
1847      * last state in order to restart it when the user returns.
1848      */
1849     public static class RunningTaskInfo implements Parcelable {
1850         /**
1851          * A unique identifier for this task.
1852          */
1853         public int id;
1854 
1855         /**
1856          * The stack that currently contains this task.
1857          * @hide
1858          */
1859         public int stackId;
1860 
1861         /**
1862          * The component launched as the first activity in the task.  This can
1863          * be considered the "application" of this task.
1864          */
1865         public ComponentName baseActivity;
1866 
1867         /**
1868          * The activity component at the top of the history stack of the task.
1869          * This is what the user is currently doing.
1870          */
1871         public ComponentName topActivity;
1872 
1873         /**
1874          * Thumbnail representation of the task's current state.  Currently
1875          * always null.
1876          */
1877         public Bitmap thumbnail;
1878 
1879         /**
1880          * Description of the task's current state.
1881          */
1882         public CharSequence description;
1883 
1884         /**
1885          * Number of activities in this task.
1886          */
1887         public int numActivities;
1888 
1889         /**
1890          * Number of activities that are currently running (not stopped
1891          * and persisted) in this task.
1892          */
1893         public int numRunning;
1894 
1895         /**
1896          * Last time task was run. For sorting.
1897          * @hide
1898          */
1899         public long lastActiveTime;
1900 
1901         /**
1902          * True if the task can go in the docked stack.
1903          * @hide
1904          */
1905         public boolean supportsSplitScreenMultiWindow;
1906 
1907         /**
1908          * The resize mode of the task. See {@link ActivityInfo#resizeMode}.
1909          * @hide
1910          */
1911         public int resizeMode;
1912 
RunningTaskInfo()1913         public RunningTaskInfo() {
1914         }
1915 
describeContents()1916         public int describeContents() {
1917             return 0;
1918         }
1919 
writeToParcel(Parcel dest, int flags)1920         public void writeToParcel(Parcel dest, int flags) {
1921             dest.writeInt(id);
1922             dest.writeInt(stackId);
1923             ComponentName.writeToParcel(baseActivity, dest);
1924             ComponentName.writeToParcel(topActivity, dest);
1925             if (thumbnail != null) {
1926                 dest.writeInt(1);
1927                 thumbnail.writeToParcel(dest, 0);
1928             } else {
1929                 dest.writeInt(0);
1930             }
1931             TextUtils.writeToParcel(description, dest,
1932                     Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
1933             dest.writeInt(numActivities);
1934             dest.writeInt(numRunning);
1935             dest.writeInt(supportsSplitScreenMultiWindow ? 1 : 0);
1936             dest.writeInt(resizeMode);
1937         }
1938 
readFromParcel(Parcel source)1939         public void readFromParcel(Parcel source) {
1940             id = source.readInt();
1941             stackId = source.readInt();
1942             baseActivity = ComponentName.readFromParcel(source);
1943             topActivity = ComponentName.readFromParcel(source);
1944             if (source.readInt() != 0) {
1945                 thumbnail = Bitmap.CREATOR.createFromParcel(source);
1946             } else {
1947                 thumbnail = null;
1948             }
1949             description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
1950             numActivities = source.readInt();
1951             numRunning = source.readInt();
1952             supportsSplitScreenMultiWindow = source.readInt() != 0;
1953             resizeMode = source.readInt();
1954         }
1955 
1956         public static final Creator<RunningTaskInfo> CREATOR = new Creator<RunningTaskInfo>() {
1957             public RunningTaskInfo createFromParcel(Parcel source) {
1958                 return new RunningTaskInfo(source);
1959             }
1960             public RunningTaskInfo[] newArray(int size) {
1961                 return new RunningTaskInfo[size];
1962             }
1963         };
1964 
RunningTaskInfo(Parcel source)1965         private RunningTaskInfo(Parcel source) {
1966             readFromParcel(source);
1967         }
1968     }
1969 
1970     /**
1971      * Get the list of tasks associated with the calling application.
1972      *
1973      * @return The list of tasks associated with the application making this call.
1974      * @throws SecurityException
1975      */
getAppTasks()1976     public List<ActivityManager.AppTask> getAppTasks() {
1977         ArrayList<AppTask> tasks = new ArrayList<AppTask>();
1978         List<IBinder> appTasks;
1979         try {
1980             appTasks = getService().getAppTasks(mContext.getPackageName());
1981         } catch (RemoteException e) {
1982             throw e.rethrowFromSystemServer();
1983         }
1984         int numAppTasks = appTasks.size();
1985         for (int i = 0; i < numAppTasks; i++) {
1986             tasks.add(new AppTask(IAppTask.Stub.asInterface(appTasks.get(i))));
1987         }
1988         return tasks;
1989     }
1990 
1991     /**
1992      * Return the current design dimensions for {@link AppTask} thumbnails, for use
1993      * with {@link #addAppTask}.
1994      */
getAppTaskThumbnailSize()1995     public Size getAppTaskThumbnailSize() {
1996         synchronized (this) {
1997             ensureAppTaskThumbnailSizeLocked();
1998             return new Size(mAppTaskThumbnailSize.x, mAppTaskThumbnailSize.y);
1999         }
2000     }
2001 
ensureAppTaskThumbnailSizeLocked()2002     private void ensureAppTaskThumbnailSizeLocked() {
2003         if (mAppTaskThumbnailSize == null) {
2004             try {
2005                 mAppTaskThumbnailSize = getService().getAppTaskThumbnailSize();
2006             } catch (RemoteException e) {
2007                 throw e.rethrowFromSystemServer();
2008             }
2009         }
2010     }
2011 
2012     /**
2013      * Add a new {@link AppTask} for the calling application.  This will create a new
2014      * recents entry that is added to the <b>end</b> of all existing recents.
2015      *
2016      * @param activity The activity that is adding the entry.   This is used to help determine
2017      * the context that the new recents entry will be in.
2018      * @param intent The Intent that describes the recents entry.  This is the same Intent that
2019      * you would have used to launch the activity for it.  In generally you will want to set
2020      * both {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT} and
2021      * {@link Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS}; the latter is required since this recents
2022      * entry will exist without an activity, so it doesn't make sense to not retain it when
2023      * its activity disappears.  The given Intent here also must have an explicit ComponentName
2024      * set on it.
2025      * @param description Optional additional description information.
2026      * @param thumbnail Thumbnail to use for the recents entry.  Should be the size given by
2027      * {@link #getAppTaskThumbnailSize()}.  If the bitmap is not that exact size, it will be
2028      * recreated in your process, probably in a way you don't like, before the recents entry
2029      * is added.
2030      *
2031      * @return Returns the task id of the newly added app task, or -1 if the add failed.  The
2032      * most likely cause of failure is that there is no more room for more tasks for your app.
2033      */
addAppTask(@onNull Activity activity, @NonNull Intent intent, @Nullable TaskDescription description, @NonNull Bitmap thumbnail)2034     public int addAppTask(@NonNull Activity activity, @NonNull Intent intent,
2035             @Nullable TaskDescription description, @NonNull Bitmap thumbnail) {
2036         Point size;
2037         synchronized (this) {
2038             ensureAppTaskThumbnailSizeLocked();
2039             size = mAppTaskThumbnailSize;
2040         }
2041         final int tw = thumbnail.getWidth();
2042         final int th = thumbnail.getHeight();
2043         if (tw != size.x || th != size.y) {
2044             Bitmap bm = Bitmap.createBitmap(size.x, size.y, thumbnail.getConfig());
2045 
2046             // Use ScaleType.CENTER_CROP, except we leave the top edge at the top.
2047             float scale;
2048             float dx = 0, dy = 0;
2049             if (tw * size.x > size.y * th) {
2050                 scale = (float) size.x / (float) th;
2051                 dx = (size.y - tw * scale) * 0.5f;
2052             } else {
2053                 scale = (float) size.y / (float) tw;
2054                 dy = (size.x - th * scale) * 0.5f;
2055             }
2056             Matrix matrix = new Matrix();
2057             matrix.setScale(scale, scale);
2058             matrix.postTranslate((int) (dx + 0.5f), 0);
2059 
2060             Canvas canvas = new Canvas(bm);
2061             canvas.drawBitmap(thumbnail, matrix, null);
2062             canvas.setBitmap(null);
2063 
2064             thumbnail = bm;
2065         }
2066         if (description == null) {
2067             description = new TaskDescription();
2068         }
2069         try {
2070             return getService().addAppTask(activity.getActivityToken(),
2071                     intent, description, thumbnail);
2072         } catch (RemoteException e) {
2073             throw e.rethrowFromSystemServer();
2074         }
2075     }
2076 
2077     /**
2078      * Return a list of the tasks that are currently running, with
2079      * the most recent being first and older ones after in order.  Note that
2080      * "running" does not mean any of the task's code is currently loaded or
2081      * activity -- the task may have been frozen by the system, so that it
2082      * can be restarted in its previous state when next brought to the
2083      * foreground.
2084      *
2085      * <p><b>Note: this method is only intended for debugging and presenting
2086      * task management user interfaces</b>.  This should never be used for
2087      * core logic in an application, such as deciding between different
2088      * behaviors based on the information found here.  Such uses are
2089      * <em>not</em> supported, and will likely break in the future.  For
2090      * example, if multiple applications can be actively running at the
2091      * same time, assumptions made about the meaning of the data here for
2092      * purposes of control flow will be incorrect.</p>
2093      *
2094      * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method
2095      * is no longer available to third party
2096      * applications: the introduction of document-centric recents means
2097      * it can leak person information to the caller.  For backwards compatibility,
2098      * it will still retu rn a small subset of its data: at least the caller's
2099      * own tasks, and possibly some other tasks
2100      * such as home that are known to not be sensitive.
2101      *
2102      * @param maxNum The maximum number of entries to return in the list.  The
2103      * actual number returned may be smaller, depending on how many tasks the
2104      * user has started.
2105      *
2106      * @return Returns a list of RunningTaskInfo records describing each of
2107      * the running tasks.
2108      */
2109     @Deprecated
getRunningTasks(int maxNum)2110     public List<RunningTaskInfo> getRunningTasks(int maxNum)
2111             throws SecurityException {
2112         try {
2113             return getService().getTasks(maxNum, 0);
2114         } catch (RemoteException e) {
2115             throw e.rethrowFromSystemServer();
2116         }
2117     }
2118 
2119     /**
2120      * Completely remove the given task.
2121      *
2122      * @param taskId Identifier of the task to be removed.
2123      * @return Returns true if the given task was found and removed.
2124      *
2125      * @hide
2126      */
removeTask(int taskId)2127     public boolean removeTask(int taskId) throws SecurityException {
2128         try {
2129             return getService().removeTask(taskId);
2130         } catch (RemoteException e) {
2131             throw e.rethrowFromSystemServer();
2132         }
2133     }
2134 
2135     /**
2136      * Metadata related to the {@link TaskThumbnail}.
2137      *
2138      * @hide
2139      */
2140     public static class TaskThumbnailInfo implements Parcelable {
2141         /** @hide */
2142         public static final String ATTR_TASK_THUMBNAILINFO_PREFIX = "task_thumbnailinfo_";
2143         private static final String ATTR_TASK_WIDTH =
2144                 ATTR_TASK_THUMBNAILINFO_PREFIX + "task_width";
2145         private static final String ATTR_TASK_HEIGHT =
2146                 ATTR_TASK_THUMBNAILINFO_PREFIX + "task_height";
2147         private static final String ATTR_SCREEN_ORIENTATION =
2148                 ATTR_TASK_THUMBNAILINFO_PREFIX + "screen_orientation";
2149 
2150         public int taskWidth;
2151         public int taskHeight;
2152         public int screenOrientation = Configuration.ORIENTATION_UNDEFINED;
2153 
TaskThumbnailInfo()2154         public TaskThumbnailInfo() {
2155             // Do nothing
2156         }
2157 
TaskThumbnailInfo(Parcel source)2158         private TaskThumbnailInfo(Parcel source) {
2159             readFromParcel(source);
2160         }
2161 
2162         /**
2163          * Resets this info state to the initial state.
2164          * @hide
2165          */
reset()2166         public void reset() {
2167             taskWidth = 0;
2168             taskHeight = 0;
2169             screenOrientation = Configuration.ORIENTATION_UNDEFINED;
2170         }
2171 
2172         /**
2173          * Copies from another ThumbnailInfo.
2174          */
copyFrom(TaskThumbnailInfo o)2175         public void copyFrom(TaskThumbnailInfo o) {
2176             taskWidth = o.taskWidth;
2177             taskHeight = o.taskHeight;
2178             screenOrientation = o.screenOrientation;
2179         }
2180 
2181         /** @hide */
saveToXml(XmlSerializer out)2182         public void saveToXml(XmlSerializer out) throws IOException {
2183             out.attribute(null, ATTR_TASK_WIDTH, Integer.toString(taskWidth));
2184             out.attribute(null, ATTR_TASK_HEIGHT, Integer.toString(taskHeight));
2185             out.attribute(null, ATTR_SCREEN_ORIENTATION, Integer.toString(screenOrientation));
2186         }
2187 
2188         /** @hide */
restoreFromXml(String attrName, String attrValue)2189         public void restoreFromXml(String attrName, String attrValue) {
2190             if (ATTR_TASK_WIDTH.equals(attrName)) {
2191                 taskWidth = Integer.parseInt(attrValue);
2192             } else if (ATTR_TASK_HEIGHT.equals(attrName)) {
2193                 taskHeight = Integer.parseInt(attrValue);
2194             } else if (ATTR_SCREEN_ORIENTATION.equals(attrName)) {
2195                 screenOrientation = Integer.parseInt(attrValue);
2196             }
2197         }
2198 
describeContents()2199         public int describeContents() {
2200             return 0;
2201         }
2202 
writeToParcel(Parcel dest, int flags)2203         public void writeToParcel(Parcel dest, int flags) {
2204             dest.writeInt(taskWidth);
2205             dest.writeInt(taskHeight);
2206             dest.writeInt(screenOrientation);
2207         }
2208 
readFromParcel(Parcel source)2209         public void readFromParcel(Parcel source) {
2210             taskWidth = source.readInt();
2211             taskHeight = source.readInt();
2212             screenOrientation = source.readInt();
2213         }
2214 
2215         public static final Creator<TaskThumbnailInfo> CREATOR = new Creator<TaskThumbnailInfo>() {
2216             public TaskThumbnailInfo createFromParcel(Parcel source) {
2217                 return new TaskThumbnailInfo(source);
2218             }
2219             public TaskThumbnailInfo[] newArray(int size) {
2220                 return new TaskThumbnailInfo[size];
2221             }
2222         };
2223     }
2224 
2225     /** @hide */
2226     public static class TaskThumbnail implements Parcelable {
2227         public Bitmap mainThumbnail;
2228         public ParcelFileDescriptor thumbnailFileDescriptor;
2229         public TaskThumbnailInfo thumbnailInfo;
2230 
TaskThumbnail()2231         public TaskThumbnail() {
2232         }
2233 
TaskThumbnail(Parcel source)2234         private TaskThumbnail(Parcel source) {
2235             readFromParcel(source);
2236         }
2237 
describeContents()2238         public int describeContents() {
2239             if (thumbnailFileDescriptor != null) {
2240                 return thumbnailFileDescriptor.describeContents();
2241             }
2242             return 0;
2243         }
2244 
writeToParcel(Parcel dest, int flags)2245         public void writeToParcel(Parcel dest, int flags) {
2246             if (mainThumbnail != null) {
2247                 dest.writeInt(1);
2248                 mainThumbnail.writeToParcel(dest, flags);
2249             } else {
2250                 dest.writeInt(0);
2251             }
2252             if (thumbnailFileDescriptor != null) {
2253                 dest.writeInt(1);
2254                 thumbnailFileDescriptor.writeToParcel(dest, flags);
2255             } else {
2256                 dest.writeInt(0);
2257             }
2258             if (thumbnailInfo != null) {
2259                 dest.writeInt(1);
2260                 thumbnailInfo.writeToParcel(dest, flags);
2261             } else {
2262                 dest.writeInt(0);
2263             }
2264         }
2265 
readFromParcel(Parcel source)2266         public void readFromParcel(Parcel source) {
2267             if (source.readInt() != 0) {
2268                 mainThumbnail = Bitmap.CREATOR.createFromParcel(source);
2269             } else {
2270                 mainThumbnail = null;
2271             }
2272             if (source.readInt() != 0) {
2273                 thumbnailFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(source);
2274             } else {
2275                 thumbnailFileDescriptor = null;
2276             }
2277             if (source.readInt() != 0) {
2278                 thumbnailInfo = TaskThumbnailInfo.CREATOR.createFromParcel(source);
2279             } else {
2280                 thumbnailInfo = null;
2281             }
2282         }
2283 
2284         public static final Creator<TaskThumbnail> CREATOR = new Creator<TaskThumbnail>() {
2285             public TaskThumbnail createFromParcel(Parcel source) {
2286                 return new TaskThumbnail(source);
2287             }
2288             public TaskThumbnail[] newArray(int size) {
2289                 return new TaskThumbnail[size];
2290             }
2291         };
2292     }
2293 
2294     /**
2295      * Represents a task snapshot.
2296      * @hide
2297      */
2298     public static class TaskSnapshot implements Parcelable {
2299 
2300         private final GraphicBuffer mSnapshot;
2301         private final int mOrientation;
2302         private final Rect mContentInsets;
2303         private final boolean mReducedResolution;
2304         private final float mScale;
2305 
TaskSnapshot(GraphicBuffer snapshot, int orientation, Rect contentInsets, boolean reducedResolution, float scale)2306         public TaskSnapshot(GraphicBuffer snapshot, int orientation, Rect contentInsets,
2307                 boolean reducedResolution, float scale) {
2308             mSnapshot = snapshot;
2309             mOrientation = orientation;
2310             mContentInsets = new Rect(contentInsets);
2311             mReducedResolution = reducedResolution;
2312             mScale = scale;
2313         }
2314 
TaskSnapshot(Parcel source)2315         private TaskSnapshot(Parcel source) {
2316             mSnapshot = source.readParcelable(null /* classLoader */);
2317             mOrientation = source.readInt();
2318             mContentInsets = source.readParcelable(null /* classLoader */);
2319             mReducedResolution = source.readBoolean();
2320             mScale = source.readFloat();
2321         }
2322 
2323         /**
2324          * @return The graphic buffer representing the screenshot.
2325          */
getSnapshot()2326         public GraphicBuffer getSnapshot() {
2327             return mSnapshot;
2328         }
2329 
2330         /**
2331          * @return The screen orientation the screenshot was taken in.
2332          */
getOrientation()2333         public int getOrientation() {
2334             return mOrientation;
2335         }
2336 
2337         /**
2338          * @return The system/content insets on the snapshot. These can be clipped off in order to
2339          *         remove any areas behind system bars in the snapshot.
2340          */
getContentInsets()2341         public Rect getContentInsets() {
2342             return mContentInsets;
2343         }
2344 
2345         /**
2346          * @return Whether this snapshot is a down-sampled version of the full resolution.
2347          */
isReducedResolution()2348         public boolean isReducedResolution() {
2349             return mReducedResolution;
2350         }
2351 
2352         /**
2353          * @return The scale this snapshot was taken in.
2354          */
getScale()2355         public float getScale() {
2356             return mScale;
2357         }
2358 
2359         @Override
describeContents()2360         public int describeContents() {
2361             return 0;
2362         }
2363 
2364         @Override
writeToParcel(Parcel dest, int flags)2365         public void writeToParcel(Parcel dest, int flags) {
2366             dest.writeParcelable(mSnapshot, 0);
2367             dest.writeInt(mOrientation);
2368             dest.writeParcelable(mContentInsets, 0);
2369             dest.writeBoolean(mReducedResolution);
2370             dest.writeFloat(mScale);
2371         }
2372 
2373         @Override
toString()2374         public String toString() {
2375             return "TaskSnapshot{mSnapshot=" + mSnapshot + " mOrientation=" + mOrientation
2376                     + " mContentInsets=" + mContentInsets.toShortString()
2377                     + " mReducedResolution=" + mReducedResolution + " mScale=" + mScale;
2378         }
2379 
2380         public static final Creator<TaskSnapshot> CREATOR = new Creator<TaskSnapshot>() {
2381             public TaskSnapshot createFromParcel(Parcel source) {
2382                 return new TaskSnapshot(source);
2383             }
2384             public TaskSnapshot[] newArray(int size) {
2385                 return new TaskSnapshot[size];
2386             }
2387         };
2388     }
2389 
2390     /** @hide */
getTaskThumbnail(int id)2391     public TaskThumbnail getTaskThumbnail(int id) throws SecurityException {
2392         try {
2393             return getService().getTaskThumbnail(id);
2394         } catch (RemoteException e) {
2395             throw e.rethrowFromSystemServer();
2396         }
2397     }
2398 
2399     /** @hide */
2400     @IntDef(flag = true, prefix = { "MOVE_TASK_" }, value = {
2401             MOVE_TASK_WITH_HOME,
2402             MOVE_TASK_NO_USER_ACTION,
2403     })
2404     @Retention(RetentionPolicy.SOURCE)
2405     public @interface MoveTaskFlags {}
2406 
2407     /**
2408      * Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
2409      * activity along with the task, so it is positioned immediately behind
2410      * the task.
2411      */
2412     public static final int MOVE_TASK_WITH_HOME = 0x00000001;
2413 
2414     /**
2415      * Flag for {@link #moveTaskToFront(int, int)}: don't count this as a
2416      * user-instigated action, so the current activity will not receive a
2417      * hint that the user is leaving.
2418      */
2419     public static final int MOVE_TASK_NO_USER_ACTION = 0x00000002;
2420 
2421     /**
2422      * Equivalent to calling {@link #moveTaskToFront(int, int, Bundle)}
2423      * with a null options argument.
2424      *
2425      * @param taskId The identifier of the task to be moved, as found in
2426      * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
2427      * @param flags Additional operational flags.
2428      */
2429     @RequiresPermission(android.Manifest.permission.REORDER_TASKS)
moveTaskToFront(int taskId, @MoveTaskFlags int flags)2430     public void moveTaskToFront(int taskId, @MoveTaskFlags int flags) {
2431         moveTaskToFront(taskId, flags, null);
2432     }
2433 
2434     /**
2435      * Ask that the task associated with a given task ID be moved to the
2436      * front of the stack, so it is now visible to the user.
2437      *
2438      * @param taskId The identifier of the task to be moved, as found in
2439      * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
2440      * @param flags Additional operational flags.
2441      * @param options Additional options for the operation, either null or
2442      * as per {@link Context#startActivity(Intent, android.os.Bundle)
2443      * Context.startActivity(Intent, Bundle)}.
2444      */
2445     @RequiresPermission(android.Manifest.permission.REORDER_TASKS)
moveTaskToFront(int taskId, @MoveTaskFlags int flags, Bundle options)2446     public void moveTaskToFront(int taskId, @MoveTaskFlags int flags, Bundle options) {
2447         try {
2448             getService().moveTaskToFront(taskId, flags, options);
2449         } catch (RemoteException e) {
2450             throw e.rethrowFromSystemServer();
2451         }
2452     }
2453 
2454     /**
2455      * Information you can retrieve about a particular Service that is
2456      * currently running in the system.
2457      */
2458     public static class RunningServiceInfo implements Parcelable {
2459         /**
2460          * The service component.
2461          */
2462         public ComponentName service;
2463 
2464         /**
2465          * If non-zero, this is the process the service is running in.
2466          */
2467         public int pid;
2468 
2469         /**
2470          * The UID that owns this service.
2471          */
2472         public int uid;
2473 
2474         /**
2475          * The name of the process this service runs in.
2476          */
2477         public String process;
2478 
2479         /**
2480          * Set to true if the service has asked to run as a foreground process.
2481          */
2482         public boolean foreground;
2483 
2484         /**
2485          * The time when the service was first made active, either by someone
2486          * starting or binding to it.  This
2487          * is in units of {@link android.os.SystemClock#elapsedRealtime()}.
2488          */
2489         public long activeSince;
2490 
2491         /**
2492          * Set to true if this service has been explicitly started.
2493          */
2494         public boolean started;
2495 
2496         /**
2497          * Number of clients connected to the service.
2498          */
2499         public int clientCount;
2500 
2501         /**
2502          * Number of times the service's process has crashed while the service
2503          * is running.
2504          */
2505         public int crashCount;
2506 
2507         /**
2508          * The time when there was last activity in the service (either
2509          * explicit requests to start it or clients binding to it).  This
2510          * is in units of {@link android.os.SystemClock#uptimeMillis()}.
2511          */
2512         public long lastActivityTime;
2513 
2514         /**
2515          * If non-zero, this service is not currently running, but scheduled to
2516          * restart at the given time.
2517          */
2518         public long restarting;
2519 
2520         /**
2521          * Bit for {@link #flags}: set if this service has been
2522          * explicitly started.
2523          */
2524         public static final int FLAG_STARTED = 1<<0;
2525 
2526         /**
2527          * Bit for {@link #flags}: set if the service has asked to
2528          * run as a foreground process.
2529          */
2530         public static final int FLAG_FOREGROUND = 1<<1;
2531 
2532         /**
2533          * Bit for {@link #flags}: set if the service is running in a
2534          * core system process.
2535          */
2536         public static final int FLAG_SYSTEM_PROCESS = 1<<2;
2537 
2538         /**
2539          * Bit for {@link #flags}: set if the service is running in a
2540          * persistent process.
2541          */
2542         public static final int FLAG_PERSISTENT_PROCESS = 1<<3;
2543 
2544         /**
2545          * Running flags.
2546          */
2547         public int flags;
2548 
2549         /**
2550          * For special services that are bound to by system code, this is
2551          * the package that holds the binding.
2552          */
2553         public String clientPackage;
2554 
2555         /**
2556          * For special services that are bound to by system code, this is
2557          * a string resource providing a user-visible label for who the
2558          * client is.
2559          */
2560         public int clientLabel;
2561 
RunningServiceInfo()2562         public RunningServiceInfo() {
2563         }
2564 
describeContents()2565         public int describeContents() {
2566             return 0;
2567         }
2568 
writeToParcel(Parcel dest, int flags)2569         public void writeToParcel(Parcel dest, int flags) {
2570             ComponentName.writeToParcel(service, dest);
2571             dest.writeInt(pid);
2572             dest.writeInt(uid);
2573             dest.writeString(process);
2574             dest.writeInt(foreground ? 1 : 0);
2575             dest.writeLong(activeSince);
2576             dest.writeInt(started ? 1 : 0);
2577             dest.writeInt(clientCount);
2578             dest.writeInt(crashCount);
2579             dest.writeLong(lastActivityTime);
2580             dest.writeLong(restarting);
2581             dest.writeInt(this.flags);
2582             dest.writeString(clientPackage);
2583             dest.writeInt(clientLabel);
2584         }
2585 
readFromParcel(Parcel source)2586         public void readFromParcel(Parcel source) {
2587             service = ComponentName.readFromParcel(source);
2588             pid = source.readInt();
2589             uid = source.readInt();
2590             process = source.readString();
2591             foreground = source.readInt() != 0;
2592             activeSince = source.readLong();
2593             started = source.readInt() != 0;
2594             clientCount = source.readInt();
2595             crashCount = source.readInt();
2596             lastActivityTime = source.readLong();
2597             restarting = source.readLong();
2598             flags = source.readInt();
2599             clientPackage = source.readString();
2600             clientLabel = source.readInt();
2601         }
2602 
2603         public static final Creator<RunningServiceInfo> CREATOR = new Creator<RunningServiceInfo>() {
2604             public RunningServiceInfo createFromParcel(Parcel source) {
2605                 return new RunningServiceInfo(source);
2606             }
2607             public RunningServiceInfo[] newArray(int size) {
2608                 return new RunningServiceInfo[size];
2609             }
2610         };
2611 
RunningServiceInfo(Parcel source)2612         private RunningServiceInfo(Parcel source) {
2613             readFromParcel(source);
2614         }
2615     }
2616 
2617     /**
2618      * Return a list of the services that are currently running.
2619      *
2620      * <p><b>Note: this method is only intended for debugging or implementing
2621      * service management type user interfaces.</b></p>
2622      *
2623      * @deprecated As of {@link android.os.Build.VERSION_CODES#O}, this method
2624      * is no longer available to third party applications.  For backwards compatibility,
2625      * it will still return the caller's own services.
2626      *
2627      * @param maxNum The maximum number of entries to return in the list.  The
2628      * actual number returned may be smaller, depending on how many services
2629      * are running.
2630      *
2631      * @return Returns a list of RunningServiceInfo records describing each of
2632      * the running tasks.
2633      */
2634     @Deprecated
getRunningServices(int maxNum)2635     public List<RunningServiceInfo> getRunningServices(int maxNum)
2636             throws SecurityException {
2637         try {
2638             return getService()
2639                     .getServices(maxNum, 0);
2640         } catch (RemoteException e) {
2641             throw e.rethrowFromSystemServer();
2642         }
2643     }
2644 
2645     /**
2646      * Returns a PendingIntent you can start to show a control panel for the
2647      * given running service.  If the service does not have a control panel,
2648      * null is returned.
2649      */
getRunningServiceControlPanel(ComponentName service)2650     public PendingIntent getRunningServiceControlPanel(ComponentName service)
2651             throws SecurityException {
2652         try {
2653             return getService()
2654                     .getRunningServiceControlPanel(service);
2655         } catch (RemoteException e) {
2656             throw e.rethrowFromSystemServer();
2657         }
2658     }
2659 
2660     /**
2661      * Information you can retrieve about the available memory through
2662      * {@link ActivityManager#getMemoryInfo}.
2663      */
2664     public static class MemoryInfo implements Parcelable {
2665         /**
2666          * The available memory on the system.  This number should not
2667          * be considered absolute: due to the nature of the kernel, a significant
2668          * portion of this memory is actually in use and needed for the overall
2669          * system to run well.
2670          */
2671         public long availMem;
2672 
2673         /**
2674          * The total memory accessible by the kernel.  This is basically the
2675          * RAM size of the device, not including below-kernel fixed allocations
2676          * like DMA buffers, RAM for the baseband CPU, etc.
2677          */
2678         public long totalMem;
2679 
2680         /**
2681          * The threshold of {@link #availMem} at which we consider memory to be
2682          * low and start killing background services and other non-extraneous
2683          * processes.
2684          */
2685         public long threshold;
2686 
2687         /**
2688          * Set to true if the system considers itself to currently be in a low
2689          * memory situation.
2690          */
2691         public boolean lowMemory;
2692 
2693         /** @hide */
2694         public long hiddenAppThreshold;
2695         /** @hide */
2696         public long secondaryServerThreshold;
2697         /** @hide */
2698         public long visibleAppThreshold;
2699         /** @hide */
2700         public long foregroundAppThreshold;
2701 
MemoryInfo()2702         public MemoryInfo() {
2703         }
2704 
describeContents()2705         public int describeContents() {
2706             return 0;
2707         }
2708 
writeToParcel(Parcel dest, int flags)2709         public void writeToParcel(Parcel dest, int flags) {
2710             dest.writeLong(availMem);
2711             dest.writeLong(totalMem);
2712             dest.writeLong(threshold);
2713             dest.writeInt(lowMemory ? 1 : 0);
2714             dest.writeLong(hiddenAppThreshold);
2715             dest.writeLong(secondaryServerThreshold);
2716             dest.writeLong(visibleAppThreshold);
2717             dest.writeLong(foregroundAppThreshold);
2718         }
2719 
readFromParcel(Parcel source)2720         public void readFromParcel(Parcel source) {
2721             availMem = source.readLong();
2722             totalMem = source.readLong();
2723             threshold = source.readLong();
2724             lowMemory = source.readInt() != 0;
2725             hiddenAppThreshold = source.readLong();
2726             secondaryServerThreshold = source.readLong();
2727             visibleAppThreshold = source.readLong();
2728             foregroundAppThreshold = source.readLong();
2729         }
2730 
2731         public static final Creator<MemoryInfo> CREATOR
2732                 = new Creator<MemoryInfo>() {
2733             public MemoryInfo createFromParcel(Parcel source) {
2734                 return new MemoryInfo(source);
2735             }
2736             public MemoryInfo[] newArray(int size) {
2737                 return new MemoryInfo[size];
2738             }
2739         };
2740 
MemoryInfo(Parcel source)2741         private MemoryInfo(Parcel source) {
2742             readFromParcel(source);
2743         }
2744     }
2745 
2746     /**
2747      * Return general information about the memory state of the system.  This
2748      * can be used to help decide how to manage your own memory, though note
2749      * that polling is not recommended and
2750      * {@link android.content.ComponentCallbacks2#onTrimMemory(int)
2751      * ComponentCallbacks2.onTrimMemory(int)} is the preferred way to do this.
2752      * Also see {@link #getMyMemoryState} for how to retrieve the current trim
2753      * level of your process as needed, which gives a better hint for how to
2754      * manage its memory.
2755      */
getMemoryInfo(MemoryInfo outInfo)2756     public void getMemoryInfo(MemoryInfo outInfo) {
2757         try {
2758             getService().getMemoryInfo(outInfo);
2759         } catch (RemoteException e) {
2760             throw e.rethrowFromSystemServer();
2761         }
2762     }
2763 
2764     /**
2765      * Information you can retrieve about an ActivityStack in the system.
2766      * @hide
2767      */
2768     public static class StackInfo implements Parcelable {
2769         public int stackId;
2770         public Rect bounds = new Rect();
2771         public int[] taskIds;
2772         public String[] taskNames;
2773         public Rect[] taskBounds;
2774         public int[] taskUserIds;
2775         public ComponentName topActivity;
2776         public int displayId;
2777         public int userId;
2778         public boolean visible;
2779         // Index of the stack in the display's stack list, can be used for comparison of stack order
2780         public int position;
2781 
2782         @Override
describeContents()2783         public int describeContents() {
2784             return 0;
2785         }
2786 
2787         @Override
writeToParcel(Parcel dest, int flags)2788         public void writeToParcel(Parcel dest, int flags) {
2789             dest.writeInt(stackId);
2790             dest.writeInt(bounds.left);
2791             dest.writeInt(bounds.top);
2792             dest.writeInt(bounds.right);
2793             dest.writeInt(bounds.bottom);
2794             dest.writeIntArray(taskIds);
2795             dest.writeStringArray(taskNames);
2796             final int boundsCount = taskBounds == null ? 0 : taskBounds.length;
2797             dest.writeInt(boundsCount);
2798             for (int i = 0; i < boundsCount; i++) {
2799                 dest.writeInt(taskBounds[i].left);
2800                 dest.writeInt(taskBounds[i].top);
2801                 dest.writeInt(taskBounds[i].right);
2802                 dest.writeInt(taskBounds[i].bottom);
2803             }
2804             dest.writeIntArray(taskUserIds);
2805             dest.writeInt(displayId);
2806             dest.writeInt(userId);
2807             dest.writeInt(visible ? 1 : 0);
2808             dest.writeInt(position);
2809             if (topActivity != null) {
2810                 dest.writeInt(1);
2811                 topActivity.writeToParcel(dest, 0);
2812             } else {
2813                 dest.writeInt(0);
2814             }
2815         }
2816 
readFromParcel(Parcel source)2817         public void readFromParcel(Parcel source) {
2818             stackId = source.readInt();
2819             bounds = new Rect(
2820                     source.readInt(), source.readInt(), source.readInt(), source.readInt());
2821             taskIds = source.createIntArray();
2822             taskNames = source.createStringArray();
2823             final int boundsCount = source.readInt();
2824             if (boundsCount > 0) {
2825                 taskBounds = new Rect[boundsCount];
2826                 for (int i = 0; i < boundsCount; i++) {
2827                     taskBounds[i] = new Rect();
2828                     taskBounds[i].set(
2829                             source.readInt(), source.readInt(), source.readInt(), source.readInt());
2830                 }
2831             } else {
2832                 taskBounds = null;
2833             }
2834             taskUserIds = source.createIntArray();
2835             displayId = source.readInt();
2836             userId = source.readInt();
2837             visible = source.readInt() > 0;
2838             position = source.readInt();
2839             if (source.readInt() > 0) {
2840                 topActivity = ComponentName.readFromParcel(source);
2841             }
2842         }
2843 
2844         public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
2845             @Override
2846             public StackInfo createFromParcel(Parcel source) {
2847                 return new StackInfo(source);
2848             }
2849             @Override
2850             public StackInfo[] newArray(int size) {
2851                 return new StackInfo[size];
2852             }
2853         };
2854 
StackInfo()2855         public StackInfo() {
2856         }
2857 
StackInfo(Parcel source)2858         private StackInfo(Parcel source) {
2859             readFromParcel(source);
2860         }
2861 
toString(String prefix)2862         public String toString(String prefix) {
2863             StringBuilder sb = new StringBuilder(256);
2864             sb.append(prefix); sb.append("Stack id="); sb.append(stackId);
2865                     sb.append(" bounds="); sb.append(bounds.toShortString());
2866                     sb.append(" displayId="); sb.append(displayId);
2867                     sb.append(" userId="); sb.append(userId);
2868                     sb.append("\n");
2869             prefix = prefix + "  ";
2870             for (int i = 0; i < taskIds.length; ++i) {
2871                 sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
2872                         sb.append(": "); sb.append(taskNames[i]);
2873                         if (taskBounds != null) {
2874                             sb.append(" bounds="); sb.append(taskBounds[i].toShortString());
2875                         }
2876                         sb.append(" userId=").append(taskUserIds[i]);
2877                         sb.append(" visible=").append(visible);
2878                         if (topActivity != null) {
2879                             sb.append(" topActivity=").append(topActivity);
2880                         }
2881                         sb.append("\n");
2882             }
2883             return sb.toString();
2884         }
2885 
2886         @Override
toString()2887         public String toString() {
2888             return toString("");
2889         }
2890     }
2891 
2892     /**
2893      * @hide
2894      */
clearApplicationUserData(String packageName, IPackageDataObserver observer)2895     public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) {
2896         try {
2897             return getService().clearApplicationUserData(packageName,
2898                     observer, UserHandle.myUserId());
2899         } catch (RemoteException e) {
2900             throw e.rethrowFromSystemServer();
2901         }
2902     }
2903 
2904     /**
2905      * Permits an application to erase its own data from disk.  This is equivalent to
2906      * the user choosing to clear the app's data from within the device settings UI.  It
2907      * erases all dynamic data associated with the app -- its private data and data in its
2908      * private area on external storage -- but does not remove the installed application
2909      * itself, nor any OBB files.
2910      *
2911      * @return {@code true} if the application successfully requested that the application's
2912      *     data be erased; {@code false} otherwise.
2913      */
clearApplicationUserData()2914     public boolean clearApplicationUserData() {
2915         return clearApplicationUserData(mContext.getPackageName(), null);
2916     }
2917 
2918 
2919     /**
2920      * Permits an application to get the persistent URI permissions granted to another.
2921      *
2922      * <p>Typically called by Settings.
2923      *
2924      * @param packageName application to look for the granted permissions
2925      * @return list of granted URI permissions
2926      *
2927      * @hide
2928      */
getGrantedUriPermissions(String packageName)2929     public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName) {
2930         try {
2931             return getService().getGrantedUriPermissions(packageName,
2932                     UserHandle.myUserId());
2933         } catch (RemoteException e) {
2934             throw e.rethrowFromSystemServer();
2935         }
2936     }
2937 
2938     /**
2939      * Permits an application to clear the persistent URI permissions granted to another.
2940      *
2941      * <p>Typically called by Settings.
2942      *
2943      * @param packageName application to clear its granted permissions
2944      *
2945      * @hide
2946      */
clearGrantedUriPermissions(String packageName)2947     public void clearGrantedUriPermissions(String packageName) {
2948         try {
2949             getService().clearGrantedUriPermissions(packageName,
2950                     UserHandle.myUserId());
2951         } catch (RemoteException e) {
2952             throw e.rethrowFromSystemServer();
2953         }
2954     }
2955 
2956     /**
2957      * Information you can retrieve about any processes that are in an error condition.
2958      */
2959     public static class ProcessErrorStateInfo implements Parcelable {
2960         /**
2961          * Condition codes
2962          */
2963         public static final int NO_ERROR = 0;
2964         public static final int CRASHED = 1;
2965         public static final int NOT_RESPONDING = 2;
2966 
2967         /**
2968          * The condition that the process is in.
2969          */
2970         public int condition;
2971 
2972         /**
2973          * The process name in which the crash or error occurred.
2974          */
2975         public String processName;
2976 
2977         /**
2978          * The pid of this process; 0 if none
2979          */
2980         public int pid;
2981 
2982         /**
2983          * The kernel user-ID that has been assigned to this process;
2984          * currently this is not a unique ID (multiple applications can have
2985          * the same uid).
2986          */
2987         public int uid;
2988 
2989         /**
2990          * The activity name associated with the error, if known.  May be null.
2991          */
2992         public String tag;
2993 
2994         /**
2995          * A short message describing the error condition.
2996          */
2997         public String shortMsg;
2998 
2999         /**
3000          * A long message describing the error condition.
3001          */
3002         public String longMsg;
3003 
3004         /**
3005          * The stack trace where the error originated.  May be null.
3006          */
3007         public String stackTrace;
3008 
3009         /**
3010          * to be deprecated: This value will always be null.
3011          */
3012         public byte[] crashData = null;
3013 
ProcessErrorStateInfo()3014         public ProcessErrorStateInfo() {
3015         }
3016 
3017         @Override
describeContents()3018         public int describeContents() {
3019             return 0;
3020         }
3021 
3022         @Override
writeToParcel(Parcel dest, int flags)3023         public void writeToParcel(Parcel dest, int flags) {
3024             dest.writeInt(condition);
3025             dest.writeString(processName);
3026             dest.writeInt(pid);
3027             dest.writeInt(uid);
3028             dest.writeString(tag);
3029             dest.writeString(shortMsg);
3030             dest.writeString(longMsg);
3031             dest.writeString(stackTrace);
3032         }
3033 
readFromParcel(Parcel source)3034         public void readFromParcel(Parcel source) {
3035             condition = source.readInt();
3036             processName = source.readString();
3037             pid = source.readInt();
3038             uid = source.readInt();
3039             tag = source.readString();
3040             shortMsg = source.readString();
3041             longMsg = source.readString();
3042             stackTrace = source.readString();
3043         }
3044 
3045         public static final Creator<ProcessErrorStateInfo> CREATOR =
3046                 new Creator<ProcessErrorStateInfo>() {
3047             public ProcessErrorStateInfo createFromParcel(Parcel source) {
3048                 return new ProcessErrorStateInfo(source);
3049             }
3050             public ProcessErrorStateInfo[] newArray(int size) {
3051                 return new ProcessErrorStateInfo[size];
3052             }
3053         };
3054 
ProcessErrorStateInfo(Parcel source)3055         private ProcessErrorStateInfo(Parcel source) {
3056             readFromParcel(source);
3057         }
3058     }
3059 
3060     /**
3061      * Returns a list of any processes that are currently in an error condition.  The result
3062      * will be null if all processes are running properly at this time.
3063      *
3064      * @return Returns a list of ProcessErrorStateInfo records, or null if there are no
3065      * current error conditions (it will not return an empty list).  This list ordering is not
3066      * specified.
3067      */
getProcessesInErrorState()3068     public List<ProcessErrorStateInfo> getProcessesInErrorState() {
3069         try {
3070             return getService().getProcessesInErrorState();
3071         } catch (RemoteException e) {
3072             throw e.rethrowFromSystemServer();
3073         }
3074     }
3075 
3076     /**
3077      * Information you can retrieve about a running process.
3078      */
3079     public static class RunningAppProcessInfo implements Parcelable {
3080         /**
3081          * The name of the process that this object is associated with
3082          */
3083         public String processName;
3084 
3085         /**
3086          * The pid of this process; 0 if none
3087          */
3088         public int pid;
3089 
3090         /**
3091          * The user id of this process.
3092          */
3093         public int uid;
3094 
3095         /**
3096          * All packages that have been loaded into the process.
3097          */
3098         public String pkgList[];
3099 
3100         /**
3101          * Constant for {@link #flags}: this is an app that is unable to
3102          * correctly save its state when going to the background,
3103          * so it can not be killed while in the background.
3104          * @hide
3105          */
3106         public static final int FLAG_CANT_SAVE_STATE = 1<<0;
3107 
3108         /**
3109          * Constant for {@link #flags}: this process is associated with a
3110          * persistent system app.
3111          * @hide
3112          */
3113         public static final int FLAG_PERSISTENT = 1<<1;
3114 
3115         /**
3116          * Constant for {@link #flags}: this process is associated with a
3117          * persistent system app.
3118          * @hide
3119          */
3120         public static final int FLAG_HAS_ACTIVITIES = 1<<2;
3121 
3122         /**
3123          * Flags of information.  May be any of
3124          * {@link #FLAG_CANT_SAVE_STATE}.
3125          * @hide
3126          */
3127         public int flags;
3128 
3129         /**
3130          * Last memory trim level reported to the process: corresponds to
3131          * the values supplied to {@link android.content.ComponentCallbacks2#onTrimMemory(int)
3132          * ComponentCallbacks2.onTrimMemory(int)}.
3133          */
3134         public int lastTrimLevel;
3135 
3136         /** @hide */
3137         @IntDef(prefix = { "IMPORTANCE_" }, value = {
3138                 IMPORTANCE_FOREGROUND,
3139                 IMPORTANCE_FOREGROUND_SERVICE,
3140                 IMPORTANCE_TOP_SLEEPING,
3141                 IMPORTANCE_VISIBLE,
3142                 IMPORTANCE_PERCEPTIBLE,
3143                 IMPORTANCE_CANT_SAVE_STATE,
3144                 IMPORTANCE_SERVICE,
3145                 IMPORTANCE_CACHED,
3146                 IMPORTANCE_GONE,
3147         })
3148         @Retention(RetentionPolicy.SOURCE)
3149         public @interface Importance {}
3150 
3151         /**
3152          * Constant for {@link #importance}: This process is running the
3153          * foreground UI; that is, it is the thing currently at the top of the screen
3154          * that the user is interacting with.
3155          */
3156         public static final int IMPORTANCE_FOREGROUND = 100;
3157 
3158         /**
3159          * Constant for {@link #importance}: This process is running a foreground
3160          * service, for example to perform music playback even while the user is
3161          * not immediately in the app.  This generally indicates that the process
3162          * is doing something the user actively cares about.
3163          */
3164         public static final int IMPORTANCE_FOREGROUND_SERVICE = 125;
3165 
3166         /**
3167          * Constant for {@link #importance}: This process is running the foreground
3168          * UI, but the device is asleep so it is not visible to the user.  This means
3169          * the user is not really aware of the process, because they can not see or
3170          * interact with it, but it is quite important because it what they expect to
3171          * return to once unlocking the device.
3172          */
3173         public static final int IMPORTANCE_TOP_SLEEPING = 150;
3174 
3175         /**
3176          * Constant for {@link #importance}: This process is running something
3177          * that is actively visible to the user, though not in the immediate
3178          * foreground.  This may be running a window that is behind the current
3179          * foreground (so paused and with its state saved, not interacting with
3180          * the user, but visible to them to some degree); it may also be running
3181          * other services under the system's control that it inconsiders important.
3182          */
3183         public static final int IMPORTANCE_VISIBLE = 200;
3184 
3185         /**
3186          * Constant for {@link #importance}: {@link #IMPORTANCE_PERCEPTIBLE} had this wrong value
3187          * before {@link Build.VERSION_CODES#O}.  Since the {@link Build.VERSION_CODES#O} SDK,
3188          * the value of {@link #IMPORTANCE_PERCEPTIBLE} has been fixed.
3189          *
3190          * <p>The system will return this value instead of {@link #IMPORTANCE_PERCEPTIBLE}
3191          * on Android versions below {@link Build.VERSION_CODES#O}.
3192          *
3193          * <p>On Android version {@link Build.VERSION_CODES#O} and later, this value will still be
3194          * returned for apps with the target API level below {@link Build.VERSION_CODES#O}.
3195          * For apps targeting version {@link Build.VERSION_CODES#O} and later,
3196          * the correct value {@link #IMPORTANCE_PERCEPTIBLE} will be returned.
3197          */
3198         public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;
3199 
3200         /**
3201          * Constant for {@link #importance}: This process is not something the user
3202          * is directly aware of, but is otherwise perceptible to them to some degree.
3203          */
3204         public static final int IMPORTANCE_PERCEPTIBLE = 230;
3205 
3206         /**
3207          * Constant for {@link #importance}: {@link #IMPORTANCE_CANT_SAVE_STATE} had
3208          * this wrong value
3209          * before {@link Build.VERSION_CODES#O}.  Since the {@link Build.VERSION_CODES#O} SDK,
3210          * the value of {@link #IMPORTANCE_CANT_SAVE_STATE} has been fixed.
3211          *
3212          * <p>The system will return this value instead of {@link #IMPORTANCE_CANT_SAVE_STATE}
3213          * on Android versions below {@link Build.VERSION_CODES#O}.
3214          *
3215          * <p>On Android version {@link Build.VERSION_CODES#O} after, this value will still be
3216          * returned for apps with the target API level below {@link Build.VERSION_CODES#O}.
3217          * For apps targeting version {@link Build.VERSION_CODES#O} and later,
3218          * the correct value {@link #IMPORTANCE_CANT_SAVE_STATE} will be returned.
3219          *
3220          * @hide
3221          */
3222         public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
3223 
3224         /**
3225          * Constant for {@link #importance}: This process is running an
3226          * application that can not save its state, and thus can't be killed
3227          * while in the background.
3228          * @hide
3229          */
3230         public static final int IMPORTANCE_CANT_SAVE_STATE= 270;
3231 
3232         /**
3233          * Constant for {@link #importance}: This process is contains services
3234          * that should remain running.  These are background services apps have
3235          * started, not something the user is aware of, so they may be killed by
3236          * the system relatively freely (though it is generally desired that they
3237          * stay running as long as they want to).
3238          */
3239         public static final int IMPORTANCE_SERVICE = 300;
3240 
3241         /**
3242          * Constant for {@link #importance}: This process process contains
3243          * cached code that is expendable, not actively running any app components
3244          * we care about.
3245          */
3246         public static final int IMPORTANCE_CACHED = 400;
3247 
3248         /**
3249          * @deprecated Renamed to {@link #IMPORTANCE_CACHED}.
3250          */
3251         public static final int IMPORTANCE_BACKGROUND = IMPORTANCE_CACHED;
3252 
3253         /**
3254          * Constant for {@link #importance}: This process is empty of any
3255          * actively running code.
3256          * @deprecated This value is no longer reported, use {@link #IMPORTANCE_CACHED} instead.
3257          */
3258         @Deprecated
3259         public static final int IMPORTANCE_EMPTY = 500;
3260 
3261         /**
3262          * Constant for {@link #importance}: This process does not exist.
3263          */
3264         public static final int IMPORTANCE_GONE = 1000;
3265 
3266         /**
3267          * Convert a proc state to the correspondent IMPORTANCE_* constant.  If the return value
3268          * will be passed to a client, use {@link #procStateToImportanceForClient}.
3269          * @hide
3270          */
procStateToImportance(int procState)3271         public static @Importance int procStateToImportance(int procState) {
3272             if (procState == PROCESS_STATE_NONEXISTENT) {
3273                 return IMPORTANCE_GONE;
3274             } else if (procState >= PROCESS_STATE_HOME) {
3275                 return IMPORTANCE_CACHED;
3276             } else if (procState >= PROCESS_STATE_SERVICE) {
3277                 return IMPORTANCE_SERVICE;
3278             } else if (procState > PROCESS_STATE_HEAVY_WEIGHT) {
3279                 return IMPORTANCE_CANT_SAVE_STATE;
3280             } else if (procState >= PROCESS_STATE_TRANSIENT_BACKGROUND) {
3281                 return IMPORTANCE_PERCEPTIBLE;
3282             } else if (procState >= PROCESS_STATE_IMPORTANT_FOREGROUND) {
3283                 return IMPORTANCE_VISIBLE;
3284             } else if (procState >= PROCESS_STATE_TOP_SLEEPING) {
3285                 return IMPORTANCE_TOP_SLEEPING;
3286             } else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE) {
3287                 return IMPORTANCE_FOREGROUND_SERVICE;
3288             } else {
3289                 return IMPORTANCE_FOREGROUND;
3290             }
3291         }
3292 
3293         /**
3294          * Convert a proc state to the correspondent IMPORTANCE_* constant for a client represented
3295          * by a given {@link Context}, with converting {@link #IMPORTANCE_PERCEPTIBLE}
3296          * and {@link #IMPORTANCE_CANT_SAVE_STATE} to the corresponding "wrong" value if the
3297          * client's target SDK < {@link VERSION_CODES#O}.
3298          * @hide
3299          */
procStateToImportanceForClient(int procState, Context clientContext)3300         public static @Importance int procStateToImportanceForClient(int procState,
3301                 Context clientContext) {
3302             return procStateToImportanceForTargetSdk(procState,
3303                     clientContext.getApplicationInfo().targetSdkVersion);
3304         }
3305 
3306         /**
3307          * See {@link #procStateToImportanceForClient}.
3308          * @hide
3309          */
procStateToImportanceForTargetSdk(int procState, int targetSdkVersion)3310         public static @Importance int procStateToImportanceForTargetSdk(int procState,
3311                 int targetSdkVersion) {
3312             final int importance = procStateToImportance(procState);
3313 
3314             // For pre O apps, convert to the old, wrong values.
3315             if (targetSdkVersion < VERSION_CODES.O) {
3316                 switch (importance) {
3317                     case IMPORTANCE_PERCEPTIBLE:
3318                         return IMPORTANCE_PERCEPTIBLE_PRE_26;
3319                     case IMPORTANCE_CANT_SAVE_STATE:
3320                         return IMPORTANCE_CANT_SAVE_STATE_PRE_26;
3321                 }
3322             }
3323             return importance;
3324         }
3325 
3326         /** @hide */
importanceToProcState(@mportance int importance)3327         public static int importanceToProcState(@Importance int importance) {
3328             if (importance == IMPORTANCE_GONE) {
3329                 return PROCESS_STATE_NONEXISTENT;
3330             } else if (importance >= IMPORTANCE_CACHED) {
3331                 return PROCESS_STATE_HOME;
3332             } else if (importance >= IMPORTANCE_SERVICE) {
3333                 return PROCESS_STATE_SERVICE;
3334             } else if (importance > IMPORTANCE_CANT_SAVE_STATE) {
3335                 return PROCESS_STATE_HEAVY_WEIGHT;
3336             } else if (importance >= IMPORTANCE_PERCEPTIBLE) {
3337                 return PROCESS_STATE_TRANSIENT_BACKGROUND;
3338             } else if (importance >= IMPORTANCE_VISIBLE) {
3339                 return PROCESS_STATE_IMPORTANT_FOREGROUND;
3340             } else if (importance >= IMPORTANCE_TOP_SLEEPING) {
3341                 return PROCESS_STATE_TOP_SLEEPING;
3342             } else if (importance >= IMPORTANCE_FOREGROUND_SERVICE) {
3343                 return PROCESS_STATE_FOREGROUND_SERVICE;
3344             } else {
3345                 return PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
3346             }
3347         }
3348 
3349         /**
3350          * The relative importance level that the system places on this process.
3351          * These constants are numbered so that "more important" values are
3352          * always smaller than "less important" values.
3353          */
3354         public @Importance int importance;
3355 
3356         /**
3357          * An additional ordering within a particular {@link #importance}
3358          * category, providing finer-grained information about the relative
3359          * utility of processes within a category.  This number means nothing
3360          * except that a smaller values are more recently used (and thus
3361          * more important).  Currently an LRU value is only maintained for
3362          * the {@link #IMPORTANCE_CACHED} category, though others may
3363          * be maintained in the future.
3364          */
3365         public int lru;
3366 
3367         /**
3368          * Constant for {@link #importanceReasonCode}: nothing special has
3369          * been specified for the reason for this level.
3370          */
3371         public static final int REASON_UNKNOWN = 0;
3372 
3373         /**
3374          * Constant for {@link #importanceReasonCode}: one of the application's
3375          * content providers is being used by another process.  The pid of
3376          * the client process is in {@link #importanceReasonPid} and the
3377          * target provider in this process is in
3378          * {@link #importanceReasonComponent}.
3379          */
3380         public static final int REASON_PROVIDER_IN_USE = 1;
3381 
3382         /**
3383          * Constant for {@link #importanceReasonCode}: one of the application's
3384          * content providers is being used by another process.  The pid of
3385          * the client process is in {@link #importanceReasonPid} and the
3386          * target provider in this process is in
3387          * {@link #importanceReasonComponent}.
3388          */
3389         public static final int REASON_SERVICE_IN_USE = 2;
3390 
3391         /**
3392          * The reason for {@link #importance}, if any.
3393          */
3394         public int importanceReasonCode;
3395 
3396         /**
3397          * For the specified values of {@link #importanceReasonCode}, this
3398          * is the process ID of the other process that is a client of this
3399          * process.  This will be 0 if no other process is using this one.
3400          */
3401         public int importanceReasonPid;
3402 
3403         /**
3404          * For the specified values of {@link #importanceReasonCode}, this
3405          * is the name of the component that is being used in this process.
3406          */
3407         public ComponentName importanceReasonComponent;
3408 
3409         /**
3410          * When {@link #importanceReasonPid} is non-0, this is the importance
3411          * of the other pid. @hide
3412          */
3413         public int importanceReasonImportance;
3414 
3415         /**
3416          * Current process state, as per PROCESS_STATE_* constants.
3417          * @hide
3418          */
3419         public int processState;
3420 
RunningAppProcessInfo()3421         public RunningAppProcessInfo() {
3422             importance = IMPORTANCE_FOREGROUND;
3423             importanceReasonCode = REASON_UNKNOWN;
3424             processState = PROCESS_STATE_IMPORTANT_FOREGROUND;
3425         }
3426 
RunningAppProcessInfo(String pProcessName, int pPid, String pArr[])3427         public RunningAppProcessInfo(String pProcessName, int pPid, String pArr[]) {
3428             processName = pProcessName;
3429             pid = pPid;
3430             pkgList = pArr;
3431         }
3432 
describeContents()3433         public int describeContents() {
3434             return 0;
3435         }
3436 
writeToParcel(Parcel dest, int flags)3437         public void writeToParcel(Parcel dest, int flags) {
3438             dest.writeString(processName);
3439             dest.writeInt(pid);
3440             dest.writeInt(uid);
3441             dest.writeStringArray(pkgList);
3442             dest.writeInt(this.flags);
3443             dest.writeInt(lastTrimLevel);
3444             dest.writeInt(importance);
3445             dest.writeInt(lru);
3446             dest.writeInt(importanceReasonCode);
3447             dest.writeInt(importanceReasonPid);
3448             ComponentName.writeToParcel(importanceReasonComponent, dest);
3449             dest.writeInt(importanceReasonImportance);
3450             dest.writeInt(processState);
3451         }
3452 
readFromParcel(Parcel source)3453         public void readFromParcel(Parcel source) {
3454             processName = source.readString();
3455             pid = source.readInt();
3456             uid = source.readInt();
3457             pkgList = source.readStringArray();
3458             flags = source.readInt();
3459             lastTrimLevel = source.readInt();
3460             importance = source.readInt();
3461             lru = source.readInt();
3462             importanceReasonCode = source.readInt();
3463             importanceReasonPid = source.readInt();
3464             importanceReasonComponent = ComponentName.readFromParcel(source);
3465             importanceReasonImportance = source.readInt();
3466             processState = source.readInt();
3467         }
3468 
3469         public static final Creator<RunningAppProcessInfo> CREATOR =
3470             new Creator<RunningAppProcessInfo>() {
3471             public RunningAppProcessInfo createFromParcel(Parcel source) {
3472                 return new RunningAppProcessInfo(source);
3473             }
3474             public RunningAppProcessInfo[] newArray(int size) {
3475                 return new RunningAppProcessInfo[size];
3476             }
3477         };
3478 
RunningAppProcessInfo(Parcel source)3479         private RunningAppProcessInfo(Parcel source) {
3480             readFromParcel(source);
3481         }
3482     }
3483 
3484     /**
3485      * Returns a list of application processes installed on external media
3486      * that are running on the device.
3487      *
3488      * <p><b>Note: this method is only intended for debugging or building
3489      * a user-facing process management UI.</b></p>
3490      *
3491      * @return Returns a list of ApplicationInfo records, or null if none
3492      * This list ordering is not specified.
3493      * @hide
3494      */
getRunningExternalApplications()3495     public List<ApplicationInfo> getRunningExternalApplications() {
3496         try {
3497             return getService().getRunningExternalApplications();
3498         } catch (RemoteException e) {
3499             throw e.rethrowFromSystemServer();
3500         }
3501     }
3502 
3503     /**
3504      * Sets the memory trim mode for a process and schedules a memory trim operation.
3505      *
3506      * <p><b>Note: this method is only intended for testing framework.</b></p>
3507      *
3508      * @return Returns true if successful.
3509      * @hide
3510      */
setProcessMemoryTrimLevel(String process, int userId, int level)3511     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3512         try {
3513             return getService().setProcessMemoryTrimLevel(process, userId,
3514                     level);
3515         } catch (RemoteException e) {
3516             throw e.rethrowFromSystemServer();
3517         }
3518     }
3519 
3520     /**
3521      * Returns a list of application processes that are running on the device.
3522      *
3523      * <p><b>Note: this method is only intended for debugging or building
3524      * a user-facing process management UI.</b></p>
3525      *
3526      * @return Returns a list of RunningAppProcessInfo records, or null if there are no
3527      * running processes (it will not return an empty list).  This list ordering is not
3528      * specified.
3529      */
getRunningAppProcesses()3530     public List<RunningAppProcessInfo> getRunningAppProcesses() {
3531         try {
3532             return getService().getRunningAppProcesses();
3533         } catch (RemoteException e) {
3534             throw e.rethrowFromSystemServer();
3535         }
3536     }
3537 
3538     /**
3539      * Return the importance of a given package name, based on the processes that are
3540      * currently running.  The return value is one of the importance constants defined
3541      * in {@link RunningAppProcessInfo}, giving you the highest importance of all the
3542      * processes that this package has code running inside of.  If there are no processes
3543      * running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
3544      * @hide
3545      */
3546     @SystemApi @TestApi
3547     @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
getPackageImportance(String packageName)3548     public @RunningAppProcessInfo.Importance int getPackageImportance(String packageName) {
3549         try {
3550             int procState = getService().getPackageProcessState(packageName,
3551                     mContext.getOpPackageName());
3552             return RunningAppProcessInfo.procStateToImportanceForClient(procState, mContext);
3553         } catch (RemoteException e) {
3554             throw e.rethrowFromSystemServer();
3555         }
3556     }
3557 
3558     /**
3559      * Return the importance of a given uid, based on the processes that are
3560      * currently running.  The return value is one of the importance constants defined
3561      * in {@link RunningAppProcessInfo}, giving you the highest importance of all the
3562      * processes that this uid has running.  If there are no processes
3563      * running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
3564      * @hide
3565      */
3566     @SystemApi @TestApi
3567     @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
getUidImportance(int uid)3568     public @RunningAppProcessInfo.Importance int getUidImportance(int uid) {
3569         try {
3570             int procState = getService().getUidProcessState(uid,
3571                     mContext.getOpPackageName());
3572             return RunningAppProcessInfo.procStateToImportanceForClient(procState, mContext);
3573         } catch (RemoteException e) {
3574             throw e.rethrowFromSystemServer();
3575         }
3576     }
3577 
3578     /**
3579      * Callback to get reports about changes to the importance of a uid.  Use with
3580      * {@link #addOnUidImportanceListener}.
3581      * @hide
3582      */
3583     @SystemApi @TestApi
3584     public interface OnUidImportanceListener {
3585         /**
3586          * The importance if a given uid has changed.  Will be one of the importance
3587          * values in {@link RunningAppProcessInfo};
3588          * {@link RunningAppProcessInfo#IMPORTANCE_GONE IMPORTANCE_GONE} will be reported
3589          * when the uid is no longer running at all.  This callback will happen on a thread
3590          * from a thread pool, not the main UI thread.
3591          * @param uid The uid whose importance has changed.
3592          * @param importance The new importance value as per {@link RunningAppProcessInfo}.
3593          */
onUidImportance(int uid, @RunningAppProcessInfo.Importance int importance)3594         void onUidImportance(int uid, @RunningAppProcessInfo.Importance int importance);
3595     }
3596 
3597     /**
3598      * Start monitoring changes to the imoportance of uids running in the system.
3599      * @param listener The listener callback that will receive change reports.
3600      * @param importanceCutpoint The level of importance in which the caller is interested
3601      * in differences.  For example, if {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}
3602      * is used here, you will receive a call each time a uids importance transitions between
3603      * being <= {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE} and
3604      * > {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}.
3605      *
3606      * <p>The caller must hold the {@link android.Manifest.permission#PACKAGE_USAGE_STATS}
3607      * permission to use this feature.</p>
3608      *
3609      * @throws IllegalArgumentException If the listener is already registered.
3610      * @throws SecurityException If the caller does not hold
3611      * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}.
3612      * @hide
3613      */
3614     @SystemApi @TestApi
3615     @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
addOnUidImportanceListener(OnUidImportanceListener listener, @RunningAppProcessInfo.Importance int importanceCutpoint)3616     public void addOnUidImportanceListener(OnUidImportanceListener listener,
3617             @RunningAppProcessInfo.Importance int importanceCutpoint) {
3618         synchronized (this) {
3619             if (mImportanceListeners.containsKey(listener)) {
3620                 throw new IllegalArgumentException("Listener already registered: " + listener);
3621             }
3622             // TODO: implement the cut point in the system process to avoid IPCs.
3623             UidObserver observer = new UidObserver(listener, mContext);
3624             try {
3625                 getService().registerUidObserver(observer,
3626                         UID_OBSERVER_PROCSTATE | UID_OBSERVER_GONE,
3627                         RunningAppProcessInfo.importanceToProcState(importanceCutpoint),
3628                         mContext.getOpPackageName());
3629             } catch (RemoteException e) {
3630                 throw e.rethrowFromSystemServer();
3631             }
3632             mImportanceListeners.put(listener, observer);
3633         }
3634     }
3635 
3636     /**
3637      * Remove an importance listener that was previously registered with
3638      * {@link #addOnUidImportanceListener}.
3639      *
3640      * @throws IllegalArgumentException If the listener is not registered.
3641      * @hide
3642      */
3643     @SystemApi @TestApi
3644     @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
removeOnUidImportanceListener(OnUidImportanceListener listener)3645     public void removeOnUidImportanceListener(OnUidImportanceListener listener) {
3646         synchronized (this) {
3647             UidObserver observer = mImportanceListeners.remove(listener);
3648             if (observer == null) {
3649                 throw new IllegalArgumentException("Listener not registered: " + listener);
3650             }
3651             try {
3652                 getService().unregisterUidObserver(observer);
3653             } catch (RemoteException e) {
3654                 throw e.rethrowFromSystemServer();
3655             }
3656         }
3657     }
3658 
3659     /**
3660      * Return global memory state information for the calling process.  This
3661      * does not fill in all fields of the {@link RunningAppProcessInfo}.  The
3662      * only fields that will be filled in are
3663      * {@link RunningAppProcessInfo#pid},
3664      * {@link RunningAppProcessInfo#uid},
3665      * {@link RunningAppProcessInfo#lastTrimLevel},
3666      * {@link RunningAppProcessInfo#importance},
3667      * {@link RunningAppProcessInfo#lru}, and
3668      * {@link RunningAppProcessInfo#importanceReasonCode}.
3669      */
getMyMemoryState(RunningAppProcessInfo outState)3670     static public void getMyMemoryState(RunningAppProcessInfo outState) {
3671         try {
3672             getService().getMyMemoryState(outState);
3673         } catch (RemoteException e) {
3674             throw e.rethrowFromSystemServer();
3675         }
3676     }
3677 
3678     /**
3679      * Return information about the memory usage of one or more processes.
3680      *
3681      * <p><b>Note: this method is only intended for debugging or building
3682      * a user-facing process management UI.</b></p>
3683      *
3684      * @param pids The pids of the processes whose memory usage is to be
3685      * retrieved.
3686      * @return Returns an array of memory information, one for each
3687      * requested pid.
3688      */
getProcessMemoryInfo(int[] pids)3689     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
3690         try {
3691             return getService().getProcessMemoryInfo(pids);
3692         } catch (RemoteException e) {
3693             throw e.rethrowFromSystemServer();
3694         }
3695     }
3696 
3697     /**
3698      * @deprecated This is now just a wrapper for
3699      * {@link #killBackgroundProcesses(String)}; the previous behavior here
3700      * is no longer available to applications because it allows them to
3701      * break other applications by removing their alarms, stopping their
3702      * services, etc.
3703      */
3704     @Deprecated
restartPackage(String packageName)3705     public void restartPackage(String packageName) {
3706         killBackgroundProcesses(packageName);
3707     }
3708 
3709     /**
3710      * Have the system immediately kill all background processes associated
3711      * with the given package.  This is the same as the kernel killing those
3712      * processes to reclaim memory; the system will take care of restarting
3713      * these processes in the future as needed.
3714      *
3715      * @param packageName The name of the package whose processes are to
3716      * be killed.
3717      */
3718     @RequiresPermission(Manifest.permission.KILL_BACKGROUND_PROCESSES)
killBackgroundProcesses(String packageName)3719     public void killBackgroundProcesses(String packageName) {
3720         try {
3721             getService().killBackgroundProcesses(packageName,
3722                     UserHandle.myUserId());
3723         } catch (RemoteException e) {
3724             throw e.rethrowFromSystemServer();
3725         }
3726     }
3727 
3728     /**
3729      * Kills the specified UID.
3730      * @param uid The UID to kill.
3731      * @param reason The reason for the kill.
3732      *
3733      * @hide
3734      */
3735     @SystemApi
3736     @RequiresPermission(Manifest.permission.KILL_UID)
killUid(int uid, String reason)3737     public void killUid(int uid, String reason) {
3738         try {
3739             getService().killUid(UserHandle.getAppId(uid),
3740                     UserHandle.getUserId(uid), reason);
3741         } catch (RemoteException e) {
3742             throw e.rethrowFromSystemServer();
3743         }
3744     }
3745 
3746     /**
3747      * Have the system perform a force stop of everything associated with
3748      * the given application package.  All processes that share its uid
3749      * will be killed, all services it has running stopped, all activities
3750      * removed, etc.  In addition, a {@link Intent#ACTION_PACKAGE_RESTARTED}
3751      * broadcast will be sent, so that any of its registered alarms can
3752      * be stopped, notifications removed, etc.
3753      *
3754      * <p>You must hold the permission
3755      * {@link android.Manifest.permission#FORCE_STOP_PACKAGES} to be able to
3756      * call this method.
3757      *
3758      * @param packageName The name of the package to be stopped.
3759      * @param userId The user for which the running package is to be stopped.
3760      *
3761      * @hide This is not available to third party applications due to
3762      * it allowing them to break other applications by stopping their
3763      * services, removing their alarms, etc.
3764      */
forceStopPackageAsUser(String packageName, int userId)3765     public void forceStopPackageAsUser(String packageName, int userId) {
3766         try {
3767             getService().forceStopPackage(packageName, userId);
3768         } catch (RemoteException e) {
3769             throw e.rethrowFromSystemServer();
3770         }
3771     }
3772 
3773     /**
3774      * @see #forceStopPackageAsUser(String, int)
3775      * @hide
3776      */
3777     @SystemApi
3778     @RequiresPermission(Manifest.permission.FORCE_STOP_PACKAGES)
forceStopPackage(String packageName)3779     public void forceStopPackage(String packageName) {
3780         forceStopPackageAsUser(packageName, UserHandle.myUserId());
3781     }
3782 
3783     /**
3784      * Get the device configuration attributes.
3785      */
getDeviceConfigurationInfo()3786     public ConfigurationInfo getDeviceConfigurationInfo() {
3787         try {
3788             return getService().getDeviceConfigurationInfo();
3789         } catch (RemoteException e) {
3790             throw e.rethrowFromSystemServer();
3791         }
3792     }
3793 
3794     /**
3795      * Get the preferred density of icons for the launcher. This is used when
3796      * custom drawables are created (e.g., for shortcuts).
3797      *
3798      * @return density in terms of DPI
3799      */
getLauncherLargeIconDensity()3800     public int getLauncherLargeIconDensity() {
3801         final Resources res = mContext.getResources();
3802         final int density = res.getDisplayMetrics().densityDpi;
3803         final int sw = res.getConfiguration().smallestScreenWidthDp;
3804 
3805         if (sw < 600) {
3806             // Smaller than approx 7" tablets, use the regular icon size.
3807             return density;
3808         }
3809 
3810         switch (density) {
3811             case DisplayMetrics.DENSITY_LOW:
3812                 return DisplayMetrics.DENSITY_MEDIUM;
3813             case DisplayMetrics.DENSITY_MEDIUM:
3814                 return DisplayMetrics.DENSITY_HIGH;
3815             case DisplayMetrics.DENSITY_TV:
3816                 return DisplayMetrics.DENSITY_XHIGH;
3817             case DisplayMetrics.DENSITY_HIGH:
3818                 return DisplayMetrics.DENSITY_XHIGH;
3819             case DisplayMetrics.DENSITY_XHIGH:
3820                 return DisplayMetrics.DENSITY_XXHIGH;
3821             case DisplayMetrics.DENSITY_XXHIGH:
3822                 return DisplayMetrics.DENSITY_XHIGH * 2;
3823             default:
3824                 // The density is some abnormal value.  Return some other
3825                 // abnormal value that is a reasonable scaling of it.
3826                 return (int)((density*1.5f)+.5f);
3827         }
3828     }
3829 
3830     /**
3831      * Get the preferred launcher icon size. This is used when custom drawables
3832      * are created (e.g., for shortcuts).
3833      *
3834      * @return dimensions of square icons in terms of pixels
3835      */
getLauncherLargeIconSize()3836     public int getLauncherLargeIconSize() {
3837         return getLauncherLargeIconSizeInner(mContext);
3838     }
3839 
getLauncherLargeIconSizeInner(Context context)3840     static int getLauncherLargeIconSizeInner(Context context) {
3841         final Resources res = context.getResources();
3842         final int size = res.getDimensionPixelSize(android.R.dimen.app_icon_size);
3843         final int sw = res.getConfiguration().smallestScreenWidthDp;
3844 
3845         if (sw < 600) {
3846             // Smaller than approx 7" tablets, use the regular icon size.
3847             return size;
3848         }
3849 
3850         final int density = res.getDisplayMetrics().densityDpi;
3851 
3852         switch (density) {
3853             case DisplayMetrics.DENSITY_LOW:
3854                 return (size * DisplayMetrics.DENSITY_MEDIUM) / DisplayMetrics.DENSITY_LOW;
3855             case DisplayMetrics.DENSITY_MEDIUM:
3856                 return (size * DisplayMetrics.DENSITY_HIGH) / DisplayMetrics.DENSITY_MEDIUM;
3857             case DisplayMetrics.DENSITY_TV:
3858                 return (size * DisplayMetrics.DENSITY_XHIGH) / DisplayMetrics.DENSITY_HIGH;
3859             case DisplayMetrics.DENSITY_HIGH:
3860                 return (size * DisplayMetrics.DENSITY_XHIGH) / DisplayMetrics.DENSITY_HIGH;
3861             case DisplayMetrics.DENSITY_XHIGH:
3862                 return (size * DisplayMetrics.DENSITY_XXHIGH) / DisplayMetrics.DENSITY_XHIGH;
3863             case DisplayMetrics.DENSITY_XXHIGH:
3864                 return (size * DisplayMetrics.DENSITY_XHIGH*2) / DisplayMetrics.DENSITY_XXHIGH;
3865             default:
3866                 // The density is some abnormal value.  Return some other
3867                 // abnormal value that is a reasonable scaling of it.
3868                 return (int)((size*1.5f) + .5f);
3869         }
3870     }
3871 
3872     /**
3873      * Returns "true" if the user interface is currently being messed with
3874      * by a monkey.
3875      */
isUserAMonkey()3876     public static boolean isUserAMonkey() {
3877         try {
3878             return getService().isUserAMonkey();
3879         } catch (RemoteException e) {
3880             throw e.rethrowFromSystemServer();
3881         }
3882     }
3883 
3884     /**
3885      * Returns "true" if device is running in a test harness.
3886      */
isRunningInTestHarness()3887     public static boolean isRunningInTestHarness() {
3888         return SystemProperties.getBoolean("ro.test_harness", false);
3889     }
3890 
3891     /**
3892      * Returns the launch count of each installed package.
3893      *
3894      * @hide
3895      */
3896     /*public Map<String, Integer> getAllPackageLaunchCounts() {
3897         try {
3898             IUsageStats usageStatsService = IUsageStats.Stub.asInterface(
3899                     ServiceManager.getService("usagestats"));
3900             if (usageStatsService == null) {
3901                 return new HashMap<String, Integer>();
3902             }
3903 
3904             UsageStats.PackageStats[] allPkgUsageStats = usageStatsService.getAllPkgUsageStats(
3905                     ActivityThread.currentPackageName());
3906             if (allPkgUsageStats == null) {
3907                 return new HashMap<String, Integer>();
3908             }
3909 
3910             Map<String, Integer> launchCounts = new HashMap<String, Integer>();
3911             for (UsageStats.PackageStats pkgUsageStats : allPkgUsageStats) {
3912                 launchCounts.put(pkgUsageStats.getPackageName(), pkgUsageStats.getLaunchCount());
3913             }
3914 
3915             return launchCounts;
3916         } catch (RemoteException e) {
3917             Log.w(TAG, "Could not query launch counts", e);
3918             return new HashMap<String, Integer>();
3919         }
3920     }*/
3921 
3922     /** @hide */
checkComponentPermission(String permission, int uid, int owningUid, boolean exported)3923     public static int checkComponentPermission(String permission, int uid,
3924             int owningUid, boolean exported) {
3925         // Root, system server get to do everything.
3926         final int appId = UserHandle.getAppId(uid);
3927         if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
3928             return PackageManager.PERMISSION_GRANTED;
3929         }
3930         // Isolated processes don't get any permissions.
3931         if (UserHandle.isIsolated(uid)) {
3932             return PackageManager.PERMISSION_DENIED;
3933         }
3934         // If there is a uid that owns whatever is being accessed, it has
3935         // blanket access to it regardless of the permissions it requires.
3936         if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) {
3937             return PackageManager.PERMISSION_GRANTED;
3938         }
3939         // If the target is not exported, then nobody else can get to it.
3940         if (!exported) {
3941             /*
3942             RuntimeException here = new RuntimeException("here");
3943             here.fillInStackTrace();
3944             Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid,
3945                     here);
3946             */
3947             return PackageManager.PERMISSION_DENIED;
3948         }
3949         if (permission == null) {
3950             return PackageManager.PERMISSION_GRANTED;
3951         }
3952         try {
3953             return AppGlobals.getPackageManager()
3954                     .checkUidPermission(permission, uid);
3955         } catch (RemoteException e) {
3956             throw e.rethrowFromSystemServer();
3957         }
3958     }
3959 
3960     /** @hide */
checkUidPermission(String permission, int uid)3961     public static int checkUidPermission(String permission, int uid) {
3962         try {
3963             return AppGlobals.getPackageManager()
3964                     .checkUidPermission(permission, uid);
3965         } catch (RemoteException e) {
3966             throw e.rethrowFromSystemServer();
3967         }
3968     }
3969 
3970     /**
3971      * @hide
3972      * Helper for dealing with incoming user arguments to system service calls.
3973      * Takes care of checking permissions and converting USER_CURRENT to the
3974      * actual current user.
3975      *
3976      * @param callingPid The pid of the incoming call, as per Binder.getCallingPid().
3977      * @param callingUid The uid of the incoming call, as per Binder.getCallingUid().
3978      * @param userId The user id argument supplied by the caller -- this is the user
3979      * they want to run as.
3980      * @param allowAll If true, we will allow USER_ALL.  This means you must be prepared
3981      * to get a USER_ALL returned and deal with it correctly.  If false,
3982      * an exception will be thrown if USER_ALL is supplied.
3983      * @param requireFull If true, the caller must hold
3984      * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} to be able to run as a
3985      * different user than their current process; otherwise they must hold
3986      * {@link android.Manifest.permission#INTERACT_ACROSS_USERS}.
3987      * @param name Optional textual name of the incoming call; only for generating error messages.
3988      * @param callerPackage Optional package name of caller; only for error messages.
3989      *
3990      * @return Returns the user ID that the call should run as.  Will always be a concrete
3991      * user number, unless <var>allowAll</var> is true in which case it could also be
3992      * USER_ALL.
3993      */
handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage)3994     public static int handleIncomingUser(int callingPid, int callingUid, int userId,
3995             boolean allowAll, boolean requireFull, String name, String callerPackage) {
3996         if (UserHandle.getUserId(callingUid) == userId) {
3997             return userId;
3998         }
3999         try {
4000             return getService().handleIncomingUser(callingPid,
4001                     callingUid, userId, allowAll, requireFull, name, callerPackage);
4002         } catch (RemoteException e) {
4003             throw e.rethrowFromSystemServer();
4004         }
4005     }
4006 
4007     /**
4008      * Gets the userId of the current foreground user. Requires system permissions.
4009      * @hide
4010      */
4011     @SystemApi
4012     @RequiresPermission(anyOf = {
4013             "android.permission.INTERACT_ACROSS_USERS",
4014             "android.permission.INTERACT_ACROSS_USERS_FULL"
4015     })
getCurrentUser()4016     public static int getCurrentUser() {
4017         UserInfo ui;
4018         try {
4019             ui = getService().getCurrentUser();
4020             return ui != null ? ui.id : 0;
4021         } catch (RemoteException e) {
4022             throw e.rethrowFromSystemServer();
4023         }
4024     }
4025 
4026     /**
4027      * @param userid the user's id. Zero indicates the default user.
4028      * @hide
4029      */
switchUser(int userid)4030     public boolean switchUser(int userid) {
4031         try {
4032             return getService().switchUser(userid);
4033         } catch (RemoteException e) {
4034             throw e.rethrowFromSystemServer();
4035         }
4036     }
4037 
4038     /**
4039      * Logs out current current foreground user by switching to the system user and stopping the
4040      * user being switched from.
4041      * @hide
4042      */
logoutCurrentUser()4043     public static void logoutCurrentUser() {
4044         int currentUser = ActivityManager.getCurrentUser();
4045         if (currentUser != UserHandle.USER_SYSTEM) {
4046             try {
4047                 getService().switchUser(UserHandle.USER_SYSTEM);
4048                 getService().stopUser(currentUser, /* force= */ false, null);
4049             } catch (RemoteException e) {
4050                 e.rethrowFromSystemServer();
4051             }
4052         }
4053     }
4054 
4055     /** {@hide} */
4056     public static final int FLAG_OR_STOPPED = 1 << 0;
4057     /** {@hide} */
4058     public static final int FLAG_AND_LOCKED = 1 << 1;
4059     /** {@hide} */
4060     public static final int FLAG_AND_UNLOCKED = 1 << 2;
4061     /** {@hide} */
4062     public static final int FLAG_AND_UNLOCKING_OR_UNLOCKED = 1 << 3;
4063 
4064     /**
4065      * Return whether the given user is actively running.  This means that
4066      * the user is in the "started" state, not "stopped" -- it is currently
4067      * allowed to run code through scheduled alarms, receiving broadcasts,
4068      * etc.  A started user may be either the current foreground user or a
4069      * background user; the result here does not distinguish between the two.
4070      * @param userId the user's id. Zero indicates the default user.
4071      * @hide
4072      */
isUserRunning(int userId)4073     public boolean isUserRunning(int userId) {
4074         try {
4075             return getService().isUserRunning(userId, 0);
4076         } catch (RemoteException e) {
4077             throw e.rethrowFromSystemServer();
4078         }
4079     }
4080 
4081     /** {@hide} */
isVrModePackageEnabled(ComponentName component)4082     public boolean isVrModePackageEnabled(ComponentName component) {
4083         try {
4084             return getService().isVrModePackageEnabled(component);
4085         } catch (RemoteException e) {
4086             throw e.rethrowFromSystemServer();
4087         }
4088     }
4089 
4090     /**
4091      * Perform a system dump of various state associated with the given application
4092      * package name.  This call blocks while the dump is being performed, so should
4093      * not be done on a UI thread.  The data will be written to the given file
4094      * descriptor as text.
4095      * @param fd The file descriptor that the dump should be written to.  The file
4096      * descriptor is <em>not</em> closed by this function; the caller continues to
4097      * own it.
4098      * @param packageName The name of the package that is to be dumped.
4099      */
4100     @RequiresPermission(Manifest.permission.DUMP)
dumpPackageState(FileDescriptor fd, String packageName)4101     public void dumpPackageState(FileDescriptor fd, String packageName) {
4102         dumpPackageStateStatic(fd, packageName);
4103     }
4104 
4105     /**
4106      * @hide
4107      */
dumpPackageStateStatic(FileDescriptor fd, String packageName)4108     public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) {
4109         FileOutputStream fout = new FileOutputStream(fd);
4110         PrintWriter pw = new FastPrintWriter(fout);
4111         dumpService(pw, fd, "package", new String[] { packageName });
4112         pw.println();
4113         dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] {
4114                 "-a", "package", packageName });
4115         pw.println();
4116         dumpService(pw, fd, "meminfo", new String[] { "--local", "--package", packageName });
4117         pw.println();
4118         dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName });
4119         pw.println();
4120         dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName });
4121         pw.println();
4122         dumpService(pw, fd, BatteryStats.SERVICE_NAME, new String[] { packageName });
4123         pw.flush();
4124     }
4125 
4126     /**
4127      * @hide
4128      */
isSystemReady()4129     public static boolean isSystemReady() {
4130         if (!sSystemReady) {
4131             if (ActivityThread.isSystem()) {
4132                 sSystemReady =
4133                         LocalServices.getService(ActivityManagerInternal.class).isSystemReady();
4134             } else {
4135                 // Since this is being called from outside system server, system should be
4136                 // ready by now.
4137                 sSystemReady = true;
4138             }
4139         }
4140         return sSystemReady;
4141     }
4142 
4143     /**
4144      * @hide
4145      */
broadcastStickyIntent(Intent intent, int userId)4146     public static void broadcastStickyIntent(Intent intent, int userId) {
4147         broadcastStickyIntent(intent, AppOpsManager.OP_NONE, userId);
4148     }
4149 
4150     /**
4151      * Convenience for sending a sticky broadcast.  For internal use only.
4152      *
4153      * @hide
4154      */
broadcastStickyIntent(Intent intent, int appOp, int userId)4155     public static void broadcastStickyIntent(Intent intent, int appOp, int userId) {
4156         try {
4157             getService().broadcastIntent(
4158                     null, intent, null, null, Activity.RESULT_OK, null, null,
4159                     null /*permission*/, appOp, null, false, true, userId);
4160         } catch (RemoteException ex) {
4161         }
4162     }
4163 
4164     /**
4165      * @hide
4166      */
noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, String tag)4167     public static void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg,
4168             String tag) {
4169         try {
4170             getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null,
4171                     sourceUid, sourcePkg, tag);
4172         } catch (RemoteException ex) {
4173         }
4174     }
4175 
4176     /**
4177      * @hide
4178      */
noteAlarmStart(PendingIntent ps, int sourceUid, String tag)4179     public static void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) {
4180         try {
4181             getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag);
4182         } catch (RemoteException ex) {
4183         }
4184     }
4185 
4186     /**
4187      * @hide
4188      */
noteAlarmFinish(PendingIntent ps, int sourceUid, String tag)4189     public static void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) {
4190         try {
4191             getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag);
4192         } catch (RemoteException ex) {
4193         }
4194     }
4195 
4196     /**
4197      * @hide
4198      */
getService()4199     public static IActivityManager getService() {
4200         return IActivityManagerSingleton.get();
4201     }
4202 
4203     private static final Singleton<IActivityManager> IActivityManagerSingleton =
4204             new Singleton<IActivityManager>() {
4205                 @Override
4206                 protected IActivityManager create() {
4207                     final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
4208                     final IActivityManager am = IActivityManager.Stub.asInterface(b);
4209                     return am;
4210                 }
4211             };
4212 
dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args)4213     private static void dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args) {
4214         pw.print("DUMP OF SERVICE "); pw.print(name); pw.println(":");
4215         IBinder service = ServiceManager.checkService(name);
4216         if (service == null) {
4217             pw.println("  (Service not found)");
4218             return;
4219         }
4220         TransferPipe tp = null;
4221         try {
4222             pw.flush();
4223             tp = new TransferPipe();
4224             tp.setBufferPrefix("  ");
4225             service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
4226             tp.go(fd, 10000);
4227         } catch (Throwable e) {
4228             if (tp != null) {
4229                 tp.kill();
4230             }
4231             pw.println("Failure dumping service:");
4232             e.printStackTrace(pw);
4233         }
4234     }
4235 
4236     /**
4237      * Request that the system start watching for the calling process to exceed a pss
4238      * size as given here.  Once called, the system will look for any occasions where it
4239      * sees the associated process with a larger pss size and, when this happens, automatically
4240      * pull a heap dump from it and allow the user to share the data.  Note that this request
4241      * continues running even if the process is killed and restarted.  To remove the watch,
4242      * use {@link #clearWatchHeapLimit()}.
4243      *
4244      * <p>This API only work if the calling process has been marked as
4245      * {@link ApplicationInfo#FLAG_DEBUGGABLE} or this is running on a debuggable
4246      * (userdebug or eng) build.</p>
4247      *
4248      * <p>Callers can optionally implement {@link #ACTION_REPORT_HEAP_LIMIT} to directly
4249      * handle heap limit reports themselves.</p>
4250      *
4251      * @param pssSize The size in bytes to set the limit at.
4252      */
setWatchHeapLimit(long pssSize)4253     public void setWatchHeapLimit(long pssSize) {
4254         try {
4255             getService().setDumpHeapDebugLimit(null, 0, pssSize,
4256                     mContext.getPackageName());
4257         } catch (RemoteException e) {
4258             throw e.rethrowFromSystemServer();
4259         }
4260     }
4261 
4262     /**
4263      * Action an app can implement to handle reports from {@link #setWatchHeapLimit(long)}.
4264      * If your package has an activity handling this action, it will be launched with the
4265      * heap data provided to it the same way as {@link Intent#ACTION_SEND}.  Note that to
4266      * match the activty must support this action and a MIME type of "*&#47;*".
4267      */
4268     public static final String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
4269 
4270     /**
4271      * Clear a heap watch limit previously set by {@link #setWatchHeapLimit(long)}.
4272      */
clearWatchHeapLimit()4273     public void clearWatchHeapLimit() {
4274         try {
4275             getService().setDumpHeapDebugLimit(null, 0, 0, null);
4276         } catch (RemoteException e) {
4277             throw e.rethrowFromSystemServer();
4278         }
4279     }
4280 
4281     /**
4282      * @hide
4283      */
startLockTaskMode(int taskId)4284     public void startLockTaskMode(int taskId) {
4285         try {
4286             getService().startLockTaskModeById(taskId);
4287         } catch (RemoteException e) {
4288             throw e.rethrowFromSystemServer();
4289         }
4290     }
4291 
4292     /**
4293      * @hide
4294      */
stopLockTaskMode()4295     public void stopLockTaskMode() {
4296         try {
4297             getService().stopLockTaskMode();
4298         } catch (RemoteException e) {
4299             throw e.rethrowFromSystemServer();
4300         }
4301     }
4302 
4303     /**
4304      * Return whether currently in lock task mode.  When in this mode
4305      * no new tasks can be created or switched to.
4306      *
4307      * @see Activity#startLockTask()
4308      *
4309      * @deprecated Use {@link #getLockTaskModeState} instead.
4310      */
4311     @Deprecated
isInLockTaskMode()4312     public boolean isInLockTaskMode() {
4313         return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
4314     }
4315 
4316     /**
4317      * Return the current state of task locking. The three possible outcomes
4318      * are {@link #LOCK_TASK_MODE_NONE}, {@link #LOCK_TASK_MODE_LOCKED}
4319      * and {@link #LOCK_TASK_MODE_PINNED}.
4320      *
4321      * @see Activity#startLockTask()
4322      */
getLockTaskModeState()4323     public int getLockTaskModeState() {
4324         try {
4325             return getService().getLockTaskModeState();
4326         } catch (RemoteException e) {
4327             throw e.rethrowFromSystemServer();
4328         }
4329     }
4330 
4331     /**
4332      * Enable more aggressive scheduling for latency-sensitive low-runtime VR threads. Only one
4333      * thread can be a VR thread in a process at a time, and that thread may be subject to
4334      * restrictions on the amount of time it can run.
4335      *
4336      * If persistent VR mode is set, whatever thread has been granted aggressive scheduling via this
4337      * method will return to normal operation, and calling this method will do nothing while
4338      * persistent VR mode is enabled.
4339      *
4340      * To reset the VR thread for an application, a tid of 0 can be passed.
4341      *
4342      * @see android.os.Process#myTid()
4343      * @param tid tid of the VR thread
4344      */
setVrThread(int tid)4345     public static void setVrThread(int tid) {
4346         try {
4347             getService().setVrThread(tid);
4348         } catch (RemoteException e) {
4349             // pass
4350         }
4351     }
4352 
4353     /**
4354      * Enable more aggressive scheduling for latency-sensitive low-runtime VR threads that persist
4355      * beyond a single process. Only one thread can be a
4356      * persistent VR thread at a time, and that thread may be subject to restrictions on the amount
4357      * of time it can run. Calling this method will disable aggressive scheduling for non-persistent
4358      * VR threads set via {@link #setVrThread}. If persistent VR mode is disabled then the
4359      * persistent VR thread loses its new scheduling priority; this method must be called again to
4360      * set the persistent thread.
4361      *
4362      * To reset the persistent VR thread, a tid of 0 can be passed.
4363      *
4364      * @see android.os.Process#myTid()
4365      * @param tid tid of the VR thread
4366      * @hide
4367      */
4368     @RequiresPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
setPersistentVrThread(int tid)4369     public static void setPersistentVrThread(int tid) {
4370         try {
4371             getService().setPersistentVrThread(tid);
4372         } catch (RemoteException e) {
4373             // pass
4374         }
4375     }
4376 
4377     /**
4378      * The AppTask allows you to manage your own application's tasks.
4379      * See {@link android.app.ActivityManager#getAppTasks()}
4380      */
4381     public static class AppTask {
4382         private IAppTask mAppTaskImpl;
4383 
4384         /** @hide */
AppTask(IAppTask task)4385         public AppTask(IAppTask task) {
4386             mAppTaskImpl = task;
4387         }
4388 
4389         /**
4390          * Finishes all activities in this task and removes it from the recent tasks list.
4391          */
finishAndRemoveTask()4392         public void finishAndRemoveTask() {
4393             try {
4394                 mAppTaskImpl.finishAndRemoveTask();
4395             } catch (RemoteException e) {
4396                 throw e.rethrowFromSystemServer();
4397             }
4398         }
4399 
4400         /**
4401          * Get the RecentTaskInfo associated with this task.
4402          *
4403          * @return The RecentTaskInfo for this task, or null if the task no longer exists.
4404          */
getTaskInfo()4405         public RecentTaskInfo getTaskInfo() {
4406             try {
4407                 return mAppTaskImpl.getTaskInfo();
4408             } catch (RemoteException e) {
4409                 throw e.rethrowFromSystemServer();
4410             }
4411         }
4412 
4413         /**
4414          * Bring this task to the foreground.  If it contains activities, they will be
4415          * brought to the foreground with it and their instances re-created if needed.
4416          * If it doesn't contain activities, the root activity of the task will be
4417          * re-launched.
4418          */
moveToFront()4419         public void moveToFront() {
4420             try {
4421                 mAppTaskImpl.moveToFront();
4422             } catch (RemoteException e) {
4423                 throw e.rethrowFromSystemServer();
4424             }
4425         }
4426 
4427         /**
4428          * Start an activity in this task.  Brings the task to the foreground.  If this task
4429          * is not currently active (that is, its id < 0), then a new activity for the given
4430          * Intent will be launched as the root of the task and the task brought to the
4431          * foreground.  Otherwise, if this task is currently active and the Intent does not specify
4432          * an activity to launch in a new task, then a new activity for the given Intent will
4433          * be launched on top of the task and the task brought to the foreground.  If this
4434          * task is currently active and the Intent specifies {@link Intent#FLAG_ACTIVITY_NEW_TASK}
4435          * or would otherwise be launched in to a new task, then the activity not launched but
4436          * this task be brought to the foreground and a new intent delivered to the top
4437          * activity if appropriate.
4438          *
4439          * <p>In other words, you generally want to use an Intent here that does not specify
4440          * {@link Intent#FLAG_ACTIVITY_NEW_TASK} or {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT},
4441          * and let the system do the right thing.</p>
4442          *
4443          * @param intent The Intent describing the new activity to be launched on the task.
4444          * @param options Optional launch options.
4445          *
4446          * @see Activity#startActivity(android.content.Intent, android.os.Bundle)
4447          */
startActivity(Context context, Intent intent, Bundle options)4448         public void startActivity(Context context, Intent intent, Bundle options) {
4449             ActivityThread thread = ActivityThread.currentActivityThread();
4450             thread.getInstrumentation().execStartActivityFromAppTask(context,
4451                     thread.getApplicationThread(), mAppTaskImpl, intent, options);
4452         }
4453 
4454         /**
4455          * Modify the {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag in the root
4456          * Intent of this AppTask.
4457          *
4458          * @param exclude If true, {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} will
4459          * be set; otherwise, it will be cleared.
4460          */
setExcludeFromRecents(boolean exclude)4461         public void setExcludeFromRecents(boolean exclude) {
4462             try {
4463                 mAppTaskImpl.setExcludeFromRecents(exclude);
4464             } catch (RemoteException e) {
4465                 throw e.rethrowFromSystemServer();
4466             }
4467         }
4468     }
4469 }
4470