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