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