OSDN Git Service

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