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