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