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