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