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