ActivityStackSupervisor.java revision 529c8e4cf24375ca21b5d61fb6b34e7010d6edad
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 mDefaultMinimalSizeOfResizeableTask = -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                    final ProcessRecord app = mService.getProcessRecordLocked(
1101                            aInfo.processName, aInfo.applicationInfo.uid, true);
1102                    // If the process already started, we can't wait for debugger and shouldn't
1103                    // modify the debug settings.
1104                    // For non-persistent debug, normally we set the debug app here, and restores
1105                    // to the original at attachApplication time. However, if the app process
1106                    // already exists, we won't get another attachApplication, and the debug setting
1107                    // never gets restored. Furthermore, if we get two such calls back-to-back,
1108                    // both mOrigDebugApp and mDebugApp will become the same app, and it won't be
1109                    // cleared even if we get attachApplication after the app process is killed.
1110                    if (app == null || app.thread == null) {
1111                        mService.setDebugApp(aInfo.processName, true, false);
1112                    } else {
1113                        Slog.w(TAG, "Ignoring waitForDebugger because process already exists");
1114                    }
1115                }
1116
1117                if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
1118                    mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
1119                }
1120
1121                if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
1122                    mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
1123                }
1124
1125                if (profilerInfo != null) {
1126                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
1127                }
1128            }
1129        }
1130        return aInfo;
1131    }
1132
1133    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
1134        return resolveIntent(intent, resolvedType, userId, 0);
1135    }
1136
1137    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
1138        try {
1139            return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
1140                    PackageManager.MATCH_DEFAULT_ONLY | flags
1141                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
1142        } catch (RemoteException e) {
1143        }
1144        return null;
1145    }
1146
1147    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
1148            ProfilerInfo profilerInfo, int userId) {
1149        final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId);
1150        return resolveActivity(intent, rInfo, startFlags, profilerInfo);
1151    }
1152
1153    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
1154            boolean andResume, boolean checkConfig) throws RemoteException {
1155
1156        if (!allPausedActivitiesComplete()) {
1157            // While there are activities pausing we skipping starting any new activities until
1158            // pauses are complete. NOTE: that we also do this for activities that are starting in
1159            // the paused state because they will first be resumed then paused on the client side.
1160            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
1161                    "realStartActivityLocked: Skipping start of r=" + r
1162                    + " some activities pausing...");
1163            return false;
1164        }
1165
1166        if (andResume) {
1167            r.startFreezingScreenLocked(app, 0);
1168            mWindowManager.setAppVisibility(r.appToken, true);
1169
1170            // schedule launch ticks to collect information about slow apps.
1171            r.startLaunchTickingLocked();
1172        }
1173
1174        // Have the window manager re-evaluate the orientation of
1175        // the screen based on the new activity order.  Note that
1176        // as a result of this, it can call back into the activity
1177        // manager with a new orientation.  We don't care about that,
1178        // because the activity is not currently running so we are
1179        // just restarting it anyway.
1180        if (checkConfig) {
1181            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1182                    mService.mConfiguration,
1183                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
1184            mService.updateConfigurationLocked(config, r, false);
1185        }
1186
1187        r.app = app;
1188        app.waitingToKill = null;
1189        r.launchCount++;
1190        r.lastLaunchTime = SystemClock.uptimeMillis();
1191
1192        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
1193
1194        int idx = app.activities.indexOf(r);
1195        if (idx < 0) {
1196            app.activities.add(r);
1197        }
1198        mService.updateLruProcessLocked(app, true, null);
1199        mService.updateOomAdjLocked();
1200
1201        final TaskRecord task = r.task;
1202        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
1203                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
1204            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
1205        }
1206
1207        final ActivityStack stack = task.stack;
1208        try {
1209            if (app.thread == null) {
1210                throw new RemoteException();
1211            }
1212            List<ResultInfo> results = null;
1213            List<ReferrerIntent> newIntents = null;
1214            if (andResume) {
1215                results = r.results;
1216                newIntents = r.newIntents;
1217            }
1218            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1219                    "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
1220                    + " newIntents=" + newIntents + " andResume=" + andResume);
1221            if (andResume) {
1222                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
1223                        r.userId, System.identityHashCode(r),
1224                        task.taskId, r.shortComponentName);
1225            }
1226            if (r.isHomeActivity()) {
1227                // Home process is the root process of the task.
1228                mService.mHomeProcess = task.mActivities.get(0).app;
1229            }
1230            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
1231                                      PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
1232            r.sleeping = false;
1233            r.forceNewConfig = false;
1234            mService.showAskCompatModeDialogLocked(r);
1235            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1236            ProfilerInfo profilerInfo = null;
1237            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1238                if (mService.mProfileProc == null || mService.mProfileProc == app) {
1239                    mService.mProfileProc = app;
1240                    final String profileFile = mService.mProfileFile;
1241                    if (profileFile != null) {
1242                        ParcelFileDescriptor profileFd = mService.mProfileFd;
1243                        if (profileFd != null) {
1244                            try {
1245                                profileFd = profileFd.dup();
1246                            } catch (IOException e) {
1247                                if (profileFd != null) {
1248                                    try {
1249                                        profileFd.close();
1250                                    } catch (IOException o) {
1251                                    }
1252                                    profileFd = null;
1253                                }
1254                            }
1255                        }
1256
1257                        profilerInfo = new ProfilerInfo(profileFile, profileFd,
1258                                mService.mSamplingInterval, mService.mAutoStopProfiler);
1259                    }
1260                }
1261            }
1262
1263            if (andResume) {
1264                app.hasShownUi = true;
1265                app.pendingUiClean = true;
1266            }
1267            app.forceProcessStateUpTo(mService.mTopProcessState);
1268            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1269                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
1270                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
1271                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
1272                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
1273
1274            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
1275                // This may be a heavy-weight process!  Note that the package
1276                // manager will ensure that only activity can run in the main
1277                // process of the .apk, which is the only thing that will be
1278                // considered heavy-weight.
1279                if (app.processName.equals(app.info.packageName)) {
1280                    if (mService.mHeavyWeightProcess != null
1281                            && mService.mHeavyWeightProcess != app) {
1282                        Slog.w(TAG, "Starting new heavy weight process " + app
1283                                + " when already running "
1284                                + mService.mHeavyWeightProcess);
1285                    }
1286                    mService.mHeavyWeightProcess = app;
1287                    Message msg = mService.mHandler.obtainMessage(
1288                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1289                    msg.obj = r;
1290                    mService.mHandler.sendMessage(msg);
1291                }
1292            }
1293
1294        } catch (RemoteException e) {
1295            if (r.launchFailed) {
1296                // This is the second time we failed -- finish activity
1297                // and give up.
1298                Slog.e(TAG, "Second failure launching "
1299                      + r.intent.getComponent().flattenToShortString()
1300                      + ", giving up", e);
1301                mService.appDiedLocked(app);
1302                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1303                        "2nd-crash", false);
1304                return false;
1305            }
1306
1307            // This is the first time we failed -- restart process and
1308            // retry.
1309            app.activities.remove(r);
1310            throw e;
1311        }
1312
1313        r.launchFailed = false;
1314        if (stack.updateLRUListLocked(r)) {
1315            Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
1316        }
1317
1318        if (andResume) {
1319            // As part of the process of launching, ActivityThread also performs
1320            // a resume.
1321            stack.minimalResumeActivityLocked(r);
1322        } else {
1323            // This activity is not starting in the resumed state... which should look like we asked
1324            // it to pause+stop (but remain visible), and it has done so and reported back the
1325            // current icicle and other state.
1326            if (DEBUG_STATES) Slog.v(TAG_STATES,
1327                    "Moving to PAUSED: " + r + " (starting in paused state)");
1328            r.state = PAUSED;
1329        }
1330
1331        // Launch the new version setup screen if needed.  We do this -after-
1332        // launching the initial activity (that is, home), so that it can have
1333        // a chance to initialize itself while in the background, making the
1334        // switch back to it faster and look better.
1335        if (isFocusedStack(stack)) {
1336            mService.startSetupActivityLocked();
1337        }
1338
1339        // Update any services we are bound to that might care about whether
1340        // their client may have activities.
1341        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
1342
1343        return true;
1344    }
1345
1346    void startSpecificActivityLocked(ActivityRecord r,
1347            boolean andResume, boolean checkConfig) {
1348        // Is this activity's application already running?
1349        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1350                r.info.applicationInfo.uid, true);
1351
1352        r.task.stack.setLaunchTime(r);
1353
1354        if (app != null && app.thread != null) {
1355            try {
1356                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1357                        || !"android".equals(r.info.packageName)) {
1358                    // Don't add this if it is a platform component that is marked
1359                    // to run in multiple processes, because this is actually
1360                    // part of the framework so doesn't make sense to track as a
1361                    // separate apk in the process.
1362                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
1363                            mService.mProcessStats);
1364                }
1365                realStartActivityLocked(r, app, andResume, checkConfig);
1366                return;
1367            } catch (RemoteException e) {
1368                Slog.w(TAG, "Exception when starting activity "
1369                        + r.intent.getComponent().flattenToShortString(), e);
1370            }
1371
1372            // If a dead object exception was thrown -- fall through to
1373            // restart the application.
1374        }
1375
1376        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1377                "activity", r.intent.getComponent(), false, false, true);
1378    }
1379
1380    boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo,
1381            String resultWho, int requestCode, int callingPid, int callingUid,
1382            String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp,
1383            ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options) {
1384        final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
1385                callingUid);
1386        if (startAnyPerm ==  PERMISSION_GRANTED) {
1387            return true;
1388        }
1389        final int componentRestriction = getComponentRestrictionForCallingPackage(
1390                aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity);
1391        final int actionRestriction = getActionRestrictionForCallingPackage(
1392                intent.getAction(), callingPackage, callingPid, callingUid);
1393        if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
1394                || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1395            if (resultRecord != null) {
1396                resultStack.sendActivityResultLocked(-1,
1397                        resultRecord, resultWho, requestCode,
1398                        Activity.RESULT_CANCELED, null);
1399            }
1400            final String msg;
1401            if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1402                msg = "Permission Denial: starting " + intent.toString()
1403                        + " from " + callerApp + " (pid=" + callingPid
1404                        + ", uid=" + callingUid + ")" + " with revoked permission "
1405                        + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
1406            } else if (!aInfo.exported) {
1407                msg = "Permission Denial: starting " + intent.toString()
1408                        + " from " + callerApp + " (pid=" + callingPid
1409                        + ", uid=" + callingUid + ")"
1410                        + " not exported from uid " + aInfo.applicationInfo.uid;
1411            } else {
1412                msg = "Permission Denial: starting " + intent.toString()
1413                        + " from " + callerApp + " (pid=" + callingPid
1414                        + ", uid=" + callingUid + ")"
1415                        + " requires " + aInfo.permission;
1416            }
1417            Slog.w(TAG, msg);
1418            throw new SecurityException(msg);
1419        }
1420
1421        if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
1422            final String message = "Appop Denial: starting " + intent.toString()
1423                    + " from " + callerApp + " (pid=" + callingPid
1424                    + ", uid=" + callingUid + ")"
1425                    + " requires " + AppOpsManager.permissionToOp(
1426                            ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
1427            Slog.w(TAG, message);
1428            return false;
1429        } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
1430            final String message = "Appop Denial: starting " + intent.toString()
1431                    + " from " + callerApp + " (pid=" + callingPid
1432                    + ", uid=" + callingUid + ")"
1433                    + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
1434            Slog.w(TAG, message);
1435            return false;
1436        }
1437        if (options != null && options.getLaunchTaskId() != -1) {
1438            final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS,
1439                    callingPid, callingUid);
1440            if (startInTaskPerm != PERMISSION_GRANTED) {
1441                final String msg = "Permission Denial: starting " + intent.toString()
1442                        + " from " + callerApp + " (pid=" + callingPid
1443                        + ", uid=" + callingUid + ") with launchTaskId="
1444                        + options.getLaunchTaskId();
1445                Slog.w(TAG, msg);
1446                throw new SecurityException(msg);
1447            }
1448        }
1449
1450        return true;
1451    }
1452
1453    UserInfo getUserInfo(int userId) {
1454        final long identity = Binder.clearCallingIdentity();
1455        try {
1456            return UserManager.get(mService.mContext).getUserInfo(userId);
1457        } finally {
1458            Binder.restoreCallingIdentity(identity);
1459        }
1460    }
1461
1462    private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
1463            String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
1464        if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
1465                callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
1466                == PackageManager.PERMISSION_DENIED) {
1467            return ACTIVITY_RESTRICTION_PERMISSION;
1468        }
1469
1470        if (activityInfo.permission == null) {
1471            return ACTIVITY_RESTRICTION_NONE;
1472        }
1473
1474        final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
1475        if (opCode == AppOpsManager.OP_NONE) {
1476            return ACTIVITY_RESTRICTION_NONE;
1477        }
1478
1479        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1480                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1481            if (!ignoreTargetSecurity) {
1482                return ACTIVITY_RESTRICTION_APPOP;
1483            }
1484        }
1485
1486        return ACTIVITY_RESTRICTION_NONE;
1487    }
1488
1489    private int getActionRestrictionForCallingPackage(String action,
1490            String callingPackage, int callingPid, int callingUid) {
1491        if (action == null) {
1492            return ACTIVITY_RESTRICTION_NONE;
1493        }
1494
1495        String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
1496        if (permission == null) {
1497            return ACTIVITY_RESTRICTION_NONE;
1498        }
1499
1500        final PackageInfo packageInfo;
1501        try {
1502            packageInfo = mService.mContext.getPackageManager()
1503                    .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
1504        } catch (PackageManager.NameNotFoundException e) {
1505            Slog.i(TAG, "Cannot find package info for " + callingPackage);
1506            return ACTIVITY_RESTRICTION_NONE;
1507        }
1508
1509        if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
1510            return ACTIVITY_RESTRICTION_NONE;
1511        }
1512
1513        if (mService.checkPermission(permission, callingPid, callingUid) ==
1514                PackageManager.PERMISSION_DENIED) {
1515            return ACTIVITY_RESTRICTION_PERMISSION;
1516        }
1517
1518        final int opCode = AppOpsManager.permissionToOpCode(permission);
1519        if (opCode == AppOpsManager.OP_NONE) {
1520            return ACTIVITY_RESTRICTION_NONE;
1521        }
1522
1523        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1524                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1525            return ACTIVITY_RESTRICTION_APPOP;
1526        }
1527
1528        return ACTIVITY_RESTRICTION_NONE;
1529    }
1530
1531    boolean moveActivityStackToFront(ActivityRecord r, String reason) {
1532        if (r == null) {
1533            // Not sure what you are trying to do, but it is not going to work...
1534            return false;
1535        }
1536        final TaskRecord task = r.task;
1537        if (task == null || task.stack == null) {
1538            Slog.w(TAG, "Can't move stack to front for r=" + r + " task=" + task);
1539            return false;
1540        }
1541        task.stack.moveToFront(reason, task);
1542        return true;
1543    }
1544
1545    void setLaunchSource(int uid) {
1546        mLaunchingActivity.setWorkSource(new WorkSource(uid));
1547    }
1548
1549    void acquireLaunchWakelock() {
1550        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1551            throw new IllegalStateException("Calling must be system uid");
1552        }
1553        mLaunchingActivity.acquire();
1554        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1555            // To be safe, don't allow the wake lock to be held for too long.
1556            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1557        }
1558    }
1559
1560    /**
1561     * Called when the frontmost task is idle.
1562     * @return the state of mService.mBooting before this was called.
1563     */
1564    private boolean checkFinishBootingLocked() {
1565        final boolean booting = mService.mBooting;
1566        boolean enableScreen = false;
1567        mService.mBooting = false;
1568        if (!mService.mBooted) {
1569            mService.mBooted = true;
1570            enableScreen = true;
1571        }
1572        if (booting || enableScreen) {
1573            mService.postFinishBooting(booting, enableScreen);
1574        }
1575        return booting;
1576    }
1577
1578    // Checked.
1579    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1580            Configuration config) {
1581        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
1582
1583        ArrayList<ActivityRecord> finishes = null;
1584        ArrayList<UserState> startingUsers = null;
1585        int NS = 0;
1586        int NF = 0;
1587        boolean booting = false;
1588        boolean activityRemoved = false;
1589
1590        ActivityRecord r = ActivityRecord.forTokenLocked(token);
1591        if (r != null) {
1592            if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
1593                    + Debug.getCallers(4));
1594            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1595            r.finishLaunchTickingLocked();
1596            if (fromTimeout) {
1597                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1598            }
1599
1600            // This is a hack to semi-deal with a race condition
1601            // in the client where it can be constructed with a
1602            // newer configuration from when we asked it to launch.
1603            // We'll update with whatever configuration it now says
1604            // it used to launch.
1605            if (config != null) {
1606                r.configuration = config;
1607            }
1608
1609            // We are now idle.  If someone is waiting for a thumbnail from
1610            // us, we can now deliver.
1611            r.idle = true;
1612
1613            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1614            if (isFocusedStack(r.task.stack) || fromTimeout) {
1615                booting = checkFinishBootingLocked();
1616            }
1617        }
1618
1619        if (allResumedActivitiesIdle()) {
1620            if (r != null) {
1621                mService.scheduleAppGcsLocked();
1622            }
1623
1624            if (mLaunchingActivity.isHeld()) {
1625                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1626                if (VALIDATE_WAKE_LOCK_CALLER &&
1627                        Binder.getCallingUid() != Process.myUid()) {
1628                    throw new IllegalStateException("Calling must be system uid");
1629                }
1630                mLaunchingActivity.release();
1631            }
1632            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1633        }
1634
1635        // Atomically retrieve all of the other things to do.
1636        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true);
1637        NS = stops != null ? stops.size() : 0;
1638        if ((NF = mFinishingActivities.size()) > 0) {
1639            finishes = new ArrayList<>(mFinishingActivities);
1640            mFinishingActivities.clear();
1641        }
1642
1643        if (mStartingUsers.size() > 0) {
1644            startingUsers = new ArrayList<>(mStartingUsers);
1645            mStartingUsers.clear();
1646        }
1647
1648        // Stop any activities that are scheduled to do so but have been
1649        // waiting for the next one to start.
1650        for (int i = 0; i < NS; i++) {
1651            r = stops.get(i);
1652            final ActivityStack stack = r.task.stack;
1653            if (stack != null) {
1654                if (r.finishing) {
1655                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1656                } else {
1657                    stack.stopActivityLocked(r);
1658                }
1659            }
1660        }
1661
1662        // Finish any activities that are scheduled to do so but have been
1663        // waiting for the next one to start.
1664        for (int i = 0; i < NF; i++) {
1665            r = finishes.get(i);
1666            final ActivityStack stack = r.task.stack;
1667            if (stack != null) {
1668                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
1669            }
1670        }
1671
1672        if (!booting) {
1673            // Complete user switch
1674            if (startingUsers != null) {
1675                for (int i = 0; i < startingUsers.size(); i++) {
1676                    mService.mUserController.finishUserSwitch(startingUsers.get(i));
1677                }
1678            }
1679        }
1680
1681        mService.trimApplications();
1682        //dump();
1683        //mWindowManager.dump();
1684
1685        if (activityRemoved) {
1686            resumeFocusedStackTopActivityLocked();
1687        }
1688
1689        return r;
1690    }
1691
1692    boolean handleAppDiedLocked(ProcessRecord app) {
1693        boolean hasVisibleActivities = false;
1694        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1695            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1696            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1697                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1698            }
1699        }
1700        return hasVisibleActivities;
1701    }
1702
1703    void closeSystemDialogsLocked() {
1704        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1705            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1706            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1707                stacks.get(stackNdx).closeSystemDialogsLocked();
1708            }
1709        }
1710    }
1711
1712    void removeUserLocked(int userId) {
1713        mUserStackInFront.delete(userId);
1714    }
1715
1716    /**
1717     * Update the last used stack id for non-current user (current user's last
1718     * used stack is the focused stack)
1719     */
1720    void updateUserStackLocked(int userId, ActivityStack stack) {
1721        if (userId != mCurrentUser) {
1722            mUserStackInFront.put(userId, stack != null ? stack.getStackId() : HOME_STACK_ID);
1723        }
1724    }
1725
1726    /**
1727     * @return true if some activity was finished (or would have finished if doit were true).
1728     */
1729    boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
1730            boolean doit, boolean evenPersistent, int userId) {
1731        boolean didSomething = false;
1732        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1733            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1734            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1735                final ActivityStack stack = stacks.get(stackNdx);
1736                if (stack.finishDisabledPackageActivitiesLocked(
1737                        packageName, filterByClasses, doit, evenPersistent, userId)) {
1738                    didSomething = true;
1739                }
1740            }
1741        }
1742        return didSomething;
1743    }
1744
1745    void updatePreviousProcessLocked(ActivityRecord r) {
1746        // Now that this process has stopped, we may want to consider
1747        // it to be the previous app to try to keep around in case
1748        // the user wants to return to it.
1749
1750        // First, found out what is currently the foreground app, so that
1751        // we don't blow away the previous app if this activity is being
1752        // hosted by the process that is actually still the foreground.
1753        ProcessRecord fgApp = null;
1754        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1755            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1756            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1757                final ActivityStack stack = stacks.get(stackNdx);
1758                if (isFocusedStack(stack)) {
1759                    if (stack.mResumedActivity != null) {
1760                        fgApp = stack.mResumedActivity.app;
1761                    } else if (stack.mPausingActivity != null) {
1762                        fgApp = stack.mPausingActivity.app;
1763                    }
1764                    break;
1765                }
1766            }
1767        }
1768
1769        // Now set this one as the previous process, only if that really
1770        // makes sense to.
1771        if (r.app != null && fgApp != null && r.app != fgApp
1772                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
1773                && r.app != mService.mHomeProcess) {
1774            mService.mPreviousProcess = r.app;
1775            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1776        }
1777    }
1778
1779    boolean resumeFocusedStackTopActivityLocked() {
1780        return resumeFocusedStackTopActivityLocked(null, null, null);
1781    }
1782
1783    boolean resumeFocusedStackTopActivityLocked(
1784            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1785        if (targetStack != null && isFocusedStack(targetStack)) {
1786            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1787        }
1788        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
1789        if (r == null || r.state != RESUMED) {
1790            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
1791        }
1792        return false;
1793    }
1794
1795    void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
1796        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1797            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1798            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1799                stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo);
1800            }
1801        }
1802    }
1803
1804    TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
1805        TaskRecord finishedTask = null;
1806        ActivityStack focusedStack = getFocusedStack();
1807        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1808            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1809            final int numStacks = stacks.size();
1810            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1811                final ActivityStack stack = stacks.get(stackNdx);
1812                TaskRecord t = stack.finishTopRunningActivityLocked(app, reason);
1813                if (stack == focusedStack || finishedTask == null) {
1814                    finishedTask = t;
1815                }
1816            }
1817        }
1818        return finishedTask;
1819    }
1820
1821    void finishVoiceTask(IVoiceInteractionSession session) {
1822        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1823            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1824            final int numStacks = stacks.size();
1825            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1826                final ActivityStack stack = stacks.get(stackNdx);
1827                stack.finishVoiceTask(session);
1828            }
1829        }
1830    }
1831
1832    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options,
1833            String reason, boolean forceNonResizeable) {
1834        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
1835            mUserLeaving = true;
1836        }
1837        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
1838            // Caller wants the home activity moved with it.  To accomplish this,
1839            // we'll just indicate that this task returns to the home task.
1840            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1841        }
1842        if (task.stack == null) {
1843            Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
1844                    + task + " to front. Stack is null");
1845            return;
1846        }
1847
1848        if (task.isResizeable() && options != null) {
1849            int stackId = options.getLaunchStackId();
1850            if (canUseActivityOptionsLaunchBounds(options, stackId)) {
1851                final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds());
1852                task.updateOverrideConfiguration(bounds);
1853                if (stackId == INVALID_STACK_ID) {
1854                    stackId = task.getLaunchStackId();
1855                }
1856                if (stackId != task.stack.mStackId) {
1857                    final ActivityStack stack = moveTaskToStackUncheckedLocked(
1858                            task, stackId, ON_TOP, !FORCE_FOCUS, reason);
1859                    stackId = stack.mStackId;
1860                    // moveTaskToStackUncheckedLocked() should already placed the task on top,
1861                    // still need moveTaskToFrontLocked() below for any transition settings.
1862                }
1863                if (StackId.resizeStackWithLaunchBounds(stackId)) {
1864                    resizeStackLocked(stackId, bounds,
1865                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
1866                            !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME);
1867                } else {
1868                    // WM resizeTask must be done after the task is moved to the correct stack,
1869                    // because Task's setBounds() also updates dim layer's bounds, but that has
1870                    // dependency on the stack.
1871                    mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig,
1872                            false /* relayout */, false /* forced */);
1873                }
1874            }
1875        }
1876
1877        final ActivityRecord r = task.getTopActivity();
1878        task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
1879                r == null ? null : r.appTimeTracker, reason);
1880
1881        if (DEBUG_STACK) Slog.d(TAG_STACK,
1882                "findTaskToMoveToFront: moved to front of stack=" + task.stack);
1883
1884        handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId,
1885                forceNonResizeable);
1886    }
1887
1888    boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
1889        // We use the launch bounds in the activity options is the device supports freeform
1890        // window management or is launching into the pinned stack.
1891        if (options.getLaunchBounds() == null) {
1892            return false;
1893        }
1894        return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID)
1895                || mService.mSupportsFreeformWindowManagement;
1896    }
1897
1898    ActivityStack getStack(int stackId) {
1899        return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
1900    }
1901
1902    ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
1903        ActivityContainer activityContainer = mActivityContainers.get(stackId);
1904        if (activityContainer != null) {
1905            return activityContainer.mStack;
1906        }
1907        if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
1908            return null;
1909        }
1910        return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
1911    }
1912
1913    ArrayList<ActivityStack> getStacks() {
1914        ArrayList<ActivityStack> allStacks = new ArrayList<>();
1915        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1916            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
1917        }
1918        return allStacks;
1919    }
1920
1921    IBinder getHomeActivityToken() {
1922        ActivityRecord homeActivity = getHomeActivity();
1923        if (homeActivity != null) {
1924            return homeActivity.appToken;
1925        }
1926        return null;
1927    }
1928
1929    ActivityRecord getHomeActivity() {
1930        return getHomeActivityForUser(mCurrentUser);
1931    }
1932
1933    ActivityRecord getHomeActivityForUser(int userId) {
1934        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
1935        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1936            final TaskRecord task = tasks.get(taskNdx);
1937            if (task.isHomeTask()) {
1938                final ArrayList<ActivityRecord> activities = task.mActivities;
1939                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1940                    final ActivityRecord r = activities.get(activityNdx);
1941                    if (r.isHomeActivity()
1942                            && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
1943                        return r;
1944                    }
1945                }
1946            }
1947        }
1948        return null;
1949    }
1950
1951    /**
1952     * Returns if a stack should be treated as if it's docked. Returns true if the stack is
1953     * the docked stack itself, or if it's side-by-side to the docked stack.
1954     */
1955    boolean isStackDockedInEffect(int stackId) {
1956        return stackId == DOCKED_STACK_ID ||
1957                (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null);
1958    }
1959
1960    ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
1961            IActivityContainerCallback callback) {
1962        ActivityContainer activityContainer =
1963                new VirtualActivityContainer(parentActivity, callback);
1964        mActivityContainers.put(activityContainer.mStackId, activityContainer);
1965        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
1966                "createActivityContainer: " + activityContainer);
1967        parentActivity.mChildContainers.add(activityContainer);
1968        return activityContainer;
1969    }
1970
1971    void removeChildActivityContainers(ActivityRecord parentActivity) {
1972        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
1973        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
1974            ActivityContainer container = childStacks.remove(containerNdx);
1975            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
1976                    + container);
1977            container.release();
1978        }
1979    }
1980
1981    void deleteActivityContainer(IActivityContainer container) {
1982        ActivityContainer activityContainer = (ActivityContainer)container;
1983        if (activityContainer != null) {
1984            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
1985                    "deleteActivityContainer: callers=" + Debug.getCallers(4));
1986            final int stackId = activityContainer.mStackId;
1987            mActivityContainers.remove(stackId);
1988            mWindowManager.removeStack(stackId);
1989        }
1990    }
1991
1992    void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
1993            boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) {
1994        if (stackId == DOCKED_STACK_ID) {
1995            resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null,
1996                    preserveWindows);
1997            return;
1998        }
1999        final ActivityStack stack = getStack(stackId);
2000        if (stack == null) {
2001            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2002            return;
2003        }
2004
2005        if (!allowResizeInDockedMode && getStack(DOCKED_STACK_ID) != null) {
2006            // If the docked stack exist we don't allow resizes of stacks not caused by the docked
2007            // stack size changing so things don't get out of sync.
2008            return;
2009        }
2010
2011        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
2012        mWindowManager.deferSurfaceLayout();
2013        try {
2014            resizeStackUncheckedLocked(stack, bounds, tempTaskBounds, tempTaskInsetBounds);
2015            if (!deferResume) {
2016                stack.ensureVisibleActivitiesConfigurationLocked(
2017                        stack.topRunningActivityLocked(), preserveWindows);
2018            }
2019        } finally {
2020            mWindowManager.continueSurfaceLayout();
2021            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2022        }
2023    }
2024
2025    void deferUpdateBounds(int stackId) {
2026        final ActivityStack stack = getStack(stackId);
2027        if (stack != null) {
2028            stack.deferUpdateBounds();
2029        }
2030    }
2031
2032    void continueUpdateBounds(int stackId) {
2033        final ActivityStack stack = getStack(stackId);
2034        if (stack != null) {
2035            stack.continueUpdateBounds();
2036        }
2037    }
2038
2039    void notifyAppTransitionDone() {
2040        continueUpdateBounds(HOME_STACK_ID);
2041        for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
2042            final int taskId = mResizingTasksDuringAnimation.valueAt(i);
2043            if (anyTaskForIdLocked(taskId) != null) {
2044                mWindowManager.setTaskDockedResizing(taskId, false);
2045            }
2046        }
2047        mResizingTasksDuringAnimation.clear();
2048    }
2049
2050    void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
2051            Rect tempTaskInsetBounds) {
2052        bounds = TaskRecord.validateBounds(bounds);
2053
2054        if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) {
2055            return;
2056        }
2057
2058        mTmpBounds.clear();
2059        mTmpConfigs.clear();
2060        mTmpInsetBounds.clear();
2061        final ArrayList<TaskRecord> tasks = stack.getAllTasks();
2062        final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
2063        final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds;
2064        for (int i = tasks.size() - 1; i >= 0; i--) {
2065            final TaskRecord task = tasks.get(i);
2066            if (task.isResizeable()) {
2067                if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
2068                    // For freeform stack we don't adjust the size of the tasks to match that
2069                    // of the stack, but we do try to make sure the tasks are still contained
2070                    // with the bounds of the stack.
2071                    tempRect2.set(task.mBounds);
2072                    fitWithinBounds(tempRect2, bounds);
2073                    task.updateOverrideConfiguration(tempRect2);
2074                } else {
2075                    task.updateOverrideConfiguration(taskBounds, insetBounds);
2076                }
2077            }
2078
2079            mTmpConfigs.put(task.taskId, task.mOverrideConfig);
2080            mTmpBounds.put(task.taskId, task.mBounds);
2081            if (tempTaskInsetBounds != null) {
2082                mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
2083            }
2084        }
2085
2086        // We might trigger a configuration change. Save the current task bounds for freezing.
2087        mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
2088        stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs,
2089                mTmpBounds, mTmpInsetBounds);
2090        stack.setBounds(bounds);
2091    }
2092
2093    void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) {
2094        final ActivityStack stack = getStack(fromStackId);
2095        if (stack == null) {
2096            return;
2097        }
2098
2099        mWindowManager.deferSurfaceLayout();
2100        try {
2101            if (fromStackId == DOCKED_STACK_ID) {
2102
2103                // We are moving all tasks from the docked stack to the fullscreen stack,
2104                // which is dismissing the docked stack, so resize all other stacks to
2105                // fullscreen here already so we don't end up with resize trashing.
2106                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
2107                    if (StackId.isResizeableByDockedStack(i)) {
2108                        ActivityStack otherStack = getStack(i);
2109                        if (otherStack != null) {
2110                            resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS,
2111                                    true /* allowResizeInDockedMode */, DEFER_RESUME);
2112                        }
2113                    }
2114                }
2115
2116                // Also disable docked stack resizing since we have manually adjusted the
2117                // size of other stacks above and we don't want to trigger a docked stack
2118                // resize when we remove task from it below and it is detached from the
2119                // display because it no longer contains any tasks.
2120                mAllowDockedStackResize = false;
2121            }
2122            final ArrayList<TaskRecord> tasks = stack.getAllTasks();
2123            final int size = tasks.size();
2124            if (onTop) {
2125                for (int i = 0; i < size; i++) {
2126                    moveTaskToStackLocked(tasks.get(i).taskId,
2127                            FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/,
2128                            "moveTasksToFullscreenStack", ANIMATE, DEFER_RESUME);
2129                }
2130
2131                ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
2132                resumeFocusedStackTopActivityLocked();
2133            } else {
2134                for (int i = size - 1; i >= 0; i--) {
2135                    positionTaskInStackLocked(tasks.get(i).taskId,
2136                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
2137                }
2138            }
2139        } finally {
2140            mAllowDockedStackResize = true;
2141            mWindowManager.continueSurfaceLayout();
2142        }
2143    }
2144
2145    void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
2146            Rect tempDockedTaskInsetBounds,
2147            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows) {
2148
2149        if (!mAllowDockedStackResize) {
2150            // Docked stack resize currently disabled.
2151            return;
2152        }
2153
2154        final ActivityStack stack = getStack(DOCKED_STACK_ID);
2155        if (stack == null) {
2156            Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
2157            return;
2158        }
2159
2160        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack");
2161        mWindowManager.deferSurfaceLayout();
2162        try {
2163            // Don't allow re-entry while resizing. E.g. due to docked stack detaching.
2164            mAllowDockedStackResize = false;
2165            ActivityRecord r = stack.topRunningActivityLocked();
2166            resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds,
2167                    tempDockedTaskInsetBounds);
2168
2169            // TODO: Checking for isAttached might not be needed as if the user passes in null
2170            // dockedBounds then they want the docked stack to be dismissed.
2171            if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) {
2172                // The dock stack either was dismissed or went fullscreen, which is kinda the same.
2173                // In this case we make all other static stacks fullscreen and move all
2174                // docked stack tasks to the fullscreen stack.
2175                moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP);
2176
2177                // stack shouldn't contain anymore activities, so nothing to resume.
2178                r = null;
2179            } else {
2180                // Docked stacks occupy a dedicated region on screen so the size of all other
2181                // static stacks need to be adjusted so they don't overlap with the docked stack.
2182                // We get the bounds to use from window manager which has been adjusted for any
2183                // screen controls and is also the same for all stacks.
2184                mWindowManager.getStackDockedModeBounds(
2185                        HOME_STACK_ID, tempRect, true /* ignoreVisibility */);
2186                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
2187                    if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) {
2188                        resizeStackLocked(i, tempRect, tempOtherTaskBounds,
2189                                tempOtherTaskInsetBounds, preserveWindows,
2190                                true /* allowResizeInDockedMode */, !DEFER_RESUME);
2191                    }
2192                }
2193            }
2194            stack.ensureVisibleActivitiesConfigurationLocked(r, preserveWindows);
2195        } finally {
2196            mAllowDockedStackResize = true;
2197            mWindowManager.continueSurfaceLayout();
2198            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2199        }
2200
2201        mResizeDockedStackTimeout.notifyResizing(dockedBounds,
2202                tempDockedTaskBounds != null
2203                || tempDockedTaskInsetBounds != null
2204                || tempOtherTaskBounds != null
2205                || tempOtherTaskInsetBounds != null);
2206    }
2207
2208    void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
2209        final ActivityStack stack = getStack(PINNED_STACK_ID);
2210        if (stack == null) {
2211            Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
2212            return;
2213        }
2214        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack");
2215        mWindowManager.deferSurfaceLayout();
2216        try {
2217            ActivityRecord r = stack.topRunningActivityLocked();
2218            resizeStackUncheckedLocked(stack, pinnedBounds, tempPinnedTaskBounds,
2219                    null);
2220            stack.ensureVisibleActivitiesConfigurationLocked(r, false);
2221        } finally {
2222            mWindowManager.continueSurfaceLayout();
2223            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2224        }
2225    }
2226
2227    boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow,
2228            boolean deferResume) {
2229        if (!task.isResizeable()) {
2230            Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
2231            return true;
2232        }
2233
2234        // If this is a forced resize, let it go through even if the bounds is not changing,
2235        // as we might need a relayout due to surface size change (to/from fullscreen).
2236        final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
2237        if (Objects.equals(task.mBounds, bounds) && !forced) {
2238            // Nothing to do here...
2239            return true;
2240        }
2241        bounds = TaskRecord.validateBounds(bounds);
2242
2243        if (!mWindowManager.isValidTaskId(task.taskId)) {
2244            // Task doesn't exist in window manager yet (e.g. was restored from recents).
2245            // All we can do for now is update the bounds so it can be used when the task is
2246            // added to window manager.
2247            task.updateOverrideConfiguration(bounds);
2248            if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
2249                // re-restore the task so it can have the proper stack association.
2250                restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID);
2251            }
2252            return true;
2253        }
2254
2255        // Do not move the task to another stack here.
2256        // This method assumes that the task is already placed in the right stack.
2257        // we do not mess with that decision and we only do the resize!
2258
2259        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId);
2260
2261        final Configuration overrideConfig =  task.updateOverrideConfiguration(bounds);
2262        // This variable holds information whether the configuration didn't change in a significant
2263        // way and the activity was kept the way it was. If it's false, it means the activity had
2264        // to be relaunched due to configuration change.
2265        boolean kept = true;
2266        if (overrideConfig != null) {
2267            final ActivityRecord r = task.topRunningActivityLocked();
2268            if (r != null) {
2269                final ActivityStack stack = task.stack;
2270                kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow);
2271
2272                if (!deferResume) {
2273
2274                    // All other activities must be made visible with their correct configuration.
2275                    ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
2276                    if (!kept) {
2277                        resumeFocusedStackTopActivityLocked();
2278                    }
2279                }
2280            }
2281        }
2282        mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced);
2283
2284        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2285        return kept;
2286    }
2287
2288    ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
2289        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2290        if (activityDisplay == null) {
2291            return null;
2292        }
2293
2294        ActivityContainer activityContainer = new ActivityContainer(stackId);
2295        mActivityContainers.put(stackId, activityContainer);
2296        activityContainer.attachToDisplayLocked(activityDisplay, onTop);
2297        return activityContainer.mStack;
2298    }
2299
2300    int getNextStackId() {
2301        while (true) {
2302            if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID
2303                    && getStack(mNextFreeStackId) == null) {
2304                break;
2305            }
2306            mNextFreeStackId++;
2307        }
2308        return mNextFreeStackId;
2309    }
2310
2311    /**
2312     * Restores a recent task to a stack
2313     * @param task The recent task to be restored.
2314     * @param stackId The stack to restore the task to (default launch stack will be used
2315     *                if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}).
2316     * @return true if the task has been restored successfully.
2317     */
2318    private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
2319        if (stackId == INVALID_STACK_ID) {
2320            stackId = task.getLaunchStackId();
2321        } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) {
2322            // Preferred stack is the docked stack, but the task can't go in the docked stack.
2323            // Put it in the fullscreen stack.
2324            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
2325        }
2326
2327        if (task.stack != null) {
2328            // Task has already been restored once. See if we need to do anything more
2329            if (task.stack.mStackId == stackId) {
2330                // Nothing else to do since it is already restored in the right stack.
2331                return true;
2332            }
2333            // Remove current stack association, so we can re-associate the task with the
2334            // right stack below.
2335            task.stack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING);
2336        }
2337
2338        final ActivityStack stack =
2339                getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
2340
2341        if (stack == null) {
2342            // What does this mean??? Not sure how we would get here...
2343            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2344                    "Unable to find/create stack to restore recent task=" + task);
2345            return false;
2346        }
2347
2348        stack.addTask(task, false, "restoreRecentTask");
2349        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2350                "Added restored task=" + task + " to stack=" + stack);
2351        final ArrayList<ActivityRecord> activities = task.mActivities;
2352        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2353            stack.addConfigOverride(activities.get(activityNdx), task);
2354        }
2355        return true;
2356    }
2357
2358    /**
2359     * Moves the specified task record to the input stack id.
2360     * WARNING: This method performs an unchecked/raw move of the task and
2361     * can leave the system in an unstable state if used incorrectly.
2362     * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack.
2363     * @param task Task to move.
2364     * @param stackId Id of stack to move task to.
2365     * @param toTop True if the task should be placed at the top of the stack.
2366     * @param forceFocus if focus should be moved to the new stack
2367     * @param reason Reason the task is been moved.
2368     * @return The stack the task was moved to.
2369     */
2370    ActivityStack moveTaskToStackUncheckedLocked(
2371            TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
2372
2373        if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) {
2374            throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't "
2375                    + "support multi-window task=" + task + " to stackId=" + stackId);
2376        }
2377
2378        final ActivityRecord r = task.topRunningActivityLocked();
2379        final ActivityStack prevStack = task.stack;
2380        final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r);
2381        final boolean wasResumed = prevStack.mResumedActivity == r;
2382        // In some cases the focused stack isn't the front stack. E.g. pinned stack.
2383        // Whenever we are moving the top activity from the front stack we want to make sure to move
2384        // the stack to the front.
2385        final boolean wasFront = isFrontStack(prevStack)
2386                && (prevStack.topRunningActivityLocked() == r);
2387
2388        if (stackId == DOCKED_STACK_ID && !task.isResizeable()) {
2389            // We don't allow moving a unresizeable task to the docked stack since the docked
2390            // stack is used for split-screen mode and will cause things like the docked divider to
2391            // show up. We instead leave the task in its current stack or move it to the fullscreen
2392            // stack if it isn't currently in a stack.
2393            stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
2394            Slog.w(TAG, "Can not move unresizeable task=" + task
2395                    + " to docked stack. Moving to stackId=" + stackId + " instead.");
2396        }
2397
2398        // Temporarily disable resizeablility of task we are moving. We don't want it to be resized
2399        // if a docked stack is created below which will lead to the stack we are moving from and
2400        // its resizeable tasks being resized.
2401        task.mTemporarilyUnresizable = true;
2402        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop);
2403        task.mTemporarilyUnresizable = false;
2404        mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop);
2405        stack.addTask(task, toTop, reason);
2406
2407        // If the task had focus before (or we're requested to move focus),
2408        // move focus to the new stack by moving the stack to the front.
2409        stack.moveToFrontAndResumeStateIfNeeded(
2410                r, forceFocus || wasFocused || wasFront, wasResumed, reason);
2411
2412        return stack;
2413    }
2414
2415    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
2416            String reason, boolean animate) {
2417        return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate,
2418                false /* deferResume */);
2419    }
2420
2421    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
2422            String reason, boolean animate, boolean deferResume) {
2423        final TaskRecord task = anyTaskForIdLocked(taskId);
2424        if (task == null) {
2425            Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
2426            return false;
2427        }
2428
2429        if (task.stack != null && task.stack.mStackId == stackId) {
2430            // You are already in the right stack silly...
2431            Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId);
2432            return true;
2433        }
2434
2435        if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
2436            throw new IllegalArgumentException("moveTaskToStack:"
2437                    + "Attempt to move task " + taskId + " to unsupported freeform stack");
2438        }
2439
2440        final ActivityRecord topActivity = task.getTopActivity();
2441        final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID;
2442        final boolean mightReplaceWindow =
2443                StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) && topActivity != null;
2444        if (mightReplaceWindow) {
2445            // We are about to relaunch the activity because its configuration changed due to
2446            // being maximized, i.e. size change. The activity will first remove the old window
2447            // and then add a new one. This call will tell window manager about this, so it can
2448            // preserve the old window until the new one is drawn. This prevents having a gap
2449            // between the removal and addition, in which no window is visible. We also want the
2450            // entrance of the new window to be properly animated.
2451            // Note here we always set the replacing window first, as the flags might be needed
2452            // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
2453            mWindowManager.setReplacingWindow(topActivity.appToken, animate);
2454        }
2455
2456        mWindowManager.deferSurfaceLayout();
2457        final int preferredLaunchStackId = stackId;
2458        boolean kept = true;
2459        try {
2460            final ActivityStack stack = moveTaskToStackUncheckedLocked(
2461                    task, stackId, toTop, forceFocus, reason + " moveTaskToStack");
2462            stackId = stack.mStackId;
2463
2464            if (!animate) {
2465                stack.mNoAnimActivities.add(topActivity);
2466            }
2467
2468            // We might trigger a configuration change. Save the current task bounds for freezing.
2469            mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
2470
2471            // Make sure the task has the appropriate bounds/size for the stack it is in.
2472            if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
2473                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
2474                        !mightReplaceWindow, deferResume);
2475            } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
2476                Rect bounds = task.getLaunchBounds();
2477                if (bounds == null) {
2478                    stack.layoutTaskInStack(task, null);
2479                    bounds = task.mBounds;
2480                }
2481                kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow,
2482                        deferResume);
2483            } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
2484                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
2485                        !mightReplaceWindow, deferResume);
2486            }
2487        } finally {
2488            mWindowManager.continueSurfaceLayout();
2489        }
2490
2491        if (mightReplaceWindow) {
2492            // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
2493            // window), we need to clear the replace window settings. Otherwise, we schedule a
2494            // timeout to remove the old window if the replacing window is not coming in time.
2495            mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept);
2496        }
2497
2498        if (!deferResume) {
2499
2500            // The task might have already been running and its visibility needs to be synchronized with
2501            // the visibility of the stack / windows.
2502            ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
2503            resumeFocusedStackTopActivityLocked();
2504        }
2505
2506        handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId);
2507
2508        return (preferredLaunchStackId == stackId);
2509    }
2510
2511    boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) {
2512        final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
2513        if (stack == null) {
2514            throw new IllegalArgumentException(
2515                    "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId);
2516        }
2517
2518        final ActivityRecord r = stack.topRunningActivityLocked();
2519        if (r == null) {
2520            Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity"
2521                    + " in stack=" + stack);
2522            return false;
2523        }
2524
2525        if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
2526            Slog.w(TAG,
2527                    "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for "
2528                            + " r=" + r);
2529            return false;
2530        }
2531
2532        moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds);
2533        return true;
2534    }
2535
2536    void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) {
2537        mWindowManager.deferSurfaceLayout();
2538        try {
2539            final TaskRecord task = r.task;
2540
2541            if (r == task.stack.getVisibleBehindActivity()) {
2542                // An activity can't be pinned and visible behind at the same time. Go ahead and
2543                // release it from been visible behind before pinning.
2544                requestVisibleBehindLocked(r, false);
2545            }
2546
2547            // Need to make sure the pinned stack exist so we can resize it below...
2548            final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
2549
2550            // Resize the pinned stack to match the current size of the task the activity we are
2551            // going to be moving is currently contained in. We do this to have the right starting
2552            // animation bounds for the pinned stack to the desired bounds the caller wants.
2553            resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
2554                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
2555                    true /* allowResizeInDockedMode */, !DEFER_RESUME);
2556
2557            if (task.mActivities.size() == 1) {
2558                // There is only one activity in the task. So, we can just move the task over to
2559                // the stack without re-parenting the activity in a different task.
2560                if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
2561                    // Move the home stack forward if the task we just moved to the pinned stack
2562                    // was launched from home so home should be visible behind it.
2563                    moveHomeStackToFront(reason);
2564                }
2565                moveTaskToStackLocked(
2566                        task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE);
2567            } else {
2568                stack.moveActivityToStack(r);
2569            }
2570        } finally {
2571            mWindowManager.continueSurfaceLayout();
2572        }
2573
2574        // The task might have already been running and its visibility needs to be synchronized
2575        // with the visibility of the stack / windows.
2576        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2577        resumeFocusedStackTopActivityLocked();
2578
2579        mWindowManager.animateResizePinnedStack(bounds, -1);
2580        mService.notifyActivityPinnedLocked();
2581    }
2582
2583    void positionTaskInStackLocked(int taskId, int stackId, int position) {
2584        final TaskRecord task = anyTaskForIdLocked(taskId);
2585        if (task == null) {
2586            Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
2587            return;
2588        }
2589        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
2590
2591        task.updateOverrideConfigurationForStack(stack);
2592
2593        mWindowManager.positionTaskInStack(
2594                taskId, stackId, position, task.mBounds, task.mOverrideConfig);
2595        stack.positionTask(task, position);
2596        // The task might have already been running and its visibility needs to be synchronized with
2597        // the visibility of the stack / windows.
2598        stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2599        resumeFocusedStackTopActivityLocked();
2600    }
2601
2602    ActivityRecord findTaskLocked(ActivityRecord r) {
2603        mTmpFindTaskResult.r = null;
2604        mTmpFindTaskResult.matchedByRootAffinity = false;
2605        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
2606        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2607            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2608            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2609                final ActivityStack stack = stacks.get(stackNdx);
2610                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2611                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
2612                    continue;
2613                }
2614                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2615                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
2616                            "Skipping stack: (new task not allowed) " + stack);
2617                    continue;
2618                }
2619                stack.findTaskLocked(r, mTmpFindTaskResult);
2620                // It is possible to have task in multiple stacks with the same root affinity.
2621                // If the match we found was based on root affinity we keep on looking to see if
2622                // there is a better match in another stack. We eventually return the match based
2623                // on root affinity if we don't find a better match.
2624                if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) {
2625                    return mTmpFindTaskResult.r;
2626                }
2627            }
2628        }
2629        if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found");
2630        return mTmpFindTaskResult.r;
2631    }
2632
2633    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2634        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2635            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2636            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2637                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2638                if (ar != null) {
2639                    return ar;
2640                }
2641            }
2642        }
2643        return null;
2644    }
2645
2646    void goingToSleepLocked() {
2647        scheduleSleepTimeout();
2648        if (!mGoingToSleep.isHeld()) {
2649            mGoingToSleep.acquire();
2650            if (mLaunchingActivity.isHeld()) {
2651                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2652                    throw new IllegalStateException("Calling must be system uid");
2653                }
2654                mLaunchingActivity.release();
2655                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2656            }
2657        }
2658        checkReadyForSleepLocked();
2659    }
2660
2661    boolean shutdownLocked(int timeout) {
2662        goingToSleepLocked();
2663
2664        boolean timedout = false;
2665        final long endTime = System.currentTimeMillis() + timeout;
2666        while (true) {
2667            boolean cantShutdown = false;
2668            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2669                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2670                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2671                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2672                }
2673            }
2674            if (cantShutdown) {
2675                long timeRemaining = endTime - System.currentTimeMillis();
2676                if (timeRemaining > 0) {
2677                    try {
2678                        mService.wait(timeRemaining);
2679                    } catch (InterruptedException e) {
2680                    }
2681                } else {
2682                    Slog.w(TAG, "Activity manager shutdown timed out");
2683                    timedout = true;
2684                    break;
2685                }
2686            } else {
2687                break;
2688            }
2689        }
2690
2691        // Force checkReadyForSleep to complete.
2692        mSleepTimeout = true;
2693        checkReadyForSleepLocked();
2694
2695        return timedout;
2696    }
2697
2698    void comeOutOfSleepIfNeededLocked() {
2699        removeSleepTimeouts();
2700        if (mGoingToSleep.isHeld()) {
2701            mGoingToSleep.release();
2702        }
2703        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2704            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2705            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2706                final ActivityStack stack = stacks.get(stackNdx);
2707                stack.awakeFromSleepingLocked();
2708                if (isFocusedStack(stack)) {
2709                    resumeFocusedStackTopActivityLocked();
2710                }
2711            }
2712        }
2713        mGoingToSleepActivities.clear();
2714    }
2715
2716    void activitySleptLocked(ActivityRecord r) {
2717        mGoingToSleepActivities.remove(r);
2718        checkReadyForSleepLocked();
2719    }
2720
2721    void checkReadyForSleepLocked() {
2722        if (!mService.isSleepingOrShuttingDown()) {
2723            // Do not care.
2724            return;
2725        }
2726
2727        if (!mSleepTimeout) {
2728            boolean dontSleep = false;
2729            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2730                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2731                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2732                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2733                }
2734            }
2735
2736            if (mStoppingActivities.size() > 0) {
2737                // Still need to tell some activities to stop; can't sleep yet.
2738                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
2739                        + mStoppingActivities.size() + " activities");
2740                scheduleIdleLocked();
2741                dontSleep = true;
2742            }
2743
2744            if (mGoingToSleepActivities.size() > 0) {
2745                // Still need to tell some activities to sleep; can't sleep yet.
2746                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
2747                        + mGoingToSleepActivities.size() + " activities");
2748                dontSleep = true;
2749            }
2750
2751            if (dontSleep) {
2752                return;
2753            }
2754        }
2755
2756        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2757            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2758            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2759                stacks.get(stackNdx).goToSleep();
2760            }
2761        }
2762
2763        removeSleepTimeouts();
2764
2765        if (mGoingToSleep.isHeld()) {
2766            mGoingToSleep.release();
2767        }
2768        if (mService.mShuttingDown) {
2769            mService.notifyAll();
2770        }
2771    }
2772
2773    boolean reportResumedActivityLocked(ActivityRecord r) {
2774        final ActivityStack stack = r.task.stack;
2775        if (isFocusedStack(stack)) {
2776            mService.updateUsageStats(r, true);
2777        }
2778        if (allResumedActivitiesComplete()) {
2779            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2780            mWindowManager.executeAppTransition();
2781            return true;
2782        }
2783        return false;
2784    }
2785
2786    void handleAppCrashLocked(ProcessRecord app) {
2787        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2788            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2789            int stackNdx = stacks.size() - 1;
2790            while (stackNdx >= 0) {
2791                stacks.get(stackNdx).handleAppCrashLocked(app);
2792                stackNdx--;
2793            }
2794        }
2795    }
2796
2797    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
2798        final ActivityStack stack = r.task.stack;
2799        if (stack == null) {
2800            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2801                    "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
2802            return false;
2803        }
2804
2805        if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) {
2806            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r
2807                    + " visible=" + visible + " stackId=" + stack.mStackId
2808                    + " can't contain visible behind activities");
2809            return false;
2810        }
2811
2812        final boolean isVisible = stack.hasVisibleBehindActivity();
2813        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2814                "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
2815
2816        final ActivityRecord top = topRunningActivityLocked();
2817        if (top == null || top == r || (visible == isVisible)) {
2818            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
2819            stack.setVisibleBehindActivity(visible ? r : null);
2820            return true;
2821        }
2822
2823        // A non-top activity is reporting a visibility change.
2824        if (visible && top.fullscreen) {
2825            // Let the caller know that it can't be seen.
2826            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2827                    "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
2828                    + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
2829                    + top.app.thread);
2830            return false;
2831        } else if (!visible && stack.getVisibleBehindActivity() != r) {
2832            // Only the activity set as currently visible behind should actively reset its
2833            // visible behind state.
2834            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2835                    "requestVisibleBehind: returning visible=" + visible
2836                    + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
2837                    + " r=" + r);
2838            return false;
2839        }
2840
2841        stack.setVisibleBehindActivity(visible ? r : null);
2842        if (!visible) {
2843            // If there is a translucent home activity, we need to force it stop being translucent,
2844            // because we can't depend on the application to necessarily perform that operation.
2845            // Check out b/14469711 for details.
2846            final ActivityRecord next = stack.findNextTranslucentActivity(r);
2847            if (next != null && next.isHomeActivity()) {
2848                mService.convertFromTranslucent(next.appToken);
2849            }
2850        }
2851        if (top.app != null && top.app.thread != null) {
2852            // Notify the top app of the change.
2853            try {
2854                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
2855            } catch (RemoteException e) {
2856            }
2857        }
2858        return true;
2859    }
2860
2861    // Called when WindowManager has finished animating the launchingBehind activity to the back.
2862    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2863        final TaskRecord task = r.task;
2864        final ActivityStack stack = task.stack;
2865
2866        r.mLaunchTaskBehind = false;
2867        task.setLastThumbnailLocked(stack.screenshotActivitiesLocked(r));
2868        mRecentTasks.addLocked(task);
2869        mService.notifyTaskStackChangedLocked();
2870        mWindowManager.setAppVisibility(r.appToken, false);
2871
2872        // When launching tasks behind, update the last active time of the top task after the new
2873        // task has been shown briefly
2874        final ActivityRecord top = stack.topActivity();
2875        if (top != null) {
2876            top.task.touchActiveTime();
2877        }
2878    }
2879
2880    void scheduleLaunchTaskBehindComplete(IBinder token) {
2881        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2882    }
2883
2884    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
2885            boolean preserveWindows) {
2886        // First the front stacks. In case any are not fullscreen and are in front of home.
2887        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2888            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2889            final int topStackNdx = stacks.size() - 1;
2890            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2891                final ActivityStack stack = stacks.get(stackNdx);
2892                stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
2893            }
2894        }
2895    }
2896
2897    void invalidateTaskLayers() {
2898        mTaskLayersChanged = true;
2899    }
2900
2901    void rankTaskLayersIfNeeded() {
2902        if (!mTaskLayersChanged) {
2903            return;
2904        }
2905        mTaskLayersChanged = false;
2906        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
2907            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2908            int baseLayer = 0;
2909            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2910                baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer);
2911            }
2912        }
2913    }
2914
2915    void clearOtherAppTimeTrackers(AppTimeTracker except) {
2916        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2917            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2918            final int topStackNdx = stacks.size() - 1;
2919            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2920                final ActivityStack stack = stacks.get(stackNdx);
2921                stack.clearOtherAppTimeTrackers(except);
2922            }
2923        }
2924    }
2925
2926    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2927        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2928            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2929            final int numStacks = stacks.size();
2930            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2931                final ActivityStack stack = stacks.get(stackNdx);
2932                stack.scheduleDestroyActivities(app, reason);
2933            }
2934        }
2935    }
2936
2937    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
2938        // Examine all activities currently running in the process.
2939        TaskRecord firstTask = null;
2940        // Tasks is non-null only if two or more tasks are found.
2941        ArraySet<TaskRecord> tasks = null;
2942        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
2943        for (int i = 0; i < app.activities.size(); i++) {
2944            ActivityRecord r = app.activities.get(i);
2945            // First, if we find an activity that is in the process of being destroyed,
2946            // then we just aren't going to do anything for now; we want things to settle
2947            // down before we try to prune more activities.
2948            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
2949                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
2950                return;
2951            }
2952            // Don't consider any activies that are currently not in a state where they
2953            // can be destroyed.
2954            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
2955                    || r.state == PAUSED || r.state == STOPPING) {
2956                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
2957                continue;
2958            }
2959            if (r.task != null) {
2960                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task
2961                        + " from " + r);
2962                if (firstTask == null) {
2963                    firstTask = r.task;
2964                } else if (firstTask != r.task) {
2965                    if (tasks == null) {
2966                        tasks = new ArraySet<>();
2967                        tasks.add(firstTask);
2968                    }
2969                    tasks.add(r.task);
2970                }
2971            }
2972        }
2973        if (tasks == null) {
2974            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
2975            return;
2976        }
2977        // If we have activities in multiple tasks that are in a position to be destroyed,
2978        // let's iterate through the tasks and release the oldest one.
2979        final int numDisplays = mActivityDisplays.size();
2980        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2981            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2982            // Step through all stacks starting from behind, to hit the oldest things first.
2983            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
2984                final ActivityStack stack = stacks.get(stackNdx);
2985                // Try to release activities in this stack; if we manage to, we are done.
2986                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
2987                    return;
2988                }
2989            }
2990        }
2991    }
2992
2993    boolean switchUserLocked(int userId, UserState uss) {
2994        final int focusStackId = mFocusedStack.getStackId();
2995        // We dismiss the docked stack whenever we switch users.
2996        moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, focusStackId == DOCKED_STACK_ID);
2997
2998        mUserStackInFront.put(mCurrentUser, focusStackId);
2999        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
3000        mCurrentUser = userId;
3001
3002        mStartingUsers.add(uss);
3003        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3004            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3005            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3006                final ActivityStack stack = stacks.get(stackNdx);
3007                stack.switchUserLocked(userId);
3008                TaskRecord task = stack.topTask();
3009                if (task != null) {
3010                    mWindowManager.moveTaskToTop(task.taskId);
3011                }
3012            }
3013        }
3014
3015        ActivityStack stack = getStack(restoreStackId);
3016        if (stack == null) {
3017            stack = mHomeStack;
3018        }
3019        final boolean homeInFront = stack.isHomeStack();
3020        if (stack.isOnHomeDisplay()) {
3021            stack.moveToFront("switchUserOnHomeDisplay");
3022        } else {
3023            // Stack was moved to another display while user was swapped out.
3024            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
3025        }
3026        return homeInFront;
3027    }
3028
3029    /** Checks whether the userid is a profile of the current user. */
3030    boolean isCurrentProfileLocked(int userId) {
3031        if (userId == mCurrentUser) return true;
3032        return mService.mUserController.isCurrentProfileLocked(userId);
3033    }
3034
3035    /** Checks whether the activity should be shown for current user. */
3036    boolean okToShowLocked(ActivityRecord r) {
3037        return r != null && (isCurrentProfileLocked(r.userId)
3038                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
3039    }
3040
3041    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
3042        ArrayList<ActivityRecord> stops = null;
3043
3044        final boolean nowVisible = allResumedActivitiesVisible();
3045        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3046            ActivityRecord s = mStoppingActivities.get(activityNdx);
3047            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
3048            if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
3049                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
3050            if (waitingVisible && nowVisible) {
3051                mWaitingVisibleActivities.remove(s);
3052                if (s.finishing) {
3053                    // If this activity is finishing, it is sitting on top of
3054                    // everyone else but we now know it is no longer needed...
3055                    // so get rid of it.  Otherwise, we need to go through the
3056                    // normal flow and hide it once we determine that it is
3057                    // hidden by the activities in front of it.
3058                    if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
3059                    mWindowManager.setAppVisibility(s.appToken, false);
3060                }
3061            }
3062            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
3063                if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
3064                if (stops == null) {
3065                    stops = new ArrayList<>();
3066                }
3067                stops.add(s);
3068                mStoppingActivities.remove(activityNdx);
3069            }
3070        }
3071
3072        return stops;
3073    }
3074
3075    void validateTopActivitiesLocked() {
3076        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3077            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3078            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3079                final ActivityStack stack = stacks.get(stackNdx);
3080                final ActivityRecord r = stack.topRunningActivityLocked();
3081                final ActivityState state = r == null ? DESTROYED : r.state;
3082                if (isFocusedStack(stack)) {
3083                    if (r == null) Slog.e(TAG,
3084                            "validateTop...: null top activity, stack=" + stack);
3085                    else {
3086                        final ActivityRecord pausing = stack.mPausingActivity;
3087                        if (pausing != null && pausing == r) Slog.e(TAG,
3088                                "validateTop...: top stack has pausing activity r=" + r
3089                                + " state=" + state);
3090                        if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
3091                                "validateTop...: activity in front not resumed r=" + r
3092                                + " state=" + state);
3093                    }
3094                } else {
3095                    final ActivityRecord resumed = stack.mResumedActivity;
3096                    if (resumed != null && resumed == r) Slog.e(TAG,
3097                            "validateTop...: back stack has resumed activity r=" + r
3098                            + " state=" + state);
3099                    if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
3100                            "validateTop...: activity in back resumed r=" + r + " state=" + state);
3101                }
3102            }
3103        }
3104    }
3105
3106    private String lockTaskModeToString() {
3107        switch (mLockTaskModeState) {
3108            case LOCK_TASK_MODE_LOCKED:
3109                return "LOCKED";
3110            case LOCK_TASK_MODE_PINNED:
3111                return "PINNED";
3112            case LOCK_TASK_MODE_NONE:
3113                return "NONE";
3114            default: return "unknown=" + mLockTaskModeState;
3115        }
3116    }
3117
3118    public void dump(PrintWriter pw, String prefix) {
3119        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3120                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3121        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3122        pw.print(prefix);
3123        pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
3124        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3125        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3126        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
3127                final SparseArray<String[]> packages = mService.mLockTaskPackages;
3128                if (packages.size() > 0) {
3129                    pw.println(" mLockTaskPackages (userId:packages)=");
3130                    for (int i = 0; i < packages.size(); ++i) {
3131                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
3132                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
3133                    }
3134                }
3135                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
3136    }
3137
3138    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3139        return mFocusedStack.getDumpActivitiesLocked(name);
3140    }
3141
3142    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3143            boolean needSep, String prefix) {
3144        if (activity != null) {
3145            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3146                if (needSep) {
3147                    pw.println();
3148                }
3149                pw.print(prefix);
3150                pw.println(activity);
3151                return true;
3152            }
3153        }
3154        return false;
3155    }
3156
3157    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3158            boolean dumpClient, String dumpPackage) {
3159        boolean printed = false;
3160        boolean needSep = false;
3161        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3162            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3163            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3164                    pw.println(" (activities from top to bottom):");
3165            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3166            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3167                final ActivityStack stack = stacks.get(stackNdx);
3168                StringBuilder stackHeader = new StringBuilder(128);
3169                stackHeader.append("  Stack #");
3170                stackHeader.append(stack.mStackId);
3171                stackHeader.append(":");
3172                stackHeader.append("\n");
3173                stackHeader.append("  mFullscreen=" + stack.mFullscreen);
3174                stackHeader.append("\n");
3175                stackHeader.append("  mBounds=" + stack.mBounds);
3176                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3177                        needSep, stackHeader.toString());
3178                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3179                        !dumpAll, false, dumpPackage, true,
3180                        "    Running activities (most recent first):", null);
3181
3182                needSep = printed;
3183                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3184                        "    mPausingActivity: ");
3185                if (pr) {
3186                    printed = true;
3187                    needSep = false;
3188                }
3189                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3190                        "    mResumedActivity: ");
3191                if (pr) {
3192                    printed = true;
3193                    needSep = false;
3194                }
3195                if (dumpAll) {
3196                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3197                            "    mLastPausedActivity: ");
3198                    if (pr) {
3199                        printed = true;
3200                        needSep = true;
3201                    }
3202                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3203                            needSep, "    mLastNoHistoryActivity: ");
3204                }
3205                needSep = printed;
3206            }
3207        }
3208
3209        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3210                false, dumpPackage, true, "  Activities waiting to finish:", null);
3211        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3212                false, dumpPackage, true, "  Activities waiting to stop:", null);
3213        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3214                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3215                null);
3216        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3217                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3218        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3219                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3220
3221        return printed;
3222    }
3223
3224    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3225            String prefix, String label, boolean complete, boolean brief, boolean client,
3226            String dumpPackage, boolean needNL, String header1, String header2) {
3227        TaskRecord lastTask = null;
3228        String innerPrefix = null;
3229        String[] args = null;
3230        boolean printed = false;
3231        for (int i=list.size()-1; i>=0; i--) {
3232            final ActivityRecord r = list.get(i);
3233            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3234                continue;
3235            }
3236            if (innerPrefix == null) {
3237                innerPrefix = prefix + "      ";
3238                args = new String[0];
3239            }
3240            printed = true;
3241            final boolean full = !brief && (complete || !r.isInHistory());
3242            if (needNL) {
3243                pw.println("");
3244                needNL = false;
3245            }
3246            if (header1 != null) {
3247                pw.println(header1);
3248                header1 = null;
3249            }
3250            if (header2 != null) {
3251                pw.println(header2);
3252                header2 = null;
3253            }
3254            if (lastTask != r.task) {
3255                lastTask = r.task;
3256                pw.print(prefix);
3257                pw.print(full ? "* " : "  ");
3258                pw.println(lastTask);
3259                if (full) {
3260                    lastTask.dump(pw, prefix + "  ");
3261                } else if (complete) {
3262                    // Complete + brief == give a summary.  Isn't that obvious?!?
3263                    if (lastTask.intent != null) {
3264                        pw.print(prefix); pw.print("  ");
3265                                pw.println(lastTask.intent.toInsecureStringWithClip());
3266                    }
3267                }
3268            }
3269            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3270            pw.print(" #"); pw.print(i); pw.print(": ");
3271            pw.println(r);
3272            if (full) {
3273                r.dump(pw, innerPrefix);
3274            } else if (complete) {
3275                // Complete + brief == give a summary.  Isn't that obvious?!?
3276                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3277                if (r.app != null) {
3278                    pw.print(innerPrefix); pw.println(r.app);
3279                }
3280            }
3281            if (client && r.app != null && r.app.thread != null) {
3282                // flush anything that is already in the PrintWriter since the thread is going
3283                // to write to the file descriptor directly
3284                pw.flush();
3285                try {
3286                    TransferPipe tp = new TransferPipe();
3287                    try {
3288                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3289                                r.appToken, innerPrefix, args);
3290                        // Short timeout, since blocking here can
3291                        // deadlock with the application.
3292                        tp.go(fd, 2000);
3293                    } finally {
3294                        tp.kill();
3295                    }
3296                } catch (IOException e) {
3297                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3298                } catch (RemoteException e) {
3299                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3300                }
3301                needNL = true;
3302            }
3303        }
3304        return printed;
3305    }
3306
3307    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3308        if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3309                "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3310        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3311        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3312    }
3313
3314    final void scheduleIdleLocked() {
3315        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3316    }
3317
3318    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3319        if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
3320                + Debug.getCallers(4));
3321        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3322    }
3323
3324    final void scheduleResumeTopActivities() {
3325        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3326            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3327        }
3328    }
3329
3330    void removeSleepTimeouts() {
3331        mSleepTimeout = false;
3332        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3333    }
3334
3335    final void scheduleSleepTimeout() {
3336        removeSleepTimeouts();
3337        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3338    }
3339
3340    @Override
3341    public void onDisplayAdded(int displayId) {
3342        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
3343        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3344    }
3345
3346    @Override
3347    public void onDisplayRemoved(int displayId) {
3348        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
3349        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3350    }
3351
3352    @Override
3353    public void onDisplayChanged(int displayId) {
3354        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
3355        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3356    }
3357
3358    private void handleDisplayAdded(int displayId) {
3359        boolean newDisplay;
3360        synchronized (mService) {
3361            newDisplay = mActivityDisplays.get(displayId) == null;
3362            if (newDisplay) {
3363                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3364                if (activityDisplay.mDisplay == null) {
3365                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3366                    return;
3367                }
3368                mActivityDisplays.put(displayId, activityDisplay);
3369                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
3370            }
3371        }
3372        if (newDisplay) {
3373            mWindowManager.onDisplayAdded(displayId);
3374        }
3375    }
3376
3377    private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
3378        mDefaultMinimalSizeOfResizeableTask =
3379                mService.mContext.getResources().getDimensionPixelSize(
3380                        com.android.internal.R.dimen.default_minimal_size_resizable_task);
3381    }
3382
3383    private void handleDisplayRemoved(int displayId) {
3384        synchronized (mService) {
3385            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3386            if (activityDisplay != null) {
3387                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3388                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3389                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3390                }
3391                mActivityDisplays.remove(displayId);
3392            }
3393        }
3394        mWindowManager.onDisplayRemoved(displayId);
3395    }
3396
3397    private void handleDisplayChanged(int displayId) {
3398        synchronized (mService) {
3399            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3400            if (activityDisplay != null) {
3401                // TODO: Update the bounds.
3402            }
3403        }
3404        mWindowManager.onDisplayChanged(displayId);
3405    }
3406
3407    private StackInfo getStackInfoLocked(ActivityStack stack) {
3408        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
3409        StackInfo info = new StackInfo();
3410        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3411        info.displayId = Display.DEFAULT_DISPLAY;
3412        info.stackId = stack.mStackId;
3413        info.userId = stack.mCurrentUser;
3414        info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
3415        info.position = display != null
3416                ? display.mStacks.indexOf(stack)
3417                : 0;
3418
3419        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3420        final int numTasks = tasks.size();
3421        int[] taskIds = new int[numTasks];
3422        String[] taskNames = new String[numTasks];
3423        Rect[] taskBounds = new Rect[numTasks];
3424        int[] taskUserIds = new int[numTasks];
3425        for (int i = 0; i < numTasks; ++i) {
3426            final TaskRecord task = tasks.get(i);
3427            taskIds[i] = task.taskId;
3428            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3429                    : task.realActivity != null ? task.realActivity.flattenToString()
3430                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3431                    : "unknown";
3432            taskBounds[i] = new Rect();
3433            mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
3434            taskUserIds[i] = task.userId;
3435        }
3436        info.taskIds = taskIds;
3437        info.taskNames = taskNames;
3438        info.taskBounds = taskBounds;
3439        info.taskUserIds = taskUserIds;
3440
3441        final ActivityRecord top = stack.topRunningActivityLocked();
3442        info.topActivity = top != null ? top.intent.getComponent() : null;
3443        return info;
3444    }
3445
3446    StackInfo getStackInfoLocked(int stackId) {
3447        ActivityStack stack = getStack(stackId);
3448        if (stack != null) {
3449            return getStackInfoLocked(stack);
3450        }
3451        return null;
3452    }
3453
3454    ArrayList<StackInfo> getAllStackInfosLocked() {
3455        ArrayList<StackInfo> list = new ArrayList<>();
3456        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3457            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3458            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3459                list.add(getStackInfoLocked(stacks.get(ndx)));
3460            }
3461        }
3462        return list;
3463    }
3464
3465    TaskRecord getLockedTaskLocked() {
3466        final int top = mLockTaskModeTasks.size() - 1;
3467        if (top >= 0) {
3468            return mLockTaskModeTasks.get(top);
3469        }
3470        return null;
3471    }
3472
3473    boolean isLockedTask(TaskRecord task) {
3474        return mLockTaskModeTasks.contains(task);
3475    }
3476
3477    boolean isLastLockedTask(TaskRecord task) {
3478        return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
3479    }
3480
3481    void removeLockedTaskLocked(final TaskRecord task) {
3482        if (!mLockTaskModeTasks.remove(task)) {
3483            return;
3484        }
3485        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
3486        if (mLockTaskModeTasks.isEmpty()) {
3487            // Last one.
3488            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
3489                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
3490            final Message lockTaskMsg = Message.obtain();
3491            lockTaskMsg.arg1 = task.userId;
3492            lockTaskMsg.what = LOCK_TASK_END_MSG;
3493            mHandler.sendMessage(lockTaskMsg);
3494        }
3495    }
3496
3497    void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) {
3498        handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId,
3499                false /* forceNonResizable */);
3500    }
3501
3502    void handleNonResizableTaskIfNeeded(
3503            TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) {
3504        if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
3505                || task.isHomeTask()) {
3506            return;
3507        }
3508
3509        final ActivityRecord topActivity = task.getTopActivity();
3510        if (!task.canGoInDockedStack() || forceNonResizable) {
3511            // Display a warning toast that we tried to put a non-dockable task in the docked stack.
3512            mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
3513
3514            // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
3515            // we need to move it to top of fullscreen stack, otherwise it will be covered.
3516            moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID);
3517        } else if (topActivity != null && topActivity.isNonResizableOrForced()
3518                && !topActivity.noDisplay) {
3519            String packageName = topActivity.appInfo.packageName;
3520            mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0,
3521                    packageName).sendToTarget();
3522        }
3523    }
3524
3525    void showLockTaskToast() {
3526        mLockTaskNotify.showToast(mLockTaskModeState);
3527    }
3528
3529    void showLockTaskEscapeMessageLocked(TaskRecord task) {
3530        if (mLockTaskModeTasks.contains(task)) {
3531            mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
3532        }
3533    }
3534
3535    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
3536            boolean andResume) {
3537        if (task == null) {
3538            // Take out of lock task mode if necessary
3539            final TaskRecord lockedTask = getLockedTaskLocked();
3540            if (lockedTask != null) {
3541                removeLockedTaskLocked(lockedTask);
3542                if (!mLockTaskModeTasks.isEmpty()) {
3543                    // There are locked tasks remaining, can only finish this task, not unlock it.
3544                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3545                            "setLockTaskModeLocked: Tasks remaining, can't unlock");
3546                    lockedTask.performClearTaskLocked();
3547                    resumeFocusedStackTopActivityLocked();
3548                    return;
3549                }
3550            }
3551            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3552                    "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
3553            return;
3554        }
3555
3556        // Should have already been checked, but do it again.
3557        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
3558            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3559                    "setLockTaskModeLocked: Can't lock due to auth");
3560            return;
3561        }
3562        if (isLockTaskModeViolation(task)) {
3563            Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
3564            return;
3565        }
3566
3567        if (mLockTaskModeTasks.isEmpty()) {
3568            // First locktask.
3569            final Message lockTaskMsg = Message.obtain();
3570            lockTaskMsg.obj = task.intent.getComponent().getPackageName();
3571            lockTaskMsg.arg1 = task.userId;
3572            lockTaskMsg.what = LOCK_TASK_START_MSG;
3573            lockTaskMsg.arg2 = lockTaskModeState;
3574            mHandler.sendMessage(lockTaskMsg);
3575        }
3576        // Add it or move it to the top.
3577        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
3578                " Callers=" + Debug.getCallers(4));
3579        mLockTaskModeTasks.remove(task);
3580        mLockTaskModeTasks.add(task);
3581
3582        if (task.mLockTaskUid == -1) {
3583            task.mLockTaskUid = task.effectiveUid;
3584        }
3585
3586        if (andResume) {
3587            findTaskToMoveToFrontLocked(task, 0, null, reason,
3588                    lockTaskModeState != LOCK_TASK_MODE_NONE);
3589            resumeFocusedStackTopActivityLocked();
3590        } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
3591            handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId,
3592                    true /* forceNonResizable */);
3593        }
3594    }
3595
3596    boolean isLockTaskModeViolation(TaskRecord task) {
3597        return isLockTaskModeViolation(task, false);
3598    }
3599
3600    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
3601        if (getLockedTaskLocked() == task && !isNewClearTask) {
3602            return false;
3603        }
3604        final int lockTaskAuth = task.mLockTaskAuth;
3605        switch (lockTaskAuth) {
3606            case LOCK_TASK_AUTH_DONT_LOCK:
3607                return !mLockTaskModeTasks.isEmpty();
3608            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
3609            case LOCK_TASK_AUTH_LAUNCHABLE:
3610            case LOCK_TASK_AUTH_WHITELISTED:
3611                return false;
3612            case LOCK_TASK_AUTH_PINNABLE:
3613                // Pinnable tasks can't be launched on top of locktask tasks.
3614                return !mLockTaskModeTasks.isEmpty();
3615            default:
3616                Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
3617                return true;
3618        }
3619    }
3620
3621    void onLockTaskPackagesUpdatedLocked() {
3622        boolean didSomething = false;
3623        for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
3624            final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
3625            final boolean wasWhitelisted =
3626                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3627                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3628            lockedTask.setLockTaskAuth();
3629            final boolean isWhitelisted =
3630                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3631                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3632            if (wasWhitelisted && !isWhitelisted) {
3633                // Lost whitelisting authorization. End it now.
3634                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
3635                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
3636                removeLockedTaskLocked(lockedTask);
3637                lockedTask.performClearTaskLocked();
3638                didSomething = true;
3639            }
3640        }
3641        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3642            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3643            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3644                final ActivityStack stack = stacks.get(stackNdx);
3645                stack.onLockTaskPackagesUpdatedLocked();
3646            }
3647        }
3648        final ActivityRecord r = topRunningActivityLocked();
3649        final TaskRecord task = r != null ? r.task : null;
3650        if (mLockTaskModeTasks.isEmpty() && task != null
3651                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
3652            // This task must have just been authorized.
3653            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
3654                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
3655            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
3656                    false);
3657            didSomething = true;
3658        }
3659        if (didSomething) {
3660            resumeFocusedStackTopActivityLocked();
3661        }
3662    }
3663
3664    int getLockTaskModeState() {
3665        return mLockTaskModeState;
3666    }
3667
3668    void activityRelaunchedLocked(IBinder token) {
3669        mWindowManager.notifyAppRelaunchingFinished(token);
3670    }
3671
3672    void activityRelaunchingLocked(ActivityRecord r) {
3673        mWindowManager.notifyAppRelaunching(r.appToken);
3674    }
3675
3676    void logStackState() {
3677        mActivityMetricsLogger.logWindowState();
3678    }
3679
3680    void scheduleReportMultiWindowModeChanged(TaskRecord task) {
3681        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3682            final ActivityRecord r = task.mActivities.get(i);
3683            if (r.app != null && r.app.thread != null) {
3684                mMultiWindowModeChangedActivities.add(r);
3685            }
3686        }
3687
3688        if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
3689            mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
3690        }
3691    }
3692
3693    void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) {
3694        final ActivityStack stack = task.stack;
3695        if (prevStack == null || prevStack == stack
3696                || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
3697            return;
3698        }
3699
3700        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3701            final ActivityRecord r = task.mActivities.get(i);
3702            if (r.app != null && r.app.thread != null) {
3703                mPipModeChangedActivities.add(r);
3704            }
3705        }
3706
3707        if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
3708            mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
3709        }
3710    }
3711
3712    void setDockedStackMinimized(boolean minimized) {
3713        mIsDockMinimized = minimized;
3714        if (minimized) {
3715            // Docked stack is not visible, no need to confirm credentials for its top activity.
3716            return;
3717        }
3718        final ActivityStack dockedStack = getStack(StackId.DOCKED_STACK_ID);
3719        if (dockedStack == null) {
3720            return;
3721        }
3722        final ActivityRecord top = dockedStack.topRunningActivityLocked();
3723        if (top != null && mService.mUserController.shouldConfirmCredentials(top.userId)) {
3724            mService.mActivityStarter.showConfirmDeviceCredential(top.userId);
3725        }
3726    }
3727
3728    private final class ActivityStackSupervisorHandler extends Handler {
3729
3730        public ActivityStackSupervisorHandler(Looper looper) {
3731            super(looper);
3732        }
3733
3734        void activityIdleInternal(ActivityRecord r) {
3735            synchronized (mService) {
3736                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3737            }
3738        }
3739
3740        @Override
3741        public void handleMessage(Message msg) {
3742            switch (msg.what) {
3743                case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
3744                    synchronized (mService) {
3745                        for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
3746                            final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
3747                            r.scheduleMultiWindowModeChanged();
3748                        }
3749                    }
3750                } break;
3751                case REPORT_PIP_MODE_CHANGED_MSG: {
3752                    synchronized (mService) {
3753                        for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
3754                            final ActivityRecord r = mPipModeChangedActivities.remove(i);
3755                            r.schedulePictureInPictureModeChanged();
3756                        }
3757                    }
3758                } break;
3759                case IDLE_TIMEOUT_MSG: {
3760                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3761                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3762                    if (mService.mDidDexOpt) {
3763                        mService.mDidDexOpt = false;
3764                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3765                        nmsg.obj = msg.obj;
3766                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3767                        return;
3768                    }
3769                    // We don't at this point know if the activity is fullscreen,
3770                    // so we need to be conservative and assume it isn't.
3771                    activityIdleInternal((ActivityRecord)msg.obj);
3772                } break;
3773                case IDLE_NOW_MSG: {
3774                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3775                    activityIdleInternal((ActivityRecord)msg.obj);
3776                } break;
3777                case RESUME_TOP_ACTIVITY_MSG: {
3778                    synchronized (mService) {
3779                        resumeFocusedStackTopActivityLocked();
3780                    }
3781                } break;
3782                case SLEEP_TIMEOUT_MSG: {
3783                    synchronized (mService) {
3784                        if (mService.isSleepingOrShuttingDown()) {
3785                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3786                            mSleepTimeout = true;
3787                            checkReadyForSleepLocked();
3788                        }
3789                    }
3790                } break;
3791                case LAUNCH_TIMEOUT_MSG: {
3792                    if (mService.mDidDexOpt) {
3793                        mService.mDidDexOpt = false;
3794                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3795                        return;
3796                    }
3797                    synchronized (mService) {
3798                        if (mLaunchingActivity.isHeld()) {
3799                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3800                            if (VALIDATE_WAKE_LOCK_CALLER
3801                                    && Binder.getCallingUid() != Process.myUid()) {
3802                                throw new IllegalStateException("Calling must be system uid");
3803                            }
3804                            mLaunchingActivity.release();
3805                        }
3806                    }
3807                } break;
3808                case HANDLE_DISPLAY_ADDED: {
3809                    handleDisplayAdded(msg.arg1);
3810                } break;
3811                case HANDLE_DISPLAY_CHANGED: {
3812                    handleDisplayChanged(msg.arg1);
3813                } break;
3814                case HANDLE_DISPLAY_REMOVED: {
3815                    handleDisplayRemoved(msg.arg1);
3816                } break;
3817                case CONTAINER_CALLBACK_VISIBILITY: {
3818                    final ActivityContainer container = (ActivityContainer) msg.obj;
3819                    final IActivityContainerCallback callback = container.mCallback;
3820                    if (callback != null) {
3821                        try {
3822                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3823                        } catch (RemoteException e) {
3824                        }
3825                    }
3826                } break;
3827                case LOCK_TASK_START_MSG: {
3828                    // When lock task starts, we disable the status bars.
3829                    try {
3830                        if (mLockTaskNotify == null) {
3831                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3832                        }
3833                        mLockTaskNotify.show(true);
3834                        mLockTaskModeState = msg.arg2;
3835                        if (getStatusBarService() != null) {
3836                            int flags = 0;
3837                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
3838                                flags = StatusBarManager.DISABLE_MASK
3839                                        & (~StatusBarManager.DISABLE_BACK);
3840                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
3841                                flags = StatusBarManager.DISABLE_MASK
3842                                        & (~StatusBarManager.DISABLE_BACK)
3843                                        & (~StatusBarManager.DISABLE_HOME)
3844                                        & (~StatusBarManager.DISABLE_RECENT);
3845                            }
3846                            getStatusBarService().disable(flags, mToken,
3847                                    mService.mContext.getPackageName());
3848                        }
3849                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3850                        if (getDevicePolicyManager() != null) {
3851                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3852                                    (String)msg.obj, msg.arg1);
3853                        }
3854                    } catch (RemoteException ex) {
3855                        throw new RuntimeException(ex);
3856                    }
3857                } break;
3858                case LOCK_TASK_END_MSG: {
3859                    // When lock task ends, we enable the status bars.
3860                    try {
3861                        if (getStatusBarService() != null) {
3862                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3863                                    mService.mContext.getPackageName());
3864                        }
3865                        mWindowManager.reenableKeyguard(mToken);
3866                        if (getDevicePolicyManager() != null) {
3867                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3868                                    msg.arg1);
3869                        }
3870                        if (mLockTaskNotify == null) {
3871                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3872                        }
3873                        mLockTaskNotify.show(false);
3874                        try {
3875                            boolean shouldLockKeyguard = Settings.Secure.getInt(
3876                                    mService.mContext.getContentResolver(),
3877                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
3878                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
3879                                mWindowManager.lockNow(null);
3880                                mWindowManager.dismissKeyguard();
3881                                new LockPatternUtils(mService.mContext)
3882                                        .requireCredentialEntry(UserHandle.USER_ALL);
3883                            }
3884                        } catch (SettingNotFoundException e) {
3885                            // No setting, don't lock.
3886                        }
3887                    } catch (RemoteException ex) {
3888                        throw new RuntimeException(ex);
3889                    } finally {
3890                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
3891                    }
3892                } break;
3893                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
3894                    if (mLockTaskNotify == null) {
3895                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
3896                    }
3897                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
3898                } break;
3899                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3900                    final ActivityContainer container = (ActivityContainer) msg.obj;
3901                    final IActivityContainerCallback callback = container.mCallback;
3902                    if (callback != null) {
3903                        try {
3904                            callback.onAllActivitiesComplete(container.asBinder());
3905                        } catch (RemoteException e) {
3906                        }
3907                    }
3908                } break;
3909                case LAUNCH_TASK_BEHIND_COMPLETE: {
3910                    synchronized (mService) {
3911                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
3912                        if (r != null) {
3913                            handleLaunchTaskBehindCompleteLocked(r);
3914                        }
3915                    }
3916                } break;
3917
3918            }
3919        }
3920    }
3921
3922    class ActivityContainer extends android.app.IActivityContainer.Stub {
3923        final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK |
3924                FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3925        final int mStackId;
3926        IActivityContainerCallback mCallback = null;
3927        final ActivityStack mStack;
3928        ActivityRecord mParentActivity = null;
3929        String mIdString;
3930
3931        boolean mVisible = true;
3932
3933        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3934        ActivityDisplay mActivityDisplay;
3935
3936        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3937        final static int CONTAINER_STATE_NO_SURFACE = 1;
3938        final static int CONTAINER_STATE_FINISHING = 2;
3939        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3940
3941        ActivityContainer(int stackId) {
3942            synchronized (mService) {
3943                mStackId = stackId;
3944                mStack = new ActivityStack(this, mRecentTasks);
3945                mIdString = "ActivtyContainer{" + mStackId + "}";
3946                if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
3947            }
3948        }
3949
3950        void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
3951            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
3952                    + " to display=" + activityDisplay + " onTop=" + onTop);
3953            mActivityDisplay = activityDisplay;
3954            mStack.attachDisplay(activityDisplay, onTop);
3955            activityDisplay.attachActivities(mStack, onTop);
3956        }
3957
3958        @Override
3959        public void attachToDisplay(int displayId) {
3960            synchronized (mService) {
3961                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3962                if (activityDisplay == null) {
3963                    return;
3964                }
3965                attachToDisplayLocked(activityDisplay, true);
3966            }
3967        }
3968
3969        @Override
3970        public int getDisplayId() {
3971            synchronized (mService) {
3972                if (mActivityDisplay != null) {
3973                    return mActivityDisplay.mDisplayId;
3974                }
3975            }
3976            return -1;
3977        }
3978
3979        @Override
3980        public int getStackId() {
3981            synchronized (mService) {
3982                return mStackId;
3983            }
3984        }
3985
3986        @Override
3987        public boolean injectEvent(InputEvent event) {
3988            final long origId = Binder.clearCallingIdentity();
3989            try {
3990                synchronized (mService) {
3991                    if (mActivityDisplay != null) {
3992                        return mInputManagerInternal.injectInputEvent(event,
3993                                mActivityDisplay.mDisplayId,
3994                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3995                    }
3996                }
3997                return false;
3998            } finally {
3999                Binder.restoreCallingIdentity(origId);
4000            }
4001        }
4002
4003        @Override
4004        public void release() {
4005            synchronized (mService) {
4006                if (mContainerState == CONTAINER_STATE_FINISHING) {
4007                    return;
4008                }
4009                mContainerState = CONTAINER_STATE_FINISHING;
4010
4011                long origId = Binder.clearCallingIdentity();
4012                try {
4013                    mStack.finishAllActivitiesLocked(false);
4014                    mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack);
4015                } finally {
4016                    Binder.restoreCallingIdentity(origId);
4017                }
4018            }
4019        }
4020
4021        protected void detachLocked() {
4022            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
4023                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
4024            if (mActivityDisplay != null) {
4025                mActivityDisplay.detachActivitiesLocked(mStack);
4026                mActivityDisplay = null;
4027                mStack.detachDisplay();
4028            }
4029        }
4030
4031        @Override
4032        public final int startActivity(Intent intent) {
4033            return mService.startActivity(intent, this);
4034        }
4035
4036        @Override
4037        public final int startActivityIntentSender(IIntentSender intentSender)
4038                throws TransactionTooLargeException {
4039            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
4040
4041            if (!(intentSender instanceof PendingIntentRecord)) {
4042                throw new IllegalArgumentException("Bad PendingIntent object");
4043            }
4044
4045            final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
4046                    Binder.getCallingUid(), mCurrentUser, false,
4047                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4048
4049            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
4050            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
4051                    pendingIntent.key.requestResolvedType);
4052
4053            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
4054                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
4055        }
4056
4057        void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
4058            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
4059            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
4060                throw new SecurityException(
4061                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
4062            }
4063        }
4064
4065        @Override
4066        public IBinder asBinder() {
4067            return this;
4068        }
4069
4070        @Override
4071        public void setSurface(Surface surface, int width, int height, int density) {
4072            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
4073        }
4074
4075        ActivityStackSupervisor getOuter() {
4076            return ActivityStackSupervisor.this;
4077        }
4078
4079        boolean isAttachedLocked() {
4080            return mActivityDisplay != null;
4081        }
4082
4083        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
4084        void setVisible(boolean visible) {
4085            if (mVisible != visible) {
4086                mVisible = visible;
4087                if (mCallback != null) {
4088                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
4089                            0 /* unused */, this).sendToTarget();
4090                }
4091            }
4092        }
4093
4094        void setDrawn() {
4095        }
4096
4097        // You can always start a new task on a regular ActivityStack.
4098        boolean isEligibleForNewTasks() {
4099            return true;
4100        }
4101
4102        void onTaskListEmptyLocked() {
4103            detachLocked();
4104            deleteActivityContainer(this);
4105            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
4106        }
4107
4108        @Override
4109        public String toString() {
4110            return mIdString + (mActivityDisplay == null ? "N" : "A");
4111        }
4112    }
4113
4114    private class VirtualActivityContainer extends ActivityContainer {
4115        Surface mSurface;
4116        boolean mDrawn = false;
4117
4118        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
4119            super(getNextStackId());
4120            mParentActivity = parent;
4121            mCallback = callback;
4122            mContainerState = CONTAINER_STATE_NO_SURFACE;
4123            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
4124        }
4125
4126        @Override
4127        public void setSurface(Surface surface, int width, int height, int density) {
4128            super.setSurface(surface, width, height, density);
4129
4130            synchronized (mService) {
4131                final long origId = Binder.clearCallingIdentity();
4132                try {
4133                    setSurfaceLocked(surface, width, height, density);
4134                } finally {
4135                    Binder.restoreCallingIdentity(origId);
4136                }
4137            }
4138        }
4139
4140        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
4141            if (mContainerState == CONTAINER_STATE_FINISHING) {
4142                return;
4143            }
4144            VirtualActivityDisplay virtualActivityDisplay =
4145                    (VirtualActivityDisplay) mActivityDisplay;
4146            if (virtualActivityDisplay == null) {
4147                virtualActivityDisplay =
4148                        new VirtualActivityDisplay(width, height, density);
4149                mActivityDisplay = virtualActivityDisplay;
4150                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
4151                attachToDisplayLocked(virtualActivityDisplay, true);
4152            }
4153
4154            if (mSurface != null) {
4155                mSurface.release();
4156            }
4157
4158            mSurface = surface;
4159            if (surface != null) {
4160                resumeFocusedStackTopActivityLocked();
4161            } else {
4162                mContainerState = CONTAINER_STATE_NO_SURFACE;
4163                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
4164                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
4165                    mStack.startPausingLocked(false, true, false, false);
4166                }
4167            }
4168
4169            setSurfaceIfReadyLocked();
4170
4171            if (DEBUG_STACK) Slog.d(TAG_STACK,
4172                    "setSurface: " + this + " to display=" + virtualActivityDisplay);
4173        }
4174
4175        @Override
4176        boolean isAttachedLocked() {
4177            return mSurface != null && super.isAttachedLocked();
4178        }
4179
4180        @Override
4181        void setDrawn() {
4182            synchronized (mService) {
4183                mDrawn = true;
4184                setSurfaceIfReadyLocked();
4185            }
4186        }
4187
4188        // Never start a new task on an ActivityView if it isn't explicitly specified.
4189        @Override
4190        boolean isEligibleForNewTasks() {
4191            return false;
4192        }
4193
4194        private void setSurfaceIfReadyLocked() {
4195            if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
4196                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
4197            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
4198                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
4199                mContainerState = CONTAINER_STATE_HAS_SURFACE;
4200            }
4201        }
4202    }
4203
4204    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
4205     * attached {@link ActivityStack}s */
4206    class ActivityDisplay {
4207        /** Actual Display this object tracks. */
4208        int mDisplayId;
4209        Display mDisplay;
4210        DisplayInfo mDisplayInfo = new DisplayInfo();
4211
4212        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
4213         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
4214        final ArrayList<ActivityStack> mStacks = new ArrayList<>();
4215
4216        ActivityRecord mVisibleBehindActivity;
4217
4218        ActivityDisplay() {
4219        }
4220
4221        // After instantiation, check that mDisplay is not null before using this. The alternative
4222        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
4223        ActivityDisplay(int displayId) {
4224            final Display display = mDisplayManager.getDisplay(displayId);
4225            if (display == null) {
4226                return;
4227            }
4228            init(display);
4229        }
4230
4231        void init(Display display) {
4232            mDisplay = display;
4233            mDisplayId = display.getDisplayId();
4234            mDisplay.getDisplayInfo(mDisplayInfo);
4235        }
4236
4237        void attachActivities(ActivityStack stack, boolean onTop) {
4238            if (DEBUG_STACK) Slog.v(TAG_STACK,
4239                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId
4240                    + " onTop=" + onTop);
4241            if (onTop) {
4242                mStacks.add(stack);
4243            } else {
4244                mStacks.add(0, stack);
4245            }
4246        }
4247
4248        void detachActivitiesLocked(ActivityStack stack) {
4249            if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
4250                    + " from displayId=" + mDisplayId);
4251            mStacks.remove(stack);
4252        }
4253
4254        void setVisibleBehindActivity(ActivityRecord r) {
4255            mVisibleBehindActivity = r;
4256        }
4257
4258        boolean hasVisibleBehindActivity() {
4259            return mVisibleBehindActivity != null;
4260        }
4261
4262        @Override
4263        public String toString() {
4264            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4265        }
4266    }
4267
4268    class VirtualActivityDisplay extends ActivityDisplay {
4269        VirtualDisplay mVirtualDisplay;
4270
4271        VirtualActivityDisplay(int width, int height, int density) {
4272            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4273            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4274                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4275                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4276                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4277
4278            init(mVirtualDisplay.getDisplay());
4279
4280            mWindowManager.handleDisplayAdded(mDisplayId);
4281        }
4282
4283        void setSurface(Surface surface) {
4284            if (mVirtualDisplay != null) {
4285                mVirtualDisplay.setSurface(surface);
4286            }
4287        }
4288
4289        @Override
4290        void detachActivitiesLocked(ActivityStack stack) {
4291            super.detachActivitiesLocked(stack);
4292            if (mVirtualDisplay != null) {
4293                mVirtualDisplay.release();
4294                mVirtualDisplay = null;
4295            }
4296        }
4297
4298        @Override
4299        public String toString() {
4300            return "VirtualActivityDisplay={" + mDisplayId + "}";
4301        }
4302    }
4303
4304    /**
4305     * Adjust bounds to stay within stack bounds.
4306     *
4307     * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
4308     * that keep them unchanged, but be contained within the stack bounds.
4309     *
4310     * @param bounds Bounds to be adjusted.
4311     * @param stackBounds Bounds within which the other bounds should remain.
4312     */
4313    private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
4314        if (stackBounds == null || stackBounds.contains(bounds)) {
4315            return;
4316        }
4317
4318        if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
4319            final int maxRight = stackBounds.right
4320                    - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
4321            int horizontalDiff = stackBounds.left - bounds.left;
4322            if ((horizontalDiff < 0 && bounds.left >= maxRight)
4323                    || (bounds.left + horizontalDiff >= maxRight)) {
4324                horizontalDiff = maxRight - bounds.left;
4325            }
4326            bounds.left += horizontalDiff;
4327            bounds.right += horizontalDiff;
4328        }
4329
4330        if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
4331            final int maxBottom = stackBounds.bottom
4332                    - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
4333            int verticalDiff = stackBounds.top - bounds.top;
4334            if ((verticalDiff < 0 && bounds.top >= maxBottom)
4335                    || (bounds.top + verticalDiff >= maxBottom)) {
4336                verticalDiff = maxBottom - bounds.top;
4337            }
4338            bounds.top += verticalDiff;
4339            bounds.bottom += verticalDiff;
4340        }
4341    }
4342
4343    ActivityStack findStackBehind(ActivityStack stack) {
4344        // TODO(multi-display): We are only looking for stacks on the default display.
4345        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
4346        if (display == null) {
4347            return null;
4348        }
4349        final ArrayList<ActivityStack> stacks = display.mStacks;
4350        for (int i = stacks.size() - 1; i >= 0; i--) {
4351            if (stacks.get(i) == stack && i > 0) {
4352                return stacks.get(i - 1);
4353            }
4354        }
4355        throw new IllegalStateException("Failed to find a stack behind stack=" + stack
4356                + " in=" + stacks);
4357    }
4358
4359    /**
4360     * Puts a task into resizing mode during the next app transition.
4361     *
4362     * @param taskId the id of the task to put into resizing mode
4363     */
4364    private void setResizingDuringAnimation(int taskId) {
4365        mResizingTasksDuringAnimation.add(taskId);
4366        mWindowManager.setTaskDockedResizing(taskId, true);
4367    }
4368
4369    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4370        final TaskRecord task;
4371        final int callingUid;
4372        final String callingPackage;
4373        final Intent intent;
4374        final int userId;
4375        final ActivityOptions activityOptions = (bOptions != null)
4376                ? new ActivityOptions(bOptions) : null;
4377        final int launchStackId = (activityOptions != null)
4378                ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4379        if (launchStackId == HOME_STACK_ID) {
4380            throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4381                    + taskId + " can't be launch in the home stack.");
4382        }
4383
4384        if (launchStackId == DOCKED_STACK_ID) {
4385            mWindowManager.setDockedStackCreateState(
4386                    activityOptions.getDockCreateMode(), null /* initialBounds */);
4387
4388            // Defer updating the stack in which recents is until the app transition is done, to
4389            // not run into issues where we still need to draw the task in recents but the
4390            // docked stack is already created.
4391            deferUpdateBounds(HOME_STACK_ID);
4392            mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
4393        }
4394
4395        task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4396        if (task == null) {
4397            continueUpdateBounds(HOME_STACK_ID);
4398            mWindowManager.executeAppTransition();
4399            throw new IllegalArgumentException(
4400                    "startActivityFromRecentsInner: Task " + taskId + " not found.");
4401        }
4402
4403        if (launchStackId != INVALID_STACK_ID) {
4404            if (task.stack.mStackId != launchStackId) {
4405                moveTaskToStackLocked(
4406                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4407                        ANIMATE);
4408            }
4409        }
4410
4411        // If the user must confirm credentials (e.g. when first launching a work app and the
4412        // Work Challenge is present) let startActivityInPackage handle the intercepting.
4413        if (!mService.mUserController.shouldConfirmCredentials(task.userId)
4414                && task.getRootActivity() != null) {
4415            mActivityMetricsLogger.notifyActivityLaunching();
4416            mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
4417            mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
4418                    task.getTopActivity());
4419
4420            // If we are launching the task in the docked stack, put it into resizing mode so
4421            // the window renders full-screen with the background filling the void. Also only
4422            // call this at the end to make sure that tasks exists on the window manager side.
4423            if (launchStackId == DOCKED_STACK_ID) {
4424                setResizingDuringAnimation(taskId);
4425            }
4426            return ActivityManager.START_TASK_TO_FRONT;
4427        }
4428        callingUid = task.mCallingUid;
4429        callingPackage = task.mCallingPackage;
4430        intent = task.intent;
4431        intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4432        userId = task.userId;
4433        int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
4434                null, null, 0, 0, bOptions, userId, null, task);
4435        if (launchStackId == DOCKED_STACK_ID) {
4436            setResizingDuringAnimation(task.taskId);
4437        }
4438        return result;
4439    }
4440
4441    /**
4442     * @return a list of activities which are the top ones in each visible stack. The first
4443     * entry will be the focused activity.
4444     */
4445    public List<IBinder> getTopVisibleActivities() {
4446        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
4447        if (display == null) {
4448            return Collections.EMPTY_LIST;
4449        }
4450        ArrayList<IBinder> topActivityTokens = new ArrayList<>();
4451        final ArrayList<ActivityStack> stacks = display.mStacks;
4452        for (int i = stacks.size() - 1; i >= 0; i--) {
4453            ActivityStack stack = stacks.get(i);
4454            if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) {
4455                ActivityRecord top = stack.topActivity();
4456                if (top != null) {
4457                    if (stack == mFocusedStack) {
4458                        topActivityTokens.add(0, top.appToken);
4459                    } else {
4460                        topActivityTokens.add(top.appToken);
4461                    }
4462                }
4463            }
4464        }
4465        return topActivityTokens;
4466    }
4467}
4468