ActivityStackSupervisor.java revision cd13d33ee53371f306a1e5c0caa2b292906e4e17
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.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
127import static android.content.pm.PackageManager.PERMISSION_GRANTED;
128import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
153import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
154import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
155import static com.android.server.am.ActivityManagerService.ANIMATE;
156import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
157import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG;
158import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG;
159import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
160import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
161import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
162import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
163import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
164import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
165import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
166import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
167import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
168import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
169import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
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        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
1789        return false;
1790    }
1791
1792    void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
1793        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1794            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1795            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1796                stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo);
1797            }
1798        }
1799    }
1800
1801    TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
1802        TaskRecord finishedTask = null;
1803        ActivityStack focusedStack = getFocusedStack();
1804        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1805            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1806            final int numStacks = stacks.size();
1807            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1808                final ActivityStack stack = stacks.get(stackNdx);
1809                TaskRecord t = stack.finishTopRunningActivityLocked(app, reason);
1810                if (stack == focusedStack || finishedTask == null) {
1811                    finishedTask = t;
1812                }
1813            }
1814        }
1815        return finishedTask;
1816    }
1817
1818    void finishVoiceTask(IVoiceInteractionSession session) {
1819        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1820            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1821            final int numStacks = stacks.size();
1822            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1823                final ActivityStack stack = stacks.get(stackNdx);
1824                stack.finishVoiceTask(session);
1825            }
1826        }
1827    }
1828
1829    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options,
1830            String reason, boolean forceNonResizeable) {
1831        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
1832            mUserLeaving = true;
1833        }
1834        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
1835            // Caller wants the home activity moved with it.  To accomplish this,
1836            // we'll just indicate that this task returns to the home task.
1837            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1838        }
1839        if (task.stack == null) {
1840            Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
1841                    + task + " to front. Stack is null");
1842            return;
1843        }
1844
1845        if (task.isResizeable() && options != null) {
1846            int stackId = options.getLaunchStackId();
1847            if (canUseActivityOptionsLaunchBounds(options, stackId)) {
1848                final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds());
1849                task.updateOverrideConfiguration(bounds);
1850                if (stackId == INVALID_STACK_ID) {
1851                    stackId = task.getLaunchStackId();
1852                }
1853                if (stackId != task.stack.mStackId) {
1854                    final ActivityStack stack = moveTaskToStackUncheckedLocked(
1855                            task, stackId, ON_TOP, !FORCE_FOCUS, reason);
1856                    stackId = stack.mStackId;
1857                    // moveTaskToStackUncheckedLocked() should already placed the task on top,
1858                    // still need moveTaskToFrontLocked() below for any transition settings.
1859                }
1860                if (StackId.resizeStackWithLaunchBounds(stackId)) {
1861                    resizeStackLocked(stackId, bounds,
1862                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
1863                            !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME);
1864                } else {
1865                    // WM resizeTask must be done after the task is moved to the correct stack,
1866                    // because Task's setBounds() also updates dim layer's bounds, but that has
1867                    // dependency on the stack.
1868                    mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig,
1869                            false /* relayout */, false /* forced */);
1870                }
1871            }
1872        }
1873
1874        final ActivityRecord r = task.getTopActivity();
1875        task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
1876                r == null ? null : r.appTimeTracker, reason);
1877
1878        if (DEBUG_STACK) Slog.d(TAG_STACK,
1879                "findTaskToMoveToFront: moved to front of stack=" + task.stack);
1880
1881        handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId,
1882                forceNonResizeable);
1883    }
1884
1885    boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
1886        // We use the launch bounds in the activity options is the device supports freeform
1887        // window management or is launching into the pinned stack.
1888        if (options.getLaunchBounds() == null) {
1889            return false;
1890        }
1891        return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID)
1892                || mService.mSupportsFreeformWindowManagement;
1893    }
1894
1895    ActivityStack getStack(int stackId) {
1896        return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
1897    }
1898
1899    ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
1900        ActivityContainer activityContainer = mActivityContainers.get(stackId);
1901        if (activityContainer != null) {
1902            return activityContainer.mStack;
1903        }
1904        if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
1905            return null;
1906        }
1907        return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
1908    }
1909
1910    ArrayList<ActivityStack> getStacks() {
1911        ArrayList<ActivityStack> allStacks = new ArrayList<>();
1912        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1913            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
1914        }
1915        return allStacks;
1916    }
1917
1918    IBinder getHomeActivityToken() {
1919        ActivityRecord homeActivity = getHomeActivity();
1920        if (homeActivity != null) {
1921            return homeActivity.appToken;
1922        }
1923        return null;
1924    }
1925
1926    ActivityRecord getHomeActivity() {
1927        return getHomeActivityForUser(mCurrentUser);
1928    }
1929
1930    ActivityRecord getHomeActivityForUser(int userId) {
1931        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
1932        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1933            final TaskRecord task = tasks.get(taskNdx);
1934            if (task.isHomeTask()) {
1935                final ArrayList<ActivityRecord> activities = task.mActivities;
1936                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1937                    final ActivityRecord r = activities.get(activityNdx);
1938                    if (r.isHomeActivity()
1939                            && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
1940                        return r;
1941                    }
1942                }
1943            }
1944        }
1945        return null;
1946    }
1947
1948    /**
1949     * Returns if a stack should be treated as if it's docked. Returns true if the stack is
1950     * the docked stack itself, or if it's side-by-side to the docked stack.
1951     */
1952    boolean isStackDockedInEffect(int stackId) {
1953        return stackId == DOCKED_STACK_ID ||
1954                (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null);
1955    }
1956
1957    ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
1958            IActivityContainerCallback callback) {
1959        ActivityContainer activityContainer =
1960                new VirtualActivityContainer(parentActivity, callback);
1961        mActivityContainers.put(activityContainer.mStackId, activityContainer);
1962        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
1963                "createActivityContainer: " + activityContainer);
1964        parentActivity.mChildContainers.add(activityContainer);
1965        return activityContainer;
1966    }
1967
1968    void removeChildActivityContainers(ActivityRecord parentActivity) {
1969        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
1970        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
1971            ActivityContainer container = childStacks.remove(containerNdx);
1972            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
1973                    + container);
1974            container.release();
1975        }
1976    }
1977
1978    void deleteActivityContainer(IActivityContainer container) {
1979        ActivityContainer activityContainer = (ActivityContainer)container;
1980        if (activityContainer != null) {
1981            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
1982                    "deleteActivityContainer: callers=" + Debug.getCallers(4));
1983            final int stackId = activityContainer.mStackId;
1984            mActivityContainers.remove(stackId);
1985            mWindowManager.removeStack(stackId);
1986        }
1987    }
1988
1989    void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
1990            boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) {
1991        if (stackId == DOCKED_STACK_ID) {
1992            resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null,
1993                    preserveWindows);
1994            return;
1995        }
1996        final ActivityStack stack = getStack(stackId);
1997        if (stack == null) {
1998            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1999            return;
2000        }
2001
2002        if (!allowResizeInDockedMode && getStack(DOCKED_STACK_ID) != null) {
2003            // If the docked stack exist we don't allow resizes of stacks not caused by the docked
2004            // stack size changing so things don't get out of sync.
2005            return;
2006        }
2007
2008        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
2009        mWindowManager.deferSurfaceLayout();
2010        try {
2011            resizeStackUncheckedLocked(stack, bounds, tempTaskBounds, tempTaskInsetBounds);
2012            if (!deferResume) {
2013                ensureConfigurationAndResume(
2014                        stack, stack.topRunningActivityLocked(), preserveWindows);
2015            }
2016        } finally {
2017            mWindowManager.continueSurfaceLayout();
2018            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2019        }
2020    }
2021
2022    void deferUpdateBounds(int stackId) {
2023        final ActivityStack stack = getStack(stackId);
2024        if (stack != null) {
2025            stack.deferUpdateBounds();
2026        }
2027    }
2028
2029    void continueUpdateBounds(int stackId) {
2030        final ActivityStack stack = getStack(stackId);
2031        if (stack != null) {
2032            stack.continueUpdateBounds();
2033        }
2034    }
2035
2036    void notifyAppTransitionDone() {
2037        continueUpdateBounds(HOME_STACK_ID);
2038        for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
2039            final int taskId = mResizingTasksDuringAnimation.valueAt(i);
2040            if (anyTaskForIdLocked(taskId) != null) {
2041                mWindowManager.setTaskDockedResizing(taskId, false);
2042            }
2043        }
2044        mResizingTasksDuringAnimation.clear();
2045    }
2046
2047    void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
2048            Rect tempTaskInsetBounds) {
2049        bounds = TaskRecord.validateBounds(bounds);
2050
2051        if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) {
2052            return;
2053        }
2054
2055        mTmpBounds.clear();
2056        mTmpConfigs.clear();
2057        mTmpInsetBounds.clear();
2058        final ArrayList<TaskRecord> tasks = stack.getAllTasks();
2059        final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
2060        final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds;
2061        for (int i = tasks.size() - 1; i >= 0; i--) {
2062            final TaskRecord task = tasks.get(i);
2063            if (task.isResizeable()) {
2064                if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
2065                    // For freeform stack we don't adjust the size of the tasks to match that
2066                    // of the stack, but we do try to make sure the tasks are still contained
2067                    // with the bounds of the stack.
2068                    tempRect2.set(task.mBounds);
2069                    fitWithinBounds(tempRect2, bounds);
2070                    task.updateOverrideConfiguration(tempRect2);
2071                } else {
2072                    task.updateOverrideConfiguration(taskBounds, insetBounds);
2073                }
2074            }
2075
2076            mTmpConfigs.put(task.taskId, task.mOverrideConfig);
2077            mTmpBounds.put(task.taskId, task.mBounds);
2078            if (tempTaskInsetBounds != null) {
2079                mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
2080            }
2081        }
2082
2083        // We might trigger a configuration change. Save the current task bounds for freezing.
2084        mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
2085        stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs,
2086                mTmpBounds, mTmpInsetBounds);
2087        stack.setBounds(bounds);
2088    }
2089
2090    private void ensureConfigurationAndResume(ActivityStack stack, ActivityRecord r,
2091            boolean preserveWindows) {
2092        if (r == null || !r.visible) {
2093            return;
2094        }
2095        final boolean updated = stack.ensureActivityConfigurationLocked(r, 0,
2096                preserveWindows);
2097        if (!updated) {
2098            resumeFocusedStackTopActivityLocked();
2099        }
2100    }
2101
2102    void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) {
2103        final ActivityStack stack = getStack(fromStackId);
2104        if (stack == null) {
2105            return;
2106        }
2107
2108        mWindowManager.deferSurfaceLayout();
2109        try {
2110            if (fromStackId == DOCKED_STACK_ID) {
2111
2112                // We are moving all tasks from the docked stack to the fullscreen stack,
2113                // which is dismissing the docked stack, so resize all other stacks to
2114                // fullscreen here already so we don't end up with resize trashing.
2115                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
2116                    if (StackId.isResizeableByDockedStack(i)) {
2117                        ActivityStack otherStack = getStack(i);
2118                        if (otherStack != null) {
2119                            resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS,
2120                                    true /* allowResizeInDockedMode */, DEFER_RESUME);
2121                        }
2122                    }
2123                }
2124
2125                // Also disable docked stack resizing since we have manually adjusted the
2126                // size of other stacks above and we don't want to trigger a docked stack
2127                // resize when we remove task from it below and it is detached from the
2128                // display because it no longer contains any tasks.
2129                mAllowDockedStackResize = false;
2130            }
2131            final ArrayList<TaskRecord> tasks = stack.getAllTasks();
2132            final int size = tasks.size();
2133            if (onTop) {
2134                for (int i = 0; i < size; i++) {
2135                    moveTaskToStackLocked(tasks.get(i).taskId,
2136                            FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/,
2137                            "moveTasksToFullscreenStack", ANIMATE);
2138                }
2139            } else {
2140                for (int i = size - 1; i >= 0; i--) {
2141                    positionTaskInStackLocked(tasks.get(i).taskId,
2142                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
2143                }
2144            }
2145        } finally {
2146            mAllowDockedStackResize = true;
2147            mWindowManager.continueSurfaceLayout();
2148        }
2149    }
2150
2151    void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
2152            Rect tempDockedTaskInsetBounds,
2153            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows) {
2154
2155        if (!mAllowDockedStackResize) {
2156            // Docked stack resize currently disabled.
2157            return;
2158        }
2159
2160        final ActivityStack stack = getStack(DOCKED_STACK_ID);
2161        if (stack == null) {
2162            Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
2163            return;
2164        }
2165
2166        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack");
2167        mWindowManager.deferSurfaceLayout();
2168        try {
2169            // Don't allow re-entry while resizing. E.g. due to docked stack detaching.
2170            mAllowDockedStackResize = false;
2171            ActivityRecord r = stack.topRunningActivityLocked();
2172            resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds,
2173                    tempDockedTaskInsetBounds);
2174
2175            // TODO: Checking for isAttached might not be needed as if the user passes in null
2176            // dockedBounds then they want the docked stack to be dismissed.
2177            if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) {
2178                // The dock stack either was dismissed or went fullscreen, which is kinda the same.
2179                // In this case we make all other static stacks fullscreen and move all
2180                // docked stack tasks to the fullscreen stack.
2181                moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP);
2182
2183                // stack shouldn't contain anymore activities, so nothing to resume.
2184                r = null;
2185            } else {
2186                // Docked stacks occupy a dedicated region on screen so the size of all other
2187                // static stacks need to be adjusted so they don't overlap with the docked stack.
2188                // We get the bounds to use from window manager which has been adjusted for any
2189                // screen controls and is also the same for all stacks.
2190                mWindowManager.getStackDockedModeBounds(
2191                        HOME_STACK_ID, tempRect, true /* ignoreVisibility */);
2192                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
2193                    if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) {
2194                        resizeStackLocked(i, tempRect, tempOtherTaskBounds,
2195                                tempOtherTaskInsetBounds, preserveWindows,
2196                                true /* allowResizeInDockedMode */, !DEFER_RESUME);
2197                    }
2198                }
2199            }
2200            ensureConfigurationAndResume(stack, r, preserveWindows);
2201        } finally {
2202            mAllowDockedStackResize = true;
2203            mWindowManager.continueSurfaceLayout();
2204            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2205        }
2206
2207        mResizeDockedStackTimeout.notifyResizing(dockedBounds,
2208                tempDockedTaskBounds != null
2209                || tempDockedTaskInsetBounds != null
2210                || tempOtherTaskBounds != null
2211                || tempOtherTaskInsetBounds != null);
2212    }
2213
2214    void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
2215        final ActivityStack stack = getStack(PINNED_STACK_ID);
2216        if (stack == null) {
2217            Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
2218            return;
2219        }
2220        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack");
2221        mWindowManager.deferSurfaceLayout();
2222        try {
2223            ActivityRecord r = stack.topRunningActivityLocked();
2224            resizeStackUncheckedLocked(stack, pinnedBounds, tempPinnedTaskBounds,
2225                    null);
2226            ensureConfigurationAndResume(stack, r, false);
2227        } finally {
2228            mWindowManager.continueSurfaceLayout();
2229            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2230        }
2231    }
2232
2233    boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow,
2234            boolean deferResume) {
2235        if (!task.isResizeable()) {
2236            Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
2237            return true;
2238        }
2239
2240        // If this is a forced resize, let it go through even if the bounds is not changing,
2241        // as we might need a relayout due to surface size change (to/from fullscreen).
2242        final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
2243        if (Objects.equals(task.mBounds, bounds) && !forced) {
2244            // Nothing to do here...
2245            return true;
2246        }
2247        bounds = TaskRecord.validateBounds(bounds);
2248
2249        if (!mWindowManager.isValidTaskId(task.taskId)) {
2250            // Task doesn't exist in window manager yet (e.g. was restored from recents).
2251            // All we can do for now is update the bounds so it can be used when the task is
2252            // added to window manager.
2253            task.updateOverrideConfiguration(bounds);
2254            if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
2255                // re-restore the task so it can have the proper stack association.
2256                restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID);
2257            }
2258            return true;
2259        }
2260
2261        // Do not move the task to another stack here.
2262        // This method assumes that the task is already placed in the right stack.
2263        // we do not mess with that decision and we only do the resize!
2264
2265        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId);
2266
2267        final Configuration overrideConfig =  task.updateOverrideConfiguration(bounds);
2268        // This variable holds information whether the configuration didn't change in a significant
2269        // way and the activity was kept the way it was. If it's false, it means the activity had
2270        // to be relaunched due to configuration change.
2271        boolean kept = true;
2272        if (overrideConfig != null) {
2273            final ActivityRecord r = task.topRunningActivityLocked();
2274            if (r != null) {
2275                final ActivityStack stack = task.stack;
2276                kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow);
2277
2278                if (!deferResume) {
2279
2280                    // All other activities must be made visible with their correct configuration.
2281                    ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
2282                    if (!kept) {
2283                        resumeFocusedStackTopActivityLocked();
2284                    }
2285                }
2286            }
2287        }
2288        mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced);
2289
2290        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
2291        return kept;
2292    }
2293
2294    ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
2295        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2296        if (activityDisplay == null) {
2297            return null;
2298        }
2299
2300        ActivityContainer activityContainer = new ActivityContainer(stackId);
2301        mActivityContainers.put(stackId, activityContainer);
2302        activityContainer.attachToDisplayLocked(activityDisplay, onTop);
2303        return activityContainer.mStack;
2304    }
2305
2306    int getNextStackId() {
2307        while (true) {
2308            if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID
2309                    && getStack(mNextFreeStackId) == null) {
2310                break;
2311            }
2312            mNextFreeStackId++;
2313        }
2314        return mNextFreeStackId;
2315    }
2316
2317    /**
2318     * Restores a recent task to a stack
2319     * @param task The recent task to be restored.
2320     * @param stackId The stack to restore the task to (default launch stack will be used
2321     *                if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}).
2322     * @return true if the task has been restored successfully.
2323     */
2324    private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
2325        if (stackId == INVALID_STACK_ID) {
2326            stackId = task.getLaunchStackId();
2327        } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) {
2328            // Preferred stack is the docked stack, but the task can't go in the docked stack.
2329            // Put it in the fullscreen stack.
2330            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
2331        }
2332
2333        if (task.stack != null) {
2334            // Task has already been restored once. See if we need to do anything more
2335            if (task.stack.mStackId == stackId) {
2336                // Nothing else to do since it is already restored in the right stack.
2337                return true;
2338            }
2339            // Remove current stack association, so we can re-associate the task with the
2340            // right stack below.
2341            task.stack.removeTask(task, "restoreRecentTaskLocked", MOVING);
2342        }
2343
2344        final ActivityStack stack =
2345                getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
2346
2347        if (stack == null) {
2348            // What does this mean??? Not sure how we would get here...
2349            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2350                    "Unable to find/create stack to restore recent task=" + task);
2351            return false;
2352        }
2353
2354        stack.addTask(task, false, "restoreRecentTask");
2355        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2356                "Added restored task=" + task + " to stack=" + stack);
2357        final ArrayList<ActivityRecord> activities = task.mActivities;
2358        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2359            stack.addConfigOverride(activities.get(activityNdx), task);
2360        }
2361        return true;
2362    }
2363
2364    /**
2365     * Moves the specified task record to the input stack id.
2366     * WARNING: This method performs an unchecked/raw move of the task and
2367     * can leave the system in an unstable state if used incorrectly.
2368     * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack.
2369     * @param task Task to move.
2370     * @param stackId Id of stack to move task to.
2371     * @param toTop True if the task should be placed at the top of the stack.
2372     * @param forceFocus if focus should be moved to the new stack
2373     * @param reason Reason the task is been moved.
2374     * @return The stack the task was moved to.
2375     */
2376    ActivityStack moveTaskToStackUncheckedLocked(
2377            TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
2378
2379        if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) {
2380            throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't "
2381                    + "support multi-window task=" + task + " to stackId=" + stackId);
2382        }
2383
2384        final ActivityRecord r = task.getTopActivity();
2385        final ActivityStack prevStack = task.stack;
2386        final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r);
2387        final boolean wasResumed = prevStack.mResumedActivity == r;
2388        // In some cases the focused stack isn't the front stack. E.g. pinned stack.
2389        // Whenever we are moving the top activity from the front stack we want to make sure to move
2390        // the stack to the front.
2391        final boolean wasFront = isFrontStack(prevStack)
2392                && (prevStack.topRunningActivityLocked() == r);
2393
2394        if (stackId == DOCKED_STACK_ID && !task.isResizeable()) {
2395            // We don't allow moving a unresizeable task to the docked stack since the docked
2396            // stack is used for split-screen mode and will cause things like the docked divider to
2397            // show up. We instead leave the task in its current stack or move it to the fullscreen
2398            // stack if it isn't currently in a stack.
2399            stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
2400            Slog.w(TAG, "Can not move unresizeable task=" + task
2401                    + " to docked stack. Moving to stackId=" + stackId + " instead.");
2402        }
2403
2404        // Temporarily disable resizeablility of task we are moving. We don't want it to be resized
2405        // if a docked stack is created below which will lead to the stack we are moving from and
2406        // its resizeable tasks being resized.
2407        task.mTemporarilyUnresizable = true;
2408        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop);
2409        task.mTemporarilyUnresizable = false;
2410        mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop);
2411        stack.addTask(task, toTop, reason);
2412
2413        // If the task had focus before (or we're requested to move focus),
2414        // move focus to the new stack by moving the stack to the front.
2415        stack.moveToFrontAndResumeStateIfNeeded(
2416                r, forceFocus || wasFocused || wasFront, wasResumed, reason);
2417
2418        return stack;
2419    }
2420
2421    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
2422            String reason, boolean animate) {
2423        return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate,
2424                false /* deferResume */);
2425    }
2426
2427    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
2428            String reason, boolean animate, boolean deferResume) {
2429        final TaskRecord task = anyTaskForIdLocked(taskId);
2430        if (task == null) {
2431            Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
2432            return false;
2433        }
2434
2435        if (task.stack != null && task.stack.mStackId == stackId) {
2436            // You are already in the right stack silly...
2437            Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId);
2438            return true;
2439        }
2440
2441        if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
2442            throw new IllegalArgumentException("moveTaskToStack:"
2443                    + "Attempt to move task " + taskId + " to unsupported freeform stack");
2444        }
2445
2446        final ActivityRecord topActivity = task.getTopActivity();
2447        final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID;
2448        final boolean mightReplaceWindow =
2449                StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) && topActivity != null;
2450        if (mightReplaceWindow) {
2451            // We are about to relaunch the activity because its configuration changed due to
2452            // being maximized, i.e. size change. The activity will first remove the old window
2453            // and then add a new one. This call will tell window manager about this, so it can
2454            // preserve the old window until the new one is drawn. This prevents having a gap
2455            // between the removal and addition, in which no window is visible. We also want the
2456            // entrance of the new window to be properly animated.
2457            // Note here we always set the replacing window first, as the flags might be needed
2458            // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
2459            mWindowManager.setReplacingWindow(topActivity.appToken, animate);
2460        }
2461
2462        mWindowManager.deferSurfaceLayout();
2463        final int preferredLaunchStackId = stackId;
2464        boolean kept = true;
2465        try {
2466            final ActivityStack stack = moveTaskToStackUncheckedLocked(
2467                    task, stackId, toTop, forceFocus, reason + " moveTaskToStack");
2468            stackId = stack.mStackId;
2469
2470            if (!animate) {
2471                stack.mNoAnimActivities.add(topActivity);
2472            }
2473
2474            // We might trigger a configuration change. Save the current task bounds for freezing.
2475            mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
2476
2477            // Make sure the task has the appropriate bounds/size for the stack it is in.
2478            if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
2479                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
2480                        !mightReplaceWindow, deferResume);
2481            } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
2482                Rect bounds = task.getLaunchBounds();
2483                if (bounds == null) {
2484                    stack.layoutTaskInStack(task, null);
2485                    bounds = task.mBounds;
2486                }
2487                kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow,
2488                        deferResume);
2489            } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
2490                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
2491                        !mightReplaceWindow, deferResume);
2492            }
2493        } finally {
2494            mWindowManager.continueSurfaceLayout();
2495        }
2496
2497        if (mightReplaceWindow) {
2498            // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
2499            // window), we need to clear the replace window settings. Otherwise, we schedule a
2500            // timeout to remove the old window if the replacing window is not coming in time.
2501            mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept);
2502        }
2503
2504        if (!deferResume) {
2505
2506            // The task might have already been running and its visibility needs to be synchronized with
2507            // the visibility of the stack / windows.
2508            ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
2509            resumeFocusedStackTopActivityLocked();
2510        }
2511
2512        handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId);
2513
2514        return (preferredLaunchStackId == stackId);
2515    }
2516
2517    boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) {
2518        final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
2519        if (stack == null) {
2520            throw new IllegalArgumentException(
2521                    "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId);
2522        }
2523
2524        final ActivityRecord r = stack.topRunningActivityLocked();
2525        if (r == null) {
2526            Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity"
2527                    + " in stack=" + stack);
2528            return false;
2529        }
2530
2531        if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
2532            Slog.w(TAG,
2533                    "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for "
2534                            + " r=" + r);
2535            return false;
2536        }
2537
2538        moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds);
2539        return true;
2540    }
2541
2542    void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) {
2543        mWindowManager.deferSurfaceLayout();
2544        try {
2545            final TaskRecord task = r.task;
2546
2547            if (r == task.stack.getVisibleBehindActivity()) {
2548                // An activity can't be pinned and visible behind at the same time. Go ahead and
2549                // release it from been visible behind before pinning.
2550                requestVisibleBehindLocked(r, false);
2551            }
2552
2553            // Need to make sure the pinned stack exist so we can resize it below...
2554            final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
2555
2556            // Resize the pinned stack to match the current size of the task the activity we are
2557            // going to be moving is currently contained in. We do this to have the right starting
2558            // animation bounds for the pinned stack to the desired bounds the caller wants.
2559            resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
2560                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
2561                    true /* allowResizeInDockedMode */, !DEFER_RESUME);
2562
2563            if (task.mActivities.size() == 1) {
2564                // There is only one activity in the task. So, we can just move the task over to
2565                // the stack without re-parenting the activity in a different task.
2566                if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
2567                    // Move the home stack forward if the task we just moved to the pinned stack
2568                    // was launched from home so home should be visible behind it.
2569                    moveHomeStackToFront(reason);
2570                }
2571                moveTaskToStackLocked(
2572                        task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE);
2573            } else {
2574                stack.moveActivityToStack(r);
2575            }
2576        } finally {
2577            mWindowManager.continueSurfaceLayout();
2578        }
2579
2580        // The task might have already been running and its visibility needs to be synchronized
2581        // with the visibility of the stack / windows.
2582        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2583        resumeFocusedStackTopActivityLocked();
2584
2585        mWindowManager.animateResizePinnedStack(bounds, -1);
2586        mService.notifyActivityPinnedLocked();
2587    }
2588
2589    void positionTaskInStackLocked(int taskId, int stackId, int position) {
2590        final TaskRecord task = anyTaskForIdLocked(taskId);
2591        if (task == null) {
2592            Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
2593            return;
2594        }
2595        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
2596
2597        task.updateOverrideConfigurationForStack(stack);
2598
2599        mWindowManager.positionTaskInStack(
2600                taskId, stackId, position, task.mBounds, task.mOverrideConfig);
2601        stack.positionTask(task, position);
2602        // The task might have already been running and its visibility needs to be synchronized with
2603        // the visibility of the stack / windows.
2604        stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2605        resumeFocusedStackTopActivityLocked();
2606    }
2607
2608    ActivityRecord findTaskLocked(ActivityRecord r) {
2609        mTmpFindTaskResult.r = null;
2610        mTmpFindTaskResult.matchedByRootAffinity = false;
2611        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
2612        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2613            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2614            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2615                final ActivityStack stack = stacks.get(stackNdx);
2616                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2617                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
2618                    continue;
2619                }
2620                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2621                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
2622                            "Skipping stack: (new task not allowed) " + stack);
2623                    continue;
2624                }
2625                stack.findTaskLocked(r, mTmpFindTaskResult);
2626                // It is possible to have task in multiple stacks with the same root affinity.
2627                // If the match we found was based on root affinity we keep on looking to see if
2628                // there is a better match in another stack. We eventually return the match based
2629                // on root affinity if we don't find a better match.
2630                if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) {
2631                    return mTmpFindTaskResult.r;
2632                }
2633            }
2634        }
2635        if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found");
2636        return mTmpFindTaskResult.r;
2637    }
2638
2639    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2640        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2641            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2642            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2643                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2644                if (ar != null) {
2645                    return ar;
2646                }
2647            }
2648        }
2649        return null;
2650    }
2651
2652    void goingToSleepLocked() {
2653        scheduleSleepTimeout();
2654        if (!mGoingToSleep.isHeld()) {
2655            mGoingToSleep.acquire();
2656            if (mLaunchingActivity.isHeld()) {
2657                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2658                    throw new IllegalStateException("Calling must be system uid");
2659                }
2660                mLaunchingActivity.release();
2661                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2662            }
2663        }
2664        checkReadyForSleepLocked();
2665    }
2666
2667    boolean shutdownLocked(int timeout) {
2668        goingToSleepLocked();
2669
2670        boolean timedout = false;
2671        final long endTime = System.currentTimeMillis() + timeout;
2672        while (true) {
2673            boolean cantShutdown = false;
2674            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2675                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2676                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2677                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2678                }
2679            }
2680            if (cantShutdown) {
2681                long timeRemaining = endTime - System.currentTimeMillis();
2682                if (timeRemaining > 0) {
2683                    try {
2684                        mService.wait(timeRemaining);
2685                    } catch (InterruptedException e) {
2686                    }
2687                } else {
2688                    Slog.w(TAG, "Activity manager shutdown timed out");
2689                    timedout = true;
2690                    break;
2691                }
2692            } else {
2693                break;
2694            }
2695        }
2696
2697        // Force checkReadyForSleep to complete.
2698        mSleepTimeout = true;
2699        checkReadyForSleepLocked();
2700
2701        return timedout;
2702    }
2703
2704    void comeOutOfSleepIfNeededLocked() {
2705        removeSleepTimeouts();
2706        if (mGoingToSleep.isHeld()) {
2707            mGoingToSleep.release();
2708        }
2709        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2710            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2711            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2712                final ActivityStack stack = stacks.get(stackNdx);
2713                stack.awakeFromSleepingLocked();
2714                if (isFocusedStack(stack)) {
2715                    resumeFocusedStackTopActivityLocked();
2716                }
2717            }
2718        }
2719        mGoingToSleepActivities.clear();
2720    }
2721
2722    void activitySleptLocked(ActivityRecord r) {
2723        mGoingToSleepActivities.remove(r);
2724        checkReadyForSleepLocked();
2725    }
2726
2727    void checkReadyForSleepLocked() {
2728        if (!mService.isSleepingOrShuttingDown()) {
2729            // Do not care.
2730            return;
2731        }
2732
2733        if (!mSleepTimeout) {
2734            boolean dontSleep = false;
2735            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2736                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2737                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2738                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2739                }
2740            }
2741
2742            if (mStoppingActivities.size() > 0) {
2743                // Still need to tell some activities to stop; can't sleep yet.
2744                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
2745                        + mStoppingActivities.size() + " activities");
2746                scheduleIdleLocked();
2747                dontSleep = true;
2748            }
2749
2750            if (mGoingToSleepActivities.size() > 0) {
2751                // Still need to tell some activities to sleep; can't sleep yet.
2752                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
2753                        + mGoingToSleepActivities.size() + " activities");
2754                dontSleep = true;
2755            }
2756
2757            if (dontSleep) {
2758                return;
2759            }
2760        }
2761
2762        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2763            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2764            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2765                stacks.get(stackNdx).goToSleep();
2766            }
2767        }
2768
2769        removeSleepTimeouts();
2770
2771        if (mGoingToSleep.isHeld()) {
2772            mGoingToSleep.release();
2773        }
2774        if (mService.mShuttingDown) {
2775            mService.notifyAll();
2776        }
2777    }
2778
2779    boolean reportResumedActivityLocked(ActivityRecord r) {
2780        final ActivityStack stack = r.task.stack;
2781        if (isFocusedStack(stack)) {
2782            mService.updateUsageStats(r, true);
2783        }
2784        if (allResumedActivitiesComplete()) {
2785            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2786            mWindowManager.executeAppTransition();
2787            return true;
2788        }
2789        return false;
2790    }
2791
2792    void handleAppCrashLocked(ProcessRecord app) {
2793        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2794            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2795            int stackNdx = stacks.size() - 1;
2796            while (stackNdx >= 0) {
2797                stacks.get(stackNdx).handleAppCrashLocked(app);
2798                stackNdx--;
2799            }
2800        }
2801    }
2802
2803    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
2804        final ActivityStack stack = r.task.stack;
2805        if (stack == null) {
2806            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2807                    "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
2808            return false;
2809        }
2810
2811        if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) {
2812            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r
2813                    + " visible=" + visible + " stackId=" + stack.mStackId
2814                    + " can't contain visible behind activities");
2815            return false;
2816        }
2817
2818        final boolean isVisible = stack.hasVisibleBehindActivity();
2819        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2820                "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
2821
2822        final ActivityRecord top = topRunningActivityLocked();
2823        if (top == null || top == r || (visible == isVisible)) {
2824            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
2825            stack.setVisibleBehindActivity(visible ? r : null);
2826            return true;
2827        }
2828
2829        // A non-top activity is reporting a visibility change.
2830        if (visible && top.fullscreen) {
2831            // Let the caller know that it can't be seen.
2832            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2833                    "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
2834                    + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
2835                    + top.app.thread);
2836            return false;
2837        } else if (!visible && stack.getVisibleBehindActivity() != r) {
2838            // Only the activity set as currently visible behind should actively reset its
2839            // visible behind state.
2840            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2841                    "requestVisibleBehind: returning visible=" + visible
2842                    + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
2843                    + " r=" + r);
2844            return false;
2845        }
2846
2847        stack.setVisibleBehindActivity(visible ? r : null);
2848        if (!visible) {
2849            // If there is a translucent home activity, we need to force it stop being translucent,
2850            // because we can't depend on the application to necessarily perform that operation.
2851            // Check out b/14469711 for details.
2852            final ActivityRecord next = stack.findNextTranslucentActivity(r);
2853            if (next != null && next.isHomeActivity()) {
2854                mService.convertFromTranslucent(next.appToken);
2855            }
2856        }
2857        if (top.app != null && top.app.thread != null) {
2858            // Notify the top app of the change.
2859            try {
2860                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
2861            } catch (RemoteException e) {
2862            }
2863        }
2864        return true;
2865    }
2866
2867    // Called when WindowManager has finished animating the launchingBehind activity to the back.
2868    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2869        final TaskRecord task = r.task;
2870        final ActivityStack stack = task.stack;
2871
2872        r.mLaunchTaskBehind = false;
2873        task.setLastThumbnailLocked(stack.screenshotActivitiesLocked(r));
2874        mRecentTasks.addLocked(task);
2875        mService.notifyTaskStackChangedLocked();
2876        mWindowManager.setAppVisibility(r.appToken, false);
2877
2878        // When launching tasks behind, update the last active time of the top task after the new
2879        // task has been shown briefly
2880        final ActivityRecord top = stack.topActivity();
2881        if (top != null) {
2882            top.task.touchActiveTime();
2883        }
2884    }
2885
2886    void scheduleLaunchTaskBehindComplete(IBinder token) {
2887        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2888    }
2889
2890    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
2891            boolean preserveWindows) {
2892        // First the front stacks. In case any are not fullscreen and are in front of home.
2893        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2894            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2895            final int topStackNdx = stacks.size() - 1;
2896            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2897                final ActivityStack stack = stacks.get(stackNdx);
2898                stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
2899            }
2900        }
2901    }
2902
2903    void invalidateTaskLayers() {
2904        mTaskLayersChanged = true;
2905    }
2906
2907    void rankTaskLayersIfNeeded() {
2908        if (!mTaskLayersChanged) {
2909            return;
2910        }
2911        mTaskLayersChanged = false;
2912        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
2913            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2914            int baseLayer = 0;
2915            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2916                baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer);
2917            }
2918        }
2919    }
2920
2921    void clearOtherAppTimeTrackers(AppTimeTracker except) {
2922        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2923            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2924            final int topStackNdx = stacks.size() - 1;
2925            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2926                final ActivityStack stack = stacks.get(stackNdx);
2927                stack.clearOtherAppTimeTrackers(except);
2928            }
2929        }
2930    }
2931
2932    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2933        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2934            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2935            final int numStacks = stacks.size();
2936            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2937                final ActivityStack stack = stacks.get(stackNdx);
2938                stack.scheduleDestroyActivities(app, reason);
2939            }
2940        }
2941    }
2942
2943    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
2944        // Examine all activities currently running in the process.
2945        TaskRecord firstTask = null;
2946        // Tasks is non-null only if two or more tasks are found.
2947        ArraySet<TaskRecord> tasks = null;
2948        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
2949        for (int i = 0; i < app.activities.size(); i++) {
2950            ActivityRecord r = app.activities.get(i);
2951            // First, if we find an activity that is in the process of being destroyed,
2952            // then we just aren't going to do anything for now; we want things to settle
2953            // down before we try to prune more activities.
2954            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
2955                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
2956                return;
2957            }
2958            // Don't consider any activies that are currently not in a state where they
2959            // can be destroyed.
2960            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
2961                    || r.state == PAUSED || r.state == STOPPING) {
2962                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
2963                continue;
2964            }
2965            if (r.task != null) {
2966                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task
2967                        + " from " + r);
2968                if (firstTask == null) {
2969                    firstTask = r.task;
2970                } else if (firstTask != r.task) {
2971                    if (tasks == null) {
2972                        tasks = new ArraySet<>();
2973                        tasks.add(firstTask);
2974                    }
2975                    tasks.add(r.task);
2976                }
2977            }
2978        }
2979        if (tasks == null) {
2980            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
2981            return;
2982        }
2983        // If we have activities in multiple tasks that are in a position to be destroyed,
2984        // let's iterate through the tasks and release the oldest one.
2985        final int numDisplays = mActivityDisplays.size();
2986        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2987            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2988            // Step through all stacks starting from behind, to hit the oldest things first.
2989            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
2990                final ActivityStack stack = stacks.get(stackNdx);
2991                // Try to release activities in this stack; if we manage to, we are done.
2992                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
2993                    return;
2994                }
2995            }
2996        }
2997    }
2998
2999    boolean switchUserLocked(int userId, UserState uss) {
3000        final int focusStackId = mFocusedStack.getStackId();
3001        // We dismiss the docked stack whenever we switch users.
3002        moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, focusStackId == DOCKED_STACK_ID);
3003
3004        mUserStackInFront.put(mCurrentUser, focusStackId);
3005        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
3006        mCurrentUser = userId;
3007
3008        mStartingUsers.add(uss);
3009        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3010            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3011            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3012                final ActivityStack stack = stacks.get(stackNdx);
3013                stack.switchUserLocked(userId);
3014                TaskRecord task = stack.topTask();
3015                if (task != null) {
3016                    mWindowManager.moveTaskToTop(task.taskId);
3017                }
3018            }
3019        }
3020
3021        ActivityStack stack = getStack(restoreStackId);
3022        if (stack == null) {
3023            stack = mHomeStack;
3024        }
3025        final boolean homeInFront = stack.isHomeStack();
3026        if (stack.isOnHomeDisplay()) {
3027            stack.moveToFront("switchUserOnHomeDisplay");
3028        } else {
3029            // Stack was moved to another display while user was swapped out.
3030            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
3031        }
3032        return homeInFront;
3033    }
3034
3035    /** Checks whether the userid is a profile of the current user. */
3036    boolean isCurrentProfileLocked(int userId) {
3037        if (userId == mCurrentUser) return true;
3038        return mService.mUserController.isCurrentProfileLocked(userId);
3039    }
3040
3041    /** Checks whether the activity should be shown for current user. */
3042    boolean okToShowLocked(ActivityRecord r) {
3043        return r != null && (isCurrentProfileLocked(r.userId)
3044                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
3045    }
3046
3047    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
3048        ArrayList<ActivityRecord> stops = null;
3049
3050        final boolean nowVisible = allResumedActivitiesVisible();
3051        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3052            ActivityRecord s = mStoppingActivities.get(activityNdx);
3053            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
3054            if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
3055                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
3056            if (waitingVisible && nowVisible) {
3057                mWaitingVisibleActivities.remove(s);
3058                if (s.finishing) {
3059                    // If this activity is finishing, it is sitting on top of
3060                    // everyone else but we now know it is no longer needed...
3061                    // so get rid of it.  Otherwise, we need to go through the
3062                    // normal flow and hide it once we determine that it is
3063                    // hidden by the activities in front of it.
3064                    if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
3065                    mWindowManager.setAppVisibility(s.appToken, false);
3066                }
3067            }
3068            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
3069                if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
3070                if (stops == null) {
3071                    stops = new ArrayList<>();
3072                }
3073                stops.add(s);
3074                mStoppingActivities.remove(activityNdx);
3075            }
3076        }
3077
3078        return stops;
3079    }
3080
3081    void validateTopActivitiesLocked() {
3082        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3083            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3084            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3085                final ActivityStack stack = stacks.get(stackNdx);
3086                final ActivityRecord r = stack.topRunningActivityLocked();
3087                final ActivityState state = r == null ? DESTROYED : r.state;
3088                if (isFocusedStack(stack)) {
3089                    if (r == null) Slog.e(TAG,
3090                            "validateTop...: null top activity, stack=" + stack);
3091                    else {
3092                        final ActivityRecord pausing = stack.mPausingActivity;
3093                        if (pausing != null && pausing == r) Slog.e(TAG,
3094                                "validateTop...: top stack has pausing activity r=" + r
3095                                + " state=" + state);
3096                        if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
3097                                "validateTop...: activity in front not resumed r=" + r
3098                                + " state=" + state);
3099                    }
3100                } else {
3101                    final ActivityRecord resumed = stack.mResumedActivity;
3102                    if (resumed != null && resumed == r) Slog.e(TAG,
3103                            "validateTop...: back stack has resumed activity r=" + r
3104                            + " state=" + state);
3105                    if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
3106                            "validateTop...: activity in back resumed r=" + r + " state=" + state);
3107                }
3108            }
3109        }
3110    }
3111
3112    private String lockTaskModeToString() {
3113        switch (mLockTaskModeState) {
3114            case LOCK_TASK_MODE_LOCKED:
3115                return "LOCKED";
3116            case LOCK_TASK_MODE_PINNED:
3117                return "PINNED";
3118            case LOCK_TASK_MODE_NONE:
3119                return "NONE";
3120            default: return "unknown=" + mLockTaskModeState;
3121        }
3122    }
3123
3124    public void dump(PrintWriter pw, String prefix) {
3125        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3126                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3127        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3128        pw.print(prefix);
3129        pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
3130        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3131        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3132        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
3133                final SparseArray<String[]> packages = mService.mLockTaskPackages;
3134                if (packages.size() > 0) {
3135                    pw.println(" mLockTaskPackages (userId:packages)=");
3136                    for (int i = 0; i < packages.size(); ++i) {
3137                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
3138                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
3139                    }
3140                }
3141                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
3142    }
3143
3144    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3145        return mFocusedStack.getDumpActivitiesLocked(name);
3146    }
3147
3148    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3149            boolean needSep, String prefix) {
3150        if (activity != null) {
3151            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3152                if (needSep) {
3153                    pw.println();
3154                }
3155                pw.print(prefix);
3156                pw.println(activity);
3157                return true;
3158            }
3159        }
3160        return false;
3161    }
3162
3163    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3164            boolean dumpClient, String dumpPackage) {
3165        boolean printed = false;
3166        boolean needSep = false;
3167        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3168            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3169            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3170                    pw.println(" (activities from top to bottom):");
3171            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3172            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3173                final ActivityStack stack = stacks.get(stackNdx);
3174                StringBuilder stackHeader = new StringBuilder(128);
3175                stackHeader.append("  Stack #");
3176                stackHeader.append(stack.mStackId);
3177                stackHeader.append(":");
3178                stackHeader.append("\n");
3179                stackHeader.append("  mFullscreen=" + stack.mFullscreen);
3180                stackHeader.append("\n");
3181                stackHeader.append("  mBounds=" + stack.mBounds);
3182                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3183                        needSep, stackHeader.toString());
3184                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3185                        !dumpAll, false, dumpPackage, true,
3186                        "    Running activities (most recent first):", null);
3187
3188                needSep = printed;
3189                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3190                        "    mPausingActivity: ");
3191                if (pr) {
3192                    printed = true;
3193                    needSep = false;
3194                }
3195                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3196                        "    mResumedActivity: ");
3197                if (pr) {
3198                    printed = true;
3199                    needSep = false;
3200                }
3201                if (dumpAll) {
3202                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3203                            "    mLastPausedActivity: ");
3204                    if (pr) {
3205                        printed = true;
3206                        needSep = true;
3207                    }
3208                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3209                            needSep, "    mLastNoHistoryActivity: ");
3210                }
3211                needSep = printed;
3212            }
3213        }
3214
3215        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3216                false, dumpPackage, true, "  Activities waiting to finish:", null);
3217        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3218                false, dumpPackage, true, "  Activities waiting to stop:", null);
3219        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3220                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3221                null);
3222        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3223                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3224        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3225                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3226
3227        return printed;
3228    }
3229
3230    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3231            String prefix, String label, boolean complete, boolean brief, boolean client,
3232            String dumpPackage, boolean needNL, String header1, String header2) {
3233        TaskRecord lastTask = null;
3234        String innerPrefix = null;
3235        String[] args = null;
3236        boolean printed = false;
3237        for (int i=list.size()-1; i>=0; i--) {
3238            final ActivityRecord r = list.get(i);
3239            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3240                continue;
3241            }
3242            if (innerPrefix == null) {
3243                innerPrefix = prefix + "      ";
3244                args = new String[0];
3245            }
3246            printed = true;
3247            final boolean full = !brief && (complete || !r.isInHistory());
3248            if (needNL) {
3249                pw.println("");
3250                needNL = false;
3251            }
3252            if (header1 != null) {
3253                pw.println(header1);
3254                header1 = null;
3255            }
3256            if (header2 != null) {
3257                pw.println(header2);
3258                header2 = null;
3259            }
3260            if (lastTask != r.task) {
3261                lastTask = r.task;
3262                pw.print(prefix);
3263                pw.print(full ? "* " : "  ");
3264                pw.println(lastTask);
3265                if (full) {
3266                    lastTask.dump(pw, prefix + "  ");
3267                } else if (complete) {
3268                    // Complete + brief == give a summary.  Isn't that obvious?!?
3269                    if (lastTask.intent != null) {
3270                        pw.print(prefix); pw.print("  ");
3271                                pw.println(lastTask.intent.toInsecureStringWithClip());
3272                    }
3273                }
3274            }
3275            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3276            pw.print(" #"); pw.print(i); pw.print(": ");
3277            pw.println(r);
3278            if (full) {
3279                r.dump(pw, innerPrefix);
3280            } else if (complete) {
3281                // Complete + brief == give a summary.  Isn't that obvious?!?
3282                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3283                if (r.app != null) {
3284                    pw.print(innerPrefix); pw.println(r.app);
3285                }
3286            }
3287            if (client && r.app != null && r.app.thread != null) {
3288                // flush anything that is already in the PrintWriter since the thread is going
3289                // to write to the file descriptor directly
3290                pw.flush();
3291                try {
3292                    TransferPipe tp = new TransferPipe();
3293                    try {
3294                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3295                                r.appToken, innerPrefix, args);
3296                        // Short timeout, since blocking here can
3297                        // deadlock with the application.
3298                        tp.go(fd, 2000);
3299                    } finally {
3300                        tp.kill();
3301                    }
3302                } catch (IOException e) {
3303                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3304                } catch (RemoteException e) {
3305                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3306                }
3307                needNL = true;
3308            }
3309        }
3310        return printed;
3311    }
3312
3313    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3314        if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3315                "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3316        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3317        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3318    }
3319
3320    final void scheduleIdleLocked() {
3321        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3322    }
3323
3324    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3325        if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
3326                + Debug.getCallers(4));
3327        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3328    }
3329
3330    final void scheduleResumeTopActivities() {
3331        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3332            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3333        }
3334    }
3335
3336    void removeSleepTimeouts() {
3337        mSleepTimeout = false;
3338        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3339    }
3340
3341    final void scheduleSleepTimeout() {
3342        removeSleepTimeouts();
3343        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3344    }
3345
3346    @Override
3347    public void onDisplayAdded(int displayId) {
3348        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
3349        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3350    }
3351
3352    @Override
3353    public void onDisplayRemoved(int displayId) {
3354        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
3355        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3356    }
3357
3358    @Override
3359    public void onDisplayChanged(int displayId) {
3360        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
3361        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3362    }
3363
3364    private void handleDisplayAdded(int displayId) {
3365        boolean newDisplay;
3366        synchronized (mService) {
3367            newDisplay = mActivityDisplays.get(displayId) == null;
3368            if (newDisplay) {
3369                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3370                if (activityDisplay.mDisplay == null) {
3371                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3372                    return;
3373                }
3374                mActivityDisplays.put(displayId, activityDisplay);
3375                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
3376            }
3377        }
3378        if (newDisplay) {
3379            mWindowManager.onDisplayAdded(displayId);
3380        }
3381    }
3382
3383    private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
3384        mDefaultMinimalSizeOfResizeableTask =
3385                mService.mContext.getResources().getDimensionPixelSize(
3386                        com.android.internal.R.dimen.default_minimal_size_resizable_task);
3387    }
3388
3389    private void handleDisplayRemoved(int displayId) {
3390        synchronized (mService) {
3391            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3392            if (activityDisplay != null) {
3393                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3394                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3395                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3396                }
3397                mActivityDisplays.remove(displayId);
3398            }
3399        }
3400        mWindowManager.onDisplayRemoved(displayId);
3401    }
3402
3403    private void handleDisplayChanged(int displayId) {
3404        synchronized (mService) {
3405            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3406            if (activityDisplay != null) {
3407                // TODO: Update the bounds.
3408            }
3409        }
3410        mWindowManager.onDisplayChanged(displayId);
3411    }
3412
3413    private StackInfo getStackInfoLocked(ActivityStack stack) {
3414        StackInfo info = new StackInfo();
3415        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3416        info.displayId = Display.DEFAULT_DISPLAY;
3417        info.stackId = stack.mStackId;
3418        info.userId = stack.mCurrentUser;
3419        info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
3420
3421        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3422        final int numTasks = tasks.size();
3423        int[] taskIds = new int[numTasks];
3424        String[] taskNames = new String[numTasks];
3425        Rect[] taskBounds = new Rect[numTasks];
3426        int[] taskUserIds = new int[numTasks];
3427        for (int i = 0; i < numTasks; ++i) {
3428            final TaskRecord task = tasks.get(i);
3429            taskIds[i] = task.taskId;
3430            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3431                    : task.realActivity != null ? task.realActivity.flattenToString()
3432                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3433                    : "unknown";
3434            taskBounds[i] = new Rect();
3435            mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
3436            taskUserIds[i] = task.userId;
3437        }
3438        info.taskIds = taskIds;
3439        info.taskNames = taskNames;
3440        info.taskBounds = taskBounds;
3441        info.taskUserIds = taskUserIds;
3442
3443        final ActivityRecord top = stack.topRunningActivityLocked();
3444        info.topActivity = top != null ? top.intent.getComponent() : null;
3445        return info;
3446    }
3447
3448    StackInfo getStackInfoLocked(int stackId) {
3449        ActivityStack stack = getStack(stackId);
3450        if (stack != null) {
3451            return getStackInfoLocked(stack);
3452        }
3453        return null;
3454    }
3455
3456    ArrayList<StackInfo> getAllStackInfosLocked() {
3457        ArrayList<StackInfo> list = new ArrayList<>();
3458        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3459            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3460            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3461                list.add(getStackInfoLocked(stacks.get(ndx)));
3462            }
3463        }
3464        return list;
3465    }
3466
3467    TaskRecord getLockedTaskLocked() {
3468        final int top = mLockTaskModeTasks.size() - 1;
3469        if (top >= 0) {
3470            return mLockTaskModeTasks.get(top);
3471        }
3472        return null;
3473    }
3474
3475    boolean isLockedTask(TaskRecord task) {
3476        return mLockTaskModeTasks.contains(task);
3477    }
3478
3479    boolean isLastLockedTask(TaskRecord task) {
3480        return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
3481    }
3482
3483    void removeLockedTaskLocked(final TaskRecord task) {
3484        if (!mLockTaskModeTasks.remove(task)) {
3485            return;
3486        }
3487        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
3488        if (mLockTaskModeTasks.isEmpty()) {
3489            // Last one.
3490            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
3491                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
3492            final Message lockTaskMsg = Message.obtain();
3493            lockTaskMsg.arg1 = task.userId;
3494            lockTaskMsg.what = LOCK_TASK_END_MSG;
3495            mHandler.sendMessage(lockTaskMsg);
3496        }
3497    }
3498
3499    void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) {
3500        handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId,
3501                false /* forceNonResizable */);
3502    }
3503
3504    void handleNonResizableTaskIfNeeded(
3505            TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) {
3506        if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
3507                || task.isHomeTask()) {
3508            return;
3509        }
3510
3511        final ActivityRecord topActivity = task.getTopActivity();
3512        if (!task.canGoInDockedStack() || forceNonResizable) {
3513            // Display a warning toast that we tried to put a non-dockable task in the docked stack.
3514            mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
3515
3516            // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
3517            // we need to move it to top of fullscreen stack, otherwise it will be covered.
3518            moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID);
3519        } else if (topActivity != null && topActivity.isNonResizableOrForced()
3520                && !topActivity.noDisplay) {
3521            String packageName = topActivity.appInfo.packageName;
3522            mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0,
3523                    packageName).sendToTarget();
3524        }
3525    }
3526
3527    void showLockTaskToast() {
3528        mLockTaskNotify.showToast(mLockTaskModeState);
3529    }
3530
3531    void showLockTaskEscapeMessageLocked(TaskRecord task) {
3532        if (mLockTaskModeTasks.contains(task)) {
3533            mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
3534        }
3535    }
3536
3537    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
3538            boolean andResume) {
3539        if (task == null) {
3540            // Take out of lock task mode if necessary
3541            final TaskRecord lockedTask = getLockedTaskLocked();
3542            if (lockedTask != null) {
3543                removeLockedTaskLocked(lockedTask);
3544                if (!mLockTaskModeTasks.isEmpty()) {
3545                    // There are locked tasks remaining, can only finish this task, not unlock it.
3546                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3547                            "setLockTaskModeLocked: Tasks remaining, can't unlock");
3548                    lockedTask.performClearTaskLocked();
3549                    resumeFocusedStackTopActivityLocked();
3550                    return;
3551                }
3552            }
3553            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3554                    "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
3555            return;
3556        }
3557
3558        // Should have already been checked, but do it again.
3559        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
3560            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3561                    "setLockTaskModeLocked: Can't lock due to auth");
3562            return;
3563        }
3564        if (isLockTaskModeViolation(task)) {
3565            Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
3566            return;
3567        }
3568
3569        if (mLockTaskModeTasks.isEmpty()) {
3570            // First locktask.
3571            final Message lockTaskMsg = Message.obtain();
3572            lockTaskMsg.obj = task.intent.getComponent().getPackageName();
3573            lockTaskMsg.arg1 = task.userId;
3574            lockTaskMsg.what = LOCK_TASK_START_MSG;
3575            lockTaskMsg.arg2 = lockTaskModeState;
3576            mHandler.sendMessage(lockTaskMsg);
3577        }
3578        // Add it or move it to the top.
3579        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
3580                " Callers=" + Debug.getCallers(4));
3581        mLockTaskModeTasks.remove(task);
3582        mLockTaskModeTasks.add(task);
3583
3584        if (task.mLockTaskUid == -1) {
3585            task.mLockTaskUid = task.effectiveUid;
3586        }
3587
3588        if (andResume) {
3589            findTaskToMoveToFrontLocked(task, 0, null, reason,
3590                    lockTaskModeState != LOCK_TASK_MODE_NONE);
3591            resumeFocusedStackTopActivityLocked();
3592        } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
3593            handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId,
3594                    true /* forceNonResizable */);
3595        }
3596    }
3597
3598    boolean isLockTaskModeViolation(TaskRecord task) {
3599        return isLockTaskModeViolation(task, false);
3600    }
3601
3602    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
3603        if (getLockedTaskLocked() == task && !isNewClearTask) {
3604            return false;
3605        }
3606        final int lockTaskAuth = task.mLockTaskAuth;
3607        switch (lockTaskAuth) {
3608            case LOCK_TASK_AUTH_DONT_LOCK:
3609                return !mLockTaskModeTasks.isEmpty();
3610            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
3611            case LOCK_TASK_AUTH_LAUNCHABLE:
3612            case LOCK_TASK_AUTH_WHITELISTED:
3613                return false;
3614            case LOCK_TASK_AUTH_PINNABLE:
3615                // Pinnable tasks can't be launched on top of locktask tasks.
3616                return !mLockTaskModeTasks.isEmpty();
3617            default:
3618                Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
3619                return true;
3620        }
3621    }
3622
3623    void onLockTaskPackagesUpdatedLocked() {
3624        boolean didSomething = false;
3625        for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
3626            final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
3627            final boolean wasWhitelisted =
3628                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3629                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3630            lockedTask.setLockTaskAuth();
3631            final boolean isWhitelisted =
3632                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3633                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3634            if (wasWhitelisted && !isWhitelisted) {
3635                // Lost whitelisting authorization. End it now.
3636                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
3637                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
3638                removeLockedTaskLocked(lockedTask);
3639                lockedTask.performClearTaskLocked();
3640                didSomething = true;
3641            }
3642        }
3643        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3644            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3645            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3646                final ActivityStack stack = stacks.get(stackNdx);
3647                stack.onLockTaskPackagesUpdatedLocked();
3648            }
3649        }
3650        final ActivityRecord r = topRunningActivityLocked();
3651        final TaskRecord task = r != null ? r.task : null;
3652        if (mLockTaskModeTasks.isEmpty() && task != null
3653                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
3654            // This task must have just been authorized.
3655            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
3656                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
3657            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
3658                    false);
3659            didSomething = true;
3660        }
3661        if (didSomething) {
3662            resumeFocusedStackTopActivityLocked();
3663        }
3664    }
3665
3666    int getLockTaskModeState() {
3667        return mLockTaskModeState;
3668    }
3669
3670    void activityRelaunchedLocked(IBinder token) {
3671        mWindowManager.notifyAppRelaunchingFinished(token);
3672    }
3673
3674    void activityRelaunchingLocked(ActivityRecord r) {
3675        mWindowManager.notifyAppRelaunching(r.appToken);
3676    }
3677
3678    void logStackState() {
3679        mActivityMetricsLogger.logWindowState();
3680    }
3681
3682    void scheduleReportMultiWindowModeChanged(TaskRecord task) {
3683        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3684            final ActivityRecord r = task.mActivities.get(i);
3685            if (r.app != null && r.app.thread != null) {
3686                mMultiWindowModeChangedActivities.add(r);
3687            }
3688        }
3689
3690        if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
3691            mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
3692        }
3693    }
3694
3695    void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) {
3696        final ActivityStack stack = task.stack;
3697        if (prevStack == null || prevStack == stack
3698                || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
3699            return;
3700        }
3701
3702        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3703            final ActivityRecord r = task.mActivities.get(i);
3704            if (r.app != null && r.app.thread != null) {
3705                mPipModeChangedActivities.add(r);
3706            }
3707        }
3708
3709        if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
3710            mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
3711        }
3712    }
3713
3714    void setDockedStackMinimized(boolean minimized) {
3715        mIsDockMinimized = minimized;
3716        if (minimized) {
3717            // Docked stack is not visible, no need to confirm credentials for its top activity.
3718            return;
3719        }
3720        final ActivityStack dockedStack = getStack(StackId.DOCKED_STACK_ID);
3721        if (dockedStack == null) {
3722            return;
3723        }
3724        final ActivityRecord top = dockedStack.topRunningActivityLocked();
3725        if (top != null && mService.mUserController.shouldConfirmCredentials(top.userId)) {
3726            mService.mActivityStarter.showConfirmDeviceCredential(top.userId);
3727        }
3728    }
3729
3730    private final class ActivityStackSupervisorHandler extends Handler {
3731
3732        public ActivityStackSupervisorHandler(Looper looper) {
3733            super(looper);
3734        }
3735
3736        void activityIdleInternal(ActivityRecord r) {
3737            synchronized (mService) {
3738                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3739            }
3740        }
3741
3742        @Override
3743        public void handleMessage(Message msg) {
3744            switch (msg.what) {
3745                case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
3746                    synchronized (mService) {
3747                        for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
3748                            final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
3749                            r.scheduleMultiWindowModeChanged();
3750                        }
3751                    }
3752                } break;
3753                case REPORT_PIP_MODE_CHANGED_MSG: {
3754                    synchronized (mService) {
3755                        for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
3756                            final ActivityRecord r = mPipModeChangedActivities.remove(i);
3757                            r.schedulePictureInPictureModeChanged();
3758                        }
3759                    }
3760                } break;
3761                case IDLE_TIMEOUT_MSG: {
3762                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3763                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3764                    if (mService.mDidDexOpt) {
3765                        mService.mDidDexOpt = false;
3766                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3767                        nmsg.obj = msg.obj;
3768                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3769                        return;
3770                    }
3771                    // We don't at this point know if the activity is fullscreen,
3772                    // so we need to be conservative and assume it isn't.
3773                    activityIdleInternal((ActivityRecord)msg.obj);
3774                } break;
3775                case IDLE_NOW_MSG: {
3776                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3777                    activityIdleInternal((ActivityRecord)msg.obj);
3778                } break;
3779                case RESUME_TOP_ACTIVITY_MSG: {
3780                    synchronized (mService) {
3781                        resumeFocusedStackTopActivityLocked();
3782                    }
3783                } break;
3784                case SLEEP_TIMEOUT_MSG: {
3785                    synchronized (mService) {
3786                        if (mService.isSleepingOrShuttingDown()) {
3787                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3788                            mSleepTimeout = true;
3789                            checkReadyForSleepLocked();
3790                        }
3791                    }
3792                } break;
3793                case LAUNCH_TIMEOUT_MSG: {
3794                    if (mService.mDidDexOpt) {
3795                        mService.mDidDexOpt = false;
3796                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3797                        return;
3798                    }
3799                    synchronized (mService) {
3800                        if (mLaunchingActivity.isHeld()) {
3801                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3802                            if (VALIDATE_WAKE_LOCK_CALLER
3803                                    && Binder.getCallingUid() != Process.myUid()) {
3804                                throw new IllegalStateException("Calling must be system uid");
3805                            }
3806                            mLaunchingActivity.release();
3807                        }
3808                    }
3809                } break;
3810                case HANDLE_DISPLAY_ADDED: {
3811                    handleDisplayAdded(msg.arg1);
3812                } break;
3813                case HANDLE_DISPLAY_CHANGED: {
3814                    handleDisplayChanged(msg.arg1);
3815                } break;
3816                case HANDLE_DISPLAY_REMOVED: {
3817                    handleDisplayRemoved(msg.arg1);
3818                } break;
3819                case CONTAINER_CALLBACK_VISIBILITY: {
3820                    final ActivityContainer container = (ActivityContainer) msg.obj;
3821                    final IActivityContainerCallback callback = container.mCallback;
3822                    if (callback != null) {
3823                        try {
3824                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3825                        } catch (RemoteException e) {
3826                        }
3827                    }
3828                } break;
3829                case LOCK_TASK_START_MSG: {
3830                    // When lock task starts, we disable the status bars.
3831                    try {
3832                        if (mLockTaskNotify == null) {
3833                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3834                        }
3835                        mLockTaskNotify.show(true);
3836                        mLockTaskModeState = msg.arg2;
3837                        if (getStatusBarService() != null) {
3838                            int flags = 0;
3839                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
3840                                flags = StatusBarManager.DISABLE_MASK
3841                                        & (~StatusBarManager.DISABLE_BACK);
3842                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
3843                                flags = StatusBarManager.DISABLE_MASK
3844                                        & (~StatusBarManager.DISABLE_BACK)
3845                                        & (~StatusBarManager.DISABLE_HOME)
3846                                        & (~StatusBarManager.DISABLE_RECENT);
3847                            }
3848                            getStatusBarService().disable(flags, mToken,
3849                                    mService.mContext.getPackageName());
3850                        }
3851                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3852                        if (getDevicePolicyManager() != null) {
3853                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3854                                    (String)msg.obj, msg.arg1);
3855                        }
3856                    } catch (RemoteException ex) {
3857                        throw new RuntimeException(ex);
3858                    }
3859                } break;
3860                case LOCK_TASK_END_MSG: {
3861                    // When lock task ends, we enable the status bars.
3862                    try {
3863                        if (getStatusBarService() != null) {
3864                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3865                                    mService.mContext.getPackageName());
3866                        }
3867                        mWindowManager.reenableKeyguard(mToken);
3868                        if (getDevicePolicyManager() != null) {
3869                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3870                                    msg.arg1);
3871                        }
3872                        if (mLockTaskNotify == null) {
3873                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3874                        }
3875                        mLockTaskNotify.show(false);
3876                        try {
3877                            boolean shouldLockKeyguard = Settings.Secure.getInt(
3878                                    mService.mContext.getContentResolver(),
3879                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
3880                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
3881                                mWindowManager.lockNow(null);
3882                                mWindowManager.dismissKeyguard();
3883                                new LockPatternUtils(mService.mContext)
3884                                        .requireCredentialEntry(UserHandle.USER_ALL);
3885                            }
3886                        } catch (SettingNotFoundException e) {
3887                            // No setting, don't lock.
3888                        }
3889                    } catch (RemoteException ex) {
3890                        throw new RuntimeException(ex);
3891                    } finally {
3892                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
3893                    }
3894                } break;
3895                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
3896                    if (mLockTaskNotify == null) {
3897                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
3898                    }
3899                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
3900                } break;
3901                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3902                    final ActivityContainer container = (ActivityContainer) msg.obj;
3903                    final IActivityContainerCallback callback = container.mCallback;
3904                    if (callback != null) {
3905                        try {
3906                            callback.onAllActivitiesComplete(container.asBinder());
3907                        } catch (RemoteException e) {
3908                        }
3909                    }
3910                } break;
3911                case LAUNCH_TASK_BEHIND_COMPLETE: {
3912                    synchronized (mService) {
3913                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
3914                        if (r != null) {
3915                            handleLaunchTaskBehindCompleteLocked(r);
3916                        }
3917                    }
3918                } break;
3919
3920            }
3921        }
3922    }
3923
3924    class ActivityContainer extends android.app.IActivityContainer.Stub {
3925        final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK |
3926                FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3927        final int mStackId;
3928        IActivityContainerCallback mCallback = null;
3929        final ActivityStack mStack;
3930        ActivityRecord mParentActivity = null;
3931        String mIdString;
3932
3933        boolean mVisible = true;
3934
3935        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3936        ActivityDisplay mActivityDisplay;
3937
3938        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3939        final static int CONTAINER_STATE_NO_SURFACE = 1;
3940        final static int CONTAINER_STATE_FINISHING = 2;
3941        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3942
3943        ActivityContainer(int stackId) {
3944            synchronized (mService) {
3945                mStackId = stackId;
3946                mStack = new ActivityStack(this, mRecentTasks);
3947                mIdString = "ActivtyContainer{" + mStackId + "}";
3948                if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
3949            }
3950        }
3951
3952        void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
3953            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
3954                    + " to display=" + activityDisplay + " onTop=" + onTop);
3955            mActivityDisplay = activityDisplay;
3956            mStack.attachDisplay(activityDisplay, onTop);
3957            activityDisplay.attachActivities(mStack, onTop);
3958        }
3959
3960        @Override
3961        public void attachToDisplay(int displayId) {
3962            synchronized (mService) {
3963                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3964                if (activityDisplay == null) {
3965                    return;
3966                }
3967                attachToDisplayLocked(activityDisplay, true);
3968            }
3969        }
3970
3971        @Override
3972        public int getDisplayId() {
3973            synchronized (mService) {
3974                if (mActivityDisplay != null) {
3975                    return mActivityDisplay.mDisplayId;
3976                }
3977            }
3978            return -1;
3979        }
3980
3981        @Override
3982        public int getStackId() {
3983            synchronized (mService) {
3984                return mStackId;
3985            }
3986        }
3987
3988        @Override
3989        public boolean injectEvent(InputEvent event) {
3990            final long origId = Binder.clearCallingIdentity();
3991            try {
3992                synchronized (mService) {
3993                    if (mActivityDisplay != null) {
3994                        return mInputManagerInternal.injectInputEvent(event,
3995                                mActivityDisplay.mDisplayId,
3996                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3997                    }
3998                }
3999                return false;
4000            } finally {
4001                Binder.restoreCallingIdentity(origId);
4002            }
4003        }
4004
4005        @Override
4006        public void release() {
4007            synchronized (mService) {
4008                if (mContainerState == CONTAINER_STATE_FINISHING) {
4009                    return;
4010                }
4011                mContainerState = CONTAINER_STATE_FINISHING;
4012
4013                long origId = Binder.clearCallingIdentity();
4014                try {
4015                    mStack.finishAllActivitiesLocked(false);
4016                    mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack);
4017                } finally {
4018                    Binder.restoreCallingIdentity(origId);
4019                }
4020            }
4021        }
4022
4023        protected void detachLocked() {
4024            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
4025                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
4026            if (mActivityDisplay != null) {
4027                mActivityDisplay.detachActivitiesLocked(mStack);
4028                mActivityDisplay = null;
4029                mStack.detachDisplay();
4030            }
4031        }
4032
4033        @Override
4034        public final int startActivity(Intent intent) {
4035            return mService.startActivity(intent, this);
4036        }
4037
4038        @Override
4039        public final int startActivityIntentSender(IIntentSender intentSender)
4040                throws TransactionTooLargeException {
4041            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
4042
4043            if (!(intentSender instanceof PendingIntentRecord)) {
4044                throw new IllegalArgumentException("Bad PendingIntent object");
4045            }
4046
4047            final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
4048                    Binder.getCallingUid(), mCurrentUser, false,
4049                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4050
4051            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
4052            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
4053                    pendingIntent.key.requestResolvedType);
4054
4055            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
4056                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
4057        }
4058
4059        void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
4060            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
4061            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
4062                throw new SecurityException(
4063                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
4064            }
4065        }
4066
4067        @Override
4068        public IBinder asBinder() {
4069            return this;
4070        }
4071
4072        @Override
4073        public void setSurface(Surface surface, int width, int height, int density) {
4074            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
4075        }
4076
4077        ActivityStackSupervisor getOuter() {
4078            return ActivityStackSupervisor.this;
4079        }
4080
4081        boolean isAttachedLocked() {
4082            return mActivityDisplay != null;
4083        }
4084
4085        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
4086        void setVisible(boolean visible) {
4087            if (mVisible != visible) {
4088                mVisible = visible;
4089                if (mCallback != null) {
4090                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
4091                            0 /* unused */, this).sendToTarget();
4092                }
4093            }
4094        }
4095
4096        void setDrawn() {
4097        }
4098
4099        // You can always start a new task on a regular ActivityStack.
4100        boolean isEligibleForNewTasks() {
4101            return true;
4102        }
4103
4104        void onTaskListEmptyLocked() {
4105            detachLocked();
4106            deleteActivityContainer(this);
4107            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
4108        }
4109
4110        @Override
4111        public String toString() {
4112            return mIdString + (mActivityDisplay == null ? "N" : "A");
4113        }
4114    }
4115
4116    private class VirtualActivityContainer extends ActivityContainer {
4117        Surface mSurface;
4118        boolean mDrawn = false;
4119
4120        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
4121            super(getNextStackId());
4122            mParentActivity = parent;
4123            mCallback = callback;
4124            mContainerState = CONTAINER_STATE_NO_SURFACE;
4125            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
4126        }
4127
4128        @Override
4129        public void setSurface(Surface surface, int width, int height, int density) {
4130            super.setSurface(surface, width, height, density);
4131
4132            synchronized (mService) {
4133                final long origId = Binder.clearCallingIdentity();
4134                try {
4135                    setSurfaceLocked(surface, width, height, density);
4136                } finally {
4137                    Binder.restoreCallingIdentity(origId);
4138                }
4139            }
4140        }
4141
4142        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
4143            if (mContainerState == CONTAINER_STATE_FINISHING) {
4144                return;
4145            }
4146            VirtualActivityDisplay virtualActivityDisplay =
4147                    (VirtualActivityDisplay) mActivityDisplay;
4148            if (virtualActivityDisplay == null) {
4149                virtualActivityDisplay =
4150                        new VirtualActivityDisplay(width, height, density);
4151                mActivityDisplay = virtualActivityDisplay;
4152                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
4153                attachToDisplayLocked(virtualActivityDisplay, true);
4154            }
4155
4156            if (mSurface != null) {
4157                mSurface.release();
4158            }
4159
4160            mSurface = surface;
4161            if (surface != null) {
4162                resumeFocusedStackTopActivityLocked();
4163            } else {
4164                mContainerState = CONTAINER_STATE_NO_SURFACE;
4165                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
4166                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
4167                    mStack.startPausingLocked(false, true, false, false);
4168                }
4169            }
4170
4171            setSurfaceIfReadyLocked();
4172
4173            if (DEBUG_STACK) Slog.d(TAG_STACK,
4174                    "setSurface: " + this + " to display=" + virtualActivityDisplay);
4175        }
4176
4177        @Override
4178        boolean isAttachedLocked() {
4179            return mSurface != null && super.isAttachedLocked();
4180        }
4181
4182        @Override
4183        void setDrawn() {
4184            synchronized (mService) {
4185                mDrawn = true;
4186                setSurfaceIfReadyLocked();
4187            }
4188        }
4189
4190        // Never start a new task on an ActivityView if it isn't explicitly specified.
4191        @Override
4192        boolean isEligibleForNewTasks() {
4193            return false;
4194        }
4195
4196        private void setSurfaceIfReadyLocked() {
4197            if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
4198                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
4199            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
4200                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
4201                mContainerState = CONTAINER_STATE_HAS_SURFACE;
4202            }
4203        }
4204    }
4205
4206    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
4207     * attached {@link ActivityStack}s */
4208    class ActivityDisplay {
4209        /** Actual Display this object tracks. */
4210        int mDisplayId;
4211        Display mDisplay;
4212        DisplayInfo mDisplayInfo = new DisplayInfo();
4213
4214        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
4215         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
4216        final ArrayList<ActivityStack> mStacks = new ArrayList<>();
4217
4218        ActivityRecord mVisibleBehindActivity;
4219
4220        ActivityDisplay() {
4221        }
4222
4223        // After instantiation, check that mDisplay is not null before using this. The alternative
4224        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
4225        ActivityDisplay(int displayId) {
4226            final Display display = mDisplayManager.getDisplay(displayId);
4227            if (display == null) {
4228                return;
4229            }
4230            init(display);
4231        }
4232
4233        void init(Display display) {
4234            mDisplay = display;
4235            mDisplayId = display.getDisplayId();
4236            mDisplay.getDisplayInfo(mDisplayInfo);
4237        }
4238
4239        void attachActivities(ActivityStack stack, boolean onTop) {
4240            if (DEBUG_STACK) Slog.v(TAG_STACK,
4241                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId
4242                    + " onTop=" + onTop);
4243            if (onTop) {
4244                mStacks.add(stack);
4245            } else {
4246                mStacks.add(0, stack);
4247            }
4248        }
4249
4250        void detachActivitiesLocked(ActivityStack stack) {
4251            if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
4252                    + " from displayId=" + mDisplayId);
4253            mStacks.remove(stack);
4254        }
4255
4256        void setVisibleBehindActivity(ActivityRecord r) {
4257            mVisibleBehindActivity = r;
4258        }
4259
4260        boolean hasVisibleBehindActivity() {
4261            return mVisibleBehindActivity != null;
4262        }
4263
4264        @Override
4265        public String toString() {
4266            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4267        }
4268    }
4269
4270    class VirtualActivityDisplay extends ActivityDisplay {
4271        VirtualDisplay mVirtualDisplay;
4272
4273        VirtualActivityDisplay(int width, int height, int density) {
4274            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4275            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4276                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4277                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4278                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4279
4280            init(mVirtualDisplay.getDisplay());
4281
4282            mWindowManager.handleDisplayAdded(mDisplayId);
4283        }
4284
4285        void setSurface(Surface surface) {
4286            if (mVirtualDisplay != null) {
4287                mVirtualDisplay.setSurface(surface);
4288            }
4289        }
4290
4291        @Override
4292        void detachActivitiesLocked(ActivityStack stack) {
4293            super.detachActivitiesLocked(stack);
4294            if (mVirtualDisplay != null) {
4295                mVirtualDisplay.release();
4296                mVirtualDisplay = null;
4297            }
4298        }
4299
4300        @Override
4301        public String toString() {
4302            return "VirtualActivityDisplay={" + mDisplayId + "}";
4303        }
4304    }
4305
4306    /**
4307     * Adjust bounds to stay within stack bounds.
4308     *
4309     * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
4310     * that keep them unchanged, but be contained within the stack bounds.
4311     *
4312     * @param bounds Bounds to be adjusted.
4313     * @param stackBounds Bounds within which the other bounds should remain.
4314     */
4315    private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
4316        if (stackBounds == null || stackBounds.contains(bounds)) {
4317            return;
4318        }
4319
4320        if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
4321            final int maxRight = stackBounds.right
4322                    - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
4323            int horizontalDiff = stackBounds.left - bounds.left;
4324            if ((horizontalDiff < 0 && bounds.left >= maxRight)
4325                    || (bounds.left + horizontalDiff >= maxRight)) {
4326                horizontalDiff = maxRight - bounds.left;
4327            }
4328            bounds.left += horizontalDiff;
4329            bounds.right += horizontalDiff;
4330        }
4331
4332        if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
4333            final int maxBottom = stackBounds.bottom
4334                    - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
4335            int verticalDiff = stackBounds.top - bounds.top;
4336            if ((verticalDiff < 0 && bounds.top >= maxBottom)
4337                    || (bounds.top + verticalDiff >= maxBottom)) {
4338                verticalDiff = maxBottom - bounds.top;
4339            }
4340            bounds.top += verticalDiff;
4341            bounds.bottom += verticalDiff;
4342        }
4343    }
4344
4345    ActivityStack findStackBehind(ActivityStack stack) {
4346        // TODO(multi-display): We are only looking for stacks on the default display.
4347        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
4348        if (display == null) {
4349            return null;
4350        }
4351        final ArrayList<ActivityStack> stacks = display.mStacks;
4352        for (int i = stacks.size() - 1; i >= 0; i--) {
4353            if (stacks.get(i) == stack && i > 0) {
4354                return stacks.get(i - 1);
4355            }
4356        }
4357        throw new IllegalStateException("Failed to find a stack behind stack=" + stack
4358                + " in=" + stacks);
4359    }
4360
4361    /**
4362     * Puts a task into resizing mode during the next app transition.
4363     *
4364     * @param taskId the id of the task to put into resizing mode
4365     */
4366    private void setResizingDuringAnimation(int taskId) {
4367        mResizingTasksDuringAnimation.add(taskId);
4368        mWindowManager.setTaskDockedResizing(taskId, true);
4369    }
4370
4371    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4372        final TaskRecord task;
4373        final int callingUid;
4374        final String callingPackage;
4375        final Intent intent;
4376        final int userId;
4377        final ActivityOptions activityOptions = (bOptions != null)
4378                ? new ActivityOptions(bOptions) : null;
4379        final int launchStackId = (activityOptions != null)
4380                ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4381        if (launchStackId == HOME_STACK_ID) {
4382            throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4383                    + taskId + " can't be launch in the home stack.");
4384        }
4385
4386        if (launchStackId == DOCKED_STACK_ID) {
4387            mWindowManager.setDockedStackCreateState(
4388                    activityOptions.getDockCreateMode(), null /* initialBounds */);
4389
4390            // Defer updating the stack in which recents is until the app transition is done, to
4391            // not run into issues where we still need to draw the task in recents but the
4392            // docked stack is already created.
4393            deferUpdateBounds(HOME_STACK_ID);
4394            mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
4395        }
4396
4397        task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4398        if (task == null) {
4399            continueUpdateBounds(HOME_STACK_ID);
4400            mWindowManager.executeAppTransition();
4401            throw new IllegalArgumentException(
4402                    "startActivityFromRecentsInner: Task " + taskId + " not found.");
4403        }
4404
4405        if (launchStackId != INVALID_STACK_ID) {
4406            if (task.stack.mStackId != launchStackId) {
4407                moveTaskToStackLocked(
4408                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4409                        ANIMATE);
4410            }
4411        }
4412
4413        // If the user must confirm credentials (e.g. when first launching a work app and the
4414        // Work Challenge is present) let startActivityInPackage handle the intercepting.
4415        if (!mService.mUserController.shouldConfirmCredentials(task.userId)
4416                && task.getRootActivity() != null) {
4417            mActivityMetricsLogger.notifyActivityLaunching();
4418            mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
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