ActivityStackSupervisor.java revision 681fc7b2670542aae0f3b9ef8f6c7a88db984ea9
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(false /* fromHome */);
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(false /* fromHome */);
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            // Need to make sure the pinned stack exist so we can resize it below...
2434            final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
2435
2436            // Resize the pinned stack to match the current size of the task the activity we are
2437            // going to be moving is currently contained in. We do this to have the right starting
2438            // animation bounds for the pinned stack to the desired bounds the caller wants.
2439            resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
2440                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
2441                    true /* allowResizeInDockedMode */);
2442
2443            if (task.mActivities.size() == 1) {
2444                // There is only one activity in the task. So, we can just move the task over to
2445                // the stack without re-parenting the activity in a different task.
2446                if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
2447                    // Move the home stack forward if the task we just moved to the pinned stack
2448                    // was launched from home so home should be visible behind it.
2449                    moveHomeStackToFront(reason);
2450                }
2451                moveTaskToStackLocked(
2452                        task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE);
2453            } else {
2454                stack.moveActivityToStack(r);
2455            }
2456        } finally {
2457            mWindowManager.continueSurfaceLayout();
2458        }
2459
2460        // The task might have already been running and its visibility needs to be synchronized
2461        // with the visibility of the stack / windows.
2462        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2463        resumeFocusedStackTopActivityLocked();
2464
2465        mWindowManager.animateResizePinnedStack(bounds, -1);
2466        mService.notifyActivityPinnedLocked();
2467    }
2468
2469    void positionTaskInStackLocked(int taskId, int stackId, int position) {
2470        final TaskRecord task = anyTaskForIdLocked(taskId);
2471        if (task == null) {
2472            Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
2473            return;
2474        }
2475        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
2476
2477        task.updateOverrideConfigurationForStack(stack);
2478
2479        mWindowManager.positionTaskInStack(
2480                taskId, stackId, position, task.mBounds, task.mOverrideConfig);
2481        stack.positionTask(task, position);
2482        // The task might have already been running and its visibility needs to be synchronized with
2483        // the visibility of the stack / windows.
2484        stack.ensureActivityConfigurationLocked(task.topRunningActivityLocked(), 0,
2485                !PRESERVE_WINDOWS);
2486        stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2487        resumeFocusedStackTopActivityLocked();
2488    }
2489
2490    ActivityRecord findTaskLocked(ActivityRecord r) {
2491        mTmpFindTaskResult.r = null;
2492        mTmpFindTaskResult.matchedByRootAffinity = false;
2493        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
2494        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2495            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2496            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2497                final ActivityStack stack = stacks.get(stackNdx);
2498                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2499                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
2500                    continue;
2501                }
2502                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2503                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
2504                            "Skipping stack: (new task not allowed) " + stack);
2505                    continue;
2506                }
2507                stack.findTaskLocked(r, mTmpFindTaskResult);
2508                // It is possible to have task in multiple stacks with the same root affinity.
2509                // If the match we found was based on root affinity we keep on looking to see if
2510                // there is a better match in another stack. We eventually return the match based
2511                // on root affinity if we don't find a better match.
2512                if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) {
2513                    return mTmpFindTaskResult.r;
2514                }
2515            }
2516        }
2517        if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found");
2518        return mTmpFindTaskResult.r;
2519    }
2520
2521    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2522        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2523            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2524            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2525                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2526                if (ar != null) {
2527                    return ar;
2528                }
2529            }
2530        }
2531        return null;
2532    }
2533
2534    void goingToSleepLocked() {
2535        scheduleSleepTimeout();
2536        if (!mGoingToSleep.isHeld()) {
2537            mGoingToSleep.acquire();
2538            if (mLaunchingActivity.isHeld()) {
2539                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2540                    throw new IllegalStateException("Calling must be system uid");
2541                }
2542                mLaunchingActivity.release();
2543                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2544            }
2545        }
2546        checkReadyForSleepLocked();
2547    }
2548
2549    boolean shutdownLocked(int timeout) {
2550        goingToSleepLocked();
2551
2552        boolean timedout = false;
2553        final long endTime = System.currentTimeMillis() + timeout;
2554        while (true) {
2555            boolean cantShutdown = false;
2556            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2557                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2558                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2559                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2560                }
2561            }
2562            if (cantShutdown) {
2563                long timeRemaining = endTime - System.currentTimeMillis();
2564                if (timeRemaining > 0) {
2565                    try {
2566                        mService.wait(timeRemaining);
2567                    } catch (InterruptedException e) {
2568                    }
2569                } else {
2570                    Slog.w(TAG, "Activity manager shutdown timed out");
2571                    timedout = true;
2572                    break;
2573                }
2574            } else {
2575                break;
2576            }
2577        }
2578
2579        // Force checkReadyForSleep to complete.
2580        mSleepTimeout = true;
2581        checkReadyForSleepLocked();
2582
2583        return timedout;
2584    }
2585
2586    void comeOutOfSleepIfNeededLocked() {
2587        removeSleepTimeouts();
2588        if (mGoingToSleep.isHeld()) {
2589            mGoingToSleep.release();
2590        }
2591        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2592            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2593            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2594                final ActivityStack stack = stacks.get(stackNdx);
2595                stack.awakeFromSleepingLocked();
2596                if (isFocusedStack(stack)) {
2597                    resumeFocusedStackTopActivityLocked();
2598                }
2599            }
2600        }
2601        mGoingToSleepActivities.clear();
2602    }
2603
2604    void activitySleptLocked(ActivityRecord r) {
2605        mGoingToSleepActivities.remove(r);
2606        checkReadyForSleepLocked();
2607    }
2608
2609    void checkReadyForSleepLocked() {
2610        if (!mService.isSleepingOrShuttingDown()) {
2611            // Do not care.
2612            return;
2613        }
2614
2615        if (!mSleepTimeout) {
2616            boolean dontSleep = false;
2617            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2618                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2619                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2620                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2621                }
2622            }
2623
2624            if (mStoppingActivities.size() > 0) {
2625                // Still need to tell some activities to stop; can't sleep yet.
2626                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
2627                        + mStoppingActivities.size() + " activities");
2628                scheduleIdleLocked();
2629                dontSleep = true;
2630            }
2631
2632            if (mGoingToSleepActivities.size() > 0) {
2633                // Still need to tell some activities to sleep; can't sleep yet.
2634                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
2635                        + mGoingToSleepActivities.size() + " activities");
2636                dontSleep = true;
2637            }
2638
2639            if (dontSleep) {
2640                return;
2641            }
2642        }
2643
2644        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2645            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2646            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2647                stacks.get(stackNdx).goToSleep();
2648            }
2649        }
2650
2651        removeSleepTimeouts();
2652
2653        if (mGoingToSleep.isHeld()) {
2654            mGoingToSleep.release();
2655        }
2656        if (mService.mShuttingDown) {
2657            mService.notifyAll();
2658        }
2659    }
2660
2661    boolean reportResumedActivityLocked(ActivityRecord r) {
2662        final ActivityStack stack = r.task.stack;
2663        if (isFocusedStack(stack)) {
2664            mService.updateUsageStats(r, true);
2665        }
2666        if (allResumedActivitiesComplete()) {
2667            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2668            mWindowManager.executeAppTransition();
2669            return true;
2670        }
2671        return false;
2672    }
2673
2674    void handleAppCrashLocked(ProcessRecord app) {
2675        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2676            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2677            int stackNdx = stacks.size() - 1;
2678            while (stackNdx >= 0) {
2679                stacks.get(stackNdx).handleAppCrashLocked(app);
2680                stackNdx--;
2681            }
2682        }
2683    }
2684
2685    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
2686        final ActivityStack stack = r.task.stack;
2687        if (stack == null) {
2688            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2689                    "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
2690            return false;
2691        }
2692        final boolean isVisible = stack.hasVisibleBehindActivity();
2693        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2694                "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
2695
2696        final ActivityRecord top = topRunningActivityLocked();
2697        if (top == null || top == r || (visible == isVisible)) {
2698            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
2699            stack.setVisibleBehindActivity(visible ? r : null);
2700            return true;
2701        }
2702
2703        // A non-top activity is reporting a visibility change.
2704        if (visible && top.fullscreen) {
2705            // Let the caller know that it can't be seen.
2706            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2707                    "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
2708                    + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
2709                    + top.app.thread);
2710            return false;
2711        } else if (!visible && stack.getVisibleBehindActivity() != r) {
2712            // Only the activity set as currently visible behind should actively reset its
2713            // visible behind state.
2714            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
2715                    "requestVisibleBehind: returning visible=" + visible
2716                    + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
2717                    + " r=" + r);
2718            return false;
2719        }
2720
2721        stack.setVisibleBehindActivity(visible ? r : null);
2722        if (!visible) {
2723            // If there is a translucent home activity, we need to force it stop being translucent,
2724            // because we can't depend on the application to necessarily perform that operation.
2725            // Check out b/14469711 for details.
2726            final ActivityRecord next = stack.findNextTranslucentActivity(r);
2727            if (next != null && next.isHomeActivity()) {
2728                mService.convertFromTranslucent(next.appToken);
2729            }
2730        }
2731        if (top.app != null && top.app.thread != null) {
2732            // Notify the top app of the change.
2733            try {
2734                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
2735            } catch (RemoteException e) {
2736            }
2737        }
2738        return true;
2739    }
2740
2741    // Called when WindowManager has finished animating the launchingBehind activity to the back.
2742    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2743        final TaskRecord task = r.task;
2744        final ActivityStack stack = task.stack;
2745
2746        r.mLaunchTaskBehind = false;
2747        task.setLastThumbnailLocked(stack.screenshotActivitiesLocked(r));
2748        mRecentTasks.addLocked(task);
2749        mService.notifyTaskStackChangedLocked();
2750        mWindowManager.setAppVisibility(r.appToken, false);
2751
2752        // When launching tasks behind, update the last active time of the top task after the new
2753        // task has been shown briefly
2754        final ActivityRecord top = stack.topActivity();
2755        if (top != null) {
2756            top.task.touchActiveTime();
2757        }
2758    }
2759
2760    void scheduleLaunchTaskBehindComplete(IBinder token) {
2761        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2762    }
2763
2764    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
2765            boolean preserveWindows) {
2766        // First the front stacks. In case any are not fullscreen and are in front of home.
2767        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2768            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2769            final int topStackNdx = stacks.size() - 1;
2770            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2771                final ActivityStack stack = stacks.get(stackNdx);
2772                stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
2773            }
2774        }
2775    }
2776
2777    void invalidateTaskLayers() {
2778        mTaskLayersChanged = true;
2779    }
2780
2781    void rankTaskLayersIfNeeded() {
2782        if (!mTaskLayersChanged) {
2783            return;
2784        }
2785        mTaskLayersChanged = false;
2786        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
2787            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2788            int baseLayer = 0;
2789            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2790                baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer);
2791            }
2792        }
2793    }
2794
2795    void clearOtherAppTimeTrackers(AppTimeTracker except) {
2796        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2797            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2798            final int topStackNdx = stacks.size() - 1;
2799            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2800                final ActivityStack stack = stacks.get(stackNdx);
2801                stack.clearOtherAppTimeTrackers(except);
2802            }
2803        }
2804    }
2805
2806    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2807        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2808            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2809            final int numStacks = stacks.size();
2810            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2811                final ActivityStack stack = stacks.get(stackNdx);
2812                stack.scheduleDestroyActivities(app, reason);
2813            }
2814        }
2815    }
2816
2817    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
2818        // Examine all activities currently running in the process.
2819        TaskRecord firstTask = null;
2820        // Tasks is non-null only if two or more tasks are found.
2821        ArraySet<TaskRecord> tasks = null;
2822        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
2823        for (int i = 0; i < app.activities.size(); i++) {
2824            ActivityRecord r = app.activities.get(i);
2825            // First, if we find an activity that is in the process of being destroyed,
2826            // then we just aren't going to do anything for now; we want things to settle
2827            // down before we try to prune more activities.
2828            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
2829                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
2830                return;
2831            }
2832            // Don't consider any activies that are currently not in a state where they
2833            // can be destroyed.
2834            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
2835                    || r.state == PAUSED || r.state == STOPPING) {
2836                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
2837                continue;
2838            }
2839            if (r.task != null) {
2840                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task
2841                        + " from " + r);
2842                if (firstTask == null) {
2843                    firstTask = r.task;
2844                } else if (firstTask != r.task) {
2845                    if (tasks == null) {
2846                        tasks = new ArraySet<>();
2847                        tasks.add(firstTask);
2848                    }
2849                    tasks.add(r.task);
2850                }
2851            }
2852        }
2853        if (tasks == null) {
2854            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
2855            return;
2856        }
2857        // If we have activities in multiple tasks that are in a position to be destroyed,
2858        // let's iterate through the tasks and release the oldest one.
2859        final int numDisplays = mActivityDisplays.size();
2860        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2861            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2862            // Step through all stacks starting from behind, to hit the oldest things first.
2863            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
2864                final ActivityStack stack = stacks.get(stackNdx);
2865                // Try to release activities in this stack; if we manage to, we are done.
2866                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
2867                    return;
2868                }
2869            }
2870        }
2871    }
2872
2873    boolean switchUserLocked(int userId, UserState uss) {
2874        mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
2875        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2876        mCurrentUser = userId;
2877
2878        mStartingUsers.add(uss);
2879        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2880            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2881            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2882                final ActivityStack stack = stacks.get(stackNdx);
2883                stack.switchUserLocked(userId);
2884                TaskRecord task = stack.topTask();
2885                if (task != null) {
2886                    mWindowManager.moveTaskToTop(task.taskId);
2887                }
2888            }
2889        }
2890
2891        ActivityStack stack = getStack(restoreStackId);
2892        if (stack == null) {
2893            stack = mHomeStack;
2894        }
2895        final boolean homeInFront = stack.isHomeStack();
2896        if (stack.isOnHomeDisplay()) {
2897            stack.moveToFront("switchUserOnHomeDisplay");
2898        } else {
2899            // Stack was moved to another display while user was swapped out.
2900            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
2901        }
2902        return homeInFront;
2903    }
2904
2905    /** Checks whether the userid is a profile of the current user. */
2906    boolean isCurrentProfileLocked(int userId) {
2907        if (userId == mCurrentUser) return true;
2908        return mService.mUserController.isCurrentProfileLocked(userId);
2909    }
2910
2911    /** Checks whether the activity should be shown for current user. */
2912    boolean okToShowLocked(ActivityRecord r) {
2913        return r != null && (isCurrentProfileLocked(r.userId)
2914                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
2915    }
2916
2917    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2918        ArrayList<ActivityRecord> stops = null;
2919
2920        final boolean nowVisible = allResumedActivitiesVisible();
2921        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2922            ActivityRecord s = mStoppingActivities.get(activityNdx);
2923            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
2924            if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
2925                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
2926            if (waitingVisible && nowVisible) {
2927                mWaitingVisibleActivities.remove(s);
2928                if (s.finishing) {
2929                    // If this activity is finishing, it is sitting on top of
2930                    // everyone else but we now know it is no longer needed...
2931                    // so get rid of it.  Otherwise, we need to go through the
2932                    // normal flow and hide it once we determine that it is
2933                    // hidden by the activities in front of it.
2934                    if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
2935                    mWindowManager.setAppVisibility(s.appToken, false);
2936                }
2937            }
2938            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2939                if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
2940                if (stops == null) {
2941                    stops = new ArrayList<>();
2942                }
2943                stops.add(s);
2944                mStoppingActivities.remove(activityNdx);
2945            }
2946        }
2947
2948        return stops;
2949    }
2950
2951    void validateTopActivitiesLocked() {
2952        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2953            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2954            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2955                final ActivityStack stack = stacks.get(stackNdx);
2956                final ActivityRecord r = stack.topRunningActivityLocked();
2957                final ActivityState state = r == null ? DESTROYED : r.state;
2958                if (isFocusedStack(stack)) {
2959                    if (r == null) Slog.e(TAG,
2960                            "validateTop...: null top activity, stack=" + stack);
2961                    else {
2962                        final ActivityRecord pausing = stack.mPausingActivity;
2963                        if (pausing != null && pausing == r) Slog.e(TAG,
2964                                "validateTop...: top stack has pausing activity r=" + r
2965                                + " state=" + state);
2966                        if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
2967                                "validateTop...: activity in front not resumed r=" + r
2968                                + " state=" + state);
2969                    }
2970                } else {
2971                    final ActivityRecord resumed = stack.mResumedActivity;
2972                    if (resumed != null && resumed == r) Slog.e(TAG,
2973                            "validateTop...: back stack has resumed activity r=" + r
2974                            + " state=" + state);
2975                    if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
2976                            "validateTop...: activity in back resumed r=" + r + " state=" + state);
2977                }
2978            }
2979        }
2980    }
2981
2982    private String lockTaskModeToString() {
2983        switch (mLockTaskModeState) {
2984            case LOCK_TASK_MODE_LOCKED:
2985                return "LOCKED";
2986            case LOCK_TASK_MODE_PINNED:
2987                return "PINNED";
2988            case LOCK_TASK_MODE_NONE:
2989                return "NONE";
2990            default: return "unknown=" + mLockTaskModeState;
2991        }
2992    }
2993
2994    public void dump(PrintWriter pw, String prefix) {
2995        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2996                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2997        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2998        pw.print(prefix);
2999        pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
3000        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3001        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3002        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
3003                final SparseArray<String[]> packages = mService.mLockTaskPackages;
3004                if (packages.size() > 0) {
3005                    pw.println(" mLockTaskPackages (userId:packages)=");
3006                    for (int i = 0; i < packages.size(); ++i) {
3007                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
3008                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
3009                    }
3010                }
3011                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
3012    }
3013
3014    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3015        return mFocusedStack.getDumpActivitiesLocked(name);
3016    }
3017
3018    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3019            boolean needSep, String prefix) {
3020        if (activity != null) {
3021            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3022                if (needSep) {
3023                    pw.println();
3024                }
3025                pw.print(prefix);
3026                pw.println(activity);
3027                return true;
3028            }
3029        }
3030        return false;
3031    }
3032
3033    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3034            boolean dumpClient, String dumpPackage) {
3035        boolean printed = false;
3036        boolean needSep = false;
3037        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3038            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3039            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3040                    pw.println(" (activities from top to bottom):");
3041            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3042            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3043                final ActivityStack stack = stacks.get(stackNdx);
3044                StringBuilder stackHeader = new StringBuilder(128);
3045                stackHeader.append("  Stack #");
3046                stackHeader.append(stack.mStackId);
3047                stackHeader.append(":");
3048                stackHeader.append("\n");
3049                stackHeader.append("  mFullscreen=" + stack.mFullscreen);
3050                stackHeader.append("\n");
3051                stackHeader.append("  mBounds=" + stack.mBounds);
3052                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3053                        needSep, stackHeader.toString());
3054                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3055                        !dumpAll, false, dumpPackage, true,
3056                        "    Running activities (most recent first):", null);
3057
3058                needSep = printed;
3059                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3060                        "    mPausingActivity: ");
3061                if (pr) {
3062                    printed = true;
3063                    needSep = false;
3064                }
3065                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3066                        "    mResumedActivity: ");
3067                if (pr) {
3068                    printed = true;
3069                    needSep = false;
3070                }
3071                if (dumpAll) {
3072                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3073                            "    mLastPausedActivity: ");
3074                    if (pr) {
3075                        printed = true;
3076                        needSep = true;
3077                    }
3078                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3079                            needSep, "    mLastNoHistoryActivity: ");
3080                }
3081                needSep = printed;
3082            }
3083        }
3084
3085        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3086                false, dumpPackage, true, "  Activities waiting to finish:", null);
3087        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3088                false, dumpPackage, true, "  Activities waiting to stop:", null);
3089        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3090                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3091                null);
3092        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3093                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3094        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3095                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3096
3097        return printed;
3098    }
3099
3100    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3101            String prefix, String label, boolean complete, boolean brief, boolean client,
3102            String dumpPackage, boolean needNL, String header1, String header2) {
3103        TaskRecord lastTask = null;
3104        String innerPrefix = null;
3105        String[] args = null;
3106        boolean printed = false;
3107        for (int i=list.size()-1; i>=0; i--) {
3108            final ActivityRecord r = list.get(i);
3109            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3110                continue;
3111            }
3112            if (innerPrefix == null) {
3113                innerPrefix = prefix + "      ";
3114                args = new String[0];
3115            }
3116            printed = true;
3117            final boolean full = !brief && (complete || !r.isInHistory());
3118            if (needNL) {
3119                pw.println("");
3120                needNL = false;
3121            }
3122            if (header1 != null) {
3123                pw.println(header1);
3124                header1 = null;
3125            }
3126            if (header2 != null) {
3127                pw.println(header2);
3128                header2 = null;
3129            }
3130            if (lastTask != r.task) {
3131                lastTask = r.task;
3132                pw.print(prefix);
3133                pw.print(full ? "* " : "  ");
3134                pw.println(lastTask);
3135                if (full) {
3136                    lastTask.dump(pw, prefix + "  ");
3137                } else if (complete) {
3138                    // Complete + brief == give a summary.  Isn't that obvious?!?
3139                    if (lastTask.intent != null) {
3140                        pw.print(prefix); pw.print("  ");
3141                                pw.println(lastTask.intent.toInsecureStringWithClip());
3142                    }
3143                }
3144            }
3145            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3146            pw.print(" #"); pw.print(i); pw.print(": ");
3147            pw.println(r);
3148            if (full) {
3149                r.dump(pw, innerPrefix);
3150            } else if (complete) {
3151                // Complete + brief == give a summary.  Isn't that obvious?!?
3152                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3153                if (r.app != null) {
3154                    pw.print(innerPrefix); pw.println(r.app);
3155                }
3156            }
3157            if (client && r.app != null && r.app.thread != null) {
3158                // flush anything that is already in the PrintWriter since the thread is going
3159                // to write to the file descriptor directly
3160                pw.flush();
3161                try {
3162                    TransferPipe tp = new TransferPipe();
3163                    try {
3164                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3165                                r.appToken, innerPrefix, args);
3166                        // Short timeout, since blocking here can
3167                        // deadlock with the application.
3168                        tp.go(fd, 2000);
3169                    } finally {
3170                        tp.kill();
3171                    }
3172                } catch (IOException e) {
3173                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3174                } catch (RemoteException e) {
3175                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3176                }
3177                needNL = true;
3178            }
3179        }
3180        return printed;
3181    }
3182
3183    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3184        if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3185                "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3186        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3187        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3188    }
3189
3190    final void scheduleIdleLocked() {
3191        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3192    }
3193
3194    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3195        if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
3196                + Debug.getCallers(4));
3197        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3198    }
3199
3200    final void scheduleResumeTopActivities() {
3201        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3202            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3203        }
3204    }
3205
3206    void removeSleepTimeouts() {
3207        mSleepTimeout = false;
3208        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3209    }
3210
3211    final void scheduleSleepTimeout() {
3212        removeSleepTimeouts();
3213        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3214    }
3215
3216    @Override
3217    public void onDisplayAdded(int displayId) {
3218        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
3219        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3220    }
3221
3222    @Override
3223    public void onDisplayRemoved(int displayId) {
3224        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
3225        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3226    }
3227
3228    @Override
3229    public void onDisplayChanged(int displayId) {
3230        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
3231        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3232    }
3233
3234    private void handleDisplayAdded(int displayId) {
3235        boolean newDisplay;
3236        synchronized (mService) {
3237            newDisplay = mActivityDisplays.get(displayId) == null;
3238            if (newDisplay) {
3239                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3240                if (activityDisplay.mDisplay == null) {
3241                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3242                    return;
3243                }
3244                mActivityDisplays.put(displayId, activityDisplay);
3245                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
3246            }
3247        }
3248        if (newDisplay) {
3249            mWindowManager.onDisplayAdded(displayId);
3250        }
3251    }
3252
3253    private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
3254        mDefaultMinimalSizeOfResizeableTask =
3255                mService.mContext.getResources().getDimensionPixelSize(
3256                        com.android.internal.R.dimen.default_minimal_size_resizable_task);
3257    }
3258
3259    private void handleDisplayRemoved(int displayId) {
3260        synchronized (mService) {
3261            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3262            if (activityDisplay != null) {
3263                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3264                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3265                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3266                }
3267                mActivityDisplays.remove(displayId);
3268            }
3269        }
3270        mWindowManager.onDisplayRemoved(displayId);
3271    }
3272
3273    private void handleDisplayChanged(int displayId) {
3274        synchronized (mService) {
3275            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3276            if (activityDisplay != null) {
3277                // TODO: Update the bounds.
3278            }
3279        }
3280        mWindowManager.onDisplayChanged(displayId);
3281    }
3282
3283    private StackInfo getStackInfoLocked(ActivityStack stack) {
3284        StackInfo info = new StackInfo();
3285        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3286        info.displayId = Display.DEFAULT_DISPLAY;
3287        info.stackId = stack.mStackId;
3288        info.userId = stack.mCurrentUser;
3289
3290        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3291        final int numTasks = tasks.size();
3292        int[] taskIds = new int[numTasks];
3293        String[] taskNames = new String[numTasks];
3294        Rect[] taskBounds = new Rect[numTasks];
3295        int[] taskUserIds = new int[numTasks];
3296        for (int i = 0; i < numTasks; ++i) {
3297            final TaskRecord task = tasks.get(i);
3298            taskIds[i] = task.taskId;
3299            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3300                    : task.realActivity != null ? task.realActivity.flattenToString()
3301                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3302                    : "unknown";
3303            taskBounds[i] = new Rect();
3304            mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
3305            taskUserIds[i] = task.userId;
3306        }
3307        info.taskIds = taskIds;
3308        info.taskNames = taskNames;
3309        info.taskBounds = taskBounds;
3310        info.taskUserIds = taskUserIds;
3311        return info;
3312    }
3313
3314    StackInfo getStackInfoLocked(int stackId) {
3315        ActivityStack stack = getStack(stackId);
3316        if (stack != null) {
3317            return getStackInfoLocked(stack);
3318        }
3319        return null;
3320    }
3321
3322    ArrayList<StackInfo> getAllStackInfosLocked() {
3323        ArrayList<StackInfo> list = new ArrayList<>();
3324        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3325            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3326            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3327                list.add(getStackInfoLocked(stacks.get(ndx)));
3328            }
3329        }
3330        return list;
3331    }
3332
3333    TaskRecord getLockedTaskLocked() {
3334        final int top = mLockTaskModeTasks.size() - 1;
3335        if (top >= 0) {
3336            return mLockTaskModeTasks.get(top);
3337        }
3338        return null;
3339    }
3340
3341    boolean isLockedTask(TaskRecord task) {
3342        return mLockTaskModeTasks.contains(task);
3343    }
3344
3345    boolean isLastLockedTask(TaskRecord task) {
3346        return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
3347    }
3348
3349    void removeLockedTaskLocked(final TaskRecord task) {
3350        if (!mLockTaskModeTasks.remove(task)) {
3351            return;
3352        }
3353        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
3354        if (mLockTaskModeTasks.isEmpty()) {
3355            // Last one.
3356            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
3357                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
3358            final Message lockTaskMsg = Message.obtain();
3359            lockTaskMsg.arg1 = task.userId;
3360            lockTaskMsg.what = LOCK_TASK_END_MSG;
3361            mHandler.sendMessage(lockTaskMsg);
3362        }
3363    }
3364
3365    void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) {
3366        handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId,
3367                false /* forceNonResizable */);
3368    }
3369
3370    void handleNonResizableTaskIfNeeded(
3371            TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) {
3372        if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
3373                || task.isHomeTask()) {
3374            return;
3375        }
3376
3377        if (!task.canGoInDockedStack() || forceNonResizable) {
3378            // Display a warning toast that we tried to put a non-dockable task in the docked stack.
3379            mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
3380
3381            // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
3382            // we need to move it to top of fullscreen stack, otherwise it will be covered.
3383            mService.moveTasksToFullscreenStack(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID);
3384        } else if (task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) {
3385            String packageName = task.getTopActivity() != null
3386                    ? task.getTopActivity().appInfo.packageName : null;
3387            mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0,
3388                    packageName).sendToTarget();
3389        }
3390    }
3391
3392    void showLockTaskToast() {
3393        mLockTaskNotify.showToast(mLockTaskModeState);
3394    }
3395
3396    void showLockTaskEscapeMessageLocked(TaskRecord task) {
3397        if (mLockTaskModeTasks.contains(task)) {
3398            mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
3399        }
3400    }
3401
3402    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
3403            boolean andResume) {
3404        if (task == null) {
3405            // Take out of lock task mode if necessary
3406            final TaskRecord lockedTask = getLockedTaskLocked();
3407            if (lockedTask != null) {
3408                removeLockedTaskLocked(lockedTask);
3409                if (!mLockTaskModeTasks.isEmpty()) {
3410                    // There are locked tasks remaining, can only finish this task, not unlock it.
3411                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3412                            "setLockTaskModeLocked: Tasks remaining, can't unlock");
3413                    lockedTask.performClearTaskLocked();
3414                    resumeFocusedStackTopActivityLocked();
3415                    return;
3416                }
3417            }
3418            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3419                    "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
3420            return;
3421        }
3422
3423        // Should have already been checked, but do it again.
3424        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
3425            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3426                    "setLockTaskModeLocked: Can't lock due to auth");
3427            return;
3428        }
3429        if (isLockTaskModeViolation(task)) {
3430            Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
3431            return;
3432        }
3433
3434        if (mLockTaskModeTasks.isEmpty()) {
3435            // First locktask.
3436            final Message lockTaskMsg = Message.obtain();
3437            lockTaskMsg.obj = task.intent.getComponent().getPackageName();
3438            lockTaskMsg.arg1 = task.userId;
3439            lockTaskMsg.what = LOCK_TASK_START_MSG;
3440            lockTaskMsg.arg2 = lockTaskModeState;
3441            mHandler.sendMessage(lockTaskMsg);
3442        }
3443        // Add it or move it to the top.
3444        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
3445                " Callers=" + Debug.getCallers(4));
3446        mLockTaskModeTasks.remove(task);
3447        mLockTaskModeTasks.add(task);
3448
3449        if (task.mLockTaskUid == -1) {
3450            task.mLockTaskUid = task.effectiveUid;
3451        }
3452
3453        if (andResume) {
3454            findTaskToMoveToFrontLocked(task, 0, null, reason,
3455                    lockTaskModeState != LOCK_TASK_MODE_NONE);
3456            resumeFocusedStackTopActivityLocked();
3457        } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
3458            handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId,
3459                    true /* forceNonResizable */);
3460        }
3461    }
3462
3463    boolean isLockTaskModeViolation(TaskRecord task) {
3464        return isLockTaskModeViolation(task, false);
3465    }
3466
3467    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
3468        if (getLockedTaskLocked() == task && !isNewClearTask) {
3469            return false;
3470        }
3471        final int lockTaskAuth = task.mLockTaskAuth;
3472        switch (lockTaskAuth) {
3473            case LOCK_TASK_AUTH_DONT_LOCK:
3474                return !mLockTaskModeTasks.isEmpty();
3475            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
3476            case LOCK_TASK_AUTH_LAUNCHABLE:
3477            case LOCK_TASK_AUTH_WHITELISTED:
3478                return false;
3479            case LOCK_TASK_AUTH_PINNABLE:
3480                // Pinnable tasks can't be launched on top of locktask tasks.
3481                return !mLockTaskModeTasks.isEmpty();
3482            default:
3483                Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
3484                return true;
3485        }
3486    }
3487
3488    void onLockTaskPackagesUpdatedLocked() {
3489        boolean didSomething = false;
3490        for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
3491            final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
3492            final boolean wasWhitelisted =
3493                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3494                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3495            lockedTask.setLockTaskAuth();
3496            final boolean isWhitelisted =
3497                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3498                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3499            if (wasWhitelisted && !isWhitelisted) {
3500                // Lost whitelisting authorization. End it now.
3501                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
3502                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
3503                removeLockedTaskLocked(lockedTask);
3504                lockedTask.performClearTaskLocked();
3505                didSomething = true;
3506            }
3507        }
3508        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3509            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3510            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3511                final ActivityStack stack = stacks.get(stackNdx);
3512                stack.onLockTaskPackagesUpdatedLocked();
3513            }
3514        }
3515        final ActivityRecord r = topRunningActivityLocked();
3516        final TaskRecord task = r != null ? r.task : null;
3517        if (mLockTaskModeTasks.isEmpty() && task != null
3518                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
3519            // This task must have just been authorized.
3520            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
3521                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
3522            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
3523                    false);
3524            didSomething = true;
3525        }
3526        if (didSomething) {
3527            resumeFocusedStackTopActivityLocked();
3528        }
3529    }
3530
3531    int getLockTaskModeState() {
3532        return mLockTaskModeState;
3533    }
3534
3535    void activityRelaunchedLocked(IBinder token) {
3536        mWindowManager.notifyAppRelaunchingFinished(token);
3537    }
3538
3539    void activityRelaunchingLocked(ActivityRecord r) {
3540        mWindowManager.notifyAppRelaunching(r.appToken);
3541    }
3542
3543    void logStackState() {
3544        mActivityMetricsLogger.logWindowState();
3545    }
3546
3547    void scheduleReportMultiWindowModeChanged(TaskRecord task) {
3548        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3549            final ActivityRecord r = task.mActivities.get(i);
3550            if (r.app != null && r.app.thread != null) {
3551                mMultiWindowModeChangedActivities.add(r);
3552            }
3553        }
3554
3555        if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
3556            mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
3557        }
3558    }
3559
3560    void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) {
3561        final ActivityStack stack = task.stack;
3562        if (prevStack == null || prevStack == stack
3563                || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
3564            return;
3565        }
3566
3567        for (int i = task.mActivities.size() - 1; i >= 0; i--) {
3568            final ActivityRecord r = task.mActivities.get(i);
3569            if (r.app != null && r.app.thread != null) {
3570                mPipModeChangedActivities.add(r);
3571            }
3572        }
3573
3574        if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
3575            mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
3576        }
3577    }
3578
3579    private final class ActivityStackSupervisorHandler extends Handler {
3580
3581        public ActivityStackSupervisorHandler(Looper looper) {
3582            super(looper);
3583        }
3584
3585        void activityIdleInternal(ActivityRecord r) {
3586            synchronized (mService) {
3587                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3588            }
3589        }
3590
3591        @Override
3592        public void handleMessage(Message msg) {
3593            switch (msg.what) {
3594                case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
3595                    synchronized (mService) {
3596                        for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
3597                            final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
3598                            r.scheduleMultiWindowModeChanged();
3599                        }
3600                    }
3601                } break;
3602                case REPORT_PIP_MODE_CHANGED_MSG: {
3603                    synchronized (mService) {
3604                        for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
3605                            final ActivityRecord r = mPipModeChangedActivities.remove(i);
3606                            r.schedulePictureInPictureModeChanged();
3607                        }
3608                    }
3609                } break;
3610                case IDLE_TIMEOUT_MSG: {
3611                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3612                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3613                    if (mService.mDidDexOpt) {
3614                        mService.mDidDexOpt = false;
3615                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3616                        nmsg.obj = msg.obj;
3617                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3618                        return;
3619                    }
3620                    // We don't at this point know if the activity is fullscreen,
3621                    // so we need to be conservative and assume it isn't.
3622                    activityIdleInternal((ActivityRecord)msg.obj);
3623                } break;
3624                case IDLE_NOW_MSG: {
3625                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3626                    activityIdleInternal((ActivityRecord)msg.obj);
3627                } break;
3628                case RESUME_TOP_ACTIVITY_MSG: {
3629                    synchronized (mService) {
3630                        resumeFocusedStackTopActivityLocked();
3631                    }
3632                } break;
3633                case SLEEP_TIMEOUT_MSG: {
3634                    synchronized (mService) {
3635                        if (mService.isSleepingOrShuttingDown()) {
3636                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3637                            mSleepTimeout = true;
3638                            checkReadyForSleepLocked();
3639                        }
3640                    }
3641                } break;
3642                case LAUNCH_TIMEOUT_MSG: {
3643                    if (mService.mDidDexOpt) {
3644                        mService.mDidDexOpt = false;
3645                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3646                        return;
3647                    }
3648                    synchronized (mService) {
3649                        if (mLaunchingActivity.isHeld()) {
3650                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3651                            if (VALIDATE_WAKE_LOCK_CALLER
3652                                    && Binder.getCallingUid() != Process.myUid()) {
3653                                throw new IllegalStateException("Calling must be system uid");
3654                            }
3655                            mLaunchingActivity.release();
3656                        }
3657                    }
3658                } break;
3659                case HANDLE_DISPLAY_ADDED: {
3660                    handleDisplayAdded(msg.arg1);
3661                } break;
3662                case HANDLE_DISPLAY_CHANGED: {
3663                    handleDisplayChanged(msg.arg1);
3664                } break;
3665                case HANDLE_DISPLAY_REMOVED: {
3666                    handleDisplayRemoved(msg.arg1);
3667                } break;
3668                case CONTAINER_CALLBACK_VISIBILITY: {
3669                    final ActivityContainer container = (ActivityContainer) msg.obj;
3670                    final IActivityContainerCallback callback = container.mCallback;
3671                    if (callback != null) {
3672                        try {
3673                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3674                        } catch (RemoteException e) {
3675                        }
3676                    }
3677                } break;
3678                case LOCK_TASK_START_MSG: {
3679                    // When lock task starts, we disable the status bars.
3680                    try {
3681                        if (mLockTaskNotify == null) {
3682                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3683                        }
3684                        mLockTaskNotify.show(true);
3685                        mLockTaskModeState = msg.arg2;
3686                        if (getStatusBarService() != null) {
3687                            int flags = 0;
3688                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
3689                                flags = StatusBarManager.DISABLE_MASK
3690                                        & (~StatusBarManager.DISABLE_BACK);
3691                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
3692                                flags = StatusBarManager.DISABLE_MASK
3693                                        & (~StatusBarManager.DISABLE_BACK)
3694                                        & (~StatusBarManager.DISABLE_HOME)
3695                                        & (~StatusBarManager.DISABLE_RECENT);
3696                            }
3697                            getStatusBarService().disable(flags, mToken,
3698                                    mService.mContext.getPackageName());
3699                        }
3700                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3701                        if (getDevicePolicyManager() != null) {
3702                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3703                                    (String)msg.obj, msg.arg1);
3704                        }
3705                    } catch (RemoteException ex) {
3706                        throw new RuntimeException(ex);
3707                    }
3708                } break;
3709                case LOCK_TASK_END_MSG: {
3710                    // When lock task ends, we enable the status bars.
3711                    try {
3712                        if (getStatusBarService() != null) {
3713                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3714                                    mService.mContext.getPackageName());
3715                        }
3716                        mWindowManager.reenableKeyguard(mToken);
3717                        if (getDevicePolicyManager() != null) {
3718                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3719                                    msg.arg1);
3720                        }
3721                        if (mLockTaskNotify == null) {
3722                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3723                        }
3724                        mLockTaskNotify.show(false);
3725                        try {
3726                            boolean shouldLockKeyguard = Settings.Secure.getInt(
3727                                    mService.mContext.getContentResolver(),
3728                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
3729                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
3730                                mWindowManager.lockNow(null);
3731                                mWindowManager.dismissKeyguard();
3732                                new LockPatternUtils(mService.mContext)
3733                                        .requireCredentialEntry(UserHandle.USER_ALL);
3734                            }
3735                        } catch (SettingNotFoundException e) {
3736                            // No setting, don't lock.
3737                        }
3738                    } catch (RemoteException ex) {
3739                        throw new RuntimeException(ex);
3740                    } finally {
3741                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
3742                    }
3743                } break;
3744                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
3745                    if (mLockTaskNotify == null) {
3746                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
3747                    }
3748                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
3749                } break;
3750                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3751                    final ActivityContainer container = (ActivityContainer) msg.obj;
3752                    final IActivityContainerCallback callback = container.mCallback;
3753                    if (callback != null) {
3754                        try {
3755                            callback.onAllActivitiesComplete(container.asBinder());
3756                        } catch (RemoteException e) {
3757                        }
3758                    }
3759                } break;
3760                case LAUNCH_TASK_BEHIND_COMPLETE: {
3761                    synchronized (mService) {
3762                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
3763                        if (r != null) {
3764                            handleLaunchTaskBehindCompleteLocked(r);
3765                        }
3766                    }
3767                } break;
3768
3769            }
3770        }
3771    }
3772
3773    class ActivityContainer extends android.app.IActivityContainer.Stub {
3774        final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK |
3775                FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3776        final int mStackId;
3777        IActivityContainerCallback mCallback = null;
3778        final ActivityStack mStack;
3779        ActivityRecord mParentActivity = null;
3780        String mIdString;
3781
3782        boolean mVisible = true;
3783
3784        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3785        ActivityDisplay mActivityDisplay;
3786
3787        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3788        final static int CONTAINER_STATE_NO_SURFACE = 1;
3789        final static int CONTAINER_STATE_FINISHING = 2;
3790        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3791
3792        ActivityContainer(int stackId) {
3793            synchronized (mService) {
3794                mStackId = stackId;
3795                mStack = new ActivityStack(this, mRecentTasks);
3796                mIdString = "ActivtyContainer{" + mStackId + "}";
3797                if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
3798            }
3799        }
3800
3801        void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
3802            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
3803                    + " to display=" + activityDisplay + " onTop=" + onTop);
3804            mActivityDisplay = activityDisplay;
3805            mStack.attachDisplay(activityDisplay, onTop);
3806            activityDisplay.attachActivities(mStack, onTop);
3807        }
3808
3809        @Override
3810        public void attachToDisplay(int displayId) {
3811            synchronized (mService) {
3812                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3813                if (activityDisplay == null) {
3814                    return;
3815                }
3816                attachToDisplayLocked(activityDisplay, true);
3817            }
3818        }
3819
3820        @Override
3821        public int getDisplayId() {
3822            synchronized (mService) {
3823                if (mActivityDisplay != null) {
3824                    return mActivityDisplay.mDisplayId;
3825                }
3826            }
3827            return -1;
3828        }
3829
3830        @Override
3831        public int getStackId() {
3832            synchronized (mService) {
3833                return mStackId;
3834            }
3835        }
3836
3837        @Override
3838        public boolean injectEvent(InputEvent event) {
3839            final long origId = Binder.clearCallingIdentity();
3840            try {
3841                synchronized (mService) {
3842                    if (mActivityDisplay != null) {
3843                        return mInputManagerInternal.injectInputEvent(event,
3844                                mActivityDisplay.mDisplayId,
3845                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3846                    }
3847                }
3848                return false;
3849            } finally {
3850                Binder.restoreCallingIdentity(origId);
3851            }
3852        }
3853
3854        @Override
3855        public void release() {
3856            synchronized (mService) {
3857                if (mContainerState == CONTAINER_STATE_FINISHING) {
3858                    return;
3859                }
3860                mContainerState = CONTAINER_STATE_FINISHING;
3861
3862                long origId = Binder.clearCallingIdentity();
3863                try {
3864                    mStack.finishAllActivitiesLocked(false);
3865                    mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack);
3866                } finally {
3867                    Binder.restoreCallingIdentity(origId);
3868                }
3869            }
3870        }
3871
3872        protected void detachLocked() {
3873            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
3874                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3875            if (mActivityDisplay != null) {
3876                mActivityDisplay.detachActivitiesLocked(mStack);
3877                mActivityDisplay = null;
3878                mStack.detachDisplay();
3879            }
3880        }
3881
3882        @Override
3883        public final int startActivity(Intent intent) {
3884            return mService.startActivity(intent, this);
3885        }
3886
3887        @Override
3888        public final int startActivityIntentSender(IIntentSender intentSender)
3889                throws TransactionTooLargeException {
3890            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3891
3892            if (!(intentSender instanceof PendingIntentRecord)) {
3893                throw new IllegalArgumentException("Bad PendingIntent object");
3894            }
3895
3896            final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
3897                    Binder.getCallingUid(), mCurrentUser, false,
3898                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3899
3900            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3901            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
3902                    pendingIntent.key.requestResolvedType);
3903
3904            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
3905                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3906        }
3907
3908        void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
3909            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
3910            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3911                throw new SecurityException(
3912                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3913            }
3914        }
3915
3916        @Override
3917        public IBinder asBinder() {
3918            return this;
3919        }
3920
3921        @Override
3922        public void setSurface(Surface surface, int width, int height, int density) {
3923            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3924        }
3925
3926        ActivityStackSupervisor getOuter() {
3927            return ActivityStackSupervisor.this;
3928        }
3929
3930        boolean isAttachedLocked() {
3931            return mActivityDisplay != null;
3932        }
3933
3934        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3935        void setVisible(boolean visible) {
3936            if (mVisible != visible) {
3937                mVisible = visible;
3938                if (mCallback != null) {
3939                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3940                            0 /* unused */, this).sendToTarget();
3941                }
3942            }
3943        }
3944
3945        void setDrawn() {
3946        }
3947
3948        // You can always start a new task on a regular ActivityStack.
3949        boolean isEligibleForNewTasks() {
3950            return true;
3951        }
3952
3953        void onTaskListEmptyLocked() {
3954            detachLocked();
3955            deleteActivityContainer(this);
3956            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3957        }
3958
3959        @Override
3960        public String toString() {
3961            return mIdString + (mActivityDisplay == null ? "N" : "A");
3962        }
3963    }
3964
3965    private class VirtualActivityContainer extends ActivityContainer {
3966        Surface mSurface;
3967        boolean mDrawn = false;
3968
3969        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3970            super(getNextStackId());
3971            mParentActivity = parent;
3972            mCallback = callback;
3973            mContainerState = CONTAINER_STATE_NO_SURFACE;
3974            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3975        }
3976
3977        @Override
3978        public void setSurface(Surface surface, int width, int height, int density) {
3979            super.setSurface(surface, width, height, density);
3980
3981            synchronized (mService) {
3982                final long origId = Binder.clearCallingIdentity();
3983                try {
3984                    setSurfaceLocked(surface, width, height, density);
3985                } finally {
3986                    Binder.restoreCallingIdentity(origId);
3987                }
3988            }
3989        }
3990
3991        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3992            if (mContainerState == CONTAINER_STATE_FINISHING) {
3993                return;
3994            }
3995            VirtualActivityDisplay virtualActivityDisplay =
3996                    (VirtualActivityDisplay) mActivityDisplay;
3997            if (virtualActivityDisplay == null) {
3998                virtualActivityDisplay =
3999                        new VirtualActivityDisplay(width, height, density);
4000                mActivityDisplay = virtualActivityDisplay;
4001                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
4002                attachToDisplayLocked(virtualActivityDisplay, true);
4003            }
4004
4005            if (mSurface != null) {
4006                mSurface.release();
4007            }
4008
4009            mSurface = surface;
4010            if (surface != null) {
4011                resumeFocusedStackTopActivityLocked();
4012            } else {
4013                mContainerState = CONTAINER_STATE_NO_SURFACE;
4014                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
4015                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
4016                    mStack.startPausingLocked(false, true, false, false);
4017                }
4018            }
4019
4020            setSurfaceIfReadyLocked();
4021
4022            if (DEBUG_STACK) Slog.d(TAG_STACK,
4023                    "setSurface: " + this + " to display=" + virtualActivityDisplay);
4024        }
4025
4026        @Override
4027        boolean isAttachedLocked() {
4028            return mSurface != null && super.isAttachedLocked();
4029        }
4030
4031        @Override
4032        void setDrawn() {
4033            synchronized (mService) {
4034                mDrawn = true;
4035                setSurfaceIfReadyLocked();
4036            }
4037        }
4038
4039        // Never start a new task on an ActivityView if it isn't explicitly specified.
4040        @Override
4041        boolean isEligibleForNewTasks() {
4042            return false;
4043        }
4044
4045        private void setSurfaceIfReadyLocked() {
4046            if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
4047                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
4048            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
4049                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
4050                mContainerState = CONTAINER_STATE_HAS_SURFACE;
4051            }
4052        }
4053    }
4054
4055    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
4056     * attached {@link ActivityStack}s */
4057    class ActivityDisplay {
4058        /** Actual Display this object tracks. */
4059        int mDisplayId;
4060        Display mDisplay;
4061        DisplayInfo mDisplayInfo = new DisplayInfo();
4062
4063        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
4064         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
4065        final ArrayList<ActivityStack> mStacks = new ArrayList<>();
4066
4067        ActivityRecord mVisibleBehindActivity;
4068
4069        ActivityDisplay() {
4070        }
4071
4072        // After instantiation, check that mDisplay is not null before using this. The alternative
4073        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
4074        ActivityDisplay(int displayId) {
4075            final Display display = mDisplayManager.getDisplay(displayId);
4076            if (display == null) {
4077                return;
4078            }
4079            init(display);
4080        }
4081
4082        void init(Display display) {
4083            mDisplay = display;
4084            mDisplayId = display.getDisplayId();
4085            mDisplay.getDisplayInfo(mDisplayInfo);
4086        }
4087
4088        void attachActivities(ActivityStack stack, boolean onTop) {
4089            if (DEBUG_STACK) Slog.v(TAG_STACK,
4090                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId
4091                    + " onTop=" + onTop);
4092            if (onTop) {
4093                mStacks.add(stack);
4094            } else {
4095                mStacks.add(0, stack);
4096            }
4097        }
4098
4099        void detachActivitiesLocked(ActivityStack stack) {
4100            if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
4101                    + " from displayId=" + mDisplayId);
4102            mStacks.remove(stack);
4103        }
4104
4105        void setVisibleBehindActivity(ActivityRecord r) {
4106            mVisibleBehindActivity = r;
4107        }
4108
4109        boolean hasVisibleBehindActivity() {
4110            return mVisibleBehindActivity != null;
4111        }
4112
4113        @Override
4114        public String toString() {
4115            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4116        }
4117    }
4118
4119    class VirtualActivityDisplay extends ActivityDisplay {
4120        VirtualDisplay mVirtualDisplay;
4121
4122        VirtualActivityDisplay(int width, int height, int density) {
4123            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4124            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4125                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4126                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4127                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4128
4129            init(mVirtualDisplay.getDisplay());
4130
4131            mWindowManager.handleDisplayAdded(mDisplayId);
4132        }
4133
4134        void setSurface(Surface surface) {
4135            if (mVirtualDisplay != null) {
4136                mVirtualDisplay.setSurface(surface);
4137            }
4138        }
4139
4140        @Override
4141        void detachActivitiesLocked(ActivityStack stack) {
4142            super.detachActivitiesLocked(stack);
4143            if (mVirtualDisplay != null) {
4144                mVirtualDisplay.release();
4145                mVirtualDisplay = null;
4146            }
4147        }
4148
4149        @Override
4150        public String toString() {
4151            return "VirtualActivityDisplay={" + mDisplayId + "}";
4152        }
4153    }
4154
4155    /**
4156     * Adjust bounds to stay within stack bounds.
4157     *
4158     * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
4159     * that keep them unchanged, but be contained within the stack bounds.
4160     *
4161     * @param bounds Bounds to be adjusted.
4162     * @param stackBounds Bounds within which the other bounds should remain.
4163     */
4164    private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
4165        if (stackBounds == null || stackBounds.contains(bounds)) {
4166            return;
4167        }
4168
4169        if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
4170            final int maxRight = stackBounds.right
4171                    - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
4172            int horizontalDiff = stackBounds.left - bounds.left;
4173            if ((horizontalDiff < 0 && bounds.left >= maxRight)
4174                    || (bounds.left + horizontalDiff >= maxRight)) {
4175                horizontalDiff = maxRight - bounds.left;
4176            }
4177            bounds.left += horizontalDiff;
4178            bounds.right += horizontalDiff;
4179        }
4180
4181        if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
4182            final int maxBottom = stackBounds.bottom
4183                    - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
4184            int verticalDiff = stackBounds.top - bounds.top;
4185            if ((verticalDiff < 0 && bounds.top >= maxBottom)
4186                    || (bounds.top + verticalDiff >= maxBottom)) {
4187                verticalDiff = maxBottom - bounds.top;
4188            }
4189            bounds.top += verticalDiff;
4190            bounds.bottom += verticalDiff;
4191        }
4192    }
4193
4194    ActivityStack findStackBehind(ActivityStack stack) {
4195        // TODO(multi-display): We are only looking for stacks on the default display.
4196        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
4197        if (display == null) {
4198            return null;
4199        }
4200        final ArrayList<ActivityStack> stacks = display.mStacks;
4201        for (int i = stacks.size() - 1; i >= 0; i--) {
4202            if (stacks.get(i) == stack && i > 0) {
4203                return stacks.get(i - 1);
4204            }
4205        }
4206        throw new IllegalStateException("Failed to find a stack behind stack=" + stack
4207                + " in=" + stacks);
4208    }
4209
4210    /**
4211     * Puts a task into resizing mode during the next app transition.
4212     *
4213     * @param taskId the id of the task to put into resizing mode
4214     */
4215    private void setResizingDuringAnimation(int taskId) {
4216        mResizingTasksDuringAnimation.add(taskId);
4217        mWindowManager.setTaskDockedResizing(taskId, true);
4218    }
4219
4220    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4221        final TaskRecord task;
4222        final int callingUid;
4223        final String callingPackage;
4224        final Intent intent;
4225        final int userId;
4226        final ActivityOptions activityOptions = (bOptions != null)
4227                ? new ActivityOptions(bOptions) : null;
4228        final int launchStackId = (activityOptions != null)
4229                ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4230
4231        if (launchStackId == HOME_STACK_ID) {
4232            throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4233                    + taskId + " can't be launch in the home stack.");
4234        }
4235        task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4236        if (task == null) {
4237            throw new IllegalArgumentException(
4238                    "startActivityFromRecentsInner: Task " + taskId + " not found.");
4239        }
4240
4241        if (launchStackId != INVALID_STACK_ID) {
4242            if (launchStackId == DOCKED_STACK_ID) {
4243                mWindowManager.setDockedStackCreateState(
4244                        activityOptions.getDockCreateMode(), null /* initialBounds */);
4245
4246                // Defer updating the stack in which recents is until the app transition is done, to
4247                // not run into issues where we still need to draw the task in recents but the
4248                // docked stack is already created.
4249                deferUpdateBounds(HOME_STACK_ID);
4250                mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
4251            }
4252            if (task.stack.mStackId != launchStackId) {
4253                moveTaskToStackLocked(
4254                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4255                        ANIMATE);
4256            }
4257        }
4258
4259        // If the user must confirm credentials (e.g. when first launching a work app and the
4260        // Work Challenge is present) let startActivityInPackage handle the intercepting.
4261        if (!mService.mUserController.shouldConfirmCredentials(task.userId)
4262                && task.getRootActivity() != null) {
4263            mActivityMetricsLogger.notifyActivityLaunching();
4264            mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
4265
4266            // If we are launching the task in the docked stack, put it into resizing mode so
4267            // the window renders full-screen with the background filling the void. Also only
4268            // call this at the end to make sure that tasks exists on the window manager side.
4269            if (launchStackId == DOCKED_STACK_ID) {
4270                setResizingDuringAnimation(taskId);
4271            }
4272            return ActivityManager.START_TASK_TO_FRONT;
4273        }
4274        callingUid = task.mCallingUid;
4275        callingPackage = task.mCallingPackage;
4276        intent = task.intent;
4277        intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4278        userId = task.userId;
4279            int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
4280                    null, null, 0, 0, bOptions, userId, null, task);
4281            if (launchStackId == DOCKED_STACK_ID) {
4282                setResizingDuringAnimation(task.taskId);
4283            }
4284            return result;
4285    }
4286
4287    /**
4288     * @return a list of activities which are the top ones in each visible stack. The first
4289     * entry will be the focused activity.
4290     */
4291    public List<IBinder> getTopVisibleActivities() {
4292        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
4293        if (display == null) {
4294            return Collections.EMPTY_LIST;
4295        }
4296        ArrayList<IBinder> topActivityTokens = new ArrayList<>();
4297        final ArrayList<ActivityStack> stacks = display.mStacks;
4298        for (int i = stacks.size() - 1; i >= 0; i--) {
4299            ActivityStack stack = stacks.get(i);
4300            if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) {
4301                ActivityRecord top = stack.topActivity();
4302                if (top != null) {
4303                    if (stack == mFocusedStack) {
4304                        topActivityTokens.add(0, top.appToken);
4305                    } else {
4306                        topActivityTokens.add(top.appToken);
4307                    }
4308                }
4309            }
4310        }
4311        return topActivityTokens;
4312    }
4313}
4314