• History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
  • current directory
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.wm;
18 
19 import static android.Manifest.permission.ACTIVITY_EMBEDDING;
20 import static android.Manifest.permission.CAMERA;
21 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
22 import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
23 import static android.Manifest.permission.START_ANY_ACTIVITY;
24 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
25 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
26 import static android.app.ActivityManager.START_FLAG_DEBUG;
27 import static android.app.ActivityManager.START_FLAG_NATIVE_DEBUGGING;
28 import static android.app.ActivityManager.START_FLAG_TRACK_ALLOCATION;
29 import static android.app.ActivityManager.START_TASK_TO_FRONT;
30 import static android.app.ActivityOptions.ANIM_REMOTE_ANIMATION;
31 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
32 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
33 import static android.app.WaitResult.INVALID_DELAY;
34 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
35 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
36 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
37 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
38 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
39 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
40 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
41 import static android.content.pm.PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY;
42 import static android.content.pm.PackageManager.PERMISSION_DENIED;
43 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
44 import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
45 import static android.os.Process.INVALID_UID;
46 import static android.os.Process.SYSTEM_UID;
47 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
48 import static android.view.Display.DEFAULT_DISPLAY;
49 import static android.view.Display.INVALID_DISPLAY;
50 import static android.view.WindowManager.TRANSIT_TO_FRONT;
51 
52 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
53 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
54 import static com.android.server.wm.ActivityRecord.State.PAUSED;
55 import static com.android.server.wm.ActivityRecord.State.PAUSING;
56 import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS;
57 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
58 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
59 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE;
60 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
61 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK;
62 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
63 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IDLE;
64 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
65 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
66 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
67 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
68 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
69 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
70 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
71 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
72 import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_TASK_MSG;
73 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
74 import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED;
75 import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE;
76 import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
77 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
78 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
79 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
80 import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
81 import static com.android.server.wm.Task.TAG_CLEANUP;
82 import static com.android.server.wm.WindowContainer.POSITION_TOP;
83 
84 import android.Manifest;
85 import android.annotation.NonNull;
86 import android.annotation.Nullable;
87 import android.app.Activity;
88 import android.app.ActivityManager;
89 import android.app.ActivityManagerInternal;
90 import android.app.ActivityOptions;
91 import android.app.AppOpsManager;
92 import android.app.AppOpsManagerInternal;
93 import android.app.BackgroundStartPrivileges;
94 import android.app.IActivityClientController;
95 import android.app.ProfilerInfo;
96 import android.app.ResultInfo;
97 import android.app.TaskInfo;
98 import android.app.WaitResult;
99 import android.app.servertransaction.ActivityLifecycleItem;
100 import android.app.servertransaction.ClientTransaction;
101 import android.app.servertransaction.LaunchActivityItem;
102 import android.app.servertransaction.PauseActivityItem;
103 import android.app.servertransaction.ResumeActivityItem;
104 import android.companion.virtual.VirtualDeviceManager;
105 import android.content.ComponentName;
106 import android.content.Context;
107 import android.content.Intent;
108 import android.content.pm.ActivityInfo;
109 import android.content.pm.ApplicationInfo;
110 import android.content.pm.PackageInfo;
111 import android.content.pm.PackageManager;
112 import android.content.pm.PackageManagerInternal;
113 import android.content.pm.ResolveInfo;
114 import android.content.pm.UserInfo;
115 import android.content.res.Configuration;
116 import android.graphics.Rect;
117 import android.hardware.SensorPrivacyManager;
118 import android.hardware.SensorPrivacyManagerInternal;
119 import android.os.Binder;
120 import android.os.Build;
121 import android.os.Bundle;
122 import android.os.Debug;
123 import android.os.Handler;
124 import android.os.IBinder;
125 import android.os.Looper;
126 import android.os.Message;
127 import android.os.PowerManager;
128 import android.os.RemoteException;
129 import android.os.SystemClock;
130 import android.os.Trace;
131 import android.os.UserHandle;
132 import android.os.UserManager;
133 import android.os.WorkSource;
134 import android.provider.MediaStore;
135 import android.util.ArrayMap;
136 import android.util.MergedConfiguration;
137 import android.util.Pair;
138 import android.util.Slog;
139 import android.util.SparseArray;
140 import android.util.SparseIntArray;
141 import android.view.Display;
142 import android.widget.Toast;
143 
144 import com.android.internal.R;
145 import com.android.internal.annotations.GuardedBy;
146 import com.android.internal.annotations.VisibleForTesting;
147 import com.android.internal.content.ReferrerIntent;
148 import com.android.internal.protolog.common.ProtoLog;
149 import com.android.internal.util.ArrayUtils;
150 import com.android.internal.util.FrameworkStatsLog;
151 import com.android.internal.util.function.pooled.PooledLambda;
152 import com.android.server.LocalServices;
153 import com.android.server.UiThread;
154 import com.android.server.am.ActivityManagerService;
155 import com.android.server.am.HostingRecord;
156 import com.android.server.am.UserState;
157 import com.android.server.pm.PackageManagerServiceUtils;
158 import com.android.server.utils.Slogf;
159 import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
160 
161 import java.io.FileDescriptor;
162 import java.io.PrintWriter;
163 import java.util.ArrayList;
164 import java.util.List;
165 import java.util.function.Consumer;
166 import java.util.function.Predicate;
167 
168 // TODO: This class has become a dumping ground. Let's
169 // - Move things relating to the hierarchy to RootWindowContainer
170 // - Move things relating to activity life cycles to maybe a new class called ActivityLifeCycler
171 // - Move interface things to ActivityTaskManagerService.
172 // - All other little things to other files.
173 public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
174     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskSupervisor" : TAG_ATM;
175     private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
176     private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
177     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
178     private static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK;
179     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
180     static final String TAG_TASKS = TAG + POSTFIX_TASKS;
181 
182     /** How long we wait until giving up on the last activity telling us it is idle. */
183     private static final int IDLE_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
184 
185     /** How long we can hold the sleep wake lock before giving up. */
186     private static final int SLEEP_TIMEOUT = 5 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
187 
188     // How long we can hold the launch wake lock before giving up.
189     private static final int LAUNCH_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
190 
191     // How long we delay processing the stopping and finishing activities.
192     private static final int SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS = 200;
193 
194     /** How long we wait until giving up on the activity telling us it released the top state. */
195     private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
196 
197     /**
198      * The timeout to kill task processes if its activity didn't complete destruction in time
199      * when there is a request to remove the task with killProcess=true.
200      */
201     private static final int KILL_TASK_PROCESSES_TIMEOUT_MS = 1000;
202 
203     private static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG;
204     private static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_TASK_MSG + 1;
205     private static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_TASK_MSG + 2;
206     private static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 3;
207     private static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 4;
208     private static final int PROCESS_STOPPING_AND_FINISHING_MSG = FIRST_SUPERVISOR_TASK_MSG + 5;
209     private static final int KILL_TASK_PROCESSES_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 6;
210     private static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_TASK_MSG + 12;
211     private static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 13;
212     private static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_TASK_MSG + 14;
213     private static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_TASK_MSG + 15;
214     private static final int START_HOME_MSG = FIRST_SUPERVISOR_TASK_MSG + 16;
215     private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 17;
216 
217     // Used to indicate that windows of activities should be preserved during the resize.
218     static final boolean PRESERVE_WINDOWS = true;
219 
220     // Used to indicate if an object (e.g. task) should be moved/created
221     // at the top of its container (e.g. root task).
222     static final boolean ON_TOP = true;
223 
224     // Don't execute any calls to resume.
225     static final boolean DEFER_RESUME = true;
226 
227     // Used to indicate that a task is removed it should also be removed from recents.
228     static final boolean REMOVE_FROM_RECENTS = true;
229 
230     // Activity actions an app cannot start if it uses a permission which is not granted.
231     private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
232             new ArrayMap<>();
233 
234     static {
ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, Manifest.permission.CAMERA)235         ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE,
236                 Manifest.permission.CAMERA);
ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, Manifest.permission.CAMERA)237         ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE,
238                 Manifest.permission.CAMERA);
ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, Manifest.permission.CALL_PHONE)239         ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL,
240                 Manifest.permission.CALL_PHONE);
241     }
242 
243     /** Action restriction: launching the activity is not restricted. */
244     private static final int ACTIVITY_RESTRICTION_NONE = 0;
245     /** Action restriction: launching the activity is restricted by a permission. */
246     private static final int ACTIVITY_RESTRICTION_PERMISSION = 1;
247     /** Action restriction: launching the activity is restricted by an app op. */
248     private static final int ACTIVITY_RESTRICTION_APPOP = 2;
249 
250     // For debugging to make sure the caller when acquiring/releasing our
251     // wake lock is the system process.
252     private static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
253     /** The number of distinct task ids that can be assigned to the tasks of a single user */
254     private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;
255 
256     final ActivityTaskManagerService mService;
257     RootWindowContainer mRootWindowContainer;
258 
259     /** The historial list of recent tasks including inactive tasks */
260     RecentTasks mRecentTasks;
261 
262     /** Helper class to abstract out logic for fetching the set of currently running tasks */
263     private RunningTasks mRunningTasks;
264 
265     /** Helper for {@link Task#fillTaskInfo}. */
266     final TaskInfoHelper mTaskInfoHelper = new TaskInfoHelper();
267 
268     final OpaqueActivityHelper mOpaqueActivityHelper = new OpaqueActivityHelper();
269 
270     private final ActivityTaskSupervisorHandler mHandler;
271     final Looper mLooper;
272 
273     /** Short cut */
274     private WindowManagerService mWindowManager;
275 
276     private AppOpsManager mAppOpsManager;
277     private VirtualDeviceManager mVirtualDeviceManager;
278 
279     /** Common synchronization logic used to save things to disks. */
280     PersisterQueue mPersisterQueue;
281     LaunchParamsPersister mLaunchParamsPersister;
282     private LaunchParamsController mLaunchParamsController;
283 
284     /**
285      * The processes with changed states that should eventually call
286      * {@link WindowProcessController#computeProcessActivityState}.
287      */
288     private final ArrayList<WindowProcessController> mActivityStateChangedProcs = new ArrayList<>();
289 
290     /**
291      * Maps the task identifier that activities are currently being started in to the userId of the
292      * task. Each time a new task is created, the entry for the userId of the task is incremented
293      */
294     private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20);
295 
296     /** List of requests waiting for the target activity to be launched or visible. */
297     private final ArrayList<WaitInfo> mWaitingActivityLaunched = new ArrayList<>();
298 
299     /** List of activities that are ready to be stopped, but waiting for the next activity to
300      * settle down before doing so. */
301     final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
302 
303     /** List of activities that are ready to be finished, but waiting for the previous activity to
304      * settle down before doing so.  It contains ActivityRecord objects. */
305     final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
306 
307     /**
308      * Activities that specify No History must be removed once the user navigates away from them.
309      * If the device goes to sleep with such an activity in the paused state then we save it
310      * here and finish it later if another activity replaces it on wakeup.
311      */
312     final ArrayList<ActivityRecord> mNoHistoryActivities = new ArrayList<>();
313 
314     /** List of activities whose multi-window mode changed that we need to report to the
315      * application */
316     private final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>();
317 
318     /** List of activities whose picture-in-picture mode changed that we need to report to the
319      * application */
320     private final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
321 
322     /**
323      * Animations that for the current transition have requested not to
324      * be considered for the transition animation.
325      */
326     final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>();
327 
328     /**
329      * Cached value of the topmost resumed activity in the system. Updated when new activity is
330      * resumed.
331      */
332     private ActivityRecord mTopResumedActivity;
333 
334     /**
335      * Flag indicating whether we're currently waiting for the previous top activity to handle the
336      * loss of the state and report back before making new activity top resumed.
337      */
338     private boolean mTopResumedActivityWaitingForPrev;
339 
340     /** The target root task bounds for the picture-in-picture mode changed that we need to
341      * report to the application */
342     private Rect mPipModeChangedTargetRootTaskBounds;
343 
344     /** Used on user changes */
345     final ArrayList<UserState> mStartingUsers = new ArrayList<>();
346 
347     /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
348      * is being brought in front of us. */
349     boolean mUserLeaving = false;
350 
351     /**
352      * The system chooser activity which worked as a delegate of
353      * {@link com.android.internal.app.ResolverActivity}.
354      */
355     private ComponentName mSystemChooserActivity;
356 
357     /**
358      * We don't want to allow the device to go to sleep while in the process
359      * of launching an activity.  This is primarily to allow alarm intent
360      * receivers to launch an activity and get that to run before the device
361      * goes back to sleep.
362      */
363     PowerManager.WakeLock mLaunchingActivityWakeLock;
364 
365     /**
366      * Set when the system is going to sleep, until we have
367      * successfully paused the current activity and released our wake lock.
368      * At that point the system is allowed to actually sleep.
369      */
370     PowerManager.WakeLock mGoingToSleepWakeLock;
371 
372     /**
373      * Used to keep {@link RootWindowContainer#ensureActivitiesVisible} from being entered
374      * recursively. And only update keyguard states once the nested updates are done.
375      */
376     private int mVisibilityTransactionDepth;
377 
378     /**
379      * Whether to the visibility updates that started from {@code RootWindowContainer} should be
380      * deferred.
381      */
382     private boolean mDeferRootVisibilityUpdate;
383 
384     private ActivityMetricsLogger mActivityMetricsLogger;
385 
386     /** Check if placing task or activity on specified display is allowed. */
canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid, ActivityInfo activityInfo)387     boolean canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid,
388             ActivityInfo activityInfo) {
389         return canPlaceEntityOnDisplay(displayId, callingPid, callingUid, null /* task */,
390                 activityInfo);
391     }
392 
canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid, Task task)393     boolean canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid, Task task) {
394         return canPlaceEntityOnDisplay(displayId, callingPid, callingUid, task,
395                 null /* activityInfo */);
396     }
397 
canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid, Task task, ActivityInfo activityInfo)398     private boolean canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid,
399             Task task, ActivityInfo activityInfo) {
400         if (displayId == DEFAULT_DISPLAY) {
401             // No restrictions for the default display.
402             return true;
403         }
404         if (!mService.mSupportsMultiDisplay) {
405             // Can't launch on secondary displays if feature is not supported.
406             return false;
407         }
408 
409         if (!isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, displayId, activityInfo)) {
410             // Can't place activities to a display that has restricted launch rules.
411             // In this case the request should be made by explicitly adding target display id and
412             // by caller with corresponding permissions. See #isCallerAllowedToLaunchOnDisplay().
413             return false;
414         }
415 
416         final DisplayContent displayContent =
417                 mRootWindowContainer.getDisplayContentOrCreate(displayId);
418         if (displayContent != null) {
419             final ArrayList<ActivityInfo> activities = new ArrayList<>();
420             if (activityInfo != null) {
421                 activities.add(activityInfo);
422             }
423             if (task != null) {
424                 task.forAllActivities((r) -> {
425                     activities.add(r.info);
426                 });
427             }
428             return displayContent.mDwpcHelper.canContainActivities(activities,
429                         displayContent.getWindowingMode());
430         }
431 
432         return true;
433     }
434 
435     /**
436      * Used to keep track whether app visibilities got changed since the last pause. Useful to
437      * determine whether to invoke the task stack change listener after pausing.
438      */
439     boolean mAppVisibilitiesChangedSinceLastPause;
440 
441     private KeyguardController mKeyguardController;
442 
443     private PowerManager mPowerManager;
444     private int mDeferResumeCount;
445 
446     private boolean mInitialized;
447 
ActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper)448     public ActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper) {
449         mService = service;
450         mLooper = looper;
451         mHandler = new ActivityTaskSupervisorHandler(looper);
452     }
453 
initialize()454     public void initialize() {
455         if (mInitialized) {
456             return;
457         }
458 
459         mInitialized = true;
460         setRunningTasks(new RunningTasks());
461 
462         mActivityMetricsLogger = new ActivityMetricsLogger(this, mHandler.getLooper());
463         mKeyguardController = new KeyguardController(mService, this);
464 
465         mPersisterQueue = new PersisterQueue();
466         mLaunchParamsPersister = new LaunchParamsPersister(mPersisterQueue, this);
467         mLaunchParamsController = new LaunchParamsController(mService, mLaunchParamsPersister);
468         mLaunchParamsController.registerDefaultModifiers(this);
469     }
470 
onSystemReady()471     void onSystemReady() {
472         mLaunchParamsPersister.onSystemReady();
473     }
474 
onUserUnlocked(int userId)475     void onUserUnlocked(int userId) {
476         // Only start persisting when the first user is unlocked. The method call is
477         // idempotent so there is no side effect to call it again when the second user is
478         // unlocked.
479         mPersisterQueue.startPersisting();
480         mLaunchParamsPersister.onUnlockUser(userId);
481 
482         // Need to launch home again for those displays that do not have encryption aware home app.
483         scheduleStartHome("userUnlocked");
484     }
485 
getActivityMetricsLogger()486     public ActivityMetricsLogger getActivityMetricsLogger() {
487         return mActivityMetricsLogger;
488     }
489 
getKeyguardController()490     public KeyguardController getKeyguardController() {
491         return mKeyguardController;
492     }
493 
getSystemChooserActivity()494     ComponentName getSystemChooserActivity() {
495         if (mSystemChooserActivity == null) {
496             mSystemChooserActivity = ComponentName.unflattenFromString(
497                     mService.mContext.getResources().getString(R.string.config_chooserActivity));
498         }
499         return mSystemChooserActivity;
500     }
501 
setRecentTasks(RecentTasks recentTasks)502     void setRecentTasks(RecentTasks recentTasks) {
503         if (mRecentTasks != null) {
504             mRecentTasks.unregisterCallback(this);
505         }
506         mRecentTasks = recentTasks;
507         mRecentTasks.registerCallback(this);
508     }
509 
510     @VisibleForTesting
setRunningTasks(RunningTasks runningTasks)511     void setRunningTasks(RunningTasks runningTasks) {
512         mRunningTasks = runningTasks;
513     }
514 
getRunningTasks()515     RunningTasks getRunningTasks() {
516         return mRunningTasks;
517     }
518 
519     /**
520      * At the time when the constructor runs, the power manager has not yet been
521      * initialized.  So we initialize our wakelocks afterwards.
522      */
initPowerManagement()523     void initPowerManagement() {
524         mPowerManager = mService.mContext.getSystemService(PowerManager.class);
525         mGoingToSleepWakeLock = mPowerManager
526                 .newWakeLock(PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
527         mLaunchingActivityWakeLock = mPowerManager.newWakeLock(PARTIAL_WAKE_LOCK, "*launch*");
528         mLaunchingActivityWakeLock.setReferenceCounted(false);
529     }
530 
setWindowManager(WindowManagerService wm)531     void setWindowManager(WindowManagerService wm) {
532         mWindowManager = wm;
533         getKeyguardController().setWindowManager(wm);
534     }
535 
moveRecentsRootTaskToFront(String reason)536     void moveRecentsRootTaskToFront(String reason) {
537         final Task recentsRootTask = mRootWindowContainer.getDefaultTaskDisplayArea()
538                 .getRootTask(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
539         if (recentsRootTask != null) {
540             recentsRootTask.moveToFront(reason);
541         }
542     }
543 
setNextTaskIdForUser(int taskId, int userId)544     void setNextTaskIdForUser(int taskId, int userId) {
545         final int currentTaskId = mCurTaskIdForUser.get(userId, -1);
546         if (taskId > currentTaskId) {
547             mCurTaskIdForUser.put(userId, taskId);
548         }
549     }
550 
finishNoHistoryActivitiesIfNeeded(ActivityRecord next)551     void finishNoHistoryActivitiesIfNeeded(ActivityRecord next) {
552         for (int i = mNoHistoryActivities.size() - 1; i >= 0; --i) {
553             final ActivityRecord noHistoryActivity = mNoHistoryActivities.get(i);
554             if (!noHistoryActivity.finishing && noHistoryActivity != next
555                     && next.occludesParent()
556                     && noHistoryActivity.getDisplayId() == next.getDisplayId()) {
557                 ProtoLog.d(WM_DEBUG_STATES, "no-history finish of %s on new resume",
558                         noHistoryActivity);
559                 noHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */);
560                 mNoHistoryActivities.remove(noHistoryActivity);
561             }
562         }
563     }
564 
nextTaskIdForUser(int taskId, int userId)565     private static int nextTaskIdForUser(int taskId, int userId) {
566         int nextTaskId = taskId + 1;
567         if (nextTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) {
568             // Wrap around as there will be smaller task ids that are available now.
569             nextTaskId -= MAX_TASK_IDS_PER_USER;
570         }
571         return nextTaskId;
572     }
573 
getNextTaskIdForUser()574     int getNextTaskIdForUser() {
575         return getNextTaskIdForUser(mRootWindowContainer.mCurrentUser);
576     }
577 
getNextTaskIdForUser(int userId)578     int getNextTaskIdForUser(int userId) {
579         final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER);
580         // for a userId u, a taskId can only be in the range
581         // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER
582         // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
583         int candidateTaskId = nextTaskIdForUser(currentTaskId, userId);
584         while (mRecentTasks.containsTaskId(candidateTaskId, userId)
585                 || mRootWindowContainer.anyTaskForId(
586                         candidateTaskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS) != null) {
587             candidateTaskId = nextTaskIdForUser(candidateTaskId, userId);
588             if (candidateTaskId == currentTaskId) {
589                 // Something wrong!
590                 // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user
591                 throw new IllegalStateException("Cannot get an available task id."
592                         + " Reached limit of " + MAX_TASK_IDS_PER_USER
593                         + " running tasks per user.");
594             }
595         }
596         mCurTaskIdForUser.put(userId, candidateTaskId);
597         return candidateTaskId;
598     }
599 
waitActivityVisibleOrLaunched(WaitResult w, ActivityRecord r, LaunchingState launchingState)600     void waitActivityVisibleOrLaunched(WaitResult w, ActivityRecord r,
601             LaunchingState launchingState) {
602         if (w.result != ActivityManager.START_TASK_TO_FRONT
603                 && w.result != ActivityManager.START_SUCCESS) {
604             // Not a result code that can make activity visible or launched.
605             return;
606         }
607         final WaitInfo waitInfo = new WaitInfo(w, r.mActivityComponent, launchingState);
608         mWaitingActivityLaunched.add(waitInfo);
609         do {
610             try {
611                 mService.mGlobalLock.wait();
612             } catch (InterruptedException ignored) {
613             }
614         } while (mWaitingActivityLaunched.contains(waitInfo));
615     }
616 
cleanupActivity(ActivityRecord r)617     void cleanupActivity(ActivityRecord r) {
618         // Make sure this record is no longer in the pending finishes list.
619         // This could happen, for example, if we are trimming activities
620         // down to the max limit while they are still waiting to finish.
621         mFinishingActivities.remove(r);
622 
623         stopWaitingForActivityVisible(r);
624     }
625 
626     /** There is no valid launch time, just stop waiting. */
stopWaitingForActivityVisible(ActivityRecord r)627     void stopWaitingForActivityVisible(ActivityRecord r) {
628         reportActivityLaunched(false /* timeout */, r, WaitResult.INVALID_DELAY,
629                 WaitResult.LAUNCH_STATE_UNKNOWN);
630     }
631 
reportActivityLaunched(boolean timeout, ActivityRecord r, long totalTime, @WaitResult.LaunchState int launchState)632     void reportActivityLaunched(boolean timeout, ActivityRecord r, long totalTime,
633             @WaitResult.LaunchState int launchState) {
634         boolean changed = false;
635         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
636             final WaitInfo info = mWaitingActivityLaunched.get(i);
637             if (!info.matches(r)) {
638                 continue;
639             }
640             final WaitResult w = info.mResult;
641             w.timeout = timeout;
642             w.who = r.mActivityComponent;
643             w.totalTime = totalTime;
644             w.launchState = launchState;
645             mWaitingActivityLaunched.remove(i);
646             changed = true;
647         }
648         if (changed) {
649             mService.mGlobalLock.notifyAll();
650         }
651     }
652 
reportWaitingActivityLaunchedIfNeeded(ActivityRecord r, int result)653     void reportWaitingActivityLaunchedIfNeeded(ActivityRecord r, int result) {
654         if (mWaitingActivityLaunched.isEmpty()) {
655             return;
656         }
657 
658         if (result != START_DELIVERED_TO_TOP && result != START_TASK_TO_FRONT) {
659             return;
660         }
661 
662         boolean changed = false;
663 
664         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
665             final WaitInfo info = mWaitingActivityLaunched.get(i);
666             if (!info.matches(r)) {
667                 continue;
668             }
669             final WaitResult w = info.mResult;
670             w.result = result;
671             if (result == START_DELIVERED_TO_TOP) {
672                 // Unlike START_TASK_TO_FRONT, When an intent is delivered to top, there
673                 // will be no followup launch signals. Assign the result and launched component.
674                 w.who = r.mActivityComponent;
675                 mWaitingActivityLaunched.remove(i);
676                 changed = true;
677             }
678         }
679         if (changed) {
680             mService.mGlobalLock.notifyAll();
681         }
682     }
683 
resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, ProfilerInfo profilerInfo)684     ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
685             ProfilerInfo profilerInfo) {
686         final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;
687         if (aInfo != null) {
688             // Store the found target back into the intent, because now that
689             // we have it we never want to do this again.  For example, if the
690             // user navigates back to this point in the history, we should
691             // always restart the exact same activity.
692             intent.setComponent(new ComponentName(
693                     aInfo.applicationInfo.packageName, aInfo.name));
694 
695             final boolean requestDebug = (startFlags & (START_FLAG_DEBUG
696                     | START_FLAG_NATIVE_DEBUGGING | START_FLAG_TRACK_ALLOCATION)) != 0;
697             final boolean requestProfile = profilerInfo != null;
698             if (requestDebug || requestProfile) {
699                 final boolean debuggable = (Build.IS_DEBUGGABLE
700                         || (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0)
701                         && !aInfo.processName.equals("system");
702                 if ((requestDebug && !debuggable) || (requestProfile
703                         && (!debuggable && !aInfo.applicationInfo.isProfileableByShell()))) {
704                     Slog.w(TAG, "Ignore debugging for non-debuggable app: " + aInfo.packageName);
705                 } else {
706                      // Mimic an AMS synchronous call by passing a message to AMS and wait for AMS
707                      // to notify us that the task has completed.
708                      // TODO(b/80414790) look into further untangling for the situation where the
709                      // caller is on the same thread as the handler we are posting to.
710                     synchronized (mService.mGlobalLock) {
711                         // Post message to AMS.
712                         mService.mH.post(() -> {
713                             try {
714                                 mService.mAmInternal.setDebugFlagsForStartingActivity(aInfo,
715                                         startFlags, profilerInfo, mService.mGlobalLock);
716                             } catch (Throwable e) {
717                                 // Simply ignore it because the debugging doesn't take effect.
718                                 Slog.w(TAG, e);
719                                 synchronized (mService.mGlobalLockWithoutBoost) {
720                                     mService.mGlobalLockWithoutBoost.notifyAll();
721                                 }
722                             }
723                         });
724                         try {
725                             mService.mGlobalLock.wait();
726                         } catch (InterruptedException ignore) {
727 
728                         }
729                     }
730                 }
731             }
732             final String intentLaunchToken = intent.getLaunchToken();
733             if (aInfo.launchToken == null && intentLaunchToken != null) {
734                 aInfo.launchToken = intentLaunchToken;
735             }
736         }
737         return aInfo;
738     }
739 
resolveIntent(Intent intent, String resolvedType, int userId, int flags, int filterCallingUid, int callingPid)740     ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
741             int filterCallingUid, int callingPid) {
742         try {
743             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "resolveIntent");
744             int modifiedFlags = flags
745                     | PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS;
746             if (intent.isWebIntent()
747                         || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
748                 modifiedFlags |= PackageManager.MATCH_INSTANT;
749             }
750             int privateResolveFlags  = 0;
751             if (intent.isWebIntent()
752                         && (intent.getFlags() & Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER) != 0) {
753                 privateResolveFlags |= PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY;
754             }
755             if ((intent.getFlags() & Intent.FLAG_ACTIVITY_REQUIRE_DEFAULT) != 0) {
756                 privateResolveFlags |= PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY;
757             }
758 
759             // In order to allow cross-profile lookup, we clear the calling identity here.
760             // Note the binder identity won't affect the result, but filterCallingUid will.
761 
762             // Cross-user/profile call check are done at the entry points
763             // (e.g. AMS.startActivityAsUser).
764             final long token = Binder.clearCallingIdentity();
765             try {
766                 return mService.getPackageManagerInternalLocked().resolveIntentExported(
767                         intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true,
768                         filterCallingUid, callingPid);
769             } finally {
770                 Binder.restoreCallingIdentity(token);
771             }
772         } finally {
773             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
774         }
775     }
776 
resolveActivity(Intent intent, String resolvedType, int startFlags, ProfilerInfo profilerInfo, int userId, int filterCallingUid, int callingPid)777     ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
778             ProfilerInfo profilerInfo, int userId, int filterCallingUid, int callingPid) {
779         final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId, 0,
780                 filterCallingUid, callingPid);
781         return resolveActivity(intent, rInfo, startFlags, profilerInfo);
782     }
783 
realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig)784     boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
785             boolean andResume, boolean checkConfig) throws RemoteException {
786 
787         if (!mRootWindowContainer.allPausedActivitiesComplete()) {
788             // While there are activities pausing we skipping starting any new activities until
789             // pauses are complete. NOTE: that we also do this for activities that are starting in
790             // the paused state because they will first be resumed then paused on the client side.
791             ProtoLog.v(WM_DEBUG_STATES,
792                     "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
793                     r);
794             return false;
795         }
796 
797         final Task task = r.getTask();
798         final Task rootTask = task.getRootTask();
799 
800         beginDeferResume();
801         // The LaunchActivityItem also contains process configuration, so the configuration change
802         // from WindowProcessController#setProcess can be deferred. The major reason is that if
803         // the activity has FixedRotationAdjustments, it needs to be applied with configuration.
804         // In general, this reduces a binder transaction if process configuration is changed.
805         proc.pauseConfigurationDispatch();
806 
807         try {
808             r.startFreezingScreenLocked(proc, 0);
809 
810             // schedule launch ticks to collect information about slow apps.
811             r.startLaunchTickingLocked();
812             r.lastLaunchTime = SystemClock.uptimeMillis();
813             r.setProcess(proc);
814 
815             // Ensure activity is allowed to be resumed after process has set.
816             if (andResume && !r.canResumeByCompat()) {
817                 andResume = false;
818             }
819 
820             r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
821 
822             // Have the window manager re-evaluate the orientation of the screen based on the new
823             // activity order.  Note that as a result of this, it can call back into the activity
824             // manager with a new orientation.  We don't care about that, because the activity is
825             // not currently running so we are just restarting it anyway.
826             if (checkConfig) {
827                 // Deferring resume here because we're going to launch new activity shortly.
828                 // We don't want to perform a redundant launch of the same record while ensuring
829                 // configurations and trying to resume top activity of focused root task.
830                 mRootWindowContainer.ensureVisibilityAndConfig(r, r.getDisplayId(),
831                         false /* markFrozenIfConfigChanged */, true /* deferResume */);
832             }
833 
834             if (mKeyguardController.checkKeyguardVisibility(r) && r.allowMoveToFront()) {
835                 // We only set the visibility to true if the activity is not being launched in
836                 // background, and is allowed to be visible based on keyguard state. This avoids
837                 // setting this into motion in window manager that is later cancelled due to later
838                 // calls to ensure visible activities that set visibility back to false.
839                 r.setVisibility(true);
840             }
841 
842             final int applicationInfoUid =
843                     (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
844             if ((r.mUserId != proc.mUserId) || (r.info.applicationInfo.uid != applicationInfoUid)) {
845                 Slog.wtf(TAG,
846                         "User ID for activity changing for " + r
847                                 + " appInfo.uid=" + r.info.applicationInfo.uid
848                                 + " info.ai.uid=" + applicationInfoUid
849                                 + " old=" + r.app + " new=" + proc);
850             }
851 
852             // Send the controller to client if the process is the first time to launch activity.
853             // So the client can save binder transactions of getting the controller from activity
854             // task manager service.
855             final IActivityClientController activityClientController =
856                     proc.hasEverLaunchedActivity() ? null : mService.mActivityClientController;
857             r.launchCount++;
858 
859             if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
860 
861             final LockTaskController lockTaskController = mService.getLockTaskController();
862             if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
863                     || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
864                     || (task.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED
865                             && lockTaskController.getLockTaskModeState()
866                                     == LOCK_TASK_MODE_LOCKED)) {
867                 lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */);
868             }
869 
870             try {
871                 if (!proc.hasThread()) {
872                     throw new RemoteException();
873                 }
874                 List<ResultInfo> results = null;
875                 List<ReferrerIntent> newIntents = null;
876                 if (andResume) {
877                     // We don't need to deliver new intents and/or set results if activity is going
878                     // to pause immediately after launch.
879                     results = r.results;
880                     newIntents = r.newIntents;
881                 }
882                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
883                         "Launching: " + r + " savedState=" + r.getSavedState()
884                                 + " with results=" + results + " newIntents=" + newIntents
885                                 + " andResume=" + andResume);
886                 EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
887                         task.mTaskId, r.shortComponentName);
888                 if (r.isActivityTypeHome()) {
889                     // Home process is the root process of the task.
890                     updateHomeProcess(task.getBottomMostActivity().app);
891                 }
892                 mService.getPackageManagerInternalLocked().notifyPackageUse(
893                         r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
894                 r.forceNewConfig = false;
895                 mService.getAppWarningsLocked().onStartActivity(r);
896 
897                 // Because we could be starting an Activity in the system process this may not go
898                 // across a Binder interface which would create a new Configuration. Consequently
899                 // we have to always create a new Configuration here.
900                 final Configuration procConfig = proc.prepareConfigurationForLaunchingActivity();
901                 final MergedConfiguration mergedConfiguration = new MergedConfiguration(
902                         procConfig, r.getMergedOverrideConfiguration());
903                 r.setLastReportedConfiguration(mergedConfiguration);
904 
905                 logIfTransactionTooLarge(r.intent, r.getSavedState());
906 
907                 final TaskFragment organizedTaskFragment = r.getOrganizedTaskFragment();
908                 if (organizedTaskFragment != null) {
909                     // Sending TaskFragmentInfo to client to ensure the info is updated before
910                     // the activity creation.
911                     mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
912                             organizedTaskFragment);
913                 }
914 
915                 // Create activity launch transaction.
916                 final ClientTransaction clientTransaction = ClientTransaction.obtain(
917                         proc.getThread(), r.token);
918 
919                 final boolean isTransitionForward = r.isTransitionForward();
920                 final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
921 
922                 final int deviceId = getDeviceIdForDisplayId(r.getDisplayId());
923                 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
924                         System.identityHashCode(r), r.info,
925                         // TODO: Have this take the merged configuration instead of separate global
926                         // and override configs.
927                         mergedConfiguration.getGlobalConfiguration(),
928                         mergedConfiguration.getOverrideConfiguration(), deviceId,
929                         r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
930                         proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
931                         results, newIntents, r.takeOptions(), isTransitionForward,
932                         proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
933                         r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
934 
935                 // Set desired final state.
936                 final ActivityLifecycleItem lifecycleItem;
937                 if (andResume) {
938                     lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
939                             r.shouldSendCompatFakeFocus());
940                 } else {
941                     lifecycleItem = PauseActivityItem.obtain();
942                 }
943                 clientTransaction.setLifecycleStateRequest(lifecycleItem);
944 
945                 // Schedule transaction.
946                 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
947 
948                 if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) {
949                     // If the seq is increased, there should be something changed (e.g. registered
950                     // activity configuration).
951                     proc.setLastReportedConfiguration(procConfig);
952                 }
953                 if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
954                         && mService.mHasHeavyWeightFeature) {
955                     // This may be a heavy-weight process! Note that the package manager will ensure
956                     // that only activity can run in the main process of the .apk, which is the only
957                     // thing that will be considered heavy-weight.
958                     if (proc.mName.equals(proc.mInfo.packageName)) {
959                         if (mService.mHeavyWeightProcess != null
960                                 && mService.mHeavyWeightProcess != proc) {
961                             Slog.w(TAG, "Starting new heavy weight process " + proc
962                                     + " when already running "
963                                     + mService.mHeavyWeightProcess);
964                         }
965                         mService.setHeavyWeightProcess(r);
966                     }
967                 }
968 
969             } catch (RemoteException e) {
970                 if (r.launchFailed) {
971                     // This is the second time we failed -- finish activity and give up.
972                     Slog.e(TAG, "Second failure launching "
973                             + r.intent.getComponent().flattenToShortString() + ", giving up", e);
974                     proc.appDied("2nd-crash");
975                     r.finishIfPossible("2nd-crash", false /* oomAdj */);
976                     return false;
977                 }
978 
979                 // This is the first time we failed -- restart process and
980                 // retry.
981                 r.launchFailed = true;
982                 r.detachFromProcess();
983                 throw e;
984             }
985         } finally {
986             endDeferResume();
987             proc.resumeConfigurationDispatch();
988         }
989 
990         r.launchFailed = false;
991 
992         // TODO(lifecycler): Resume or pause requests are done as part of launch transaction,
993         // so updating the state should be done accordingly.
994         if (andResume && readyToResume()) {
995             // As part of the process of launching, ActivityThread also performs
996             // a resume.
997             rootTask.minimalResumeActivityLocked(r);
998         } else {
999             // This activity is not starting in the resumed state... which should look like we asked
1000             // it to pause+stop (but remain visible), and it has done so and reported back the
1001             // current icicle and other state.
1002             ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s "
1003                     + "(starting in paused state)", r);
1004             r.setState(PAUSED, "realStartActivityLocked");
1005             mRootWindowContainer.executeAppTransitionForAllDisplay();
1006         }
1007         // Perform OOM scoring after the activity state is set, so the process can be updated with
1008         // the latest state.
1009         proc.onStartActivity(mService.mTopProcessState, r.info);
1010 
1011         // Launch the new version setup screen if needed.  We do this -after-
1012         // launching the initial activity (that is, home), so that it can have
1013         // a chance to initialize itself while in the background, making the
1014         // switch back to it faster and look better.
1015         if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) {
1016             mService.getActivityStartController().startSetupActivity();
1017         }
1018 
1019         // Update any services we are bound to that might care about whether
1020         // their client may have activities.
1021         if (r.app != null) {
1022             r.app.updateServiceConnectionActivities();
1023         }
1024 
1025         return true;
1026     }
1027 
updateHomeProcess(WindowProcessController app)1028     void updateHomeProcess(WindowProcessController app) {
1029         if (app != null && mService.mHomeProcess != app) {
1030             scheduleStartHome("homeChanged");
1031             mService.mHomeProcess = app;
1032         }
1033     }
1034 
scheduleStartHome(String reason)1035     private void scheduleStartHome(String reason) {
1036         if (!mHandler.hasMessages(START_HOME_MSG)) {
1037             mHandler.obtainMessage(START_HOME_MSG, reason).sendToTarget();
1038         }
1039     }
1040 
logIfTransactionTooLarge(Intent intent, Bundle icicle)1041     private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
1042         int extrasSize = 0;
1043         if (intent != null) {
1044             final Bundle extras = intent.getExtras();
1045             if (extras != null) {
1046                 extrasSize = extras.getSize();
1047             }
1048         }
1049         int icicleSize = (icicle == null ? 0 : icicle.getSize());
1050         if (extrasSize + icicleSize > 200000) {
1051             Slog.e(TAG, "Transaction too large, intent: " + intent + ", extras size: " + extrasSize
1052                     + ", icicle size: " + icicleSize);
1053         }
1054     }
1055 
startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig)1056     void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
1057         // Is this activity's application already running?
1058         final WindowProcessController wpc =
1059                 mService.getProcessController(r.processName, r.info.applicationInfo.uid);
1060 
1061         boolean knownToBeDead = false;
1062         if (wpc != null && wpc.hasThread()) {
1063             try {
1064                 realStartActivityLocked(r, wpc, andResume, checkConfig);
1065                 return;
1066             } catch (RemoteException e) {
1067                 Slog.w(TAG, "Exception when starting activity "
1068                         + r.intent.getComponent().flattenToShortString(), e);
1069             }
1070 
1071             // If a dead object exception was thrown -- fall through to
1072             // restart the application.
1073             knownToBeDead = true;
1074             // Remove the process record so it won't be considered as alive.
1075             mService.mProcessNames.remove(wpc.mName, wpc.mUid);
1076             mService.mProcessMap.remove(wpc.getPid());
1077         } else if (r.intent.isSandboxActivity(mService.mContext)) {
1078             Slog.e(TAG, "Abort sandbox activity launching as no sandbox process to host it.");
1079             r.finishIfPossible("No sandbox process for the activity", false /* oomAdj */);
1080             r.launchFailed = true;
1081             r.detachFromProcess();
1082             return;
1083         }
1084 
1085         r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
1086 
1087         final boolean isTop = andResume && r.isTopRunningActivity();
1088         mService.startProcessAsync(r, knownToBeDead, isTop,
1089                 isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
1090                         : HostingRecord.HOSTING_TYPE_ACTIVITY);
1091     }
1092 
checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, @Nullable String callingFeatureId, boolean ignoreTargetSecurity, boolean launchingInTask, WindowProcessController callerApp, ActivityRecord resultRecord, Task resultRootTask)1093     boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho,
1094             int requestCode, int callingPid, int callingUid, String callingPackage,
1095             @Nullable String callingFeatureId, boolean ignoreTargetSecurity,
1096             boolean launchingInTask, WindowProcessController callerApp, ActivityRecord resultRecord,
1097             Task resultRootTask) {
1098         final boolean isCallerRecents = mService.getRecentTasks() != null
1099                 && mService.getRecentTasks().isCallerRecents(callingUid);
1100         final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
1101                 callingUid);
1102         if (startAnyPerm == PERMISSION_GRANTED || (isCallerRecents && launchingInTask)) {
1103             // If the caller has START_ANY_ACTIVITY, ignore all checks below. In addition, if the
1104             // caller is the recents component and we are specifically starting an activity in an
1105             // existing task, then also allow the activity to be fully relaunched.
1106             return true;
1107         }
1108         final int componentRestriction = getComponentRestrictionForCallingPackage(aInfo,
1109                 callingPackage, callingFeatureId, callingPid, callingUid, ignoreTargetSecurity);
1110         final int actionRestriction = getActionRestrictionForCallingPackage(
1111                 intent.getAction(), callingPackage, callingFeatureId, callingPid, callingUid);
1112         if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
1113                 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1114             if (resultRecord != null) {
1115                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
1116                         Activity.RESULT_CANCELED, null /* data */, null /* dataGrants */);
1117             }
1118             final String msg;
1119             if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1120                 msg = "Permission Denial: starting " + intent.toString()
1121                         + " from " + callerApp + " (pid=" + callingPid
1122                         + ", uid=" + callingUid + ")" + " with revoked permission "
1123                         + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
1124             } else if (!aInfo.exported) {
1125                 msg = "Permission Denial: starting " + intent.toString()
1126                         + " from " + callerApp + " (pid=" + callingPid
1127                         + ", uid=" + callingUid + ")"
1128                         + " not exported from uid " + aInfo.applicationInfo.uid;
1129             } else {
1130                 msg = "Permission Denial: starting " + intent.toString()
1131                         + " from " + callerApp + " (pid=" + callingPid
1132                         + ", uid=" + callingUid + ")"
1133                         + " requires " + aInfo.permission;
1134             }
1135             Slog.w(TAG, msg);
1136             throw new SecurityException(msg);
1137         }
1138 
1139         if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
1140             final String message = "Appop Denial: starting " + intent.toString()
1141                     + " from " + callerApp + " (pid=" + callingPid
1142                     + ", uid=" + callingUid + ")"
1143                     + " requires " + AppOpsManager.permissionToOp(
1144                             ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
1145             Slog.w(TAG, message);
1146             return false;
1147         } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
1148             final String message = "Appop Denial: starting " + intent.toString()
1149                     + " from " + callerApp + " (pid=" + callingPid
1150                     + ", uid=" + callingUid + ")"
1151                     + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
1152             Slog.w(TAG, message);
1153             return false;
1154         }
1155 
1156         return true;
1157     }
1158 
1159     /** Check if caller is allowed to launch activities on specified task display area. */
isCallerAllowedToLaunchOnTaskDisplayArea(int callingPid, int callingUid, TaskDisplayArea taskDisplayArea, ActivityInfo aInfo)1160     boolean isCallerAllowedToLaunchOnTaskDisplayArea(int callingPid, int callingUid,
1161             TaskDisplayArea taskDisplayArea, ActivityInfo aInfo) {
1162         return isCallerAllowedToLaunchOnDisplay(callingPid, callingUid,
1163                 taskDisplayArea != null ? taskDisplayArea.getDisplayId() : DEFAULT_DISPLAY, aInfo);
1164     }
1165 
1166     /** Check if caller is allowed to launch activities on specified display. */
isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, ActivityInfo aInfo)1167     boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId,
1168             ActivityInfo aInfo) {
1169         ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: displayId=%d callingPid=%d "
1170                 + "callingUid=%d", launchDisplayId, callingPid, callingUid);
1171 
1172         if (callingPid == -1 && callingUid == -1) {
1173             ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: no caller info, skip check");
1174             return true;
1175         }
1176 
1177         final DisplayContent displayContent =
1178                 mRootWindowContainer.getDisplayContentOrCreate(launchDisplayId);
1179         if (displayContent == null || displayContent.isRemoved()) {
1180             Slog.w(TAG, "Launch on display check: display not found");
1181             return false;
1182         }
1183 
1184         if ((displayContent.mDisplay.getFlags() & Display.FLAG_REAR) != 0) {
1185             Slog.w(TAG, "Launch on display check: activity launch is not allowed on rear display");
1186             return false;
1187         }
1188 
1189         // Check if the caller has enough privileges to embed activities and launch to private
1190         // displays.
1191         final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
1192                 callingUid);
1193         if (startAnyPerm == PERMISSION_GRANTED) {
1194             ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch any on display");
1195             return true;
1196         }
1197 
1198         // Check if caller is already present on display
1199         final boolean uidPresentOnDisplay = displayContent.isUidPresent(callingUid);
1200 
1201         final Display display = displayContent.mDisplay;
1202         if (!display.isTrusted()) {
1203             // Limit launching on untrusted displays because their contents can be read from Surface
1204             // by apps that created them.
1205             if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
1206                 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow launch on "
1207                         + "virtual display for not-embedded activity.");
1208                 return false;
1209             }
1210             // Check if the caller is allowed to embed activities from other apps.
1211             if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid)
1212                     == PERMISSION_DENIED && !uidPresentOnDisplay) {
1213                 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow activity "
1214                         + "embedding without permission.");
1215                 return false;
1216             }
1217         }
1218 
1219         if (!displayContent.isPrivate()) {
1220             // Checks if the caller can be shown in the given public display.
1221             int userId = UserHandle.getUserId(callingUid);
1222             int displayId = display.getDisplayId();
1223             boolean allowed = mWindowManager.mUmInternal.isUserVisible(userId, displayId);
1224             ProtoLog.d(WM_DEBUG_TASKS,
1225                     "Launch on display check: %s launch for userId=%d on displayId=%d",
1226                     (allowed ? "allow" : "disallow"), userId, displayId);
1227             return allowed;
1228         }
1229 
1230         // Check if the caller is the owner of the display.
1231         if (display.getOwnerUid() == callingUid) {
1232             ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for owner of the"
1233                     + " display");
1234             return true;
1235         }
1236 
1237         if (uidPresentOnDisplay) {
1238             ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for caller "
1239                     + "present on the display");
1240             return true;
1241         }
1242 
1243         Slog.w(TAG, "Launch on display check: denied");
1244         return false;
1245     }
1246 
getUserInfo(int userId)1247     UserInfo getUserInfo(int userId) {
1248         final long identity = Binder.clearCallingIdentity();
1249         try {
1250             return UserManager.get(mService.mContext).getUserInfo(userId);
1251         } finally {
1252             Binder.restoreCallingIdentity(identity);
1253         }
1254     }
1255 
getDeviceIdForDisplayId(int displayId)1256     int getDeviceIdForDisplayId(int displayId) {
1257         if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY)  {
1258             return Context.DEVICE_ID_DEFAULT;
1259         }
1260         if (mVirtualDeviceManager == null) {
1261             if (mService.mHasCompanionDeviceSetupFeature) {
1262                 mVirtualDeviceManager =
1263                         mService.mContext.getSystemService(VirtualDeviceManager.class);
1264             }
1265             if (mVirtualDeviceManager == null) {
1266                 return Context.DEVICE_ID_DEFAULT;
1267             }
1268         }
1269         return mVirtualDeviceManager.getDeviceIdForDisplayId(displayId);
1270     }
1271 
getAppOpsManager()1272     private AppOpsManager getAppOpsManager() {
1273         if (mAppOpsManager == null) {
1274             mAppOpsManager = mService.mContext.getSystemService(AppOpsManager.class);
1275         }
1276         return mAppOpsManager;
1277     }
1278 
getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, String callingPackage, @Nullable String callingFeatureId, int callingPid, int callingUid, boolean ignoreTargetSecurity)1279     private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
1280             String callingPackage, @Nullable String callingFeatureId, int callingPid,
1281             int callingUid, boolean ignoreTargetSecurity) {
1282         if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
1283                 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
1284                 == PERMISSION_DENIED) {
1285             return ACTIVITY_RESTRICTION_PERMISSION;
1286         }
1287 
1288         if (activityInfo.permission == null) {
1289             return ACTIVITY_RESTRICTION_NONE;
1290         }
1291 
1292         final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
1293         if (opCode == AppOpsManager.OP_NONE) {
1294             return ACTIVITY_RESTRICTION_NONE;
1295         }
1296 
1297         if (getAppOpsManager().noteOpNoThrow(opCode, callingUid,
1298                 callingPackage, callingFeatureId, "") != AppOpsManager.MODE_ALLOWED) {
1299             if (!ignoreTargetSecurity) {
1300                 return ACTIVITY_RESTRICTION_APPOP;
1301             }
1302         }
1303 
1304         return ACTIVITY_RESTRICTION_NONE;
1305     }
1306 
getActionRestrictionForCallingPackage(String action, String callingPackage, @Nullable String callingFeatureId, int callingPid, int callingUid)1307     private int getActionRestrictionForCallingPackage(String action, String callingPackage,
1308             @Nullable String callingFeatureId, int callingPid, int callingUid) {
1309         if (action == null) {
1310             return ACTIVITY_RESTRICTION_NONE;
1311         }
1312 
1313         String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
1314         if (permission == null) {
1315             return ACTIVITY_RESTRICTION_NONE;
1316         }
1317 
1318         final PackageInfo packageInfo;
1319         try {
1320             packageInfo = mService.mContext.getPackageManager()
1321                     .getPackageInfoAsUser(callingPackage, PackageManager.GET_PERMISSIONS,
1322                             UserHandle.getUserId(callingUid));
1323         } catch (PackageManager.NameNotFoundException e) {
1324             Slog.i(TAG, "Cannot find package info for " + callingPackage);
1325             return ACTIVITY_RESTRICTION_NONE;
1326         }
1327 
1328         if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
1329             return ACTIVITY_RESTRICTION_NONE;
1330         }
1331 
1332         if (mService.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) {
1333             return ACTIVITY_RESTRICTION_PERMISSION;
1334         }
1335 
1336         final int opCode = AppOpsManager.permissionToOpCode(permission);
1337         if (opCode == AppOpsManager.OP_NONE) {
1338             return ACTIVITY_RESTRICTION_NONE;
1339         }
1340 
1341         if (getAppOpsManager().noteOpNoThrow(opCode, callingUid,
1342                 callingPackage, callingFeatureId, "") != AppOpsManager.MODE_ALLOWED) {
1343             if (CAMERA.equals(permission)) {
1344                 SensorPrivacyManagerInternal spmi =
1345                         LocalServices.getService(SensorPrivacyManagerInternal.class);
1346 
1347                 final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
1348                 final boolean cameraPrivacyEnabled = spmi.isSensorPrivacyEnabled(
1349                         user.getIdentifier(), SensorPrivacyManager.Sensors.CAMERA);
1350                 if (cameraPrivacyEnabled) {
1351                     AppOpsManagerInternal aomi = LocalServices.getService(
1352                             AppOpsManagerInternal.class);
1353                     int numCameraRestrictions = aomi.getOpRestrictionCount(
1354                             AppOpsManager.OP_CAMERA, user, callingPackage, null);
1355                     if (numCameraRestrictions == 1) {
1356                         // Only restricted by the toggles, do not restrict
1357                         return ACTIVITY_RESTRICTION_NONE;
1358                     }
1359                 }
1360             }
1361             return ACTIVITY_RESTRICTION_APPOP;
1362         }
1363 
1364         return ACTIVITY_RESTRICTION_NONE;
1365     }
1366 
setLaunchSource(int uid)1367     void setLaunchSource(int uid) {
1368         mLaunchingActivityWakeLock.setWorkSource(new WorkSource(uid));
1369     }
1370 
acquireLaunchWakelock()1371     void acquireLaunchWakelock() {
1372         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
1373             throw new IllegalStateException("Calling must be system uid");
1374         }
1375         mLaunchingActivityWakeLock.acquire();
1376         if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1377             // To be safe, don't allow the wake lock to be held for too long.
1378             mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1379         }
1380     }
1381 
1382     /**
1383      * Called when all resumed tasks/root-tasks are idle.
1384      */
1385     @GuardedBy("mService")
checkFinishBootingLocked()1386     private void checkFinishBootingLocked() {
1387         final boolean booting = mService.isBooting();
1388         boolean enableScreen = false;
1389         mService.setBooting(false);
1390         if (!mService.isBooted()) {
1391             mService.setBooted(true);
1392             enableScreen = true;
1393         }
1394         if (booting || enableScreen) {
1395             mService.postFinishBooting(booting, enableScreen);
1396         }
1397     }
1398 
activityIdleInternal(ActivityRecord r, boolean fromTimeout, boolean processPausingActivities, Configuration config)1399     void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
1400             boolean processPausingActivities, Configuration config) {
1401         if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + r);
1402 
1403         if (r != null) {
1404             if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternal: Callers="
1405                     + Debug.getCallers(4));
1406             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1407             r.finishLaunchTickingLocked();
1408             if (fromTimeout) {
1409                 reportActivityLaunched(fromTimeout, r, INVALID_DELAY, -1 /* launchState */);
1410             }
1411 
1412             // This is a hack to semi-deal with a race condition
1413             // in the client where it can be constructed with a
1414             // newer configuration from when we asked it to launch.
1415             // We'll update with whatever configuration it now says
1416             // it used to launch.
1417             if (config != null) {
1418                 r.setLastReportedGlobalConfiguration(config);
1419             }
1420 
1421             // We are now idle.  If someone is waiting for a thumbnail from
1422             // us, we can now deliver.
1423             r.idle = true;
1424 
1425             // Check if able to finish booting when device is booting and all resumed activities
1426             // are idle.
1427             if ((mService.isBooting() && mRootWindowContainer.allResumedActivitiesIdle())
1428                     || fromTimeout) {
1429                 checkFinishBootingLocked();
1430             }
1431 
1432             // When activity is idle, we consider the relaunch must be successful, so let's clear
1433             // the flag.
1434             r.mRelaunchReason = RELAUNCH_REASON_NONE;
1435         }
1436 
1437         if (mRootWindowContainer.allResumedActivitiesIdle()) {
1438             if (r != null) {
1439                 mService.scheduleAppGcsLocked();
1440                 mRecentTasks.onActivityIdle(r);
1441             }
1442 
1443             if (mLaunchingActivityWakeLock.isHeld()) {
1444                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1445                 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
1446                     throw new IllegalStateException("Calling must be system uid");
1447                 }
1448                 mLaunchingActivityWakeLock.release();
1449             }
1450             mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
1451         }
1452 
1453         // Atomically retrieve all of the other things to do.
1454         processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
1455 
1456         if (DEBUG_IDLE) {
1457             Slogf.i(TAG, "activityIdleInternal(): r=%s, mStartingUsers=%s", r, mStartingUsers);
1458         }
1459 
1460         if (!mStartingUsers.isEmpty()) {
1461             final ArrayList<UserState> startingUsers = new ArrayList<>(mStartingUsers);
1462             mStartingUsers.clear();
1463             // Complete user switch.
1464             for (int i = 0; i < startingUsers.size(); i++) {
1465                 UserState userState = startingUsers.get(i);
1466                 Slogf.i(TAG, "finishing switch of user %d", userState.mHandle.getIdentifier());
1467                 mService.mAmInternal.finishUserSwitch(userState);
1468             }
1469         }
1470 
1471         mService.mH.post(() -> mService.mAmInternal.trimApplications());
1472     }
1473 
1474     /** This doesn't just find a task, it also moves the task to front. */
findTaskToMoveToFront(Task task, int flags, ActivityOptions options, String reason, boolean forceNonResizeable)1475     void findTaskToMoveToFront(Task task, int flags, ActivityOptions options, String reason,
1476             boolean forceNonResizeable) {
1477         Task currentRootTask = task.getRootTask();
1478         if (currentRootTask == null) {
1479             Slog.e(TAG, "findTaskToMoveToFront: can't move task="
1480                     + task + " to front. Root task is null");
1481             return;
1482         }
1483 
1484         try {
1485             if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
1486                 mUserLeaving = true;
1487             }
1488 
1489             mService.deferWindowLayout();
1490             final Transition newTransition = task.mTransitionController.isShellTransitionsEnabled()
1491                     ? task.mTransitionController.isCollecting() ? null
1492                     : task.mTransitionController.createTransition(TRANSIT_TO_FRONT) : null;
1493             task.mTransitionController.collect(task);
1494             reason = reason + " findTaskToMoveToFront";
1495             boolean reparented = false;
1496             if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
1497                 Task targetRootTask =
1498                         mRootWindowContainer.getOrCreateRootTask(null, options, task, ON_TOP);
1499 
1500                 if (targetRootTask != currentRootTask) {
1501                     moveHomeRootTaskToFrontIfNeeded(flags, targetRootTask.getDisplayArea(), reason);
1502                     task.reparent(targetRootTask, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT,
1503                             !ANIMATE, DEFER_RESUME, reason);
1504                     currentRootTask = targetRootTask;
1505                     reparented = true;
1506                     // task.reparent() should already placed the task on top,
1507                     // still need moveTaskToFrontLocked() below for any transition settings.
1508                 }
1509                 // The resizeTask must be done after the task is moved to the correct root task,
1510                 // because Task's setBounds() also updates dim layer's bounds, but that has
1511                 // dependency on the root task.
1512                 final Rect bounds = options.getLaunchBounds();
1513                 task.setBounds(bounds);
1514             }
1515 
1516             if (!reparented) {
1517                 moveHomeRootTaskToFrontIfNeeded(flags, currentRootTask.getDisplayArea(), reason);
1518             }
1519 
1520             final ActivityRecord r = task.getTopNonFinishingActivity();
1521             currentRootTask.moveTaskToFront(task, false /* noAnimation */, options,
1522                     r == null ? null : r.appTimeTracker, reason);
1523 
1524             if (DEBUG_ROOT_TASK) Slog.d(TAG_ROOT_TASK,
1525                     "findTaskToMoveToFront: moved to front of root task=" + currentRootTask);
1526 
1527             handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
1528                     mRootWindowContainer.getDefaultTaskDisplayArea(), currentRootTask,
1529                     forceNonResizeable);
1530             if (r != null && (options == null || !options.getDisableStartingWindow())) {
1531                 // Use a starting window to reduce the transition latency for reshowing the task.
1532                 // Note that with shell transition, this should be executed before requesting
1533                 // transition to avoid delaying the starting window.
1534                 r.showStartingWindow(true /* taskSwitch */);
1535             }
1536             if (newTransition != null) {
1537                 task.mTransitionController.requestStartTransition(newTransition, task,
1538                         options != null ? options.getRemoteTransition() : null,
1539                         null /* displayChange */);
1540             }
1541         } finally {
1542             mUserLeaving = false;
1543             mService.continueWindowLayout();
1544         }
1545     }
1546 
moveHomeRootTaskToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea, String reason)1547     private void moveHomeRootTaskToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea,
1548             String reason) {
1549         final Task focusedRootTask = taskDisplayArea.getFocusedRootTask();
1550 
1551         if ((taskDisplayArea.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
1552                 && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0)
1553                 || (focusedRootTask != null && focusedRootTask.isActivityTypeRecents())) {
1554             // We move root home task to front when we are on a fullscreen display area and
1555             // caller has requested the home activity to move with it. Or the previous root task
1556             // is recents.
1557             taskDisplayArea.moveHomeRootTaskToFront(reason);
1558         }
1559     }
1560 
canUseActivityOptionsLaunchBounds(ActivityOptions options)1561     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options) {
1562         // We use the launch bounds in the activity options is the device supports freeform
1563         // window management or is launching into the root pinned task.
1564         if (options == null || options.getLaunchBounds() == null) {
1565             return false;
1566         }
1567         return (mService.mSupportsPictureInPicture
1568                 && options.getLaunchWindowingMode() == WINDOWING_MODE_PINNED)
1569                 || mService.mSupportsFreeformWindowManagement;
1570     }
1571 
getLaunchParamsController()1572     LaunchParamsController getLaunchParamsController() {
1573         return mLaunchParamsController;
1574     }
1575 
removePinnedRootTaskInSurfaceTransaction(Task rootTask)1576     private void removePinnedRootTaskInSurfaceTransaction(Task rootTask) {
1577         /**
1578          * Workaround: Force-stop all the activities in the root pinned task before we reparent them
1579          * to the fullscreen root task.  This is to guarantee that when we are removing a root task,
1580          * that the client receives onStop() before new windowing mode is set.
1581          * We do this by detaching the root task from the display so that it will be considered
1582          * invisible when ensureActivitiesVisible() is called, and all of its activities will be
1583          * marked invisible as well and added to the stopping list.  After which we process the
1584          * stopping list by handling the idle.
1585          */
1586         rootTask.cancelAnimation();
1587         rootTask.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */);
1588         rootTask.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
1589         activityIdleInternal(null /* idleActivity */, false /* fromTimeout */,
1590                 true /* processPausingActivities */, null /* configuration */);
1591 
1592         // Reparent all the tasks to the bottom of the display
1593         final DisplayContent toDisplay =
1594                 mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY);
1595 
1596         mService.deferWindowLayout();
1597         try {
1598             rootTask.setWindowingMode(WINDOWING_MODE_UNDEFINED);
1599             if (rootTask.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
1600                 rootTask.setBounds(null);
1601             }
1602             toDisplay.getDefaultTaskDisplayArea().positionTaskBehindHome(rootTask);
1603 
1604             // Follow on the workaround: activities are kept force hidden till the new windowing
1605             // mode is set.
1606             rootTask.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, false /* set */);
1607             mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
1608             mRootWindowContainer.resumeFocusedTasksTopActivities();
1609         } finally {
1610             mService.continueWindowLayout();
1611         }
1612     }
1613 
removeRootTaskInSurfaceTransaction(Task rootTask)1614     private void removeRootTaskInSurfaceTransaction(Task rootTask) {
1615         if (rootTask.getWindowingMode() == WINDOWING_MODE_PINNED) {
1616             removePinnedRootTaskInSurfaceTransaction(rootTask);
1617         } else {
1618             rootTask.forAllLeafTasks(task -> {
1619                 removeTask(task, true /* killProcess */, REMOVE_FROM_RECENTS, "remove-root-task");
1620             }, true /* traverseTopToBottom */);
1621         }
1622     }
1623 
1624     /**
1625      * Removes the root task associated with the given {@param task}. If the {@param task} is the
1626      * pinned task, then its child tasks are not explicitly removed when the root task is
1627      * destroyed, but instead moved back onto the TaskDisplayArea.
1628      */
removeRootTask(Task task)1629     void removeRootTask(Task task) {
1630         mWindowManager.inSurfaceTransaction(() -> removeRootTaskInSurfaceTransaction(task));
1631     }
1632 
1633     /**
1634      * Removes the task with the specified task id.
1635      *
1636      * @param taskId Identifier of the task to be removed.
1637      * @param killProcess Kill any process associated with the task if possible.
1638      * @param removeFromRecents Whether to also remove the task from recents.
1639      * @return Returns true if the given task was found and removed.
1640      */
removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents, String reason, int callingUid)1641     boolean removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents,
1642             String reason, int callingUid) {
1643         final Task task =
1644                 mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
1645         if (task != null) {
1646             removeTask(task, killProcess, removeFromRecents, reason, callingUid, null);
1647             return true;
1648         }
1649         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
1650         return false;
1651     }
1652 
removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason)1653     void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) {
1654         removeTask(task, killProcess, removeFromRecents, reason, SYSTEM_UID, null);
1655     }
1656 
removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason, int callingUid, String callerActivityClassName)1657     void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason,
1658             int callingUid, String callerActivityClassName) {
1659         if (task.mInRemoveTask) {
1660             // Prevent recursion.
1661             return;
1662         }
1663         task.mTransitionController.requestCloseTransitionIfNeeded(task);
1664         // Consume the stopping activities immediately so activity manager won't skip killing
1665         // the process because it is still foreground state, i.e. RESUMED -> PAUSING set from
1666         // removeActivities -> finishIfPossible.
1667         if (killProcess) {
1668             ArrayList<ActivityRecord> activities = null;
1669             for (int i = mStoppingActivities.size() - 1; i >= 0; i--) {
1670                 final ActivityRecord r = mStoppingActivities.get(i);
1671                 if (r.getTask() == task) {
1672                     if (activities == null) {
1673                         activities = new ArrayList<>();
1674                     }
1675                     activities.add(r);
1676                     mStoppingActivities.remove(i);
1677                 }
1678             }
1679             if (activities != null) {
1680                 // This can update to background state.
1681                 for (int i = activities.size() - 1; i >= 0; i--) {
1682                     activities.get(i).stopIfPossible();
1683                 }
1684             }
1685         }
1686         task.mInRemoveTask = true;
1687         try {
1688             task.removeActivities(reason, false /* excludingTaskOverlay */);
1689             cleanUpRemovedTask(task, killProcess, removeFromRecents);
1690             mService.getLockTaskController().clearLockedTask(task);
1691             mService.getTaskChangeNotificationController().notifyTaskStackChanged();
1692             if (task.isPersistable) {
1693                 mService.notifyTaskPersisterLocked(null, true);
1694             }
1695             checkActivitySecurityForTaskClear(callingUid, task, callerActivityClassName);
1696         } finally {
1697             task.mInRemoveTask = false;
1698         }
1699     }
1700 
1701     // TODO(b/263368846) Move to live with the rest of the ASM logic.
1702     /**
1703      * Returns home if the passed in callingUid is not top of the stack, rather than returning to
1704      * previous task.
1705      */
checkActivitySecurityForTaskClear(int callingUid, Task task, String callerActivityClassName)1706     private void checkActivitySecurityForTaskClear(int callingUid, Task task,
1707             String callerActivityClassName) {
1708         // We may have already checked that the callingUid has additional clearTask privileges, and
1709         // cleared the calling identify. If so, we infer we do not need further restrictions here.
1710         if (callingUid == SYSTEM_UID || !task.isVisible() || task.inMultiWindowMode()) {
1711             return;
1712         }
1713 
1714         TaskDisplayArea displayArea = task.getTaskDisplayArea();
1715         if (displayArea == null) {
1716             // If there is no associated display area, we can not return home.
1717             return;
1718         }
1719 
1720         Pair<Boolean, Boolean> pair = doesTopActivityMatchingUidExistForAsm(task, callingUid, null);
1721         boolean shouldBlockActivitySwitchIfFeatureEnabled = !pair.first;
1722         boolean wouldBlockActivitySwitchIgnoringFlags = !pair.second;
1723 
1724         if (!wouldBlockActivitySwitchIgnoringFlags) {
1725             return;
1726         }
1727 
1728         ActivityRecord topActivity = task.getActivity(ar -> !ar.finishing && !ar.isAlwaysOnTop());
1729         FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED,
1730                 /* caller_uid */
1731                 callingUid,
1732                 /* caller_activity_class_name */
1733                 callerActivityClassName,
1734                 /* target_task_top_activity_uid */
1735                 topActivity == null ? -1 : topActivity.getUid(),
1736                 /* target_task_top_activity_class_name */
1737                 topActivity == null ? null : topActivity.info.name,
1738                 /* target_task_is_different */
1739                 false,
1740                 /* target_activity_uid */
1741                 -1,
1742                 /* target_activity_class_name */
1743                 null,
1744                 /* target_intent_action */
1745                 null,
1746                 /* target_intent_flags */
1747                 0,
1748                 /* action */
1749                 FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__FINISH_TASK,
1750                 /* version */
1751                 ActivitySecurityModelFeatureFlags.ASM_VERSION,
1752                 /* multi_window */
1753                 false,
1754                 /* bal_code */
1755                 -1
1756         );
1757 
1758         boolean restrictActivitySwitch = ActivitySecurityModelFeatureFlags
1759                 .shouldRestrictActivitySwitch(callingUid)
1760                 && shouldBlockActivitySwitchIfFeatureEnabled;
1761 
1762         PackageManager pm = mService.mContext.getPackageManager();
1763         String callingPackage = pm.getNameForUid(callingUid);
1764         final CharSequence callingLabel;
1765         if (callingPackage == null) {
1766             callingPackage = String.valueOf(callingUid);
1767             callingLabel = callingPackage;
1768         } else {
1769             callingLabel = getApplicationLabel(pm, callingPackage);
1770         }
1771 
1772         if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)) {
1773             UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
1774                     (ActivitySecurityModelFeatureFlags.DOC_LINK
1775                             + (restrictActivitySwitch ? " returned home due to "
1776                                     : " would return home due to ")
1777                             + callingLabel), Toast.LENGTH_LONG).show());
1778         }
1779 
1780         // If the activity switch should be restricted, return home rather than the
1781         // previously top task, to prevent users from being confused which app they're
1782         // viewing
1783         if (restrictActivitySwitch) {
1784             Slog.w(TAG, "[ASM] Return to home as source: " + callingPackage
1785                     + " is not on top of task t: " + task);
1786             displayArea.moveHomeActivityToTop("taskRemoved");
1787         } else {
1788             Slog.i(TAG, "[ASM] Would return to home as source: " + callingPackage
1789                     + " is not on top of task t: " + task);
1790         }
1791     }
1792 
1793     /**
1794      *  For the purpose of ASM, ‘Top UID” for a task is defined as an activity UID
1795      *  1. Which is top of the stack in z-order
1796      *      a. Excluding any activities with the flag ‘isAlwaysOnTop’ and
1797      *      b. Excluding any activities which are `finishing`
1798      *  2. Or top of an adjacent task fragment to (1)
1799      *
1800      *  The 'sourceRecord' can be considered top even if it is 'finishing'
1801      *
1802      * @return A pair where the first value is the return value matching the checks above, and the
1803      * second value is the return value disregarding the feature flag or target api levels. Use the
1804      * first value for blocking launches - the second value is only used to determine if a toast
1805      * should be displayed, and will be used alongside a feature flag in {@link ActivityStarter}.
1806      */
1807     // TODO(b/263368846) Shift to BackgroundActivityStartController once class is ready
1808     @Nullable
doesTopActivityMatchingUidExistForAsm(@ullable Task task, int uid, @Nullable ActivityRecord sourceRecord)1809     static Pair<Boolean, Boolean> doesTopActivityMatchingUidExistForAsm(@Nullable Task task,
1810             int uid, @Nullable ActivityRecord sourceRecord) {
1811         // If the source is visible, consider it 'top'.
1812         if (sourceRecord != null && sourceRecord.isVisible()) {
1813             return new Pair<>(true, true);
1814         }
1815 
1816         // Always allow actual top activity to clear task
1817         ActivityRecord topActivity = task.getTopMostActivity();
1818         if (topActivity != null && topActivity.isUid(uid)) {
1819             return new Pair<>(true, true);
1820         }
1821 
1822         // Consider the source activity, whether or not it is finishing. Do not consider any other
1823         // finishing activity.
1824         Predicate<ActivityRecord> topOfStackPredicate = (ar) -> ar.equals(sourceRecord)
1825                 || (!ar.finishing && !ar.isAlwaysOnTop());
1826 
1827         // Check top of stack (or the first task fragment for embedding).
1828         topActivity = task.getActivity(topOfStackPredicate);
1829         if (topActivity == null) {
1830             return new Pair<>(false, false);
1831         }
1832 
1833         Pair<Boolean, Boolean> pair = topActivity.allowCrossUidActivitySwitchFromBelow(uid);
1834         if (pair.first) {
1835             return new Pair<>(true, pair.second);
1836         }
1837 
1838         // Even if the top activity is not a match, we may be in an embedded activity scenario with
1839         // an adjacent task fragment. Get the second fragment.
1840         TaskFragment taskFragment = topActivity.getTaskFragment();
1841         if (taskFragment == null) {
1842             return new Pair<>(false, false);
1843         }
1844 
1845         TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
1846         if (adjacentTaskFragment == null) {
1847             return new Pair<>(false, false);
1848         }
1849 
1850         // Check the second fragment.
1851         topActivity = adjacentTaskFragment.getActivity(topOfStackPredicate);
1852         if (topActivity == null) {
1853             return new Pair<>(false, false);
1854         }
1855 
1856         return topActivity.allowCrossUidActivitySwitchFromBelow(uid);
1857     }
1858 
getApplicationLabel(PackageManager pm, String packageName)1859     static CharSequence getApplicationLabel(PackageManager pm, String packageName) {
1860         try {
1861             ApplicationInfo launchedFromPackageInfo = pm.getApplicationInfo(
1862                     packageName, PackageManager.ApplicationInfoFlags.of(0));
1863             return pm.getApplicationLabel(launchedFromPackageInfo);
1864         } catch (PackageManager.NameNotFoundException e) {
1865             return packageName;
1866         }
1867     }
1868 
1869     /** This method should only be called for leaf task. */
cleanUpRemovedTask(Task task, boolean killProcess, boolean removeFromRecents)1870     private void cleanUpRemovedTask(Task task, boolean killProcess, boolean removeFromRecents) {
1871         if (removeFromRecents) {
1872             mRecentTasks.remove(task);
1873         }
1874         final Intent baseIntent = task.getBaseIntent();
1875         final ComponentName component = baseIntent != null ? baseIntent.getComponent() : null;
1876         if (component == null) {
1877             Slog.w(TAG, "No component for base intent of task: " + task);
1878             return;
1879         }
1880 
1881         // Find any running services associated with this app and stop if needed.
1882         final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::cleanUpServices,
1883                 mService.mAmInternal, task.mUserId, component, new Intent(baseIntent));
1884         mService.mH.sendMessage(msg);
1885 
1886         if (!killProcess) {
1887             return;
1888         }
1889         // Give a chance for the client to handle Activity#onStop(). The timeout waits for
1890         // onDestroy because the client defers to report completion of stopped, the callback from
1891         // DestroyActivityItem may be called first.
1892         final ActivityRecord top = task.getTopMostActivity();
1893         if (top != null && top.finishing && !top.mAppStopped && top.lastVisibleTime > 0
1894                 && !task.mKillProcessesOnDestroyed) {
1895             task.mKillProcessesOnDestroyed = true;
1896             mHandler.sendMessageDelayed(
1897                     mHandler.obtainMessage(KILL_TASK_PROCESSES_TIMEOUT_MSG, task),
1898                     KILL_TASK_PROCESSES_TIMEOUT_MS);
1899             return;
1900         }
1901         killTaskProcessesIfPossible(task);
1902     }
1903 
killTaskProcessesOnDestroyedIfNeeded(Task task)1904     void killTaskProcessesOnDestroyedIfNeeded(Task task) {
1905         if (task == null || !task.mKillProcessesOnDestroyed) return;
1906         mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task);
1907         killTaskProcessesIfPossible(task);
1908     }
1909 
1910     /** Kills the processes in the task if it doesn't contain perceptible components. */
killTaskProcessesIfPossible(Task task)1911     private void killTaskProcessesIfPossible(Task task) {
1912         task.mKillProcessesOnDestroyed = false;
1913         final String pkg = task.getBasePackageName();
1914         ArrayList<Object> procsToKill = null;
1915         ArrayMap<String, SparseArray<WindowProcessController>> pmap =
1916                 mService.mProcessNames.getMap();
1917         for (int i = 0; i < pmap.size(); i++) {
1918 
1919             SparseArray<WindowProcessController> uids = pmap.valueAt(i);
1920             for (int j = 0; j < uids.size(); j++) {
1921                 WindowProcessController proc = uids.valueAt(j);
1922                 if (proc.mUserId != task.mUserId) {
1923                     // Don't kill process for a different user.
1924                     continue;
1925                 }
1926                 if (proc == mService.mHomeProcess) {
1927                     // Don't kill the home process along with tasks from the same package.
1928                     continue;
1929                 }
1930                 if (!proc.containsPackage(pkg)) {
1931                     // Don't kill process that is not associated with this task.
1932                     continue;
1933                 }
1934 
1935                 if (!proc.shouldKillProcessForRemovedTask(task)) {
1936                     // Don't kill process(es) that has an activity in a different task that is also
1937                     // in recents, or has an activity not stopped.
1938                     return;
1939                 }
1940 
1941                 if (proc.hasForegroundServices()) {
1942                     // Don't kill process(es) with foreground service.
1943                     return;
1944                 }
1945 
1946                 if (procsToKill == null) {
1947                     procsToKill = new ArrayList<>();
1948                 }
1949                 // Add process to kill list.
1950                 procsToKill.add(proc);
1951             }
1952         }
1953         if (procsToKill == null) return;
1954 
1955         // Kill the running processes. Post on handle since we don't want to hold the service lock
1956         // while calling into AM.
1957         final Message m = PooledLambda.obtainMessage(
1958                 ActivityManagerInternal::killProcessesForRemovedTask, mService.mAmInternal,
1959                 procsToKill);
1960         mService.mH.sendMessage(m);
1961     }
1962 
1963     /**
1964      * Called to restore the state of the task into the root task that it's supposed to go into.
1965      *
1966      * @param task The recent task to be restored.
1967      * @param aOptions The activity options to use for restoration.
1968      * @param onTop If the root task for the task should be the topmost on the display.
1969      * @return true if the task has been restored successfully.
1970      */
restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop)1971     boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) {
1972         final Task rootTask =
1973                 mRootWindowContainer.getOrCreateRootTask(null, aOptions, task, onTop);
1974         final WindowContainer parent = task.getParent();
1975 
1976         if (parent == rootTask || task == rootTask) {
1977             // Nothing else to do since it is already restored in the right root task.
1978             return true;
1979         }
1980 
1981         if (parent != null) {
1982             // Task has already been restored once. Just re-parent it to the new root task.
1983             task.reparent(rootTask, POSITION_TOP, true /*moveParents*/, "restoreRecentTaskLocked");
1984             return true;
1985         }
1986 
1987         rootTask.addChild(task, onTop, true /* showForAllUsers */);
1988         if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
1989                 "Added restored task=" + task + " to root task=" + rootTask);
1990         return true;
1991     }
1992 
1993     @Override
onRecentTaskAdded(Task task)1994     public void onRecentTaskAdded(Task task) {
1995         task.touchActiveTime();
1996     }
1997 
1998     @Override
onRecentTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess)1999     public void onRecentTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess) {
2000         if (wasTrimmed) {
2001             // Task was trimmed from the recent tasks list -- remove the active task record as well
2002             // since the user won't really be able to go back to it
2003             removeTaskById(task.mTaskId, killProcess, false /* removeFromRecents */,
2004                     "recent-task-trimmed", SYSTEM_UID);
2005         }
2006         task.removedFromRecents();
2007     }
2008 
2009     /**
2010      * Returns the reparent target root task, creating the root task if necessary.  This call
2011      * also enforces the various checks on tasks that are going to be reparented from one root
2012      * task to another.
2013      */
2014     // TODO: Look into changing users to this method to DisplayContent.resolveWindowingMode()
getReparentTargetRootTask(Task task, Task rootTask, boolean toTop)2015     Task getReparentTargetRootTask(Task task, Task rootTask, boolean toTop) {
2016         final Task prevRootTask = task.getRootTask();
2017         final int rootTaskId = rootTask.mTaskId;
2018         final boolean inMultiWindowMode = rootTask.inMultiWindowMode();
2019 
2020         // Check that we aren't reparenting to the same root task that the task is already in
2021         if (prevRootTask != null && prevRootTask.mTaskId == rootTaskId) {
2022             Slog.w(TAG, "Can not reparent to same root task, task=" + task
2023                     + " already in rootTaskId=" + rootTaskId);
2024             return prevRootTask;
2025         }
2026 
2027         // Ensure that we aren't trying to move into a multi-window root task without multi-window
2028         // support
2029         if (inMultiWindowMode && !mService.mSupportsMultiWindow) {
2030             throw new IllegalArgumentException("Device doesn't support multi-window, can not"
2031                     + " reparent task=" + task + " to root-task=" + rootTask);
2032         }
2033 
2034         // Ensure that we're not moving a task to a dynamic root task if device doesn't support
2035         // multi-display.
2036         if (rootTask.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) {
2037             throw new IllegalArgumentException("Device doesn't support multi-display, can not"
2038                     + " reparent task=" + task + " to rootTaskId=" + rootTaskId);
2039         }
2040 
2041         // Ensure that we aren't trying to move into a freeform root task without freeform support
2042         if (rootTask.getWindowingMode() == WINDOWING_MODE_FREEFORM
2043                 && !mService.mSupportsFreeformWindowManagement) {
2044             throw new IllegalArgumentException("Device doesn't support freeform, can not reparent"
2045                     + " task=" + task);
2046         }
2047 
2048         if (rootTask.inPinnedWindowingMode()) {
2049             throw new IllegalArgumentException("No support to reparent to PIP, task=" + task);
2050         }
2051 
2052         // Leave the task in its current root task or a fullscreen root task if it isn't
2053         // resizeable and the preferred root task is in multi-window mode.
2054         if (inMultiWindowMode
2055                 && !task.supportsMultiWindowInDisplayArea(rootTask.getDisplayArea())) {
2056             Slog.w(TAG, "Can not move unresizeable task=" + task + " to multi-window root task="
2057                     + rootTask + " Moving to a fullscreen root task instead.");
2058             if (prevRootTask != null) {
2059                 return prevRootTask;
2060             }
2061             rootTask = rootTask.getDisplayArea().createRootTask(
2062                     WINDOWING_MODE_FULLSCREEN, rootTask.getActivityType(), toTop);
2063         }
2064         return rootTask;
2065     }
2066 
goingToSleepLocked()2067     void goingToSleepLocked() {
2068         scheduleSleepTimeout();
2069         if (!mGoingToSleepWakeLock.isHeld()) {
2070             mGoingToSleepWakeLock.acquire();
2071             if (mLaunchingActivityWakeLock.isHeld()) {
2072                 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
2073                     throw new IllegalStateException("Calling must be system uid");
2074                 }
2075                 mLaunchingActivityWakeLock.release();
2076                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2077             }
2078         }
2079 
2080         mRootWindowContainer.applySleepTokens(false /* applyToRootTasks */);
2081 
2082         checkReadyForSleepLocked(true /* allowDelay */);
2083     }
2084 
shutdownLocked(int timeout)2085     boolean shutdownLocked(int timeout) {
2086         goingToSleepLocked();
2087 
2088         boolean timedout = false;
2089         final long endTime = System.currentTimeMillis() + timeout;
2090         while (true) {
2091             if (!mRootWindowContainer.putTasksToSleep(
2092                     true /* allowDelay */, true /* shuttingDown */)) {
2093                 long timeRemaining = endTime - System.currentTimeMillis();
2094                 if (timeRemaining > 0) {
2095                     try {
2096                         mService.mGlobalLock.wait(timeRemaining);
2097                     } catch (InterruptedException e) {
2098                     }
2099                 } else {
2100                     Slog.w(TAG, "Activity manager shutdown timed out");
2101                     timedout = true;
2102                     break;
2103                 }
2104             } else {
2105                 break;
2106             }
2107         }
2108 
2109         // Force checkReadyForSleep to complete.
2110         checkReadyForSleepLocked(false /* allowDelay */);
2111 
2112         return timedout;
2113     }
2114 
comeOutOfSleepIfNeededLocked()2115     void comeOutOfSleepIfNeededLocked() {
2116         removeSleepTimeouts();
2117         if (mGoingToSleepWakeLock.isHeld()) {
2118             mGoingToSleepWakeLock.release();
2119         }
2120     }
2121 
checkReadyForSleepLocked(boolean allowDelay)2122     void checkReadyForSleepLocked(boolean allowDelay) {
2123         if (!mService.isSleepingOrShuttingDownLocked()) {
2124             // Do not care.
2125             return;
2126         }
2127 
2128         if (!mRootWindowContainer.putTasksToSleep(
2129                 allowDelay, false /* shuttingDown */)) {
2130             return;
2131         }
2132 
2133         // End power mode launch before going sleep
2134         mService.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_ALL);
2135 
2136         // Rank task layers to make sure the {@link Task#mLayerRank} is updated.
2137         mRootWindowContainer.rankTaskLayers();
2138 
2139         removeSleepTimeouts();
2140 
2141         if (mGoingToSleepWakeLock.isHeld()) {
2142             mGoingToSleepWakeLock.release();
2143         }
2144         if (mService.mShuttingDown) {
2145             mService.mGlobalLock.notifyAll();
2146         }
2147     }
2148 
reportResumedActivityLocked(ActivityRecord r)2149     boolean reportResumedActivityLocked(ActivityRecord r) {
2150         // A resumed activity cannot be stopping. remove from list
2151         mStoppingActivities.remove(r);
2152 
2153         final Task rootTask = r.getRootTask();
2154         if (rootTask.getDisplayArea().allResumedActivitiesComplete()) {
2155             mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2156             // Make sure activity & window visibility should be identical
2157             // for all displays in this stage.
2158             mRootWindowContainer.executeAppTransitionForAllDisplay();
2159             return true;
2160         }
2161         return false;
2162     }
2163 
2164     // Called when WindowManager has finished animating the launchingBehind activity to the back.
handleLaunchTaskBehindCompleteLocked(ActivityRecord r)2165     private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2166         final Task task = r.getTask();
2167         final Task rootTask = task.getRootTask();
2168 
2169         mRecentTasks.add(task);
2170         mService.getTaskChangeNotificationController().notifyTaskStackChanged();
2171         rootTask.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2172 
2173         // When launching tasks behind, update the last active time of the top task after the new
2174         // task has been shown briefly
2175         final ActivityRecord top = rootTask.getTopNonFinishingActivity();
2176         if (top != null) {
2177             top.getTask().touchActiveTime();
2178         }
2179     }
2180 
scheduleLaunchTaskBehindComplete(IBinder token)2181     void scheduleLaunchTaskBehindComplete(IBinder token) {
2182         mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2183     }
2184 
2185     /**
2186      * Processes the activities to be stopped or destroyed. This should be called when the resumed
2187      * activities are idle or drawn.
2188      */
processStoppingAndFinishingActivities(ActivityRecord launchedActivity, boolean processPausingActivities, String reason)2189     void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
2190             boolean processPausingActivities, String reason) {
2191         // Stop any activities that are scheduled to do so but have been waiting for the transition
2192         // animation to finish.
2193         boolean displaySwapping = false;
2194         ArrayList<ActivityRecord> readyToStopActivities = null;
2195         for (int i = 0; i < mStoppingActivities.size(); i++) {
2196             final ActivityRecord s = mStoppingActivities.get(i);
2197             // Activity in a force hidden task should not be counted as animating, i.e., we want to
2198             // send onStop before any configuration change when removing pip transition is ongoing.
2199             final boolean animating = s.isInTransition()
2200                     && s.getTask() != null && !s.getTask().isForceHidden();
2201             displaySwapping |= s.isDisplaySleepingAndSwapping();
2202             ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
2203                     + "finishing=%s", s, s.nowVisible, animating, s.finishing);
2204             if ((!animating && !displaySwapping) || mService.mShuttingDown) {
2205                 if (!processPausingActivities && s.isState(PAUSING)) {
2206                     // Defer processing pausing activities in this iteration and reschedule
2207                     // a delayed idle to reprocess it again
2208                     removeIdleTimeoutForActivity(launchedActivity);
2209                     scheduleIdleTimeout(launchedActivity);
2210                     continue;
2211                 }
2212 
2213                 ProtoLog.v(WM_DEBUG_STATES, "Ready to stop: %s", s);
2214                 if (readyToStopActivities == null) {
2215                     readyToStopActivities = new ArrayList<>();
2216                 }
2217                 readyToStopActivities.add(s);
2218 
2219                 mStoppingActivities.remove(i);
2220                 i--;
2221             }
2222         }
2223 
2224         // Stopping activities are deferred processing if the display is swapping. Check again
2225         // later to ensure the stopping activities can be stopped after display swapped.
2226         if (displaySwapping) {
2227             mHandler.postDelayed(() -> {
2228                 synchronized (mService.mGlobalLock) {
2229                     scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
2230                 }
2231             }, SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS);
2232         }
2233 
2234         final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
2235         for (int i = 0; i < numReadyStops; i++) {
2236             final ActivityRecord r = readyToStopActivities.get(i);
2237             if (r.isInHistory()) {
2238                 if (r.finishing) {
2239                     // TODO(b/137329632): Wait for idle of the right activity, not just any.
2240                     r.destroyIfPossible(reason);
2241                 } else {
2242                     r.stopIfPossible();
2243                 }
2244             }
2245         }
2246 
2247         final int numFinishingActivities = mFinishingActivities.size();
2248         if (numFinishingActivities == 0) {
2249             return;
2250         }
2251 
2252         // Finish any activities that are scheduled to do so but have been waiting for the next one
2253         // to start.
2254         final ArrayList<ActivityRecord> finishingActivities = new ArrayList<>(mFinishingActivities);
2255         mFinishingActivities.clear();
2256         for (int i = 0; i < numFinishingActivities; i++) {
2257             final ActivityRecord r = finishingActivities.get(i);
2258             if (r.isInHistory()) {
2259                 r.destroyImmediately("finish-" + reason);
2260             }
2261         }
2262     }
2263 
removeHistoryRecords(WindowProcessController app)2264     void removeHistoryRecords(WindowProcessController app) {
2265         removeHistoryRecords(mStoppingActivities, app, "mStoppingActivities");
2266         removeHistoryRecords(mFinishingActivities, app, "mFinishingActivities");
2267         removeHistoryRecords(mNoHistoryActivities, app, "mNoHistoryActivities");
2268     }
2269 
removeHistoryRecords(ArrayList<ActivityRecord> list, WindowProcessController app, String listName)2270     private void removeHistoryRecords(ArrayList<ActivityRecord> list, WindowProcessController app,
2271             String listName) {
2272         int i = list.size();
2273         if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
2274                 "Removing app " + this + " from list " + listName + " with " + i + " entries");
2275         while (i > 0) {
2276             i--;
2277             ActivityRecord r = list.get(i);
2278             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r);
2279             if (r.app == app) {
2280                 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!");
2281                 list.remove(i);
2282                 r.removeTimeouts();
2283             }
2284         }
2285     }
2286 
dump(PrintWriter pw, String prefix)2287     public void dump(PrintWriter pw, String prefix) {
2288         pw.println();
2289         pw.println("ActivityTaskSupervisor state:");
2290         mRootWindowContainer.dump(pw, prefix, true /* dumpAll */);
2291         getKeyguardController().dump(pw, prefix);
2292         mService.getLockTaskController().dump(pw, prefix);
2293         pw.print(prefix);
2294         pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
2295         pw.println(prefix + "mUserRootTaskInFront=" + mRootWindowContainer.mUserRootTaskInFront);
2296         pw.println(prefix + "mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
2297         pw.print(prefix); pw.print("isHomeRecentsComponent=");
2298         pw.println(mRecentTasks.isRecentsComponentHomeActivity(mRootWindowContainer.mCurrentUser));
2299         if (!mWaitingActivityLaunched.isEmpty()) {
2300             pw.println(prefix + "mWaitingActivityLaunched=");
2301             for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
2302                 mWaitingActivityLaunched.get(i).dump(pw, prefix + "  ");
2303             }
2304         }
2305         pw.println(prefix + "mNoHistoryActivities=" + mNoHistoryActivities);
2306         pw.println();
2307     }
2308 
printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, boolean needSep, String prefix, Runnable header)2309     static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2310             boolean needSep, String prefix, Runnable header) {
2311         return printThisActivity(pw, activity, dumpPackage, INVALID_DISPLAY, needSep, prefix,
2312                 header);
2313     }
2314 
printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, int displayIdFilter, boolean needSep, String prefix, Runnable header)2315     static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2316             int displayIdFilter, boolean needSep, String prefix, Runnable header) {
2317         if (activity != null && (displayIdFilter == INVALID_DISPLAY
2318                 || displayIdFilter == activity.getDisplayId())) {
2319             if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2320                 if (needSep) {
2321                     pw.println();
2322                 }
2323                 if (header != null) {
2324                     header.run();
2325                 }
2326                 pw.print(prefix);
2327                 pw.println(activity);
2328                 return true;
2329             }
2330         }
2331         return false;
2332     }
2333 
dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage, boolean needNL, Runnable header, Task lastTask)2334     static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2335             String prefix, String label, boolean complete, boolean brief, boolean client,
2336             String dumpPackage, boolean needNL, Runnable header, Task lastTask) {
2337         boolean printed = false;
2338         for (int i = list.size() - 1; i >= 0; i--) {
2339             final ActivityRecord r = list.get(i);
2340             ActivityRecord.dumpActivity(fd, pw, i, r, prefix, label, complete, brief,
2341                     client, dumpPackage, needNL, header, lastTask);
2342             lastTask = r.getTask();
2343             header = null;
2344             needNL = client && r.attachedToProcess();
2345         }
2346         return printed;
2347     }
2348 
scheduleIdleTimeout(ActivityRecord next)2349     void scheduleIdleTimeout(ActivityRecord next) {
2350         if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdleTimeout: Callers=" + Debug.getCallers(4));
2351         Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2352         mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2353     }
2354 
scheduleIdle()2355     final void scheduleIdle() {
2356         if (!mHandler.hasMessages(IDLE_NOW_MSG)) {
2357             if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdle: Callers=" + Debug.getCallers(4));
2358             mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2359         }
2360     }
2361 
2362     /**
2363      * Updates the record of top resumed activity when it changes and handles reporting of the
2364      * state changes to previous and new top activities. It will immediately dispatch top resumed
2365      * state loss message to previous top activity (if haven't done it already). After the previous
2366      * activity releases the top state and reports back, message about acquiring top state will be
2367      * sent to the new top resumed activity.
2368      */
updateTopResumedActivityIfNeeded(String reason)2369     void updateTopResumedActivityIfNeeded(String reason) {
2370         final ActivityRecord prevTopActivity = mTopResumedActivity;
2371         final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
2372         if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) {
2373             if (mService.isSleepingLocked()) {
2374                 // There won't be a next resumed activity. The top process should still be updated
2375                 // according to the current top focused activity.
2376                 mService.updateTopApp(null /* topResumedActivity */);
2377             }
2378             return;
2379         }
2380 
2381         // Ask previous activity to release the top state.
2382         final boolean prevActivityReceivedTopState =
2383                 prevTopActivity != null && !mTopResumedActivityWaitingForPrev;
2384         // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
2385         // before the prevTopActivity one hasn't reported back yet. So server never sent the top
2386         // resumed state change message to prevTopActivity.
2387         if (prevActivityReceivedTopState
2388                 && prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
2389             scheduleTopResumedStateLossTimeout(prevTopActivity);
2390             mTopResumedActivityWaitingForPrev = true;
2391         }
2392 
2393         // Update the current top activity.
2394         mTopResumedActivity = topRootTask.getTopResumedActivity();
2395         // Update process state if there is no activity state change (e.g. focus change between
2396         // multi-window mode activities) to make sure that the current top has top oom-adj.
2397         // If the previous top is null, there should be activity state change from it, Then the
2398         // process state should also have been updated so no need to update again.
2399         if (mTopResumedActivity != null && prevTopActivity != null) {
2400             if (mTopResumedActivity.app != null) {
2401                 mTopResumedActivity.app.addToPendingTop();
2402             }
2403             mService.updateOomAdj();
2404         }
2405         // Update the last resumed activity and focused app when the top resumed activity changed
2406         // because the new top resumed activity might be already resumed and thus won't have
2407         // activity state change to update the records to AMS.
2408         if (mTopResumedActivity != null) {
2409             mService.setLastResumedActivityUncheckLocked(mTopResumedActivity, reason);
2410         }
2411         scheduleTopResumedActivityStateIfNeeded();
2412 
2413         mService.updateTopApp(mTopResumedActivity);
2414     }
2415 
2416     /** Schedule top resumed state change if previous top activity already reported back. */
scheduleTopResumedActivityStateIfNeeded()2417     private void scheduleTopResumedActivityStateIfNeeded() {
2418         if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) {
2419             mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */);
2420         }
2421     }
2422 
2423     /**
2424      * Limit the time given to the app to report handling of the state loss.
2425      */
scheduleTopResumedStateLossTimeout(ActivityRecord r)2426     private void scheduleTopResumedStateLossTimeout(ActivityRecord r) {
2427         final Message msg = mHandler.obtainMessage(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG);
2428         msg.obj = r;
2429         r.topResumedStateLossTime = SystemClock.uptimeMillis();
2430         mHandler.sendMessageDelayed(msg, TOP_RESUMED_STATE_LOSS_TIMEOUT);
2431         ProtoLog.v(WM_DEBUG_STATES, "Waiting for top state to be released by %s", r);
2432     }
2433 
2434     /**
2435      * Handle a loss of top resumed state by an activity - update internal state and inform next top
2436      * activity if needed.
2437      */
handleTopResumedStateReleased(boolean timeout)2438     void handleTopResumedStateReleased(boolean timeout) {
2439         ProtoLog.v(WM_DEBUG_STATES, "Top resumed state released %s",
2440                     (timeout ? "(due to timeout)" : "(transition complete)"));
2441 
2442         mHandler.removeMessages(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG);
2443         if (!mTopResumedActivityWaitingForPrev) {
2444             // Top resumed activity state loss already handled.
2445             return;
2446         }
2447         mTopResumedActivityWaitingForPrev = false;
2448         scheduleTopResumedActivityStateIfNeeded();
2449     }
2450 
removeIdleTimeoutForActivity(ActivityRecord r)2451     void removeIdleTimeoutForActivity(ActivityRecord r) {
2452         if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
2453                 + Debug.getCallers(4));
2454         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2455     }
2456 
scheduleResumeTopActivities()2457     final void scheduleResumeTopActivities() {
2458         if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2459             mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2460         }
2461     }
2462 
scheduleProcessStoppingAndFinishingActivitiesIfNeeded()2463     void scheduleProcessStoppingAndFinishingActivitiesIfNeeded() {
2464         if (mStoppingActivities.isEmpty() && mFinishingActivities.isEmpty()) {
2465             return;
2466         }
2467         if (mRootWindowContainer.allResumedActivitiesIdle()) {
2468             scheduleIdle();
2469             return;
2470         }
2471         if (!mHandler.hasMessages(PROCESS_STOPPING_AND_FINISHING_MSG)
2472                 && mRootWindowContainer.allResumedActivitiesVisible()) {
2473             mHandler.sendEmptyMessage(PROCESS_STOPPING_AND_FINISHING_MSG);
2474         }
2475     }
2476 
removeSleepTimeouts()2477     void removeSleepTimeouts() {
2478         mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2479     }
2480 
scheduleSleepTimeout()2481     final void scheduleSleepTimeout() {
2482         removeSleepTimeouts();
2483         mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2484     }
2485 
hasScheduledRestartTimeouts(ActivityRecord r)2486     boolean hasScheduledRestartTimeouts(ActivityRecord r) {
2487         return mHandler.hasMessages(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r);
2488     }
2489 
removeRestartTimeouts(ActivityRecord r)2490     void removeRestartTimeouts(ActivityRecord r) {
2491         mHandler.removeMessages(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r);
2492     }
2493 
scheduleRestartTimeout(ActivityRecord r)2494     final void scheduleRestartTimeout(ActivityRecord r) {
2495         removeRestartTimeouts(r);
2496         mHandler.sendMessageDelayed(mHandler.obtainMessage(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r),
2497                 WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION);
2498     }
2499 
handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask)2500     void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode,
2501             TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask) {
2502         handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredTaskDisplayArea,
2503                 actualRootTask, false /* forceNonResizable */);
2504     }
2505 
handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask, boolean forceNonResizable)2506     void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode,
2507             TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask,
2508             boolean forceNonResizable) {
2509         final boolean isSecondaryDisplayPreferred = preferredTaskDisplayArea != null
2510                 && preferredTaskDisplayArea.getDisplayId() != DEFAULT_DISPLAY;
2511         if (!task.isActivityTypeStandardOrUndefined()) {
2512             return;
2513         }
2514 
2515         // Handle incorrect launch/move to secondary display if needed.
2516         if (isSecondaryDisplayPreferred) {
2517             if (!task.canBeLaunchedOnDisplay(task.getDisplayId())) {
2518                 throw new IllegalStateException("Task resolved to incompatible display");
2519             }
2520 
2521             final DisplayContent preferredDisplay = preferredTaskDisplayArea.mDisplayContent;
2522             if (preferredDisplay != task.getDisplayContent()) {
2523                 Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplay.mDisplayId);
2524                 // Display a warning toast that we failed to put a task on a secondary display.
2525                 mService.getTaskChangeNotificationController()
2526                         .notifyActivityLaunchOnSecondaryDisplayFailed(task.getTaskInfo(),
2527                                 preferredDisplay.mDisplayId);
2528             } else if (!forceNonResizable) {
2529                 handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY);
2530             }
2531             // The information about not support secondary display should already be notified, we
2532             // don't want to show another message on default display about split-screen. And it may
2533             // be the case that a resizable activity is launched on a non-resizable task.
2534             return;
2535         }
2536 
2537         if (!forceNonResizable) {
2538             handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
2539         }
2540     }
2541 
2542     /** Notifies that the top activity of the task is forced to be resizeable. */
handleForcedResizableTaskIfNeeded(Task task, int reason)2543     private void handleForcedResizableTaskIfNeeded(Task task, int reason) {
2544         final ActivityRecord topActivity = task.getTopNonFinishingActivity();
2545         if (topActivity == null || topActivity.noDisplay
2546                 || !topActivity.canForceResizeNonResizable(task.getWindowingMode())) {
2547             return;
2548         }
2549         mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
2550                 task.mTaskId, reason, topActivity.info.applicationInfo.packageName);
2551     }
2552 
scheduleUpdateMultiWindowMode(Task task)2553     void scheduleUpdateMultiWindowMode(Task task) {
2554         task.forAllActivities(r -> {
2555             if (r.attachedToProcess()) {
2556                 mMultiWindowModeChangedActivities.add(r);
2557             }
2558         });
2559 
2560         if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
2561             mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
2562         }
2563     }
2564 
scheduleUpdatePictureInPictureModeIfNeeded(Task task, Task prevRootTask)2565     void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Task prevRootTask) {
2566         final Task rootTask = task.getRootTask();
2567         if ((prevRootTask == null || (prevRootTask != rootTask
2568                 && !prevRootTask.inPinnedWindowingMode() && !rootTask.inPinnedWindowingMode()))) {
2569             return;
2570         }
2571 
2572         scheduleUpdatePictureInPictureModeIfNeeded(task, rootTask.getRequestedOverrideBounds());
2573     }
2574 
scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds)2575     void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds) {
2576         task.forAllActivities(r -> {
2577             if (!r.attachedToProcess()) return;
2578             mPipModeChangedActivities.add(r);
2579             // If we are scheduling pip change, then remove this activity from multi-window
2580             // change list as the processing of pip change will make sure multi-window changed
2581             // message is processed in the right order relative to pip changed.
2582             mMultiWindowModeChangedActivities.remove(r);
2583         });
2584 
2585         mPipModeChangedTargetRootTaskBounds = targetRootTaskBounds;
2586 
2587         if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
2588             mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
2589         }
2590     }
2591 
wakeUp(String reason)2592     void wakeUp(String reason) {
2593         mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_APPLICATION,
2594                 "android.server.am:TURN_ON:" + reason);
2595     }
2596 
2597     /** Starts a batch of visibility updates. */
beginActivityVisibilityUpdate()2598     void beginActivityVisibilityUpdate() {
2599         if (mVisibilityTransactionDepth == 0) {
2600             getKeyguardController().updateVisibility();
2601         }
2602         mVisibilityTransactionDepth++;
2603     }
2604 
2605     /** Ends a batch of visibility updates. */
endActivityVisibilityUpdate()2606     void endActivityVisibilityUpdate() {
2607         mVisibilityTransactionDepth--;
2608         if (mVisibilityTransactionDepth == 0) {
2609             computeProcessActivityStateBatch();
2610         }
2611     }
2612 
2613     /** Returns {@code true} if the caller is on the path to update visibility. */
inActivityVisibilityUpdate()2614     boolean inActivityVisibilityUpdate() {
2615         return mVisibilityTransactionDepth > 0;
2616     }
2617 
setDeferRootVisibilityUpdate(boolean deferUpdate)2618     void setDeferRootVisibilityUpdate(boolean deferUpdate) {
2619         mDeferRootVisibilityUpdate = deferUpdate;
2620     }
2621 
isRootVisibilityUpdateDeferred()2622     boolean isRootVisibilityUpdateDeferred() {
2623         return mDeferRootVisibilityUpdate;
2624     }
2625 
2626     /**
2627      * Called when the state or visibility of an attached activity is changed.
2628      *
2629      * @param wpc The process who owns the activity.
2630      * @param forceBatch Whether to put the changed record to a pending list. If the caller is not
2631      *                   in the path of visibility update ({@link #inActivityVisibilityUpdate}), it
2632      *                   must call {@link #computeProcessActivityStateBatch} manually.
2633      */
onProcessActivityStateChanged(WindowProcessController wpc, boolean forceBatch)2634     void onProcessActivityStateChanged(WindowProcessController wpc, boolean forceBatch) {
2635         if (forceBatch || inActivityVisibilityUpdate()) {
2636             if (!mActivityStateChangedProcs.contains(wpc)) {
2637                 mActivityStateChangedProcs.add(wpc);
2638             }
2639             return;
2640         }
2641         wpc.computeProcessActivityState();
2642     }
2643 
computeProcessActivityStateBatch()2644     void computeProcessActivityStateBatch() {
2645         if (mActivityStateChangedProcs.isEmpty()) {
2646             return;
2647         }
2648         for (int i = mActivityStateChangedProcs.size() - 1; i >= 0; i--) {
2649             mActivityStateChangedProcs.get(i).computeProcessActivityState();
2650         }
2651         mActivityStateChangedProcs.clear();
2652     }
2653 
2654     /**
2655      * Begin deferring resume to avoid duplicate resumes in one pass.
2656      */
beginDeferResume()2657     void beginDeferResume() {
2658         mDeferResumeCount++;
2659     }
2660 
2661     /**
2662      * End deferring resume and determine if resume can be called.
2663      */
endDeferResume()2664     void endDeferResume() {
2665         mDeferResumeCount--;
2666     }
2667 
2668     /** @return True if resume can be called. */
readyToResume()2669     boolean readyToResume() {
2670         return mDeferResumeCount == 0;
2671     }
2672 
2673     private final class ActivityTaskSupervisorHandler extends Handler {
2674 
ActivityTaskSupervisorHandler(Looper looper)2675         ActivityTaskSupervisorHandler(Looper looper) {
2676             super(looper);
2677         }
2678 
2679         @Override
handleMessage(Message msg)2680         public void handleMessage(Message msg) {
2681             synchronized (mService.mGlobalLock) {
2682                 if (handleMessageInner(msg)) {
2683                     return;
2684                 }
2685             }
2686             // The cases that some invocations cannot be locked by WM.
2687             switch (msg.what) {
2688                 case RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG: {
2689                     final ActivityRecord r = (ActivityRecord) msg.obj;
2690                     String processName = null;
2691                     int uid = 0;
2692                     synchronized (mService.mGlobalLock) {
2693                         if (r.attachedToProcess() && r.isState(RESTARTING_PROCESS)) {
2694                             processName = r.app.mName;
2695                             uid = r.app.mUid;
2696                         }
2697                     }
2698                     if (processName != null) {
2699                         mService.mAmInternal.killProcess(processName, uid,
2700                                 "restartActivityProcessTimeout");
2701                     }
2702                 } break;
2703             }
2704         }
2705 
activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout)2706         private void activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout) {
2707             activityIdleInternal(idleActivity, fromTimeout,
2708                     fromTimeout /* processPausingActivities */, null /* config */);
2709         }
2710 
2711         /**
2712          * Handles the message with lock held.
2713          *
2714          * @return {@code true} if the message is handled.
2715          */
handleMessageInner(Message msg)2716         private boolean handleMessageInner(Message msg) {
2717             switch (msg.what) {
2718                 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
2719                     for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
2720                         final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
2721                         r.updateMultiWindowMode();
2722                     }
2723                 } break;
2724                 case REPORT_PIP_MODE_CHANGED_MSG: {
2725                     for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
2726                         final ActivityRecord r = mPipModeChangedActivities.remove(i);
2727                         r.updatePictureInPictureMode(mPipModeChangedTargetRootTaskBounds,
2728                                 false /* forceUpdate */);
2729                     }
2730                 } break;
2731                 case IDLE_TIMEOUT_MSG: {
2732                     if (DEBUG_IDLE) Slog.d(TAG_IDLE,
2733                             "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2734                     // We don't at this point know if the activity is fullscreen, so we need to be
2735                     // conservative and assume it isn't.
2736                     activityIdleFromMessage((ActivityRecord) msg.obj, true /* fromTimeout */);
2737                 } break;
2738                 case IDLE_NOW_MSG: {
2739                     if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2740                     activityIdleFromMessage((ActivityRecord) msg.obj, false /* fromTimeout */);
2741                 } break;
2742                 case RESUME_TOP_ACTIVITY_MSG: {
2743                     mRootWindowContainer.resumeFocusedTasksTopActivities();
2744                 } break;
2745                 case SLEEP_TIMEOUT_MSG: {
2746                     if (mService.isSleepingOrShuttingDownLocked()) {
2747                         Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2748                         checkReadyForSleepLocked(false /* allowDelay */);
2749                     }
2750                 } break;
2751                 case LAUNCH_TIMEOUT_MSG: {
2752                     if (mLaunchingActivityWakeLock.isHeld()) {
2753                         Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2754                         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
2755                             throw new IllegalStateException("Calling must be system uid");
2756                         }
2757                         mLaunchingActivityWakeLock.release();
2758                     }
2759                 } break;
2760                 case PROCESS_STOPPING_AND_FINISHING_MSG: {
2761                     processStoppingAndFinishingActivities(null /* launchedActivity */,
2762                             false /* processPausingActivities */, "transit");
2763                 } break;
2764                 case KILL_TASK_PROCESSES_TIMEOUT_MSG: {
2765                     final Task task = (Task) msg.obj;
2766                     if (task.mKillProcessesOnDestroyed) {
2767                         Slog.i(TAG, "Destroy timeout of remove-task, attempt to kill " + task);
2768                         killTaskProcessesIfPossible(task);
2769                     }
2770                 } break;
2771                 case LAUNCH_TASK_BEHIND_COMPLETE: {
2772                     final ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2773                     if (r != null) {
2774                         handleLaunchTaskBehindCompleteLocked(r);
2775                     }
2776                 } break;
2777                 case START_HOME_MSG: {
2778                     mHandler.removeMessages(START_HOME_MSG);
2779 
2780                     // Start home activities on displays with no activities.
2781                     mRootWindowContainer.startHomeOnEmptyDisplays((String) msg.obj);
2782                 } break;
2783                 case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: {
2784                     final ActivityRecord r = (ActivityRecord) msg.obj;
2785                     Slog.w(TAG, "Activity top resumed state loss timeout for " + r);
2786                     if (r.hasProcess()) {
2787                         mService.logAppTooSlow(r.app, r.topResumedStateLossTime,
2788                                 "top state loss for " + r);
2789                     }
2790                     handleTopResumedStateReleased(true /* timeout */);
2791                 } break;
2792                 default:
2793                     return false;
2794             }
2795             return true;
2796         }
2797     }
2798 
2799     /**
2800      * Start the given task from the recent tasks. Do not hold WM global lock when calling this
2801      * method to avoid potential deadlock or permission deny by UriGrantsManager when resolving
2802      * activity (see {@link ActivityStarter.Request#resolveActivity} and
2803      * {@link com.android.server.am.ContentProviderHelper#checkContentProviderUriPermission}).
2804      *
2805      * @return The result code of starter.
2806      */
startActivityFromRecents(int callingPid, int callingUid, int taskId, SafeActivityOptions options)2807     int startActivityFromRecents(int callingPid, int callingUid, int taskId,
2808             SafeActivityOptions options) {
2809         final Task task;
2810         final int taskCallingUid;
2811         final String callingPackage;
2812         final String callingFeatureId;
2813         final Intent intent;
2814         final int userId;
2815         final ActivityOptions activityOptions = options != null
2816                 ? options.getOptions(this)
2817                 : null;
2818         boolean moveHomeTaskForward = true;
2819         synchronized (mService.mGlobalLock) {
2820             final boolean isCallerRecents = mRecentTasks.isCallerRecents(callingUid);
2821             int activityType = ACTIVITY_TYPE_UNDEFINED;
2822             if (activityOptions != null) {
2823                 activityType = activityOptions.getLaunchActivityType();
2824                 if (activityOptions.freezeRecentTasksReordering() && (isCallerRecents
2825                         || ActivityTaskManagerService.checkPermission(MANAGE_ACTIVITY_TASKS,
2826                                 callingPid, callingUid) == PERMISSION_GRANTED)) {
2827                     mRecentTasks.setFreezeTaskListReordering();
2828                 }
2829                 if (activityOptions.getLaunchRootTask() != null) {
2830                     // Don't move home activity forward if there is a launch root set.
2831                     moveHomeTaskForward = false;
2832                 }
2833             }
2834             if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) {
2835                 throw new IllegalArgumentException("startActivityFromRecents: Task "
2836                         + taskId + " can't be launch in the home/recents root task.");
2837             }
2838 
2839             boolean shouldStartActivity = false;
2840             mService.deferWindowLayout();
2841             try {
2842                 task = mRootWindowContainer.anyTaskForId(taskId,
2843                         MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, activityOptions, ON_TOP);
2844                 if (task == null) {
2845                     mWindowManager.executeAppTransition();
2846                     throw new IllegalArgumentException(
2847                             "startActivityFromRecents: Task " + taskId + " not found.");
2848                 }
2849 
2850                 if (moveHomeTaskForward) {
2851                     // We always want to return to the home activity instead of the recents
2852                     // activity from whatever is started from the recents activity, so move
2853                     // the home root task forward.
2854                     // TODO (b/115289124): Multi-display supports for recents.
2855                     mRootWindowContainer.getDefaultTaskDisplayArea().moveHomeRootTaskToFront(
2856                             "startActivityFromRecents");
2857                 }
2858 
2859                 // If the user must confirm credentials (e.g. when first launching a work
2860                 // app and the Work Challenge is present) let startActivityInPackage handle
2861                 // the intercepting.
2862                 if (!mService.mAmInternal.shouldConfirmCredentials(task.mUserId)
2863                         && task.getRootActivity() != null) {
2864                     final ActivityRecord targetActivity = task.getTopNonFinishingActivity();
2865 
2866                     mRootWindowContainer.startPowerModeLaunchIfNeeded(
2867                             true /* forceSend */, targetActivity);
2868                     final LaunchingState launchingState =
2869                             mActivityMetricsLogger.notifyActivityLaunching(task.intent,
2870                                     // Recents always has a new launching state (not combinable).
2871                                     null /* caller */, isCallerRecents ? INVALID_UID : callingUid);
2872                     try {
2873                         mService.moveTaskToFrontLocked(null /* appThread */,
2874                                 null /* callingPackage */, task.mTaskId, 0, options);
2875                         // Apply options to prevent pendingOptions be taken when scheduling
2876                         // activity lifecycle transaction to make sure the override pending app
2877                         // transition will be applied immediately.
2878                         if (activityOptions != null
2879                                 && activityOptions.getAnimationType() == ANIM_REMOTE_ANIMATION) {
2880                             targetActivity.mPendingRemoteAnimation =
2881                                     activityOptions.getRemoteAnimationAdapter();
2882                         }
2883                         targetActivity.applyOptionsAnimation();
2884                         if (activityOptions != null && activityOptions.getLaunchCookie() != null) {
2885                             targetActivity.mLaunchCookie = activityOptions.getLaunchCookie();
2886                         }
2887                     } finally {
2888                         mActivityMetricsLogger.notifyActivityLaunched(launchingState,
2889                                 START_TASK_TO_FRONT, false /* newActivityCreated */,
2890                                 targetActivity, activityOptions);
2891                     }
2892 
2893                     mService.getActivityStartController().postStartActivityProcessingForLastStarter(
2894                             task.getTopNonFinishingActivity(), ActivityManager.START_TASK_TO_FRONT,
2895                             task.getRootTask());
2896 
2897                     // As it doesn't go to ActivityStarter.executeRequest() path, we need to resume
2898                     // app switching here also.
2899                     mService.resumeAppSwitches();
2900                     return ActivityManager.START_TASK_TO_FRONT;
2901                 }
2902                 // The task is empty or needs to show the confirmation for credential.
2903                 shouldStartActivity = true;
2904             } finally {
2905                 if (!shouldStartActivity) {
2906                     mService.continueWindowLayout();
2907                 }
2908             }
2909             taskCallingUid = task.mCallingUid;
2910             callingPackage = task.mCallingPackage;
2911             callingFeatureId = task.mCallingFeatureId;
2912             intent = task.intent;
2913             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
2914             userId = task.mUserId;
2915         }
2916         // ActivityStarter will acquire the lock where the places need, so execute the request
2917         // outside of the lock.
2918         try {
2919             // We need to temporarily disable the explicit intent filter matching enforcement
2920             // because Task does not store the resolved type of the intent data, causing filter
2921             // mismatch in certain cases. (b/240373119)
2922             PackageManagerServiceUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(true);
2923             return mService.getActivityStartController().startActivityInPackage(taskCallingUid,
2924                     callingPid, callingUid, callingPackage, callingFeatureId, intent, null, null,
2925                     null, 0, 0, options, userId, task, "startActivityFromRecents",
2926                     false /* validateIncomingUser */, null /* originatingPendingIntent */,
2927                     BackgroundStartPrivileges.NONE);
2928         } finally {
2929             PackageManagerServiceUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(false);
2930             synchronized (mService.mGlobalLock) {
2931                 mService.continueWindowLayout();
2932             }
2933         }
2934     }
2935 
2936     /** The helper to get the top opaque activity of a container. */
2937     static class OpaqueActivityHelper implements Predicate<ActivityRecord> {
2938         private ActivityRecord mStarting;
2939         private boolean mIncludeInvisibleAndFinishing;
2940 
getOpaqueActivity(@onNull WindowContainer<?> container)2941         ActivityRecord getOpaqueActivity(@NonNull WindowContainer<?> container) {
2942             mIncludeInvisibleAndFinishing = true;
2943             return container.getActivity(this,
2944                     true /* traverseTopToBottom */, null /* boundary */);
2945         }
2946 
getVisibleOpaqueActivity(@onNull WindowContainer<?> container, @Nullable ActivityRecord starting)2947         ActivityRecord getVisibleOpaqueActivity(@NonNull WindowContainer<?> container,
2948                 @Nullable ActivityRecord starting) {
2949             mStarting = starting;
2950             mIncludeInvisibleAndFinishing = false;
2951             final ActivityRecord opaque = container.getActivity(this,
2952                     true /* traverseTopToBottom */, null /* boundary */);
2953             mStarting = null;
2954             return opaque;
2955         }
2956 
2957         @Override
test(ActivityRecord r)2958         public boolean test(ActivityRecord r) {
2959             if (!mIncludeInvisibleAndFinishing && !r.visibleIgnoringKeyguard && r != mStarting) {
2960                 // Ignore invisible activities that are not the currently starting activity
2961                 // (about to be visible).
2962                 return false;
2963             }
2964             return r.occludesParent(mIncludeInvisibleAndFinishing /* includingFinishing */);
2965         }
2966     }
2967 
2968     /**
2969      * Fills the info that needs to iterate all activities of task, such as the number of
2970      * non-finishing activities and collecting launch cookies.
2971      */
2972     static class TaskInfoHelper implements Consumer<ActivityRecord> {
2973         private TaskInfo mInfo;
2974         private ActivityRecord mTopRunning;
2975 
fillAndReturnTop(Task task, TaskInfo info)2976         ActivityRecord fillAndReturnTop(Task task, TaskInfo info) {
2977             info.numActivities = 0;
2978             info.baseActivity = null;
2979             mInfo = info;
2980             task.forAllActivities(this);
2981             final ActivityRecord top = mTopRunning;
2982             mTopRunning = null;
2983             mInfo = null;
2984             return top;
2985         }
2986 
2987         @Override
accept(ActivityRecord r)2988         public void accept(ActivityRecord r) {
2989             if (r.mLaunchCookie != null) {
2990                 mInfo.addLaunchCookie(r.mLaunchCookie);
2991             }
2992             if (r.finishing) {
2993                 return;
2994             }
2995             mInfo.numActivities++;
2996             mInfo.baseActivity = r.mActivityComponent;
2997             if (mTopRunning == null) {
2998                 mTopRunning = r;
2999             }
3000         }
3001     }
3002 
3003     /**
3004      * Internal container to store a match qualifier alongside a WaitResult.
3005      */
3006     private static class WaitInfo {
3007         final WaitResult mResult;
3008         final ComponentName mTargetComponent;
3009         /**
3010          * The target component may not be the final drawn activity. The launching state is managed
3011          * by {@link ActivityMetricsLogger} that can track consecutive launching sequence.
3012          */
3013         final LaunchingState mLaunchingState;
3014 
WaitInfo(WaitResult result, ComponentName component, LaunchingState launchingState)3015         WaitInfo(WaitResult result, ComponentName component, LaunchingState launchingState) {
3016             mResult = result;
3017             mTargetComponent = component;
3018             mLaunchingState = launchingState;
3019         }
3020 
matches(ActivityRecord r)3021         boolean matches(ActivityRecord r) {
3022             if (!mLaunchingState.hasActiveTransitionInfo()) {
3023                 return mTargetComponent.equals(r.mActivityComponent);
3024             }
3025             return mLaunchingState.contains(r);
3026         }
3027 
dump(PrintWriter pw, String prefix)3028         void dump(PrintWriter pw, String prefix) {
3029             pw.println(prefix + "WaitInfo:");
3030             pw.println(prefix + "  mTargetComponent=" + mTargetComponent);
3031             pw.println(prefix + "  mResult=");
3032             mResult.dump(pw, prefix + "    ");
3033         }
3034     }
3035 }
3036