ActivityStackSupervisor.java revision c8da41e2f4f6087b5ae0e08a30962d8f5231b01c
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import android.Manifest;
20import android.app.Activity;
21import android.app.ActivityManager;
22import android.app.ActivityManager.RunningTaskInfo;
23import android.app.ActivityManager.StackId;
24import android.app.ActivityManager.StackInfo;
25import android.app.ActivityOptions;
26import android.app.AppGlobals;
27import android.app.AppOpsManager;
28import android.app.IActivityContainer;
29import android.app.IActivityContainerCallback;
30import android.app.IActivityManager;
31import android.app.IActivityManager.WaitResult;
32import android.app.ProfilerInfo;
33import android.app.ResultInfo;
34import android.app.StatusBarManager;
35import android.app.admin.IDevicePolicyManager;
36import android.content.ComponentName;
37import android.content.Context;
38import android.content.IIntentSender;
39import android.content.Intent;
40import android.content.pm.ActivityInfo;
41import android.content.pm.ApplicationInfo;
42import android.content.pm.PackageInfo;
43import android.content.pm.PackageManager;
44import android.content.pm.ResolveInfo;
45import android.content.pm.UserInfo;
46import android.content.res.Configuration;
47import android.graphics.Rect;
48import android.hardware.display.DisplayManager;
49import android.hardware.display.DisplayManager.DisplayListener;
50import android.hardware.display.DisplayManagerGlobal;
51import android.hardware.display.VirtualDisplay;
52import android.hardware.input.InputManager;
53import android.hardware.input.InputManagerInternal;
54import android.os.Binder;
55import android.os.Bundle;
56import android.os.Debug;
57import android.os.Handler;
58import android.os.IBinder;
59import android.os.Looper;
60import android.os.Message;
61import android.os.ParcelFileDescriptor;
62import android.os.PowerManager;
63import android.os.Process;
64import android.os.RemoteException;
65import android.os.ServiceManager;
66import android.os.SystemClock;
67import android.os.Trace;
68import android.os.TransactionTooLargeException;
69import android.os.UserHandle;
70import android.os.UserManager;
71import android.os.WorkSource;
72import android.provider.MediaStore;
73import android.provider.Settings;
74import android.provider.Settings.SettingNotFoundException;
75import android.service.voice.IVoiceInteractionSession;
76import android.util.ArrayMap;
77import android.util.ArraySet;
78import android.util.EventLog;
79import android.util.Slog;
80import android.util.SparseArray;
81import android.util.SparseIntArray;
82import android.view.Display;
83import android.view.DisplayInfo;
84import android.view.InputEvent;
85import android.view.Surface;
86
87import com.android.internal.content.ReferrerIntent;
88import com.android.internal.os.TransferPipe;
89import com.android.internal.statusbar.IStatusBarService;
90import com.android.internal.util.ArrayUtils;
91import com.android.internal.widget.LockPatternUtils;
92import com.android.server.LocalServices;
93import com.android.server.am.ActivityStack.ActivityState;
94import com.android.server.wm.WindowManagerService;
95
96import java.io.FileDescriptor;
97import java.io.IOException;
98import java.io.PrintWriter;
99import java.util.ArrayList;
100import java.util.Arrays;
101import java.util.Collections;
102import java.util.List;
103import java.util.Objects;
104import java.util.Set;
105
106import static android.Manifest.permission.START_ANY_ACTIVITY;
107import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
108import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
109import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
110import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
111import static android.app.ActivityManager.RESIZE_MODE_FORCED;
112import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
113import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
114import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
115import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
116import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
117import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
118import static android.app.ActivityManager.StackId.HOME_STACK_ID;
119import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
120import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
121import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
122import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
123import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
124import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
125import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
126import static android.content.pm.PackageManager.PERMISSION_GRANTED;
127import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
152import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
153import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
154import static com.android.server.am.ActivityManagerService.ANIMATE;
155import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
156import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG;
157import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG;
158import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
159import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
160import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
161import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
162import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
163import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
164import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
165import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
166import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
167import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
168import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
169import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
170import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
171import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
172import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
173import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
174import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
175
176public final class ActivityStackSupervisor implements DisplayListener {
177    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
178    private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
179    private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
180    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
181    private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
182    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
183    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
184    private static final String TAG_STACK = TAG + POSTFIX_STACK;
185    private static final String TAG_STATES = TAG + POSTFIX_STATES;
186    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
187    static final String TAG_TASKS = TAG + POSTFIX_TASKS;
188    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
189
190    /** How long we wait until giving up on the last activity telling us it is idle. */
191    static final int IDLE_TIMEOUT = 10 * 1000;
192
193    /** How long we can hold the sleep wake lock before giving up. */
194    static final int SLEEP_TIMEOUT = 5 * 1000;
195
196    // How long we can hold the launch wake lock before giving up.
197    static final int LAUNCH_TIMEOUT = 10 * 1000;
198
199    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
200    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
201    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
202    static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
203    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
204    static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
205    static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
206    static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
207    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
208    static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
209    static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
210    static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
211    static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
212    static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
213    static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
214    static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
215
216    private static final String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
217
218    private static final String LOCK_TASK_TAG = "Lock-to-App";
219
220    // Used to indicate if an object (e.g. stack) that we are trying to get
221    // should be created if it doesn't exist already.
222    static final boolean CREATE_IF_NEEDED = true;
223
224    // Used to indicate that windows of activities should be preserved during the resize.
225    static final boolean PRESERVE_WINDOWS = true;
226
227    // Used to indicate if an object (e.g. task) should be moved/created
228    // at the top of its container (e.g. stack).
229    static final boolean ON_TOP = true;
230
231    // Used to indicate that an objects (e.g. task) removal from its container
232    // (e.g. stack) is due to it moving to another container.
233    static final boolean MOVING = true;
234
235    // Force the focus to change to the stack we are moving a task to..
236    static final boolean FORCE_FOCUS = true;
237
238    // Restore task from the saved recents if it can't be found in any live stack.
239    static final boolean RESTORE_FROM_RECENTS = true;
240
241    // Don't execute any calls to resume.
242    static final boolean DEFER_RESUME = true;
243
244    // Activity actions an app cannot start if it uses a permission which is not granted.
245    private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
246            new ArrayMap<>();
247
248    static {
249        ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE,
250                Manifest.permission.CAMERA);
251        ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE,
252                Manifest.permission.CAMERA);
253        ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL,
254                Manifest.permission.CALL_PHONE);
255    }
256
257    /** Action restriction: launching the activity is not restricted. */
258    private static final int ACTIVITY_RESTRICTION_NONE = 0;
259    /** Action restriction: launching the activity is restricted by a permission. */
260    private static final int ACTIVITY_RESTRICTION_PERMISSION = 1;
261    /** Action restriction: launching the activity is restricted by an app op. */
262    private static final int ACTIVITY_RESTRICTION_APPOP = 2;
263
264    // The height/width divide used when fitting a task within a bounds with method
265    // {@link #fitWithinBounds}.
266    // We always want the task to to be visible in the bounds without affecting its size when
267    // fitting. To make sure this is the case, we don't adjust the task left or top side pass
268    // the input bounds right or bottom side minus the width or height divided by this value.
269    private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
270
271    /** Status Bar Service **/
272    private IBinder mToken = new Binder();
273    private IStatusBarService mStatusBarService;
274    private IDevicePolicyManager mDevicePolicyManager;
275
276    // For debugging to make sure the caller when acquiring/releasing our
277    // wake lock is the system process.
278    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
279    /** The number of distinct task ids that can be assigned to the tasks of a single user */
280    private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;
281
282    final ActivityManagerService mService;
283
284    private RecentTasks mRecentTasks;
285
286    final ActivityStackSupervisorHandler mHandler;
287
288    /** Short cut */
289    WindowManagerService mWindowManager;
290    DisplayManager mDisplayManager;
291
292    /** Counter for next free stack ID to use for dynamic activity stacks. */
293    private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID;
294
295    /**
296     * Maps the task identifier that activities are currently being started in to the userId of the
297     * task. Each time a new task is created, the entry for the userId of the task is incremented
298     */
299    private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20);
300
301    /** The current user */
302    int mCurrentUser;
303
304    /** The stack containing the launcher app. Assumed to always be attached to
305     * Display.DEFAULT_DISPLAY. */
306    ActivityStack mHomeStack;
307
308    /** The stack currently receiving input or launching the next activity. */
309    ActivityStack mFocusedStack;
310
311    /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
312     * been resumed. If stacks are changing position this will hold the old stack until the new
313     * stack becomes resumed after which it will be set to mFocusedStack. */
314    private ActivityStack mLastFocusedStack;
315
316    /** List of activities that are waiting for a new activity to become visible before completing
317     * whatever operation they are supposed to do. */
318    final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
319
320    /** List of processes waiting to find out about the next visible activity. */
321    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>();
322
323    /** List of processes waiting to find out about the next launched activity. */
324    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>();
325
326    /** List of activities that are ready to be stopped, but waiting for the next activity to
327     * settle down before doing so. */
328    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
329
330    /** List of activities that are ready to be finished, but waiting for the previous activity to
331     * settle down before doing so.  It contains ActivityRecord objects. */
332    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
333
334    /** List of activities that are in the process of going to sleep. */
335    final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
336
337    /** List of activities whose multi-window mode changed that we need to report to the
338     * application */
339    final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>();
340
341    /** List of activities whose picture-in-picture mode changed that we need to report to the
342     * application */
343    final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
344
345    /** Used on user changes */
346    final ArrayList<UserState> mStartingUsers = new ArrayList<>();
347
348    /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
349     * is being brought in front of us. */
350    boolean mUserLeaving = false;
351
352    /** Set when we have taken too long waiting to go to sleep. */
353    boolean mSleepTimeout = false;
354
355    /**
356     * We don't want to allow the device to go to sleep while in the process
357     * of launching an activity.  This is primarily to allow alarm intent
358     * receivers to launch an activity and get that to run before the device
359     * goes back to sleep.
360     */
361    PowerManager.WakeLock mLaunchingActivity;
362
363    /**
364     * Set when the system is going to sleep, until we have
365     * successfully paused the current activity and released our wake lock.
366     * At that point the system is allowed to actually sleep.
367     */
368    PowerManager.WakeLock mGoingToSleep;
369
370    /** Stack id of the front stack when user switched, indexed by userId. */
371    SparseIntArray mUserStackInFront = new SparseIntArray(2);
372
373    // TODO: Add listener for removal of references.
374    /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
375    private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>();
376
377    /** Mapping from displayId to display current state */
378    private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>();
379
380    InputManagerInternal mInputManagerInternal;
381
382    /** The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks
383     * may be finished until there is only one entry left. If this is empty the system is not
384     * in lockTask mode. */
385    ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>();
386    /** Store the current lock task mode. Possible values:
387     * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
388     * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
389     */
390    private int mLockTaskModeState;
391    /**
392     * Notifies the user when entering/exiting lock-task.
393     */
394    private LockTaskNotify mLockTaskNotify;
395
396    /** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */
397    boolean inResumeTopActivity;
398
399    // temp. rects used during resize calculation so we don't need to create a new object each time.
400    private final Rect tempRect = new Rect();
401    private final Rect tempRect2 = new Rect();
402
403    private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>();
404    private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
405    private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>();
406
407    // The default minimal size that will be used if the activity doesn't specify its minimal size.
408    // It will be calculated when the default display gets added.
409    int mDefaultMinimalSizeOfResizeableTask = -1;
410
411    // Whether tasks have moved and we need to rank the tasks before next OOM scoring
412    private boolean mTaskLayersChanged = true;
413
414    final ActivityMetricsLogger mActivityMetricsLogger;
415
416    private final ResizeDockedStackTimeout mResizeDockedStackTimeout;
417
418    static class FindTaskResult {
419        ActivityRecord r;
420        boolean matchedByRootAffinity;
421    }
422    private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
423
424    /**
425     * Used to keep track whether app visibilities got changed since the last pause. Useful to
426     * determine whether to invoke the task stack change listener after pausing.
427     */
428    boolean mAppVisibilitiesChangedSinceLastPause;
429
430    /**
431     * Set of tasks that are in resizing mode during an app transition to fill the "void".
432     */
433    private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>();
434
435
436    /**
437     * If set to {@code false} all calls to resize the docked stack {@link #resizeDockedStackLocked}
438     * will be ignored. Useful for the case where the caller is handling resizing of other stack and
439     * moving tasks around and doesn't want dock stack to be resized due to an automatic trigger
440     * like the docked stack going empty.
441     */
442    private boolean mAllowDockedStackResize = true;
443
444    /**
445     * Description of a request to start a new activity, which has been held
446     * due to app switches being disabled.
447     */
448    static class PendingActivityLaunch {
449        final ActivityRecord r;
450        final ActivityRecord sourceRecord;
451        final int startFlags;
452        final ActivityStack stack;
453        final ProcessRecord callerApp;
454
455        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
456                int _startFlags, ActivityStack _stack, ProcessRecord _callerApp) {
457            r = _r;
458            sourceRecord = _sourceRecord;
459            startFlags = _startFlags;
460            stack = _stack;
461            callerApp = _callerApp;
462        }
463
464        void sendErrorResult(String message) {
465            try {
466                if (callerApp.thread != null) {
467                    callerApp.thread.scheduleCrash(message);
468                }
469            } catch (RemoteException e) {
470                Slog.e(TAG, "Exception scheduling crash of failed "
471                        + "activity launcher sourceRecord=" + sourceRecord, e);
472            }
473        }
474    }
475
476    public ActivityStackSupervisor(ActivityManagerService service) {
477        mService = service;
478        mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
479        mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
480        mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
481    }
482
483    void setRecentTasks(RecentTasks recentTasks) {
484        mRecentTasks = recentTasks;
485    }
486
487    /**
488     * At the time when the constructor runs, the power manager has not yet been
489     * initialized.  So we initialize our wakelocks afterwards.
490     */
491    void initPowerManagement() {
492        PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
493        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
494        mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*launch*");
495        mLaunchingActivity.setReferenceCounted(false);
496    }
497
498    // This function returns a IStatusBarService. The value is from ServiceManager.
499    // getService and is cached.
500    private IStatusBarService getStatusBarService() {
501        synchronized (mService) {
502            if (mStatusBarService == null) {
503                mStatusBarService = IStatusBarService.Stub.asInterface(
504                    ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
505                if (mStatusBarService == null) {
506                    Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
507                }
508            }
509            return mStatusBarService;
510        }
511    }
512
513    private IDevicePolicyManager getDevicePolicyManager() {
514        synchronized (mService) {
515            if (mDevicePolicyManager == null) {
516                mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
517                    ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE));
518                if (mDevicePolicyManager == null) {
519                    Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
520                }
521            }
522            return mDevicePolicyManager;
523        }
524    }
525
526    void setWindowManager(WindowManagerService wm) {
527        synchronized (mService) {
528            mWindowManager = wm;
529
530            mDisplayManager =
531                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
532            mDisplayManager.registerDisplayListener(this, null);
533
534            Display[] displays = mDisplayManager.getDisplays();
535            for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
536                final int displayId = displays[displayNdx].getDisplayId();
537                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
538                if (activityDisplay.mDisplay == null) {
539                    throw new IllegalStateException("Default Display does not exist");
540                }
541                mActivityDisplays.put(displayId, activityDisplay);
542                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
543            }
544
545            mHomeStack = mFocusedStack = mLastFocusedStack =
546                    getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
547
548            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
549        }
550    }
551
552    void notifyActivityDrawnForKeyguard() {
553        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
554        mWindowManager.notifyActivityDrawnForKeyguard();
555    }
556
557    ActivityStack getFocusedStack() {
558        return mFocusedStack;
559    }
560
561    ActivityStack getLastStack() {
562        return mLastFocusedStack;
563    }
564
565    boolean isFocusedStack(ActivityStack stack) {
566        if (stack == null) {
567            return false;
568        }
569
570        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
571        if (parent != null) {
572            stack = parent.task.stack;
573        }
574        return stack == mFocusedStack;
575    }
576
577    /** The top most stack. */
578    boolean isFrontStack(ActivityStack stack) {
579        if (stack == null) {
580            return false;
581        }
582
583        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
584        if (parent != null) {
585            stack = parent.task.stack;
586        }
587        return stack == mHomeStack.mStacks.get((mHomeStack.mStacks.size() - 1));
588    }
589
590    /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */
591    void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) {
592        if (!focusCandidate.isFocusable()) {
593            // The focus candidate isn't focusable. Move focus to the top stack that is focusable.
594            focusCandidate = focusCandidate.getNextFocusableStackLocked();
595        }
596
597        if (focusCandidate != mFocusedStack) {
598            mLastFocusedStack = mFocusedStack;
599            mFocusedStack = focusCandidate;
600
601            EventLogTags.writeAmFocusedStack(
602                    mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(),
603                    mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason);
604        }
605
606        final ActivityRecord r = topRunningActivityLocked();
607        if (!mService.mDoingSetFocusedActivity && mService.mFocusedActivity != r) {
608            // The focus activity should always be the top activity in the focused stack.
609            // There will be chaos and anarchy if it isn't...
610            mService.setFocusedActivityLocked(r, reason + " setFocusStack");
611        }
612
613        if (mService.mBooting || !mService.mBooted) {
614            if (r != null && r.idle) {
615                checkFinishBootingLocked();
616            }
617        }
618    }
619
620    void moveHomeStackToFront(String reason) {
621        mHomeStack.moveToFront(reason);
622    }
623
624    /** Returns true if the focus activity was adjusted to the home stack top activity. */
625    boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
626        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
627            mWindowManager.showRecentApps();
628            return false;
629        }
630
631        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
632
633        final ActivityRecord top = getHomeActivity();
634        if (top == null) {
635            return false;
636        }
637        mService.setFocusedActivityLocked(top, reason);
638        return true;
639    }
640
641    boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
642        if (!mService.mBooting && !mService.mBooted) {
643            // Not ready yet!
644            return false;
645        }
646
647        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
648            mWindowManager.showRecentApps();
649            return false;
650        }
651
652        if (prev != null) {
653            prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
654        }
655
656        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
657        ActivityRecord r = getHomeActivity();
658        final String myReason = reason + " resumeHomeStackTask";
659
660        // Only resume home activity if isn't finishing.
661        if (r != null && !r.finishing) {
662            mService.setFocusedActivityLocked(r, myReason);
663            return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
664        }
665        return mService.startHomeActivityLocked(mCurrentUser, myReason);
666    }
667
668    TaskRecord anyTaskForIdLocked(int id) {
669        return anyTaskForIdLocked(id, RESTORE_FROM_RECENTS, INVALID_STACK_ID);
670    }
671
672    /**
673     * Returns a {@link TaskRecord} for the input id if available. Null otherwise.
674     * @param id Id of the task we would like returned.
675     * @param restoreFromRecents If the id was not in the active list, but was found in recents,
676     *                           restore the task from recents to the active list.
677     * @param stackId The stack to restore the task to (default launch stack will be used if
678     *                stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}).
679     */
680    TaskRecord anyTaskForIdLocked(int id, boolean restoreFromRecents, int stackId) {
681        int numDisplays = mActivityDisplays.size();
682        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
683            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
684            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
685                ActivityStack stack = stacks.get(stackNdx);
686                TaskRecord task = stack.taskForIdLocked(id);
687                if (task != null) {
688                    return task;
689                }
690            }
691        }
692
693        // Don't give up! Look in recents.
694        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
695        TaskRecord task = mRecentTasks.taskForIdLocked(id);
696        if (task == null) {
697            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
698            return null;
699        }
700
701        if (!restoreFromRecents) {
702            return task;
703        }
704
705        if (!restoreRecentTaskLocked(task, stackId)) {
706            if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
707                    "Couldn't restore task id=" + id + " found in recents");
708            return null;
709        }
710        if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
711        return task;
712    }
713
714    ActivityRecord isInAnyStackLocked(IBinder token) {
715        int numDisplays = mActivityDisplays.size();
716        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
717            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
718            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
719                final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
720                if (r != null) {
721                    return r;
722                }
723            }
724        }
725        return null;
726    }
727
728    boolean isFocusedUserLockedProfile() {
729        final int userId = mFocusedStack.topRunningActivityLocked().userId;
730        return userId != UserHandle.myUserId()
731                && mService.mUserController.shouldConfirmCredentials(userId);
732    }
733
734    void setNextTaskIdForUserLocked(int taskId, int userId) {
735        final int currentTaskId = mCurTaskIdForUser.get(userId, -1);
736        if (taskId > currentTaskId) {
737            mCurTaskIdForUser.put(userId, taskId);
738        }
739    }
740
741    int getNextTaskIdForUserLocked(int userId) {
742        final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER);
743        // for a userId u, a taskId can only be in the range
744        // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER
745        // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
746        int candidateTaskId = currentTaskId;
747        while (mRecentTasks.taskIdTakenForUserLocked(candidateTaskId, userId)
748                || anyTaskForIdLocked(candidateTaskId, !RESTORE_FROM_RECENTS,
749                        INVALID_STACK_ID) != null) {
750            candidateTaskId++;
751            if (candidateTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) {
752                // Wrap around as there will be smaller task ids that are available now.
753                candidateTaskId -= MAX_TASK_IDS_PER_USER;
754            }
755            if (candidateTaskId == currentTaskId) {
756                // Something wrong!
757                // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user
758                throw new IllegalStateException("Cannot get an available task id."
759                        + " Reached limit of " + MAX_TASK_IDS_PER_USER
760                        + " running tasks per user.");
761            }
762        }
763        mCurTaskIdForUser.put(userId, candidateTaskId);
764        return candidateTaskId;
765    }
766
767    ActivityRecord resumedAppLocked() {
768        ActivityStack stack = mFocusedStack;
769        if (stack == null) {
770            return null;
771        }
772        ActivityRecord resumedActivity = stack.mResumedActivity;
773        if (resumedActivity == null || resumedActivity.app == null) {
774            resumedActivity = stack.mPausingActivity;
775            if (resumedActivity == null || resumedActivity.app == null) {
776                resumedActivity = stack.topRunningActivityLocked();
777            }
778        }
779        return resumedActivity;
780    }
781
782    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
783        final String processName = app.processName;
784        boolean didSomething = false;
785        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
786            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
787            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
788                final ActivityStack stack = stacks.get(stackNdx);
789                if (!isFocusedStack(stack)) {
790                    continue;
791                }
792                ActivityRecord hr = stack.topRunningActivityLocked();
793                if (hr != null) {
794                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
795                            && processName.equals(hr.processName)) {
796                        try {
797                            if (realStartActivityLocked(hr, app, true, true)) {
798                                didSomething = true;
799                            }
800                        } catch (RemoteException e) {
801                            Slog.w(TAG, "Exception in new application when starting activity "
802                                  + hr.intent.getComponent().flattenToShortString(), e);
803                            throw e;
804                        }
805                    }
806                }
807            }
808        }
809        if (!didSomething) {
810            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
811        }
812        return didSomething;
813    }
814
815    boolean allResumedActivitiesIdle() {
816        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
817            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
818            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
819                final ActivityStack stack = stacks.get(stackNdx);
820                if (!isFocusedStack(stack) || stack.numActivities() == 0) {
821                    continue;
822                }
823                final ActivityRecord resumedActivity = stack.mResumedActivity;
824                if (resumedActivity == null || !resumedActivity.idle) {
825                    if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
826                             + stack.mStackId + " " + resumedActivity + " not idle");
827                    return false;
828                }
829            }
830        }
831        return true;
832    }
833
834    boolean allResumedActivitiesComplete() {
835        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
836            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
837            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
838                final ActivityStack stack = stacks.get(stackNdx);
839                if (isFocusedStack(stack)) {
840                    final ActivityRecord r = stack.mResumedActivity;
841                    if (r != null && r.state != RESUMED) {
842                        return false;
843                    }
844                }
845            }
846        }
847        // TODO: Not sure if this should check if all Paused are complete too.
848        if (DEBUG_STACK) Slog.d(TAG_STACK,
849                "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
850                mLastFocusedStack + " to=" + mFocusedStack);
851        mLastFocusedStack = mFocusedStack;
852        return true;
853    }
854
855    boolean allResumedActivitiesVisible() {
856        boolean foundResumed = false;
857        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
858            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
859            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
860                final ActivityStack stack = stacks.get(stackNdx);
861                final ActivityRecord r = stack.mResumedActivity;
862                if (r != null) {
863                    if (!r.nowVisible || mWaitingVisibleActivities.contains(r)) {
864                        return false;
865                    }
866                    foundResumed = true;
867                }
868            }
869        }
870        return foundResumed;
871    }
872
873    /**
874     * Pause all activities in either all of the stacks or just the back stacks.
875     * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
876     * @return true if any activity was paused as a result of this call.
877     */
878    boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
879        boolean someActivityPaused = false;
880        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
881            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
882            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
883                final ActivityStack stack = stacks.get(stackNdx);
884                if (!isFocusedStack(stack) && stack.mResumedActivity != null) {
885                    if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
886                            " mResumedActivity=" + stack.mResumedActivity);
887                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
888                            dontWait);
889                }
890            }
891        }
892        return someActivityPaused;
893    }
894
895    boolean allPausedActivitiesComplete() {
896        boolean pausing = true;
897        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
898            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
899            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
900                final ActivityStack stack = stacks.get(stackNdx);
901                final ActivityRecord r = stack.mPausingActivity;
902                if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) {
903                    if (DEBUG_STATES) {
904                        Slog.d(TAG_STATES,
905                                "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
906                        pausing = false;
907                    } else {
908                        return false;
909                    }
910                }
911            }
912        }
913        return pausing;
914    }
915
916    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
917            boolean resuming, boolean dontWait) {
918        // TODO: Put all stacks in supervisor and iterate through them instead.
919        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
920            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
921            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
922                final ActivityStack stack = stacks.get(stackNdx);
923                if (stack.mResumedActivity != null &&
924                        stack.mActivityContainer.mParentActivity == parent) {
925                    stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
926                }
927            }
928        }
929    }
930
931    void cancelInitializingActivities() {
932        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
933            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
934            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
935                stacks.get(stackNdx).cancelInitializingActivities();
936            }
937        }
938    }
939
940    void reportActivityVisibleLocked(ActivityRecord r) {
941        sendWaitingVisibleReportLocked(r);
942    }
943
944    void sendWaitingVisibleReportLocked(ActivityRecord r) {
945        boolean changed = false;
946        for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
947            WaitResult w = mWaitingActivityVisible.get(i);
948            if (w.who == null) {
949                changed = true;
950                w.timeout = false;
951                if (r != null) {
952                    w.who = new ComponentName(r.info.packageName, r.info.name);
953                }
954                w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
955                w.thisTime = w.totalTime;
956            }
957        }
958        if (changed) {
959            mService.notifyAll();
960        }
961    }
962
963    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
964            long thisTime, long totalTime) {
965        boolean changed = false;
966        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
967            WaitResult w = mWaitingActivityLaunched.remove(i);
968            if (w.who == null) {
969                changed = true;
970                w.timeout = timeout;
971                if (r != null) {
972                    w.who = new ComponentName(r.info.packageName, r.info.name);
973                }
974                w.thisTime = thisTime;
975                w.totalTime = totalTime;
976            }
977        }
978        if (changed) {
979            mService.notifyAll();
980        }
981    }
982
983    ActivityRecord topRunningActivityLocked() {
984        final ActivityStack focusedStack = mFocusedStack;
985        ActivityRecord r = focusedStack.topRunningActivityLocked();
986        if (r != null) {
987            return r;
988        }
989
990        // Return to the home stack.
991        final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
992        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
993            final ActivityStack stack = stacks.get(stackNdx);
994            if (stack != focusedStack && isFrontStack(stack) && stack.isFocusable()) {
995                r = stack.topRunningActivityLocked();
996                if (r != null) {
997                    return r;
998                }
999            }
1000        }
1001        return null;
1002    }
1003
1004    void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) {
1005        // Gather all of the running tasks for each stack into runningTaskLists.
1006        ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
1007                new ArrayList<ArrayList<RunningTaskInfo>>();
1008        final int numDisplays = mActivityDisplays.size();
1009        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
1010            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1011            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1012                final ActivityStack stack = stacks.get(stackNdx);
1013                ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>();
1014                runningTaskLists.add(stackTaskList);
1015                stack.getTasksLocked(stackTaskList, callingUid, allowed);
1016            }
1017        }
1018
1019        // The lists are already sorted from most recent to oldest. Just pull the most recent off
1020        // each list and add it to list. Stop when all lists are empty or maxNum reached.
1021        while (maxNum > 0) {
1022            long mostRecentActiveTime = Long.MIN_VALUE;
1023            ArrayList<RunningTaskInfo> selectedStackList = null;
1024            final int numTaskLists = runningTaskLists.size();
1025            for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
1026                ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
1027                if (!stackTaskList.isEmpty()) {
1028                    final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
1029                    if (lastActiveTime > mostRecentActiveTime) {
1030                        mostRecentActiveTime = lastActiveTime;
1031                        selectedStackList = stackTaskList;
1032                    }
1033                }
1034            }
1035            if (selectedStackList != null) {
1036                list.add(selectedStackList.remove(0));
1037                --maxNum;
1038            } else {
1039                break;
1040            }
1041        }
1042    }
1043
1044    ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
1045            ProfilerInfo profilerInfo) {
1046        final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;
1047        if (aInfo != null) {
1048            // Store the found target back into the intent, because now that
1049            // we have it we never want to do this again.  For example, if the
1050            // user navigates back to this point in the history, we should
1051            // always restart the exact same activity.
1052            intent.setComponent(new ComponentName(
1053                    aInfo.applicationInfo.packageName, aInfo.name));
1054
1055            // Don't debug things in the system process
1056            if (!aInfo.processName.equals("system")) {
1057                if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
1058                    mService.setDebugApp(aInfo.processName, true, false);
1059                }
1060
1061                if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
1062                    mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
1063                }
1064
1065                if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
1066                    mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
1067                }
1068
1069                if (profilerInfo != null) {
1070                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
1071                }
1072            }
1073        }
1074        return aInfo;
1075    }
1076
1077    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
1078        return resolveIntent(intent, resolvedType, userId, 0);
1079    }
1080
1081    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
1082        try {
1083            return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
1084                    PackageManager.MATCH_DEFAULT_ONLY | flags
1085                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
1086        } catch (RemoteException e) {
1087        }
1088        return null;
1089    }
1090
1091    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
1092            ProfilerInfo profilerInfo, int userId) {
1093        final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId);
1094        return resolveActivity(intent, rInfo, startFlags, profilerInfo);
1095    }
1096
1097    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
1098            boolean andResume, boolean checkConfig) throws RemoteException {
1099
1100        if (!allPausedActivitiesComplete()) {
1101            // While there are activities pausing we skipping starting any new activities until
1102            // pauses are complete. NOTE: that we also do this for activities that are starting in
1103            // the paused state because they will first be resumed then paused on the client side.
1104            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
1105                    "realStartActivityLocked: Skipping start of r=" + r
1106                    + " some activities pausing...");
1107            return false;
1108        }
1109
1110        if (andResume) {
1111            r.startFreezingScreenLocked(app, 0);
1112            mWindowManager.setAppVisibility(r.appToken, true);
1113
1114            // schedule launch ticks to collect information about slow apps.
1115            r.startLaunchTickingLocked();
1116        }
1117
1118        // Have the window manager re-evaluate the orientation of
1119        // the screen based on the new activity order.  Note that
1120        // as a result of this, it can call back into the activity
1121        // manager with a new orientation.  We don't care about that,
1122        // because the activity is not currently running so we are
1123        // just restarting it anyway.
1124        if (checkConfig) {
1125            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1126                    mService.mConfiguration,
1127                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
1128            mService.updateConfigurationLocked(config, r, false);
1129        }
1130
1131        r.app = app;
1132        app.waitingToKill = null;
1133        r.launchCount++;
1134        r.lastLaunchTime = SystemClock.uptimeMillis();
1135
1136        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
1137
1138        int idx = app.activities.indexOf(r);
1139        if (idx < 0) {
1140            app.activities.add(r);
1141        }
1142        mService.updateLruProcessLocked(app, true, null);
1143        mService.updateOomAdjLocked();
1144
1145        final TaskRecord task = r.task;
1146        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
1147                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
1148            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
1149        }
1150
1151        final ActivityStack stack = task.stack;
1152        try {
1153            if (app.thread == null) {
1154                throw new RemoteException();
1155            }
1156            List<ResultInfo> results = null;
1157            List<ReferrerIntent> newIntents = null;
1158            if (andResume) {
1159                results = r.results;
1160                newIntents = r.newIntents;
1161            }
1162            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1163                    "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
1164                    + " newIntents=" + newIntents + " andResume=" + andResume);
1165            if (andResume) {
1166                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
1167                        r.userId, System.identityHashCode(r),
1168                        task.taskId, r.shortComponentName);
1169            }
1170            if (r.isHomeActivity()) {
1171                // Home process is the root process of the task.
1172                mService.mHomeProcess = task.mActivities.get(0).app;
1173            }
1174            mService.notifyPackageUse(r.intent.getComponent().getPackageName());
1175            r.sleeping = false;
1176            r.forceNewConfig = false;
1177            mService.showAskCompatModeDialogLocked(r);
1178            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1179            ProfilerInfo profilerInfo = null;
1180            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1181                if (mService.mProfileProc == null || mService.mProfileProc == app) {
1182                    mService.mProfileProc = app;
1183                    final String profileFile = mService.mProfileFile;
1184                    if (profileFile != null) {
1185                        ParcelFileDescriptor profileFd = mService.mProfileFd;
1186                        if (profileFd != null) {
1187                            try {
1188                                profileFd = profileFd.dup();
1189                            } catch (IOException e) {
1190                                if (profileFd != null) {
1191                                    try {
1192                                        profileFd.close();
1193                                    } catch (IOException o) {
1194                                    }
1195                                    profileFd = null;
1196                                }
1197                            }
1198                        }
1199
1200                        profilerInfo = new ProfilerInfo(profileFile, profileFd,
1201                                mService.mSamplingInterval, mService.mAutoStopProfiler);
1202                    }
1203                }
1204            }
1205
1206            if (andResume) {
1207                app.hasShownUi = true;
1208                app.pendingUiClean = true;
1209            }
1210            app.forceProcessStateUpTo(mService.mTopProcessState);
1211            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1212                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
1213                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
1214                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
1215                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
1216
1217            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
1218                // This may be a heavy-weight process!  Note that the package
1219                // manager will ensure that only activity can run in the main
1220                // process of the .apk, which is the only thing that will be
1221                // considered heavy-weight.
1222                if (app.processName.equals(app.info.packageName)) {
1223                    if (mService.mHeavyWeightProcess != null
1224                            && mService.mHeavyWeightProcess != app) {
1225                        Slog.w(TAG, "Starting new heavy weight process " + app
1226                                + " when already running "
1227                                + mService.mHeavyWeightProcess);
1228                    }
1229                    mService.mHeavyWeightProcess = app;
1230                    Message msg = mService.mHandler.obtainMessage(
1231                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1232                    msg.obj = r;
1233                    mService.mHandler.sendMessage(msg);
1234                }
1235            }
1236
1237        } catch (RemoteException e) {
1238            if (r.launchFailed) {
1239                // This is the second time we failed -- finish activity
1240                // and give up.
1241                Slog.e(TAG, "Second failure launching "
1242                      + r.intent.getComponent().flattenToShortString()
1243                      + ", giving up", e);
1244                mService.appDiedLocked(app);
1245                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1246                        "2nd-crash", false);
1247                return false;
1248            }
1249
1250            // This is the first time we failed -- restart process and
1251            // retry.
1252            app.activities.remove(r);
1253            throw e;
1254        }
1255
1256        r.launchFailed = false;
1257        if (stack.updateLRUListLocked(r)) {
1258            Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
1259        }
1260
1261        if (andResume) {
1262            // As part of the process of launching, ActivityThread also performs
1263            // a resume.
1264            stack.minimalResumeActivityLocked(r);
1265        } else {
1266            // This activity is not starting in the resumed state... which should look like we asked
1267            // it to pause+stop (but remain visible), and it has done so and reported back the
1268            // current icicle and other state.
1269            if (DEBUG_STATES) Slog.v(TAG_STATES,
1270                    "Moving to PAUSED: " + r + " (starting in paused state)");
1271            r.state = PAUSED;
1272        }
1273
1274        // Launch the new version setup screen if needed.  We do this -after-
1275        // launching the initial activity (that is, home), so that it can have
1276        // a chance to initialize itself while in the background, making the
1277        // switch back to it faster and look better.
1278        if (isFocusedStack(stack)) {
1279            mService.startSetupActivityLocked();
1280        }
1281
1282        // Update any services we are bound to that might care about whether
1283        // their client may have activities.
1284        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
1285
1286        return true;
1287    }
1288
1289    void startSpecificActivityLocked(ActivityRecord r,
1290            boolean andResume, boolean checkConfig) {
1291        // Is this activity's application already running?
1292        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1293                r.info.applicationInfo.uid, true);
1294
1295        r.task.stack.setLaunchTime(r);
1296
1297        if (app != null && app.thread != null) {
1298            try {
1299                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1300                        || !"android".equals(r.info.packageName)) {
1301                    // Don't add this if it is a platform component that is marked
1302                    // to run in multiple processes, because this is actually
1303                    // part of the framework so doesn't make sense to track as a
1304                    // separate apk in the process.
1305                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
1306                            mService.mProcessStats);
1307                }
1308                realStartActivityLocked(r, app, andResume, checkConfig);
1309                return;
1310            } catch (RemoteException e) {
1311                Slog.w(TAG, "Exception when starting activity "
1312                        + r.intent.getComponent().flattenToShortString(), e);
1313            }
1314
1315            // If a dead object exception was thrown -- fall through to
1316            // restart the application.
1317        }
1318
1319        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1320                "activity", r.intent.getComponent(), false, false, true);
1321    }
1322
1323    boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo,
1324            String resultWho, int requestCode, int callingPid, int callingUid,
1325            String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp,
1326            ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options) {
1327        final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
1328                callingUid);
1329        if (startAnyPerm ==  PERMISSION_GRANTED) {
1330            return true;
1331        }
1332        final int componentRestriction = getComponentRestrictionForCallingPackage(
1333                aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity);
1334        final int actionRestriction = getActionRestrictionForCallingPackage(
1335                intent.getAction(), callingPackage, callingPid, callingUid);
1336        if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
1337                || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1338            if (resultRecord != null) {
1339                resultStack.sendActivityResultLocked(-1,
1340                        resultRecord, resultWho, requestCode,
1341                        Activity.RESULT_CANCELED, null);
1342            }
1343            final String msg;
1344            if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1345                msg = "Permission Denial: starting " + intent.toString()
1346                        + " from " + callerApp + " (pid=" + callingPid
1347                        + ", uid=" + callingUid + ")" + " with revoked permission "
1348                        + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
1349            } else if (!aInfo.exported) {
1350                msg = "Permission Denial: starting " + intent.toString()
1351                        + " from " + callerApp + " (pid=" + callingPid
1352                        + ", uid=" + callingUid + ")"
1353                        + " not exported from uid " + aInfo.applicationInfo.uid;
1354            } else {
1355                msg = "Permission Denial: starting " + intent.toString()
1356                        + " from " + callerApp + " (pid=" + callingPid
1357                        + ", uid=" + callingUid + ")"
1358                        + " requires " + aInfo.permission;
1359            }
1360            Slog.w(TAG, msg);
1361            throw new SecurityException(msg);
1362        }
1363
1364        if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
1365            final String message = "Appop Denial: starting " + intent.toString()
1366                    + " from " + callerApp + " (pid=" + callingPid
1367                    + ", uid=" + callingUid + ")"
1368                    + " requires " + AppOpsManager.permissionToOp(
1369                            ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
1370            Slog.w(TAG, message);
1371            return false;
1372        } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
1373            final String message = "Appop Denial: starting " + intent.toString()
1374                    + " from " + callerApp + " (pid=" + callingPid
1375                    + ", uid=" + callingUid + ")"
1376                    + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
1377            Slog.w(TAG, message);
1378            return false;
1379        }
1380        if (options != null && options.getLaunchTaskId() != -1) {
1381            final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS,
1382                    callingPid, callingUid);
1383            if (startInTaskPerm != PERMISSION_GRANTED) {
1384                final String msg = "Permission Denial: starting " + intent.toString()
1385                        + " from " + callerApp + " (pid=" + callingPid
1386                        + ", uid=" + callingUid + ") with launchTaskId="
1387                        + options.getLaunchTaskId();
1388                Slog.w(TAG, msg);
1389                throw new SecurityException(msg);
1390            }
1391        }
1392
1393        return true;
1394    }
1395
1396    UserInfo getUserInfo(int userId) {
1397        final long identity = Binder.clearCallingIdentity();
1398        try {
1399            return UserManager.get(mService.mContext).getUserInfo(userId);
1400        } finally {
1401            Binder.restoreCallingIdentity(identity);
1402        }
1403    }
1404
1405    private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
1406            String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
1407        if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
1408                callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
1409                == PackageManager.PERMISSION_DENIED) {
1410            return ACTIVITY_RESTRICTION_PERMISSION;
1411        }
1412
1413        if (activityInfo.permission == null) {
1414            return ACTIVITY_RESTRICTION_NONE;
1415        }
1416
1417        final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
1418        if (opCode == AppOpsManager.OP_NONE) {
1419            return ACTIVITY_RESTRICTION_NONE;
1420        }
1421
1422        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1423                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1424            if (!ignoreTargetSecurity) {
1425                return ACTIVITY_RESTRICTION_APPOP;
1426            }
1427        }
1428
1429        return ACTIVITY_RESTRICTION_NONE;
1430    }
1431
1432    private int getActionRestrictionForCallingPackage(String action,
1433            String callingPackage, int callingPid, int callingUid) {
1434        if (action == null) {
1435            return ACTIVITY_RESTRICTION_NONE;
1436        }
1437
1438        String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
1439        if (permission == null) {
1440            return ACTIVITY_RESTRICTION_NONE;
1441        }
1442
1443        final PackageInfo packageInfo;
1444        try {
1445            packageInfo = mService.mContext.getPackageManager()
1446                    .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
1447        } catch (PackageManager.NameNotFoundException e) {
1448            Slog.i(TAG, "Cannot find package info for " + callingPackage);
1449            return ACTIVITY_RESTRICTION_NONE;
1450        }
1451
1452        if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
1453            return ACTIVITY_RESTRICTION_NONE;
1454        }
1455
1456        if (mService.checkPermission(permission, callingPid, callingUid) ==
1457                PackageManager.PERMISSION_DENIED) {
1458            return ACTIVITY_RESTRICTION_PERMISSION;
1459        }
1460
1461        final int opCode = AppOpsManager.permissionToOpCode(permission);
1462        if (opCode == AppOpsManager.OP_NONE) {
1463            return ACTIVITY_RESTRICTION_NONE;
1464        }
1465
1466        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1467                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1468            return ACTIVITY_RESTRICTION_APPOP;
1469        }
1470
1471        return ACTIVITY_RESTRICTION_NONE;
1472    }
1473
1474    boolean moveActivityStackToFront(ActivityRecord r, String reason) {
1475        if (r == null) {
1476            // Not sure what you are trying to do, but it is not going to work...
1477            return false;
1478        }
1479        final TaskRecord task = r.task;
1480        if (task == null || task.stack == null) {
1481            Slog.w(TAG, "Can't move stack to front for r=" + r + " task=" + task);
1482            return false;
1483        }
1484        task.stack.moveToFront(reason, task);
1485        return true;
1486    }
1487
1488    void setLaunchSource(int uid) {
1489        mLaunchingActivity.setWorkSource(new WorkSource(uid));
1490    }
1491
1492    void acquireLaunchWakelock() {
1493        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1494            throw new IllegalStateException("Calling must be system uid");
1495        }
1496        mLaunchingActivity.acquire();
1497        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1498            // To be safe, don't allow the wake lock to be held for too long.
1499            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1500        }
1501    }
1502
1503    /**
1504     * Called when the frontmost task is idle.
1505     * @return the state of mService.mBooting before this was called.
1506     */
1507    private boolean checkFinishBootingLocked() {
1508        final boolean booting = mService.mBooting;
1509        boolean enableScreen = false;
1510        mService.mBooting = false;
1511        if (!mService.mBooted) {
1512            mService.mBooted = true;
1513            enableScreen = true;
1514        }
1515        if (booting || enableScreen) {
1516            mService.postFinishBooting(booting, enableScreen);
1517        }
1518        return booting;
1519    }
1520
1521    // Checked.
1522    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1523            Configuration config) {
1524        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
1525
1526        ArrayList<ActivityRecord> finishes = null;
1527        ArrayList<UserState> startingUsers = null;
1528        int NS = 0;
1529        int NF = 0;
1530        boolean booting = false;
1531        boolean activityRemoved = false;
1532
1533        ActivityRecord r = ActivityRecord.forTokenLocked(token);
1534        if (r != null) {
1535            if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
1536                    + Debug.getCallers(4));
1537            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1538            r.finishLaunchTickingLocked();
1539            if (fromTimeout) {
1540                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1541            }
1542
1543            // This is a hack to semi-deal with a race condition
1544            // in the client where it can be constructed with a
1545            // newer configuration from when we asked it to launch.
1546            // We'll update with whatever configuration it now says
1547            // it used to launch.
1548            if (config != null) {
1549                r.configuration = config;
1550            }
1551
1552            // We are now idle.  If someone is waiting for a thumbnail from
1553            // us, we can now deliver.
1554            r.idle = true;
1555
1556            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1557            if (isFocusedStack(r.task.stack) || fromTimeout) {
1558                booting = checkFinishBootingLocked();
1559            }
1560        }
1561
1562        if (allResumedActivitiesIdle()) {
1563            if (r != null) {
1564                mService.scheduleAppGcsLocked();
1565            }
1566
1567            if (mLaunchingActivity.isHeld()) {
1568                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1569                if (VALIDATE_WAKE_LOCK_CALLER &&
1570                        Binder.getCallingUid() != Process.myUid()) {
1571                    throw new IllegalStateException("Calling must be system uid");
1572                }
1573                mLaunchingActivity.release();
1574            }
1575            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1576        }
1577
1578        // Atomically retrieve all of the other things to do.
1579        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true);
1580        NS = stops != null ? stops.size() : 0;
1581        if ((NF = mFinishingActivities.size()) > 0) {
1582            finishes = new ArrayList<>(mFinishingActivities);
1583            mFinishingActivities.clear();
1584        }
1585
1586        if (mStartingUsers.size() > 0) {
1587            startingUsers = new ArrayList<>(mStartingUsers);
1588            mStartingUsers.clear();
1589        }
1590
1591        // Stop any activities that are scheduled to do so but have been
1592        // waiting for the next one to start.
1593        for (int i = 0; i < NS; i++) {
1594            r = stops.get(i);
1595            final ActivityStack stack = r.task.stack;
1596            if (stack != null) {
1597                if (r.finishing) {
1598                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1599                } else {
1600                    stack.stopActivityLocked(r);
1601                }
1602            }
1603        }
1604
1605        // Finish any activities that are scheduled to do so but have been
1606        // waiting for the next one to start.
1607        for (int i = 0; i < NF; i++) {
1608            r = finishes.get(i);
1609            final ActivityStack stack = r.task.stack;
1610            if (stack != null) {
1611                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
1612            }
1613        }
1614
1615        if (!booting) {
1616            // Complete user switch
1617            if (startingUsers != null) {
1618                for (int i = 0; i < startingUsers.size(); i++) {
1619                    mService.mUserController.finishUserSwitch(startingUsers.get(i));
1620                }
1621            }
1622        }
1623
1624        mService.trimApplications();
1625        //dump();
1626        //mWindowManager.dump();
1627
1628        if (activityRemoved) {
1629            resumeFocusedStackTopActivityLocked();
1630        }
1631
1632        return r;
1633    }
1634
1635    boolean handleAppDiedLocked(ProcessRecord app) {
1636        boolean hasVisibleActivities = false;
1637        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1638            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1639            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1640                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1641            }
1642        }
1643        return hasVisibleActivities;
1644    }
1645
1646    void closeSystemDialogsLocked() {
1647        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1648            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1649            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1650                stacks.get(stackNdx).closeSystemDialogsLocked();
1651            }
1652        }
1653    }
1654
1655    void removeUserLocked(int userId) {
1656        mUserStackInFront.delete(userId);
1657    }
1658
1659    /**
1660     * Update the last used stack id for non-current user (current user's last
1661     * used stack is the focused stack)
1662     */
1663    void updateUserStackLocked(int userId, ActivityStack stack) {
1664        if (userId != mCurrentUser) {
1665            mUserStackInFront.put(userId, stack != null ? stack.getStackId() : HOME_STACK_ID);
1666        }
1667    }
1668
1669    /**
1670     * @return true if some activity was finished (or would have finished if doit were true).
1671     */
1672    boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
1673            boolean doit, boolean evenPersistent, int userId) {
1674        boolean didSomething = false;
1675        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1676            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1677            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1678                final ActivityStack stack = stacks.get(stackNdx);
1679                if (stack.finishDisabledPackageActivitiesLocked(
1680                        packageName, filterByClasses, doit, evenPersistent, userId)) {
1681                    didSomething = true;
1682                }
1683            }
1684        }
1685        return didSomething;
1686    }
1687
1688    void updatePreviousProcessLocked(ActivityRecord r) {
1689        // Now that this process has stopped, we may want to consider
1690        // it to be the previous app to try to keep around in case
1691        // the user wants to return to it.
1692
1693        // First, found out what is currently the foreground app, so that
1694        // we don't blow away the previous app if this activity is being
1695        // hosted by the process that is actually still the foreground.
1696        ProcessRecord fgApp = null;
1697        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1698            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1699            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1700                final ActivityStack stack = stacks.get(stackNdx);
1701                if (isFocusedStack(stack)) {
1702                    if (stack.mResumedActivity != null) {
1703                        fgApp = stack.mResumedActivity.app;
1704                    } else if (stack.mPausingActivity != null) {
1705                        fgApp = stack.mPausingActivity.app;
1706                    }
1707                    break;
1708                }
1709            }
1710        }
1711
1712        // Now set this one as the previous process, only if that really
1713        // makes sense to.
1714        if (r.app != null && fgApp != null && r.app != fgApp
1715                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
1716                && r.app != mService.mHomeProcess) {
1717            mService.mPreviousProcess = r.app;
1718            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1719        }
1720    }
1721
1722    boolean resumeFocusedStackTopActivityLocked() {
1723        return resumeFocusedStackTopActivityLocked(null, null, null);
1724    }
1725
1726    boolean resumeFocusedStackTopActivityLocked(
1727            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1728        if (targetStack != null && isFocusedStack(targetStack)) {
1729            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1730        }
1731        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
1732        return false;
1733    }
1734
1735    void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
1736        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1737            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1738            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1739                stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo);
1740            }
1741        }
1742    }
1743
1744    TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
1745        TaskRecord finishedTask = null;
1746        ActivityStack focusedStack = getFocusedStack();
1747        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1748            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1749            final int numStacks = stacks.size();
1750            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1751                final ActivityStack stack = stacks.get(stackNdx);
1752                TaskRecord t = stack.finishTopRunningActivityLocked(app, reason);
1753                if (stack == focusedStack || finishedTask == null) {
1754                    finishedTask = t;
1755                }
1756            }
1757        }
1758        return finishedTask;
1759    }
1760
1761    void finishVoiceTask(IVoiceInteractionSession session) {
1762        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1763            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1764            final int numStacks = stacks.size();
1765            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1766                final ActivityStack stack = stacks.get(stackNdx);
1767                stack.finishVoiceTask(session);
1768            }
1769        }
1770    }
1771
1772    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options,
1773            String reason, boolean forceNonResizeable) {
1774        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
1775            mUserLeaving = true;
1776        }
1777        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
1778            // Caller wants the home activity moved with it.  To accomplish this,
1779            // we'll just indicate that this task returns to the home task.
1780            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1781        }
1782        if (task.stack == null) {
1783            Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
1784                    + task + " to front. Stack is null");
1785            return;
1786        }
1787
1788        if (task.isResizeable() && options != null) {
1789            int stackId = options.getLaunchStackId();
1790            if (canUseActivityOptionsLaunchBounds(options, stackId)) {
1791                final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds());
1792                task.updateOverrideConfiguration(bounds);
1793                if (stackId == INVALID_STACK_ID) {
1794                    stackId = task.getLaunchStackId();
1795                }
1796                if (stackId != task.stack.mStackId) {
1797                    final ActivityStack stack = moveTaskToStackUncheckedLocked(
1798                            task, stackId, ON_TOP, !FORCE_FOCUS, reason);
1799                    stackId = stack.mStackId;
1800                    // moveTaskToStackUncheckedLocked() should already placed the task on top,
1801                    // still need moveTaskToFrontLocked() below for any transition settings.
1802                }
1803                if (StackId.resizeStackWithLaunchBounds(stackId)) {
1804                    resizeStackLocked(stackId, bounds,
1805                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
1806                            !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME);
1807                } else {
1808                    // WM resizeTask must be done after the task is moved to the correct stack,
1809                    // because Task's setBounds() also updates dim layer's bounds, but that has
1810                    // dependency on the stack.
1811                    mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig,
1812                            false /* relayout */, false /* forced */);
1813                }
1814            }
1815        }
1816
1817        final ActivityRecord r = task.getTopActivity();
1818        task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
1819                r == null ? null : r.appTimeTracker, reason);
1820
1821        if (DEBUG_STACK) Slog.d(TAG_STACK,
1822                "findTaskToMoveToFront: moved to front of stack=" + task.stack);
1823
1824        handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId,
1825                forceNonResizeable);
1826    }
1827
1828    boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
1829        // We use the launch bounds in the activity options is the device supports freeform
1830        // window management or is launching into the pinned stack.
1831        if (options.getLaunchBounds() == null) {
1832            return false;
1833        }
1834        return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID)
1835                || mService.mSupportsFreeformWindowManagement;
1836    }
1837
1838    ActivityStack getStack(int stackId) {
1839        return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
1840    }
1841
1842    ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
1843        ActivityContainer activityContainer = mActivityContainers.get(stackId);
1844        if (activityContainer != null) {
1845            return activityContainer.mStack;
1846        }
1847        if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
1848            return null;
1849        }
1850        return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
1851    }
1852
1853    ArrayList<ActivityStack> getStacks() {
1854        ArrayList<ActivityStack> allStacks = new ArrayList<>();
1855        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1856            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
1857        }
1858        return allStacks;
1859    }
1860
1861    IBinder getHomeActivityToken() {
1862        ActivityRecord homeActivity = getHomeActivity();
1863        if (homeActivity != null) {
1864            return homeActivity.appToken;
1865        }
1866        return null;
1867    }
1868
1869    ActivityRecord getHomeActivity() {
1870        return getHomeActivityForUser(mCurrentUser);
1871    }
1872
1873    ActivityRecord getHomeActivityForUser(int userId) {
1874        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
1875        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1876            final TaskRecord task = tasks.get(taskNdx);
1877            if (task.isHomeTask()) {
1878                final ArrayList<ActivityRecord> activities = task.mActivities;
1879                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1880                    final ActivityRecord r = activities.get(activityNdx);
1881                    if (r.isHomeActivity()
1882                            && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
1883                        return r;
1884                    }
1885                }
1886            }
1887        }
1888        return null;
1889    }
1890
1891    /**
1892     * Returns if a stack should be treated as if it's docked. Returns true if the stack is
1893     * the docked stack itself, or if it's side-by-side to the docked stack.
1894     */
1895    boolean isStackDockedInEffect(int stackId) {
1896        return stackId == DOCKED_STACK_ID ||
1897                (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null);
1898    }
1899
1900    ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
1901            IActivityContainerCallback callback) {
1902        ActivityContainer activityContainer =
1903                new VirtualActivityContainer(parentActivity, callback);
1904        mActivityContainers.put(activityContainer.mStackId, activityContainer);
1905        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
1906                "createActivityContainer: " + activityContainer);
1907        parentActivity.mChildContainers.add(activityContainer);
1908        return activityContainer;
1909    }
1910
1911    void removeChildActivityContainers(ActivityRecord parentActivity) {
1912        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
1913        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
1914            ActivityContainer container = childStacks.remove(containerNdx);
1915            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
1916                    + container);
1917            container.release();
1918        }
1919    }
1920
1921    void deleteActivityContainer(IActivityContainer container) {
1922        ActivityContainer activityContainer = (ActivityContainer)container;
1923        if (activityContainer != null) {
1924            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
1925                    "deleteActivityContainer: callers=" + Debug.getCallers(4));
1926            final int stackId = activityContainer.mStackId;
1927            mActivityContainers.remove(stackId);
1928            mWindowManager.removeStack(stackId);
1929        }
1930    }
1931
1932    void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
1933            boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) {
1934        if (stackId == DOCKED_STACK_ID) {
1935            resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null,
1936                    preserveWindows);
1937            return;
1938        }
1939        final ActivityStack stack = getStack(stackId);
1940        if (stack == null) {
1941            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1942            return;
1943        }
1944
1945        if (!allowResizeInDockedMode && getStack(DOCKED_STACK_ID) != null) {
1946            // If the docked stack exist we don't allow resizes of stacks not caused by the docked
1947            // stack size changing so things don't get out of sync.
1948            return;
1949        }
1950
1951        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
1952        mWindowManager.deferSurfaceLayout();
1953        try {
1954            resizeStackUncheckedLocked(stack, bounds, tempTaskBounds, tempTaskInsetBounds);
1955            if (!deferResume) {
1956                ensureConfigurationAndResume(
1957                        stack, stack.topRunningActivityLocked(), preserveWindows);
1958            }
1959        } finally {
1960            mWindowManager.continueSurfaceLayout();
1961            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
1962        }
1963    }
1964
1965    void deferUpdateBounds(int stackId) {
1966        final ActivityStack stack = getStack(stackId);
1967        if (stack != null) {
1968            stack.deferUpdateBounds();
1969        }
1970    }
1971
1972    void continueUpdateBounds(int stackId) {
1973        final ActivityStack stack = getStack(stackId);
1974        if (stack != null) {
1975            stack.continueUpdateBounds();
1976        }
1977    }
1978
1979    void notifyAppTransitionDone() {
1980        continueUpdateBounds(HOME_STACK_ID);
1981        for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
1982            final int taskId = mResizingTasksDuringAnimation.valueAt(i);
1983            if (anyTaskForIdLocked(taskId) != null) {
1984                mWindowManager.setTaskDockedResizing(taskId, false);
1985            }
1986        }
1987        mResizingTasksDuringAnimation.clear();
1988    }
1989
1990    void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
1991            Rect tempTaskInsetBounds) {
1992        bounds = TaskRecord.validateBounds(bounds);
1993
1994        if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) {
1995            return;
1996        }
1997
1998        mTmpBounds.clear();
1999        mTmpConfigs.clear();
2000        mTmpInsetBounds.clear();
2001        final ArrayList<TaskRecord> tasks = stack.getAllTasks();
2002        final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
2003        final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds;
2004        for (int i = tasks.size() - 1; i >= 0; i--) {
2005            final TaskRecord task = tasks.get(i);
2006            if (task.isResizeable()) {
2007                if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
2008                    // For freeform stack we don't adjust the size of the tasks to match that
2009                    // of the stack, but we do try to make sure the tasks are still contained
2010                    // with the bounds of the stack.
2011                    tempRect2.set(task.mBounds);
2012                    fitWithinBounds(tempRect2, bounds);
2013                    task.updateOverrideConfiguration(tempRect2);
2014                } else {
2015                    task.updateOverrideConfiguration(taskBounds, insetBounds);
2016                }
2017            }
2018
2019            mTmpConfigs.put(task.taskId, task.mOverrideConfig);
2020            mTmpBounds.put(task.taskId, task.mBounds);
2021            if (tempTaskInsetBounds != null) {
2022                mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
2023            }
2024        }
2025
2026        // We might trigger a configuration change. Save the current task bounds for freezing.
2027        mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
2028        stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs,
2029                mTmpBounds, mTmpInsetBounds);
2030        stack.setBounds(bounds);
2031    }
2032
2033    private void ensureConfigurationAndResume(ActivityStack stack, ActivityRecord r,
2034            boolean preserveWindows) {
2035        if (r == null || !r.visible) {
2036            return;
2037        }
2038        final boolean updated = stack.ensureActivityConfigurationLocked(r, 0,
2039                preserveWindows);
2040        if (!updated) {
2041            resumeFocusedStackTopActivityLocked();
2042        }
2043    }
2044
2045    void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) {
2046        final ActivityStack stack = getStack(fromStackId);
2047        if (stack == null) {
2048            return;
2049        }
2050
2051        mWindowManager.deferSurfaceLayout();
2052        try {
2053            if (fromStackId == DOCKED_STACK_ID) {
2054
2055                // We are moving all tasks from the docked stack to the fullscreen stack,
2056                // which is dismissing the docked stack, so resize all other stacks to
2057                // fullscreen here already so we don't end up with resize trashing.
2058                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
2059                    if (StackId.isResizeableByDockedStack(i)) {
2060                        ActivityStack otherStack = getStack(i);
2061                        if (otherStack != null) {
2062                            resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS,
2063                                    true /* allowResizeInDockedMode */, DEFER_RESUME);
2064                        }
2065                    }
2066                }
2067
2068                // Also disable docked stack resizing since we have manually adjusted the
2069                // size of other stacks above and we don't want to trigger a docked stack
2070                // resize when we remove task from it below and it is detached from the
2071                // display because it no longer contains any tasks.
2072                mAllowDockedStackResize = false;
2073            }
2074            final ArrayList<TaskRecord> tasks = stack.getAllTasks();
2075            final int size = tasks.size();
2076            if (onTop) {
2077                for (int i = 0; i < size; i++) {
2078                    moveTaskToStackLocked(tasks.get(i).taskId,
2079                            FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
2080                            "moveTasksToFullscreenStack", ANIMATE);
2081                }
2082            } else {
2083                for (int i = size - 1; i >= 0; i--) {
2084                    positionTaskInStackLocked(tasks.get(i).taskId,
2085                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
2086                }
2087            }
2088        } finally {
2089            mAllowDockedStackResize = true;
2090            mWindowManager.continueSurfaceLayout();
2091        }
2092    }
2093
2094    void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
2095            Rect tempDockedTaskInsetBounds,
2096            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows) {
2097
2098        if (!mAllowDockedStackResize) {
2099            // Docked stack resize currently disabled.
2100            return;
2101        }
2102
2103        final ActivityStack stack = getStack(DOCKED_STACK_ID);
2104        if (stack == null) {
2105            Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
2106            return;
2107        }
2108
2109        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack");
2110        mWindowManager.deferSurfaceLayout();
2111        try {
2112            // Don't allow re-entry while resizing. E.g. due to docked stack detaching.
2113            mAllowDockedStackResize = false;
2114            ActivityRecord r = stack.topRunningActivityLocked();
2115            resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds,
2116                    tempDockedTaskInsetBounds);
2117
2118            // TODO: Checking for isAttached might not be needed as if the user passes in null
2119            // dockedBounds then they want the docked stack to be dismissed.
2120            if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) {
2121                // The dock stack either was dismissed or went fullscreen, which is kinda the same.
2122                // In this case we make all other static stacks fullscreen and move all
2123                // docked stack tasks to the fullscreen stack.
2124                moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP);
2125
2126                // stack shouldn't contain anymore activities, so nothing to resume.
2127                r = null;
2128            } else {
2129                // Docked stacks occupy a dedicated region on screen so the size of all other
2130                // static stacks need to be adjusted so they don't overlap with the docked stack.
2131                // We get the bounds to use from window manager which has been adjusted for any
2132                // screen controls and is also the same for all stacks.
2133                mWindowManager.getStackDockedModeBounds(
2134                        HOME_STACK_ID, tempRect, true /* ignoreVisibility */);
2135                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
2136                    if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) {
2137                        resizeStackLocked(i, tempRect, tempOtherTaskBounds,
2138                                tempOtherTaskInsetBounds, preserveWindows,
2139                                true /* allowResizeInDockedMode */, !DEFER_RESUME);
2140                    }
2141                }
2142            }
2143            ensureConfigurationAndResume(stack, r, preserveWindows);
2144        } finally {
2145            mAllowDockedStackResize = true;
2146            mWindowManager.continueSurfaceLayout();
2147            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2148        }
2149
2150        mResizeDockedStackTimeout.notifyResizing(dockedBounds,
2151                tempDockedTaskBounds != null
2152                || tempDockedTaskInsetBounds != null
2153                || tempOtherTaskBounds != null
2154                || tempOtherTaskInsetBounds != null);
2155    }
2156
2157    void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
2158        final ActivityStack stack = getStack(PINNED_STACK_ID);
2159        if (stack == null) {
2160            Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
2161            return;
2162        }
2163        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack");
2164        mWindowManager.deferSurfaceLayout();
2165        try {
2166            ActivityRecord r = stack.topRunningActivityLocked();
2167            resizeStackUncheckedLocked(stack, pinnedBounds, tempPinnedTaskBounds,
2168                    null);
2169            ensureConfigurationAndResume(stack, r, false);
2170        } finally {
2171            mWindowManager.continueSurfaceLayout();
2172            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2173        }
2174    }
2175
2176    boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow,
2177            boolean deferResume) {
2178        if (!task.isResizeable()) {
2179            Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
2180            return true;
2181        }
2182
2183        // If this is a forced resize, let it go through even if the bounds is not changing,
2184        // as we might need a relayout due to surface size change (to/from fullscreen).
2185        final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
2186        if (Objects.equals(task.mBounds, bounds) && !forced) {
2187            // Nothing to do here...
2188            return true;
2189        }
2190        bounds = TaskRecord.validateBounds(bounds);
2191
2192        if (!mWindowManager.isValidTaskId(task.taskId)) {
2193            // Task doesn't exist in window manager yet (e.g. was restored from recents).
2194            // All we can do for now is update the bounds so it can be used when the task is
2195            // added to window manager.
2196            task.updateOverrideConfiguration(bounds);
2197            if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
2198                // re-restore the task so it can have the proper stack association.
2199                restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID);
2200            }
2201            return true;
2202        }
2203
2204        // Do not move the task to another stack here.
2205        // This method assumes that the task is already placed in the right stack.
2206        // we do not mess with that decision and we only do the resize!
2207
2208        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId);
2209
2210        final Configuration overrideConfig =  task.updateOverrideConfiguration(bounds);
2211        // This variable holds information whether the configuration didn't change in a significant
2212        // way and the activity was kept the way it was. If it's false, it means the activity had
2213        // to be relaunched due to configuration change.
2214        boolean kept = true;
2215        if (overrideConfig != null) {
2216            final ActivityRecord r = task.topRunningActivityLocked();
2217            if (r != null) {
2218                final ActivityStack stack = task.stack;
2219                kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow);
2220
2221                if (!deferResume) {
2222
2223                    // All other activities must be made visible with their correct configuration.
2224                    ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
2225                    if (!kept) {
2226                        resumeFocusedStackTopActivityLocked();
2227                    }
2228                }
2229            }
2230        }
2231        mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced);
2232
2233        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2234        return kept;
2235    }
2236
2237    ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
2238        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2239        if (activityDisplay == null) {
2240            return null;
2241        }
2242
2243        ActivityContainer activityContainer = new ActivityContainer(stackId);
2244        mActivityContainers.put(stackId, activityContainer);
2245        activityContainer.attachToDisplayLocked(activityDisplay, onTop);
2246        return activityContainer.mStack;
2247    }
2248
2249    int getNextStackId() {
2250        while (true) {
2251            if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID
2252                    && getStack(mNextFreeStackId) == null) {
2253                break;
2254            }
2255            mNextFreeStackId++;
2256        }
2257        return mNextFreeStackId;
2258    }
2259
2260    /**
2261     * Restores a recent task to a stack
2262     * @param task The recent task to be restored.
2263     * @param stackId The stack to restore the task to (default launch stack will be used
2264     *                if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}).
2265     * @return true if the task has been restored successfully.
2266     */
2267    private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
2268        if (stackId == INVALID_STACK_ID) {
2269            stackId = task.getLaunchStackId();
2270        } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) {
2271            // Preferred stack is the docked stack, but the task can't go in the docked stack.
2272            // Put it in the fullscreen stack.
2273            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
2274        }
2275
2276        if (task.stack != null) {
2277            // Task has already been restored once. See if we need to do anything more
2278            if (task.stack.mStackId == stackId) {
2279                // Nothing else to do since it is already restored in the right stack.
2280                return true;
2281            }
2282            // Remove current stack association, so we can re-associate the task with the
2283            // right stack below.
2284            task.stack.removeTask(task, "restoreRecentTaskLocked", MOVING);
2285        }
2286
2287        final ActivityStack stack =
2288                getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
2289
2290        if (stack == null) {
2291            // What does this mean??? Not sure how we would get here...
2292            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2293                    "Unable to find/create stack to restore recent task=" + task);
2294            return false;
2295        }
2296
2297        stack.addTask(task, false, "restoreRecentTask");
2298        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2299                "Added restored task=" + task + " to stack=" + stack);
2300        final ArrayList<ActivityRecord> activities = task.mActivities;
2301        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2302            stack.addConfigOverride(activities.get(activityNdx), task);
2303        }
2304        return true;
2305    }
2306
2307    /**
2308     * Moves the specified task record to the input stack id.
2309     * WARNING: This method performs an unchecked/raw move of the task and
2310     * can leave the system in an unstable state if used incorrectly.
2311     * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack.
2312     * @param task Task to move.
2313     * @param stackId Id of stack to move task to.
2314     * @param toTop True if the task should be placed at the top of the stack.
2315     * @param forceFocus if focus should be moved to the new stack
2316     * @param reason Reason the task is been moved.
2317     * @return The stack the task was moved to.
2318     */
2319    ActivityStack moveTaskToStackUncheckedLocked(
2320            TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
2321
2322        if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) {
2323            throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't "
2324                    + "support multi-window task=" + task + " to stackId=" + stackId);
2325        }
2326
2327        final ActivityRecord r = task.getTopActivity();
2328        final ActivityStack prevStack = task.stack;
2329        final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r);
2330        final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r);
2331        // In some cases the focused stack isn't the front stack. E.g. pinned stack.
2332        // Whenever we are moving the top activity from the front stack we want to make sure to move
2333        // the stack to the front.
2334        final boolean wasFront = isFrontStack(prevStack)
2335                && (prevStack.topRunningActivityLocked() == r);
2336
2337        if (stackId == DOCKED_STACK_ID && !task.isResizeable()) {
2338            // We don't allow moving a unresizeable task to the docked stack since the docked
2339            // stack is used for split-screen mode and will cause things like the docked divider to
2340            // show up. We instead leave the task in its current stack or move it to the fullscreen
2341            // stack if it isn't currently in a stack.
2342            stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
2343            Slog.w(TAG, "Can not move unresizeable task=" + task
2344                    + " to docked stack. Moving to stackId=" + stackId + " instead.");
2345        }
2346
2347        // Temporarily disable resizeablility of task we are moving. We don't want it to be resized
2348        // if a docked stack is created below which will lead to the stack we are moving from and
2349        // its resizeable tasks being resized.
2350        task.mTemporarilyUnresizable = true;
2351        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop);
2352        task.mTemporarilyUnresizable = false;
2353        mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop);
2354        stack.addTask(task, toTop, reason);
2355
2356        // If the task had focus before (or we're requested to move focus),
2357        // move focus to the new stack by moving the stack to the front.
2358        stack.moveToFrontAndResumeStateIfNeeded(
2359                r, forceFocus || wasFocused || wasFront, wasResumed, reason);
2360
2361        return stack;
2362    }
2363
2364    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
2365            String reason, boolean animate) {
2366        return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate,
2367                false /* deferResume */);
2368    }
2369
2370    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
2371            String reason, boolean animate, boolean deferResume) {
2372        final TaskRecord task = anyTaskForIdLocked(taskId);
2373        if (task == null) {
2374            Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
2375            return false;
2376        }
2377
2378        if (task.stack != null && task.stack.mStackId == stackId) {
2379            // You are already in the right stack silly...
2380            Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId);
2381            return true;
2382        }
2383
2384        if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
2385            throw new IllegalArgumentException("moveTaskToStack:"
2386                    + "Attempt to move task " + taskId + " to unsupported freeform stack");
2387        }
2388
2389        final ActivityRecord topActivity = task.getTopActivity();
2390        final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID;
2391        final boolean mightReplaceWindow =
2392                StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) && topActivity != null;
2393        if (mightReplaceWindow) {
2394            // We are about to relaunch the activity because its configuration changed due to
2395            // being maximized, i.e. size change. The activity will first remove the old window
2396            // and then add a new one. This call will tell window manager about this, so it can
2397            // preserve the old window until the new one is drawn. This prevents having a gap
2398            // between the removal and addition, in which no window is visible. We also want the
2399            // entrance of the new window to be properly animated.
2400            // Note here we always set the replacing window first, as the flags might be needed
2401            // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
2402            mWindowManager.setReplacingWindow(topActivity.appToken, animate);
2403        }
2404
2405        mWindowManager.deferSurfaceLayout();
2406        final int preferredLaunchStackId = stackId;
2407        boolean kept = true;
2408        try {
2409            final ActivityStack stack = moveTaskToStackUncheckedLocked(
2410                    task, stackId, toTop, forceFocus, reason + " moveTaskToStack");
2411            stackId = stack.mStackId;
2412
2413            if (!animate) {
2414                stack.mNoAnimActivities.add(topActivity);
2415            }
2416
2417            // We might trigger a configuration change. Save the current task bounds for freezing.
2418            mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
2419
2420            // Make sure the task has the appropriate bounds/size for the stack it is in.
2421            if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
2422                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
2423                        !mightReplaceWindow, deferResume);
2424            } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
2425                Rect bounds = task.getLaunchBounds();
2426                if (bounds == null) {
2427                    stack.layoutTaskInStack(task, null);
2428                    bounds = task.mBounds;
2429                }
2430                kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow,
2431                        deferResume);
2432            } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
2433                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
2434                        !mightReplaceWindow, deferResume);
2435            }
2436        } finally {
2437            mWindowManager.continueSurfaceLayout();
2438        }
2439
2440        if (mightReplaceWindow) {
2441            // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
2442            // window), we need to clear the replace window settings. Otherwise, we schedule a
2443            // timeout to remove the old window if the replacing window is not coming in time.
2444            mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept);
2445        }
2446
2447        if (!deferResume) {
2448
2449            // The task might have already been running and its visibility needs to be synchronized with
2450            // the visibility of the stack / windows.
2451            ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
2452            resumeFocusedStackTopActivityLocked();
2453        }
2454
2455        handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId);
2456
2457        return (preferredLaunchStackId == stackId);
2458    }
2459
2460    boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) {
2461        final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
2462        if (stack == null) {
2463            throw new IllegalArgumentException(
2464                    "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId);
2465        }
2466
2467        final ActivityRecord r = stack.topRunningActivityLocked();
2468        if (r == null) {
2469            Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity"
2470                    + " in stack=" + stack);
2471            return false;
2472        }
2473
2474        if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
2475            Slog.w(TAG,
2476                    "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for "
2477                            + " r=" + r);
2478            return false;
2479        }
2480
2481        moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds);
2482        return true;
2483    }
2484
2485    void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) {
2486        mWindowManager.deferSurfaceLayout();
2487        try {
2488            final TaskRecord task = r.task;
2489
2490            // Need to make sure the pinned stack exist so we can resize it below...
2491            final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
2492
2493            // Resize the pinned stack to match the current size of the task the activity we are
2494            // going to be moving is currently contained in. We do this to have the right starting
2495            // animation bounds for the pinned stack to the desired bounds the caller wants.
2496            resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
2497                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
2498                    true /* allowResizeInDockedMode */, !DEFER_RESUME);
2499
2500            if (task.mActivities.size() == 1) {
2501                // There is only one activity in the task. So, we can just move the task over to
2502                // the stack without re-parenting the activity in a different task.
2503                if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
2504                    // Move the home stack forward if the task we just moved to the pinned stack
2505                    // was launched from home so home should be visible behind it.
2506                    moveHomeStackToFront(reason);
2507                }
2508                moveTaskToStackLocked(
2509                        task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE);
2510            } else {
2511                stack.moveActivityToStack(r);
2512            }
2513        } finally {
2514            mWindowManager.continueSurfaceLayout();
2515        }
2516
2517        // The task might have already been running and its visibility needs to be synchronized
2518        // with the visibility of the stack / windows.
2519        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2520        resumeFocusedStackTopActivityLocked();
2521
2522        mWindowManager.animateResizePinnedStack(bounds, -1);
2523        mService.notifyActivityPinnedLocked();
2524    }
2525
2526    void positionTaskInStackLocked(int taskId, int stackId, int position) {
2527        final TaskRecord task = anyTaskForIdLocked(taskId);
2528        if (task == null) {
2529            Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
2530            return;
2531        }
2532        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
2533
2534        task.updateOverrideConfigurationForStack(stack);
2535
2536        mWindowManager.positionTaskInStack(
2537                taskId, stackId, position, task.mBounds, task.mOverrideConfig);
2538        stack.positionTask(task, position);
2539        // The task might have already been running and its visibility needs to be synchronized with
2540        // the visibility of the stack / windows.
2541        stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2542        resumeFocusedStackTopActivityLocked();
2543    }
2544
2545    ActivityRecord findTaskLocked(ActivityRecord r) {
2546        mTmpFindTaskResult.r = null;
2547        mTmpFindTaskResult.matchedByRootAffinity = false;
2548        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
2549        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2550            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2551            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2552                final ActivityStack stack = stacks.get(stackNdx);
2553                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2554                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
2555                    continue;
2556                }
2557                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2558                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
2559                            "Skipping stack: (new task not allowed) " + stack);
2560                    continue;
2561                }
2562                stack.findTaskLocked(r, mTmpFindTaskResult);
2563                // It is possible to have task in multiple stacks with the same root affinity.
2564                // If the match we found was based on root affinity we keep on looking to see if
2565                // there is a better match in another stack. We eventually return the match based
2566                // on root affinity if we don't find a better match.
2567                if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) {
2568                    return mTmpFindTaskResult.r;
2569                }
2570            }
2571        }
2572        if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found");
2573        return mTmpFindTaskResult.r;
2574    }
2575
2576    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2577        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2578            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2579            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2580                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2581                if (ar != null) {
2582                    return ar;
2583                }
2584            }
2585        }
2586        return null;
2587    }
2588
2589    void goingToSleepLocked() {
2590        scheduleSleepTimeout();
2591        if (!mGoingToSleep.isHeld()) {
2592            mGoingToSleep.acquire();
2593            if (mLaunchingActivity.isHeld()) {
2594                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2595                    throw new IllegalStateException("Calling must be system uid");
2596                }
2597                mLaunchingActivity.release();
2598                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2599            }
2600        }
2601        checkReadyForSleepLocked();
2602    }
2603
2604    boolean shutdownLocked(int timeout) {
2605        goingToSleepLocked();
2606
2607        boolean timedout = false;
2608        final long endTime = System.currentTimeMillis() + timeout;
2609        while (true) {
2610            boolean cantShutdown = false;
2611            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2612                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2613                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2614                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2615                }
2616            }
2617            if (cantShutdown) {
2618                long timeRemaining = endTime - System.currentTimeMillis();
2619                if (timeRemaining > 0) {
2620                    try {
2621                        mService.wait(timeRemaining);
2622                    } catch (InterruptedException e) {
2623                    }
2624                } else {
2625                    Slog.w(TAG, "Activity manager shutdown timed out");
2626                    timedout = true;
2627                    break;
2628                }
2629            } else {
2630                break;
2631            }
2632        }
2633
2634        // Force checkReadyForSleep to complete.
2635        mSleepTimeout = true;
2636        checkReadyForSleepLocked();
2637
2638        return timedout;
2639    }
2640
2641    void comeOutOfSleepIfNeededLocked() {
2642        removeSleepTimeouts();
2643        if (mGoingToSleep.isHeld()) {
2644            mGoingToSleep.release();
2645        }
2646        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2647            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2648            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2649                final ActivityStack stack = stacks.get(stackNdx);
2650                stack.awakeFromSleepingLocked();
2651                if (isFocusedStack(stack)) {
2652                    resumeFocusedStackTopActivityLocked();
2653                }
2654            }
2655        }
2656        mGoingToSleepActivities.clear();
2657    }
2658
2659    void activitySleptLocked(ActivityRecord r) {
2660        mGoingToSleepActivities.remove(r);
2661        checkReadyForSleepLocked();
2662    }
2663
2664    void checkReadyForSleepLocked() {
2665        if (!mService.isSleepingOrShuttingDown()) {
2666            // Do not care.
2667            return;
2668        }
2669
2670        if (!mSleepTimeout) {
2671            boolean dontSleep = false;
2672            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2673                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2674                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2675                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2676                }
2677            }
2678
2679            if (mStoppingActivities.size() > 0) {
2680                // Still need to tell some activities to stop; can't sleep yet.
2681                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
2682                        + mStoppingActivities.size() + " activities");
2683                scheduleIdleLocked();
2684                dontSleep = true;
2685            }
2686
2687            if (mGoingToSleepActivities.size() > 0) {
2688                // Still need to tell some activities to sleep; can't sleep yet.
2689                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
2690                        + mGoingToSleepActivities.size() + " activities");
2691                dontSleep = true;
2692            }
2693
2694            if (dontSleep) {
2695                return;
2696            }
2697        }
2698
2699        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2700            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2701            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2702                stacks.get(stackNdx).goToSleep();
2703            }
2704        }
2705
2706        removeSleepTimeouts();
2707
2708        if (mGoingToSleep.isHeld()) {
2709            mGoingToSleep.release();
2710        }
2711        if (mService.mShuttingDown) {
2712            mService.notifyAll();
2713        }
2714    }
2715
2716    boolean reportResumedActivityLocked(ActivityRecord r) {
2717        final ActivityStack stack = r.task.stack;
2718        if (isFocusedStack(stack)) {
2719            mService.updateUsageStats(r, true);
2720        }
2721        if (allResumedActivitiesComplete()) {
2722            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2723            mWindowManager.executeAppTransition();
2724            return true;
2725        }
2726        return false;
2727    }
2728
2729    void handleAppCrashLocked(ProcessRecord app) {
2730        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2731            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2732            int stackNdx = stacks.size() - 1;
2733            while (stackNdx >= 0) {
2734                stacks.get(stackNdx).handleAppCrashLocked(app);
2735                stackNdx--;
2736            }
2737        }
2738    }
2739
2740    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
2741        final ActivityStack stack = r.task.stack;
2742        if (stack == null) {
2743            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2744                    "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
2745            return false;
2746        }
2747        final boolean isVisible = stack.hasVisibleBehindActivity();
2748        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2749                "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
2750
2751        final ActivityRecord top = topRunningActivityLocked();
2752        if (top == null || top == r || (visible == isVisible)) {
2753            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
2754            stack.setVisibleBehindActivity(visible ? r : null);
2755            return true;
2756        }
2757
2758        // A non-top activity is reporting a visibility change.
2759        if (visible && top.fullscreen) {
2760            // Let the caller know that it can't be seen.
2761            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2762                    "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
2763                    + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
2764                    + top.app.thread);
2765            return false;
2766        } else if (!visible && stack.getVisibleBehindActivity() != r) {
2767            // Only the activity set as currently visible behind should actively reset its
2768            // visible behind state.
2769            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2770                    "requestVisibleBehind: returning visible=" + visible
2771                    + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
2772                    + " r=" + r);
2773            return false;
2774        }
2775
2776        stack.setVisibleBehindActivity(visible ? r : null);
2777        if (!visible) {
2778            // If there is a translucent home activity, we need to force it stop being translucent,
2779            // because we can't depend on the application to necessarily perform that operation.
2780            // Check out b/14469711 for details.
2781            final ActivityRecord next = stack.findNextTranslucentActivity(r);
2782            if (next != null && next.isHomeActivity()) {
2783                mService.convertFromTranslucent(next.appToken);
2784            }
2785        }
2786        if (top.app != null && top.app.thread != null) {
2787            // Notify the top app of the change.
2788            try {
2789                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
2790            } catch (RemoteException e) {
2791            }
2792        }
2793        return true;
2794    }
2795
2796    // Called when WindowManager has finished animating the launchingBehind activity to the back.
2797    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2798        final TaskRecord task = r.task;
2799        final ActivityStack stack = task.stack;
2800
2801        r.mLaunchTaskBehind = false;
2802        task.setLastThumbnailLocked(stack.screenshotActivitiesLocked(r));
2803        mRecentTasks.addLocked(task);
2804        mService.notifyTaskStackChangedLocked();
2805        mWindowManager.setAppVisibility(r.appToken, false);
2806
2807        // When launching tasks behind, update the last active time of the top task after the new
2808        // task has been shown briefly
2809        final ActivityRecord top = stack.topActivity();
2810        if (top != null) {
2811            top.task.touchActiveTime();
2812        }
2813    }
2814
2815    void scheduleLaunchTaskBehindComplete(IBinder token) {
2816        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2817    }
2818
2819    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
2820            boolean preserveWindows) {
2821        // First the front stacks. In case any are not fullscreen and are in front of home.
2822        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2823            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2824            final int topStackNdx = stacks.size() - 1;
2825            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2826                final ActivityStack stack = stacks.get(stackNdx);
2827                stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
2828            }
2829        }
2830    }
2831
2832    void invalidateTaskLayers() {
2833        mTaskLayersChanged = true;
2834    }
2835
2836    void rankTaskLayersIfNeeded() {
2837        if (!mTaskLayersChanged) {
2838            return;
2839        }
2840        mTaskLayersChanged = false;
2841        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
2842            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2843            int baseLayer = 0;
2844            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2845                baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer);
2846            }
2847        }
2848    }
2849
2850    void clearOtherAppTimeTrackers(AppTimeTracker except) {
2851        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2852            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2853            final int topStackNdx = stacks.size() - 1;
2854            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2855                final ActivityStack stack = stacks.get(stackNdx);
2856                stack.clearOtherAppTimeTrackers(except);
2857            }
2858        }
2859    }
2860
2861    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2862        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2863            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2864            final int numStacks = stacks.size();
2865            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2866                final ActivityStack stack = stacks.get(stackNdx);
2867                stack.scheduleDestroyActivities(app, reason);
2868            }
2869        }
2870    }
2871
2872    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
2873        // Examine all activities currently running in the process.
2874        TaskRecord firstTask = null;
2875        // Tasks is non-null only if two or more tasks are found.
2876        ArraySet<TaskRecord> tasks = null;
2877        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
2878        for (int i = 0; i < app.activities.size(); i++) {
2879            ActivityRecord r = app.activities.get(i);
2880            // First, if we find an activity that is in the process of being destroyed,
2881            // then we just aren't going to do anything for now; we want things to settle
2882            // down before we try to prune more activities.
2883            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
2884                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
2885                return;
2886            }
2887            // Don't consider any activies that are currently not in a state where they
2888            // can be destroyed.
2889            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
2890                    || r.state == PAUSED || r.state == STOPPING) {
2891                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
2892                continue;
2893            }
2894            if (r.task != null) {
2895                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task
2896                        + " from " + r);
2897                if (firstTask == null) {
2898                    firstTask = r.task;
2899                } else if (firstTask != r.task) {
2900                    if (tasks == null) {
2901                        tasks = new ArraySet<>();
2902                        tasks.add(firstTask);
2903                    }
2904                    tasks.add(r.task);
2905                }
2906            }
2907        }
2908        if (tasks == null) {
2909            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
2910            return;
2911        }
2912        // If we have activities in multiple tasks that are in a position to be destroyed,
2913        // let's iterate through the tasks and release the oldest one.
2914        final int numDisplays = mActivityDisplays.size();
2915        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2916            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2917            // Step through all stacks starting from behind, to hit the oldest things first.
2918            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
2919                final ActivityStack stack = stacks.get(stackNdx);
2920                // Try to release activities in this stack; if we manage to, we are done.
2921                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
2922                    return;
2923                }
2924            }
2925        }
2926    }
2927
2928    boolean switchUserLocked(int userId, UserState uss) {
2929        mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
2930        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2931        mCurrentUser = userId;
2932
2933        mStartingUsers.add(uss);
2934        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2935            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2936            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2937                final ActivityStack stack = stacks.get(stackNdx);
2938                stack.switchUserLocked(userId);
2939                TaskRecord task = stack.topTask();
2940                if (task != null) {
2941                    mWindowManager.moveTaskToTop(task.taskId);
2942                }
2943            }
2944        }
2945
2946        ActivityStack stack = getStack(restoreStackId);
2947        if (stack == null) {
2948            stack = mHomeStack;
2949        }
2950        final boolean homeInFront = stack.isHomeStack();
2951        if (stack.isOnHomeDisplay()) {
2952            stack.moveToFront("switchUserOnHomeDisplay");
2953        } else {
2954            // Stack was moved to another display while user was swapped out.
2955            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
2956        }
2957        return homeInFront;
2958    }
2959
2960    /** Checks whether the userid is a profile of the current user. */
2961    boolean isCurrentProfileLocked(int userId) {
2962        if (userId == mCurrentUser) return true;
2963        return mService.mUserController.isCurrentProfileLocked(userId);
2964    }
2965
2966    /** Checks whether the activity should be shown for current user. */
2967    boolean okToShowLocked(ActivityRecord r) {
2968        return r != null && (isCurrentProfileLocked(r.userId)
2969                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
2970    }
2971
2972    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2973        ArrayList<ActivityRecord> stops = null;
2974
2975        final boolean nowVisible = allResumedActivitiesVisible();
2976        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2977            ActivityRecord s = mStoppingActivities.get(activityNdx);
2978            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
2979            if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
2980                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
2981            if (waitingVisible && nowVisible) {
2982                mWaitingVisibleActivities.remove(s);
2983                if (s.finishing) {
2984                    // If this activity is finishing, it is sitting on top of
2985                    // everyone else but we now know it is no longer needed...
2986                    // so get rid of it.  Otherwise, we need to go through the
2987                    // normal flow and hide it once we determine that it is
2988                    // hidden by the activities in front of it.
2989                    if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
2990                    mWindowManager.setAppVisibility(s.appToken, false);
2991                }
2992            }
2993            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2994                if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
2995                if (stops == null) {
2996                    stops = new ArrayList<>();
2997                }
2998                stops.add(s);
2999                mStoppingActivities.remove(activityNdx);
3000            }
3001        }
3002
3003        return stops;
3004    }
3005
3006    void validateTopActivitiesLocked() {
3007        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3008            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3009            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3010                final ActivityStack stack = stacks.get(stackNdx);
3011                final ActivityRecord r = stack.topRunningActivityLocked();
3012                final ActivityState state = r == null ? DESTROYED : r.state;
3013                if (isFocusedStack(stack)) {
3014                    if (r == null) Slog.e(TAG,
3015                            "validateTop...: null top activity, stack=" + stack);
3016                    else {
3017                        final ActivityRecord pausing = stack.mPausingActivity;
3018                        if (pausing != null && pausing == r) Slog.e(TAG,
3019                                "validateTop...: top stack has pausing activity r=" + r
3020                                + " state=" + state);
3021                        if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
3022                                "validateTop...: activity in front not resumed r=" + r
3023                                + " state=" + state);
3024                    }
3025                } else {
3026                    final ActivityRecord resumed = stack.mResumedActivity;
3027                    if (resumed != null && resumed == r) Slog.e(TAG,
3028                            "validateTop...: back stack has resumed activity r=" + r
3029                            + " state=" + state);
3030                    if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
3031                            "validateTop...: activity in back resumed r=" + r + " state=" + state);
3032                }
3033            }
3034        }
3035    }
3036
3037    private String lockTaskModeToString() {
3038        switch (mLockTaskModeState) {
3039            case LOCK_TASK_MODE_LOCKED:
3040                return "LOCKED";
3041            case LOCK_TASK_MODE_PINNED:
3042                return "PINNED";
3043            case LOCK_TASK_MODE_NONE:
3044                return "NONE";
3045            default: return "unknown=" + mLockTaskModeState;
3046        }
3047    }
3048
3049    public void dump(PrintWriter pw, String prefix) {
3050        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3051                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3052        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3053        pw.print(prefix);
3054        pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
3055        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3056        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3057        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
3058                final SparseArray<String[]> packages = mService.mLockTaskPackages;
3059                if (packages.size() > 0) {
3060                    pw.println(" mLockTaskPackages (userId:packages)=");
3061                    for (int i = 0; i < packages.size(); ++i) {
3062                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
3063                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
3064                    }
3065                }
3066                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
3067    }
3068
3069    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3070        return mFocusedStack.getDumpActivitiesLocked(name);
3071    }
3072
3073    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3074            boolean needSep, String prefix) {
3075        if (activity != null) {
3076            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3077                if (needSep) {
3078                    pw.println();
3079                }
3080                pw.print(prefix);
3081                pw.println(activity);
3082                return true;
3083            }
3084        }
3085        return false;
3086    }
3087
3088    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3089            boolean dumpClient, String dumpPackage) {
3090        boolean printed = false;
3091        boolean needSep = false;
3092        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3093            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3094            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3095                    pw.println(" (activities from top to bottom):");
3096            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3097            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3098                final ActivityStack stack = stacks.get(stackNdx);
3099                StringBuilder stackHeader = new StringBuilder(128);
3100                stackHeader.append("  Stack #");
3101                stackHeader.append(stack.mStackId);
3102                stackHeader.append(":");
3103                stackHeader.append("\n");
3104                stackHeader.append("  mFullscreen=" + stack.mFullscreen);
3105                stackHeader.append("\n");
3106                stackHeader.append("  mBounds=" + stack.mBounds);
3107                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3108                        needSep, stackHeader.toString());
3109                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3110                        !dumpAll, false, dumpPackage, true,
3111                        "    Running activities (most recent first):", null);
3112
3113                needSep = printed;
3114                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3115                        "    mPausingActivity: ");
3116                if (pr) {
3117                    printed = true;
3118                    needSep = false;
3119                }
3120                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3121                        "    mResumedActivity: ");
3122                if (pr) {
3123                    printed = true;
3124                    needSep = false;
3125                }
3126                if (dumpAll) {
3127                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3128                            "    mLastPausedActivity: ");
3129                    if (pr) {
3130                        printed = true;
3131                        needSep = true;
3132                    }
3133                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3134                            needSep, "    mLastNoHistoryActivity: ");
3135                }
3136                needSep = printed;
3137            }
3138        }
3139
3140        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3141                false, dumpPackage, true, "  Activities waiting to finish:", null);
3142        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3143                false, dumpPackage, true, "  Activities waiting to stop:", null);
3144        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3145                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3146                null);
3147        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3148                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3149        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3150                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3151
3152        return printed;
3153    }
3154
3155    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3156            String prefix, String label, boolean complete, boolean brief, boolean client,
3157            String dumpPackage, boolean needNL, String header1, String header2) {
3158        TaskRecord lastTask = null;
3159        String innerPrefix = null;
3160        String[] args = null;
3161        boolean printed = false;
3162        for (int i=list.size()-1; i>=0; i--) {
3163            final ActivityRecord r = list.get(i);
3164            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3165                continue;
3166            }
3167            if (innerPrefix == null) {
3168                innerPrefix = prefix + "      ";
3169                args = new String[0];
3170            }
3171            printed = true;
3172            final boolean full = !brief && (complete || !r.isInHistory());
3173            if (needNL) {
3174                pw.println("");
3175                needNL = false;
3176            }
3177            if (header1 != null) {
3178                pw.println(header1);
3179                header1 = null;
3180            }
3181            if (header2 != null) {
3182                pw.println(header2);
3183                header2 = null;
3184            }
3185            if (lastTask != r.task) {
3186                lastTask = r.task;
3187                pw.print(prefix);
3188                pw.print(full ? "* " : "  ");
3189                pw.println(lastTask);
3190                if (full) {
3191                    lastTask.dump(pw, prefix + "  ");
3192                } else if (complete) {
3193                    // Complete + brief == give a summary.  Isn't that obvious?!?
3194                    if (lastTask.intent != null) {
3195                        pw.print(prefix); pw.print("  ");
3196                                pw.println(lastTask.intent.toInsecureStringWithClip());
3197                    }
3198                }
3199            }
3200            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3201            pw.print(" #"); pw.print(i); pw.print(": ");
3202            pw.println(r);
3203            if (full) {
3204                r.dump(pw, innerPrefix);
3205            } else if (complete) {
3206                // Complete + brief == give a summary.  Isn't that obvious?!?
3207                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3208                if (r.app != null) {
3209                    pw.print(innerPrefix); pw.println(r.app);
3210                }
3211            }
3212            if (client && r.app != null && r.app.thread != null) {
3213                // flush anything that is already in the PrintWriter since the thread is going
3214                // to write to the file descriptor directly
3215                pw.flush();
3216                try {
3217                    TransferPipe tp = new TransferPipe();
3218                    try {
3219                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3220                                r.appToken, innerPrefix, args);
3221                        // Short timeout, since blocking here can
3222                        // deadlock with the application.
3223                        tp.go(fd, 2000);
3224                    } finally {
3225                        tp.kill();
3226                    }
3227                } catch (IOException e) {
3228                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3229                } catch (RemoteException e) {
3230                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3231                }
3232                needNL = true;
3233            }
3234        }
3235        return printed;
3236    }
3237
3238    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3239        if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3240                "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3241        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3242        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3243    }
3244
3245    final void scheduleIdleLocked() {
3246        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3247    }
3248
3249    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3250        if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
3251                + Debug.getCallers(4));
3252        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3253    }
3254
3255    final void scheduleResumeTopActivities() {
3256        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3257            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3258        }
3259    }
3260
3261    void removeSleepTimeouts() {
3262        mSleepTimeout = false;
3263        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3264    }
3265
3266    final void scheduleSleepTimeout() {
3267        removeSleepTimeouts();
3268        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3269    }
3270
3271    @Override
3272    public void onDisplayAdded(int displayId) {
3273        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
3274        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3275    }
3276
3277    @Override
3278    public void onDisplayRemoved(int displayId) {
3279        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
3280        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3281    }
3282
3283    @Override
3284    public void onDisplayChanged(int displayId) {
3285        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
3286        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3287    }
3288
3289    private void handleDisplayAdded(int displayId) {
3290        boolean newDisplay;
3291        synchronized (mService) {
3292            newDisplay = mActivityDisplays.get(displayId) == null;
3293            if (newDisplay) {
3294                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3295                if (activityDisplay.mDisplay == null) {
3296                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3297                    return;
3298                }
3299                mActivityDisplays.put(displayId, activityDisplay);
3300                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
3301            }
3302        }
3303        if (newDisplay) {
3304            mWindowManager.onDisplayAdded(displayId);
3305        }
3306    }
3307
3308    private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
3309        mDefaultMinimalSizeOfResizeableTask =
3310                mService.mContext.getResources().getDimensionPixelSize(
3311                        com.android.internal.R.dimen.default_minimal_size_resizable_task);
3312    }
3313
3314    private void handleDisplayRemoved(int displayId) {
3315        synchronized (mService) {
3316            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3317            if (activityDisplay != null) {
3318                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3319                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3320                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3321                }
3322                mActivityDisplays.remove(displayId);
3323            }
3324        }
3325        mWindowManager.onDisplayRemoved(displayId);
3326    }
3327
3328    private void handleDisplayChanged(int displayId) {
3329        synchronized (mService) {
3330            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3331            if (activityDisplay != null) {
3332                // TODO: Update the bounds.
3333            }
3334        }
3335        mWindowManager.onDisplayChanged(displayId);
3336    }
3337
3338    private StackInfo getStackInfoLocked(ActivityStack stack) {
3339        StackInfo info = new StackInfo();
3340        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3341        info.displayId = Display.DEFAULT_DISPLAY;
3342        info.stackId = stack.mStackId;
3343        info.userId = stack.mCurrentUser;
3344
3345        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3346        final int numTasks = tasks.size();
3347        int[] taskIds = new int[numTasks];
3348        String[] taskNames = new String[numTasks];
3349        Rect[] taskBounds = new Rect[numTasks];
3350        int[] taskUserIds = new int[numTasks];
3351        for (int i = 0; i < numTasks; ++i) {
3352            final TaskRecord task = tasks.get(i);
3353            taskIds[i] = task.taskId;
3354            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3355                    : task.realActivity != null ? task.realActivity.flattenToString()
3356                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3357                    : "unknown";
3358            taskBounds[i] = new Rect();
3359            mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
3360            taskUserIds[i] = task.userId;
3361        }
3362        info.taskIds = taskIds;
3363        info.taskNames = taskNames;
3364        info.taskBounds = taskBounds;
3365        info.taskUserIds = taskUserIds;
3366        return info;
3367    }
3368
3369    StackInfo getStackInfoLocked(int stackId) {
3370        ActivityStack stack = getStack(stackId);
3371        if (stack != null) {
3372            return getStackInfoLocked(stack);
3373        }
3374        return null;
3375    }
3376
3377    ArrayList<StackInfo> getAllStackInfosLocked() {
3378        ArrayList<StackInfo> list = new ArrayList<>();
3379        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3380            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3381            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3382                list.add(getStackInfoLocked(stacks.get(ndx)));
3383            }
3384        }
3385        return list;
3386    }
3387
3388    TaskRecord getLockedTaskLocked() {
3389        final int top = mLockTaskModeTasks.size() - 1;
3390        if (top >= 0) {
3391            return mLockTaskModeTasks.get(top);
3392        }
3393        return null;
3394    }
3395
3396    boolean isLockedTask(TaskRecord task) {
3397        return mLockTaskModeTasks.contains(task);
3398    }
3399
3400    boolean isLastLockedTask(TaskRecord task) {
3401        return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
3402    }
3403
3404    void removeLockedTaskLocked(final TaskRecord task) {
3405        if (!mLockTaskModeTasks.remove(task)) {
3406            return;
3407        }
3408        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
3409        if (mLockTaskModeTasks.isEmpty()) {
3410            // Last one.
3411            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
3412                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
3413            final Message lockTaskMsg = Message.obtain();
3414            lockTaskMsg.arg1 = task.userId;
3415            lockTaskMsg.what = LOCK_TASK_END_MSG;
3416            mHandler.sendMessage(lockTaskMsg);
3417        }
3418    }
3419
3420    void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) {
3421        handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId,
3422                false /* forceNonResizable */);
3423    }
3424
3425    void handleNonResizableTaskIfNeeded(
3426            TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) {
3427        if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
3428                || task.isHomeTask()) {
3429            return;
3430        }
3431
3432        if (!task.canGoInDockedStack() || forceNonResizable) {
3433            // Display a warning toast that we tried to put a non-dockable task in the docked stack.
3434            mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
3435
3436            // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
3437            // we need to move it to top of fullscreen stack, otherwise it will be covered.
3438            mService.moveTasksToFullscreenStack(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID);
3439        } else if (task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) {
3440            String packageName = task.getTopActivity() != null
3441                    ? task.getTopActivity().appInfo.packageName : null;
3442            mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0,
3443                    packageName).sendToTarget();
3444        }
3445    }
3446
3447    void showLockTaskToast() {
3448        mLockTaskNotify.showToast(mLockTaskModeState);
3449    }
3450
3451    void showLockTaskEscapeMessageLocked(TaskRecord task) {
3452        if (mLockTaskModeTasks.contains(task)) {
3453            mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
3454        }
3455    }
3456
3457    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
3458            boolean andResume) {
3459        if (task == null) {
3460            // Take out of lock task mode if necessary
3461            final TaskRecord lockedTask = getLockedTaskLocked();
3462            if (lockedTask != null) {
3463                removeLockedTaskLocked(lockedTask);
3464                if (!mLockTaskModeTasks.isEmpty()) {
3465                    // There are locked tasks remaining, can only finish this task, not unlock it.
3466                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3467                            "setLockTaskModeLocked: Tasks remaining, can't unlock");
3468                    lockedTask.performClearTaskLocked();
3469                    resumeFocusedStackTopActivityLocked();
3470                    return;
3471                }
3472            }
3473            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3474                    "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
3475            return;
3476        }
3477
3478        // Should have already been checked, but do it again.
3479        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
3480            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3481                    "setLockTaskModeLocked: Can't lock due to auth");
3482            return;
3483        }
3484        if (isLockTaskModeViolation(task)) {
3485            Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
3486            return;
3487        }
3488
3489        if (mLockTaskModeTasks.isEmpty()) {
3490            // First locktask.
3491            final Message lockTaskMsg = Message.obtain();
3492            lockTaskMsg.obj = task.intent.getComponent().getPackageName();
3493            lockTaskMsg.arg1 = task.userId;
3494            lockTaskMsg.what = LOCK_TASK_START_MSG;
3495            lockTaskMsg.arg2 = lockTaskModeState;
3496            mHandler.sendMessage(lockTaskMsg);
3497        }
3498        // Add it or move it to the top.
3499        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
3500                " Callers=" + Debug.getCallers(4));
3501        mLockTaskModeTasks.remove(task);
3502        mLockTaskModeTasks.add(task);
3503
3504        if (task.mLockTaskUid == -1) {
3505            task.mLockTaskUid = task.effectiveUid;
3506        }
3507
3508        if (andResume) {
3509            findTaskToMoveToFrontLocked(task, 0, null, reason,
3510                    lockTaskModeState != LOCK_TASK_MODE_NONE);
3511            resumeFocusedStackTopActivityLocked();
3512        } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
3513            handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId,
3514                    true /* forceNonResizable */);
3515        }
3516    }
3517
3518    boolean isLockTaskModeViolation(TaskRecord task) {
3519        return isLockTaskModeViolation(task, false);
3520    }
3521
3522    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
3523        if (getLockedTaskLocked() == task && !isNewClearTask) {
3524            return false;
3525        }
3526        final int lockTaskAuth = task.mLockTaskAuth;
3527        switch (lockTaskAuth) {
3528            case LOCK_TASK_AUTH_DONT_LOCK:
3529                return !mLockTaskModeTasks.isEmpty();
3530            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
3531            case LOCK_TASK_AUTH_LAUNCHABLE:
3532            case LOCK_TASK_AUTH_WHITELISTED:
3533                return false;
3534            case LOCK_TASK_AUTH_PINNABLE:
3535                // Pinnable tasks can't be launched on top of locktask tasks.
3536                return !mLockTaskModeTasks.isEmpty();
3537            default:
3538                Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
3539                return true;
3540        }
3541    }
3542
3543    void onLockTaskPackagesUpdatedLocked() {
3544        boolean didSomething = false;
3545        for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
3546            final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
3547            final boolean wasWhitelisted =
3548                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3549                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3550            lockedTask.setLockTaskAuth();
3551            final boolean isWhitelisted =
3552                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3553                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3554            if (wasWhitelisted && !isWhitelisted) {
3555                // Lost whitelisting authorization. End it now.
3556                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
3557                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
3558                removeLockedTaskLocked(lockedTask);
3559                lockedTask.performClearTaskLocked();
3560                didSomething = true;
3561            }
3562        }
3563        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3564            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3565            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3566                final ActivityStack stack = stacks.get(stackNdx);
3567                stack.onLockTaskPackagesUpdatedLocked();
3568            }
3569        }
3570        final ActivityRecord r = topRunningActivityLocked();
3571        final TaskRecord task = r != null ? r.task : null;
3572        if (mLockTaskModeTasks.isEmpty() && task != null
3573                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
3574            // This task must have just been authorized.
3575            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
3576                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
3577            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
3578                    false);
3579            didSomething = true;
3580        }
3581        if (didSomething) {
3582            resumeFocusedStackTopActivityLocked();
3583        }
3584    }
3585
3586    int getLockTaskModeState() {
3587        return mLockTaskModeState;
3588    }
3589
3590    void activityRelaunchedLocked(IBinder token) {
3591        mWindowManager.notifyAppRelaunchingFinished(token);
3592    }
3593
3594    void activityRelaunchingLocked(ActivityRecord r) {
3595        mWindowManager.notifyAppRelaunching(r.appToken);
3596    }
3597
3598    void logStackState() {
3599        mActivityMetricsLogger.logWindowState();
3600    }
3601
3602    void scheduleReportMultiWindowModeChanged(TaskRecord task) {
3603        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3604            final ActivityRecord r = task.mActivities.get(i);
3605            if (r.app != null && r.app.thread != null) {
3606                mMultiWindowModeChangedActivities.add(r);
3607            }
3608        }
3609
3610        if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
3611            mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
3612        }
3613    }
3614
3615    void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) {
3616        final ActivityStack stack = task.stack;
3617        if (prevStack == null || prevStack == stack
3618                || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
3619            return;
3620        }
3621
3622        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3623            final ActivityRecord r = task.mActivities.get(i);
3624            if (r.app != null && r.app.thread != null) {
3625                mPipModeChangedActivities.add(r);
3626            }
3627        }
3628
3629        if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
3630            mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
3631        }
3632    }
3633
3634    private final class ActivityStackSupervisorHandler extends Handler {
3635
3636        public ActivityStackSupervisorHandler(Looper looper) {
3637            super(looper);
3638        }
3639
3640        void activityIdleInternal(ActivityRecord r) {
3641            synchronized (mService) {
3642                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3643            }
3644        }
3645
3646        @Override
3647        public void handleMessage(Message msg) {
3648            switch (msg.what) {
3649                case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
3650                    synchronized (mService) {
3651                        for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
3652                            final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
3653                            r.scheduleMultiWindowModeChanged();
3654                        }
3655                    }
3656                } break;
3657                case REPORT_PIP_MODE_CHANGED_MSG: {
3658                    synchronized (mService) {
3659                        for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
3660                            final ActivityRecord r = mPipModeChangedActivities.remove(i);
3661                            r.schedulePictureInPictureModeChanged();
3662                        }
3663                    }
3664                } break;
3665                case IDLE_TIMEOUT_MSG: {
3666                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3667                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3668                    if (mService.mDidDexOpt) {
3669                        mService.mDidDexOpt = false;
3670                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3671                        nmsg.obj = msg.obj;
3672                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3673                        return;
3674                    }
3675                    // We don't at this point know if the activity is fullscreen,
3676                    // so we need to be conservative and assume it isn't.
3677                    activityIdleInternal((ActivityRecord)msg.obj);
3678                } break;
3679                case IDLE_NOW_MSG: {
3680                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3681                    activityIdleInternal((ActivityRecord)msg.obj);
3682                } break;
3683                case RESUME_TOP_ACTIVITY_MSG: {
3684                    synchronized (mService) {
3685                        resumeFocusedStackTopActivityLocked();
3686                    }
3687                } break;
3688                case SLEEP_TIMEOUT_MSG: {
3689                    synchronized (mService) {
3690                        if (mService.isSleepingOrShuttingDown()) {
3691                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3692                            mSleepTimeout = true;
3693                            checkReadyForSleepLocked();
3694                        }
3695                    }
3696                } break;
3697                case LAUNCH_TIMEOUT_MSG: {
3698                    if (mService.mDidDexOpt) {
3699                        mService.mDidDexOpt = false;
3700                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3701                        return;
3702                    }
3703                    synchronized (mService) {
3704                        if (mLaunchingActivity.isHeld()) {
3705                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3706                            if (VALIDATE_WAKE_LOCK_CALLER
3707                                    && Binder.getCallingUid() != Process.myUid()) {
3708                                throw new IllegalStateException("Calling must be system uid");
3709                            }
3710                            mLaunchingActivity.release();
3711                        }
3712                    }
3713                } break;
3714                case HANDLE_DISPLAY_ADDED: {
3715                    handleDisplayAdded(msg.arg1);
3716                } break;
3717                case HANDLE_DISPLAY_CHANGED: {
3718                    handleDisplayChanged(msg.arg1);
3719                } break;
3720                case HANDLE_DISPLAY_REMOVED: {
3721                    handleDisplayRemoved(msg.arg1);
3722                } break;
3723                case CONTAINER_CALLBACK_VISIBILITY: {
3724                    final ActivityContainer container = (ActivityContainer) msg.obj;
3725                    final IActivityContainerCallback callback = container.mCallback;
3726                    if (callback != null) {
3727                        try {
3728                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3729                        } catch (RemoteException e) {
3730                        }
3731                    }
3732                } break;
3733                case LOCK_TASK_START_MSG: {
3734                    // When lock task starts, we disable the status bars.
3735                    try {
3736                        if (mLockTaskNotify == null) {
3737                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3738                        }
3739                        mLockTaskNotify.show(true);
3740                        mLockTaskModeState = msg.arg2;
3741                        if (getStatusBarService() != null) {
3742                            int flags = 0;
3743                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
3744                                flags = StatusBarManager.DISABLE_MASK
3745                                        & (~StatusBarManager.DISABLE_BACK);
3746                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
3747                                flags = StatusBarManager.DISABLE_MASK
3748                                        & (~StatusBarManager.DISABLE_BACK)
3749                                        & (~StatusBarManager.DISABLE_HOME)
3750                                        & (~StatusBarManager.DISABLE_RECENT);
3751                            }
3752                            getStatusBarService().disable(flags, mToken,
3753                                    mService.mContext.getPackageName());
3754                        }
3755                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3756                        if (getDevicePolicyManager() != null) {
3757                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3758                                    (String)msg.obj, msg.arg1);
3759                        }
3760                    } catch (RemoteException ex) {
3761                        throw new RuntimeException(ex);
3762                    }
3763                } break;
3764                case LOCK_TASK_END_MSG: {
3765                    // When lock task ends, we enable the status bars.
3766                    try {
3767                        if (getStatusBarService() != null) {
3768                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3769                                    mService.mContext.getPackageName());
3770                        }
3771                        mWindowManager.reenableKeyguard(mToken);
3772                        if (getDevicePolicyManager() != null) {
3773                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3774                                    msg.arg1);
3775                        }
3776                        if (mLockTaskNotify == null) {
3777                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3778                        }
3779                        mLockTaskNotify.show(false);
3780                        try {
3781                            boolean shouldLockKeyguard = Settings.Secure.getInt(
3782                                    mService.mContext.getContentResolver(),
3783                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
3784                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
3785                                mWindowManager.lockNow(null);
3786                                mWindowManager.dismissKeyguard();
3787                                new LockPatternUtils(mService.mContext)
3788                                        .requireCredentialEntry(UserHandle.USER_ALL);
3789                            }
3790                        } catch (SettingNotFoundException e) {
3791                            // No setting, don't lock.
3792                        }
3793                    } catch (RemoteException ex) {
3794                        throw new RuntimeException(ex);
3795                    } finally {
3796                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
3797                    }
3798                } break;
3799                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
3800                    if (mLockTaskNotify == null) {
3801                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
3802                    }
3803                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
3804                } break;
3805                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3806                    final ActivityContainer container = (ActivityContainer) msg.obj;
3807                    final IActivityContainerCallback callback = container.mCallback;
3808                    if (callback != null) {
3809                        try {
3810                            callback.onAllActivitiesComplete(container.asBinder());
3811                        } catch (RemoteException e) {
3812                        }
3813                    }
3814                } break;
3815                case LAUNCH_TASK_BEHIND_COMPLETE: {
3816                    synchronized (mService) {
3817                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
3818                        if (r != null) {
3819                            handleLaunchTaskBehindCompleteLocked(r);
3820                        }
3821                    }
3822                } break;
3823
3824            }
3825        }
3826    }
3827
3828    class ActivityContainer extends android.app.IActivityContainer.Stub {
3829        final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK |
3830                FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3831        final int mStackId;
3832        IActivityContainerCallback mCallback = null;
3833        final ActivityStack mStack;
3834        ActivityRecord mParentActivity = null;
3835        String mIdString;
3836
3837        boolean mVisible = true;
3838
3839        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3840        ActivityDisplay mActivityDisplay;
3841
3842        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3843        final static int CONTAINER_STATE_NO_SURFACE = 1;
3844        final static int CONTAINER_STATE_FINISHING = 2;
3845        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3846
3847        ActivityContainer(int stackId) {
3848            synchronized (mService) {
3849                mStackId = stackId;
3850                mStack = new ActivityStack(this, mRecentTasks);
3851                mIdString = "ActivtyContainer{" + mStackId + "}";
3852                if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
3853            }
3854        }
3855
3856        void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
3857            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
3858                    + " to display=" + activityDisplay + " onTop=" + onTop);
3859            mActivityDisplay = activityDisplay;
3860            mStack.attachDisplay(activityDisplay, onTop);
3861            activityDisplay.attachActivities(mStack, onTop);
3862        }
3863
3864        @Override
3865        public void attachToDisplay(int displayId) {
3866            synchronized (mService) {
3867                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3868                if (activityDisplay == null) {
3869                    return;
3870                }
3871                attachToDisplayLocked(activityDisplay, true);
3872            }
3873        }
3874
3875        @Override
3876        public int getDisplayId() {
3877            synchronized (mService) {
3878                if (mActivityDisplay != null) {
3879                    return mActivityDisplay.mDisplayId;
3880                }
3881            }
3882            return -1;
3883        }
3884
3885        @Override
3886        public int getStackId() {
3887            synchronized (mService) {
3888                return mStackId;
3889            }
3890        }
3891
3892        @Override
3893        public boolean injectEvent(InputEvent event) {
3894            final long origId = Binder.clearCallingIdentity();
3895            try {
3896                synchronized (mService) {
3897                    if (mActivityDisplay != null) {
3898                        return mInputManagerInternal.injectInputEvent(event,
3899                                mActivityDisplay.mDisplayId,
3900                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3901                    }
3902                }
3903                return false;
3904            } finally {
3905                Binder.restoreCallingIdentity(origId);
3906            }
3907        }
3908
3909        @Override
3910        public void release() {
3911            synchronized (mService) {
3912                if (mContainerState == CONTAINER_STATE_FINISHING) {
3913                    return;
3914                }
3915                mContainerState = CONTAINER_STATE_FINISHING;
3916
3917                long origId = Binder.clearCallingIdentity();
3918                try {
3919                    mStack.finishAllActivitiesLocked(false);
3920                    mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack);
3921                } finally {
3922                    Binder.restoreCallingIdentity(origId);
3923                }
3924            }
3925        }
3926
3927        protected void detachLocked() {
3928            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
3929                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3930            if (mActivityDisplay != null) {
3931                mActivityDisplay.detachActivitiesLocked(mStack);
3932                mActivityDisplay = null;
3933                mStack.detachDisplay();
3934            }
3935        }
3936
3937        @Override
3938        public final int startActivity(Intent intent) {
3939            return mService.startActivity(intent, this);
3940        }
3941
3942        @Override
3943        public final int startActivityIntentSender(IIntentSender intentSender)
3944                throws TransactionTooLargeException {
3945            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3946
3947            if (!(intentSender instanceof PendingIntentRecord)) {
3948                throw new IllegalArgumentException("Bad PendingIntent object");
3949            }
3950
3951            final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
3952                    Binder.getCallingUid(), mCurrentUser, false,
3953                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3954
3955            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3956            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
3957                    pendingIntent.key.requestResolvedType);
3958
3959            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
3960                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3961        }
3962
3963        void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
3964            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
3965            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3966                throw new SecurityException(
3967                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3968            }
3969        }
3970
3971        @Override
3972        public IBinder asBinder() {
3973            return this;
3974        }
3975
3976        @Override
3977        public void setSurface(Surface surface, int width, int height, int density) {
3978            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3979        }
3980
3981        ActivityStackSupervisor getOuter() {
3982            return ActivityStackSupervisor.this;
3983        }
3984
3985        boolean isAttachedLocked() {
3986            return mActivityDisplay != null;
3987        }
3988
3989        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3990        void setVisible(boolean visible) {
3991            if (mVisible != visible) {
3992                mVisible = visible;
3993                if (mCallback != null) {
3994                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3995                            0 /* unused */, this).sendToTarget();
3996                }
3997            }
3998        }
3999
4000        void setDrawn() {
4001        }
4002
4003        // You can always start a new task on a regular ActivityStack.
4004        boolean isEligibleForNewTasks() {
4005            return true;
4006        }
4007
4008        void onTaskListEmptyLocked() {
4009            detachLocked();
4010            deleteActivityContainer(this);
4011            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
4012        }
4013
4014        @Override
4015        public String toString() {
4016            return mIdString + (mActivityDisplay == null ? "N" : "A");
4017        }
4018    }
4019
4020    private class VirtualActivityContainer extends ActivityContainer {
4021        Surface mSurface;
4022        boolean mDrawn = false;
4023
4024        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
4025            super(getNextStackId());
4026            mParentActivity = parent;
4027            mCallback = callback;
4028            mContainerState = CONTAINER_STATE_NO_SURFACE;
4029            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
4030        }
4031
4032        @Override
4033        public void setSurface(Surface surface, int width, int height, int density) {
4034            super.setSurface(surface, width, height, density);
4035
4036            synchronized (mService) {
4037                final long origId = Binder.clearCallingIdentity();
4038                try {
4039                    setSurfaceLocked(surface, width, height, density);
4040                } finally {
4041                    Binder.restoreCallingIdentity(origId);
4042                }
4043            }
4044        }
4045
4046        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
4047            if (mContainerState == CONTAINER_STATE_FINISHING) {
4048                return;
4049            }
4050            VirtualActivityDisplay virtualActivityDisplay =
4051                    (VirtualActivityDisplay) mActivityDisplay;
4052            if (virtualActivityDisplay == null) {
4053                virtualActivityDisplay =
4054                        new VirtualActivityDisplay(width, height, density);
4055                mActivityDisplay = virtualActivityDisplay;
4056                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
4057                attachToDisplayLocked(virtualActivityDisplay, true);
4058            }
4059
4060            if (mSurface != null) {
4061                mSurface.release();
4062            }
4063
4064            mSurface = surface;
4065            if (surface != null) {
4066                resumeFocusedStackTopActivityLocked();
4067            } else {
4068                mContainerState = CONTAINER_STATE_NO_SURFACE;
4069                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
4070                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
4071                    mStack.startPausingLocked(false, true, false, false);
4072                }
4073            }
4074
4075            setSurfaceIfReadyLocked();
4076
4077            if (DEBUG_STACK) Slog.d(TAG_STACK,
4078                    "setSurface: " + this + " to display=" + virtualActivityDisplay);
4079        }
4080
4081        @Override
4082        boolean isAttachedLocked() {
4083            return mSurface != null && super.isAttachedLocked();
4084        }
4085
4086        @Override
4087        void setDrawn() {
4088            synchronized (mService) {
4089                mDrawn = true;
4090                setSurfaceIfReadyLocked();
4091            }
4092        }
4093
4094        // Never start a new task on an ActivityView if it isn't explicitly specified.
4095        @Override
4096        boolean isEligibleForNewTasks() {
4097            return false;
4098        }
4099
4100        private void setSurfaceIfReadyLocked() {
4101            if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
4102                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
4103            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
4104                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
4105                mContainerState = CONTAINER_STATE_HAS_SURFACE;
4106            }
4107        }
4108    }
4109
4110    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
4111     * attached {@link ActivityStack}s */
4112    class ActivityDisplay {
4113        /** Actual Display this object tracks. */
4114        int mDisplayId;
4115        Display mDisplay;
4116        DisplayInfo mDisplayInfo = new DisplayInfo();
4117
4118        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
4119         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
4120        final ArrayList<ActivityStack> mStacks = new ArrayList<>();
4121
4122        ActivityRecord mVisibleBehindActivity;
4123
4124        ActivityDisplay() {
4125        }
4126
4127        // After instantiation, check that mDisplay is not null before using this. The alternative
4128        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
4129        ActivityDisplay(int displayId) {
4130            final Display display = mDisplayManager.getDisplay(displayId);
4131            if (display == null) {
4132                return;
4133            }
4134            init(display);
4135        }
4136
4137        void init(Display display) {
4138            mDisplay = display;
4139            mDisplayId = display.getDisplayId();
4140            mDisplay.getDisplayInfo(mDisplayInfo);
4141        }
4142
4143        void attachActivities(ActivityStack stack, boolean onTop) {
4144            if (DEBUG_STACK) Slog.v(TAG_STACK,
4145                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId
4146                    + " onTop=" + onTop);
4147            if (onTop) {
4148                mStacks.add(stack);
4149            } else {
4150                mStacks.add(0, stack);
4151            }
4152        }
4153
4154        void detachActivitiesLocked(ActivityStack stack) {
4155            if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
4156                    + " from displayId=" + mDisplayId);
4157            mStacks.remove(stack);
4158        }
4159
4160        void setVisibleBehindActivity(ActivityRecord r) {
4161            mVisibleBehindActivity = r;
4162        }
4163
4164        boolean hasVisibleBehindActivity() {
4165            return mVisibleBehindActivity != null;
4166        }
4167
4168        @Override
4169        public String toString() {
4170            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4171        }
4172    }
4173
4174    class VirtualActivityDisplay extends ActivityDisplay {
4175        VirtualDisplay mVirtualDisplay;
4176
4177        VirtualActivityDisplay(int width, int height, int density) {
4178            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4179            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4180                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4181                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4182                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4183
4184            init(mVirtualDisplay.getDisplay());
4185
4186            mWindowManager.handleDisplayAdded(mDisplayId);
4187        }
4188
4189        void setSurface(Surface surface) {
4190            if (mVirtualDisplay != null) {
4191                mVirtualDisplay.setSurface(surface);
4192            }
4193        }
4194
4195        @Override
4196        void detachActivitiesLocked(ActivityStack stack) {
4197            super.detachActivitiesLocked(stack);
4198            if (mVirtualDisplay != null) {
4199                mVirtualDisplay.release();
4200                mVirtualDisplay = null;
4201            }
4202        }
4203
4204        @Override
4205        public String toString() {
4206            return "VirtualActivityDisplay={" + mDisplayId + "}";
4207        }
4208    }
4209
4210    /**
4211     * Adjust bounds to stay within stack bounds.
4212     *
4213     * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
4214     * that keep them unchanged, but be contained within the stack bounds.
4215     *
4216     * @param bounds Bounds to be adjusted.
4217     * @param stackBounds Bounds within which the other bounds should remain.
4218     */
4219    private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
4220        if (stackBounds == null || stackBounds.contains(bounds)) {
4221            return;
4222        }
4223
4224        if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
4225            final int maxRight = stackBounds.right
4226                    - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
4227            int horizontalDiff = stackBounds.left - bounds.left;
4228            if ((horizontalDiff < 0 && bounds.left >= maxRight)
4229                    || (bounds.left + horizontalDiff >= maxRight)) {
4230                horizontalDiff = maxRight - bounds.left;
4231            }
4232            bounds.left += horizontalDiff;
4233            bounds.right += horizontalDiff;
4234        }
4235
4236        if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
4237            final int maxBottom = stackBounds.bottom
4238                    - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
4239            int verticalDiff = stackBounds.top - bounds.top;
4240            if ((verticalDiff < 0 && bounds.top >= maxBottom)
4241                    || (bounds.top + verticalDiff >= maxBottom)) {
4242                verticalDiff = maxBottom - bounds.top;
4243            }
4244            bounds.top += verticalDiff;
4245            bounds.bottom += verticalDiff;
4246        }
4247    }
4248
4249    ActivityStack findStackBehind(ActivityStack stack) {
4250        // TODO(multi-display): We are only looking for stacks on the default display.
4251        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
4252        if (display == null) {
4253            return null;
4254        }
4255        final ArrayList<ActivityStack> stacks = display.mStacks;
4256        for (int i = stacks.size() - 1; i >= 0; i--) {
4257            if (stacks.get(i) == stack && i > 0) {
4258                return stacks.get(i - 1);
4259            }
4260        }
4261        throw new IllegalStateException("Failed to find a stack behind stack=" + stack
4262                + " in=" + stacks);
4263    }
4264
4265    /**
4266     * Puts a task into resizing mode during the next app transition.
4267     *
4268     * @param taskId the id of the task to put into resizing mode
4269     */
4270    private void setResizingDuringAnimation(int taskId) {
4271        mResizingTasksDuringAnimation.add(taskId);
4272        mWindowManager.setTaskDockedResizing(taskId, true);
4273    }
4274
4275    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4276        final TaskRecord task;
4277        final int callingUid;
4278        final String callingPackage;
4279        final Intent intent;
4280        final int userId;
4281        final ActivityOptions activityOptions = (bOptions != null)
4282                ? new ActivityOptions(bOptions) : null;
4283        final int launchStackId = (activityOptions != null)
4284                ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4285
4286        if (launchStackId == HOME_STACK_ID) {
4287            throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4288                    + taskId + " can't be launch in the home stack.");
4289        }
4290        task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4291        if (task == null) {
4292            throw new IllegalArgumentException(
4293                    "startActivityFromRecentsInner: Task " + taskId + " not found.");
4294        }
4295
4296        if (launchStackId != INVALID_STACK_ID) {
4297            if (launchStackId == DOCKED_STACK_ID) {
4298                mWindowManager.setDockedStackCreateState(
4299                        activityOptions.getDockCreateMode(), null /* initialBounds */);
4300
4301                // Defer updating the stack in which recents is until the app transition is done, to
4302                // not run into issues where we still need to draw the task in recents but the
4303                // docked stack is already created.
4304                deferUpdateBounds(HOME_STACK_ID);
4305                mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
4306            }
4307            if (task.stack.mStackId != launchStackId) {
4308                moveTaskToStackLocked(
4309                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4310                        ANIMATE);
4311            }
4312        }
4313
4314        // If the user must confirm credentials (e.g. when first launching a work app and the
4315        // Work Challenge is present) let startActivityInPackage handle the intercepting.
4316        if (!mService.mUserController.shouldConfirmCredentials(task.userId)
4317                && task.getRootActivity() != null) {
4318            mActivityMetricsLogger.notifyActivityLaunching();
4319            mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
4320
4321            // If we are launching the task in the docked stack, put it into resizing mode so
4322            // the window renders full-screen with the background filling the void. Also only
4323            // call this at the end to make sure that tasks exists on the window manager side.
4324            if (launchStackId == DOCKED_STACK_ID) {
4325                setResizingDuringAnimation(taskId);
4326            }
4327            return ActivityManager.START_TASK_TO_FRONT;
4328        }
4329        callingUid = task.mCallingUid;
4330        callingPackage = task.mCallingPackage;
4331        intent = task.intent;
4332        intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4333        userId = task.userId;
4334            int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
4335                    null, null, 0, 0, bOptions, userId, null, task);
4336            if (launchStackId == DOCKED_STACK_ID) {
4337                setResizingDuringAnimation(task.taskId);
4338            }
4339            return result;
4340    }
4341
4342    /**
4343     * @return a list of activities which are the top ones in each visible stack. The first
4344     * entry will be the focused activity.
4345     */
4346    public List<IBinder> getTopVisibleActivities() {
4347        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
4348        if (display == null) {
4349            return Collections.EMPTY_LIST;
4350        }
4351        ArrayList<IBinder> topActivityTokens = new ArrayList<>();
4352        final ArrayList<ActivityStack> stacks = display.mStacks;
4353        for (int i = stacks.size() - 1; i >= 0; i--) {
4354            ActivityStack stack = stacks.get(i);
4355            if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) {
4356                ActivityRecord top = stack.topActivity();
4357                if (top != null) {
4358                    if (stack == mFocusedStack) {
4359                        topActivityTokens.add(0, top.appToken);
4360                    } else {
4361                        topActivityTokens.add(top.appToken);
4362                    }
4363                }
4364            }
4365        }
4366        return topActivityTokens;
4367    }
4368}
4369