OSDN Git Service

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