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