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