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                 /* task_stack */
1757                 null
1758         );
1759 
1760         boolean restrictActivitySwitch = ActivitySecurityModelFeatureFlags
1761                 .shouldRestrictActivitySwitch(callingUid)
1762                 && shouldBlockActivitySwitchIfFeatureEnabled;
1763 
1764         PackageManager pm = mService.mContext.getPackageManager();
1765         String callingPackage = pm.getNameForUid(callingUid);
1766         final CharSequence callingLabel;
1767         if (callingPackage == null) {
1768             callingPackage = String.valueOf(callingUid);
1769             callingLabel = callingPackage;
1770         } else {
1771             callingLabel = getApplicationLabel(pm, callingPackage);
1772         }
1773 
1774         if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)) {
1775             UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
1776                     (ActivitySecurityModelFeatureFlags.DOC_LINK
1777                             + (restrictActivitySwitch ? " returned home due to "
1778                                     : " would return home due to ")
1779                             + callingLabel), Toast.LENGTH_LONG).show());
1780         }
1781 
1782         // If the activity switch should be restricted, return home rather than the
1783         // previously top task, to prevent users from being confused which app they're
1784         // viewing
1785         if (restrictActivitySwitch) {
1786             Slog.w(TAG, "[ASM] Return to home as source: " + callingPackage
1787                     + " is not on top of task t: " + task);
1788             displayArea.moveHomeActivityToTop("taskRemoved");
1789         } else {
1790             Slog.i(TAG, "[ASM] Would return to home as source: " + callingPackage
1791                     + " is not on top of task t: " + task);
1792         }
1793     }
1794 
1795     /**
1796      *  For the purpose of ASM, ‘Top UID” for a task is defined as an activity UID
1797      *  1. Which is top of the stack in z-order
1798      *      a. Excluding any activities with the flag ‘isAlwaysOnTop’ and
1799      *      b. Excluding any activities which are `finishing`
1800      *  2. Or top of an adjacent task fragment to (1)
1801      *
1802      *  The 'sourceRecord' can be considered top even if it is 'finishing'
1803      *
1804      * @return A pair where the first value is the return value matching the checks above, and the
1805      * second value is the return value disregarding the feature flag or target api levels. Use the
1806      * first value for blocking launches - the second value is only used to determine if a toast
1807      * should be displayed, and will be used alongside a feature flag in {@link ActivityStarter}.
1808      */
1809     // TODO(b/263368846) Shift to BackgroundActivityStartController once class is ready
1810     @Nullable
doesTopActivityMatchingUidExistForAsm(@ullable Task task, int uid, @Nullable ActivityRecord sourceRecord)1811     static Pair<Boolean, Boolean> doesTopActivityMatchingUidExistForAsm(@Nullable Task task,
1812             int uid, @Nullable ActivityRecord sourceRecord) {
1813         // If the source is visible, consider it 'top'.
1814         if (sourceRecord != null && sourceRecord.isVisible()) {
1815             return new Pair<>(true, true);
1816         }
1817 
1818         // Always allow actual top activity to clear task
1819         ActivityRecord topActivity = task.getTopMostActivity();
1820         if (topActivity != null && topActivity.isUid(uid)) {
1821             return new Pair<>(true, true);
1822         }
1823 
1824         // Consider the source activity, whether or not it is finishing. Do not consider any other
1825         // finishing activity.
1826         Predicate<ActivityRecord> topOfStackPredicate = (ar) -> ar.equals(sourceRecord)
1827                 || (!ar.finishing && !ar.isAlwaysOnTop());
1828 
1829         // Check top of stack (or the first task fragment for embedding).
1830         topActivity = task.getActivity(topOfStackPredicate);
1831         if (topActivity == null) {
1832             return new Pair<>(false, false);
1833         }
1834 
1835         Pair<Boolean, Boolean> pair = topActivity.allowCrossUidActivitySwitchFromBelow(uid);
1836         if (pair.first) {
1837             return new Pair<>(true, pair.second);
1838         }
1839 
1840         // Even if the top activity is not a match, we may be in an embedded activity scenario with
1841         // an adjacent task fragment. Get the second fragment.
1842         TaskFragment taskFragment = topActivity.getTaskFragment();
1843         if (taskFragment == null) {
1844             return new Pair<>(false, false);
1845         }
1846 
1847         TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
1848         if (adjacentTaskFragment == null) {
1849             return new Pair<>(false, false);
1850         }
1851 
1852         // Check the second fragment.
1853         topActivity = adjacentTaskFragment.getActivity(topOfStackPredicate);
1854         if (topActivity == null) {
1855             return new Pair<>(false, false);
1856         }
1857 
1858         return topActivity.allowCrossUidActivitySwitchFromBelow(uid);
1859     }
1860 
getApplicationLabel(PackageManager pm, String packageName)1861     static CharSequence getApplicationLabel(PackageManager pm, String packageName) {
1862         try {
1863             ApplicationInfo launchedFromPackageInfo = pm.getApplicationInfo(
1864                     packageName, PackageManager.ApplicationInfoFlags.of(0));
1865             return pm.getApplicationLabel(launchedFromPackageInfo);
1866         } catch (PackageManager.NameNotFoundException e) {
1867             return packageName;
1868         }
1869     }
1870 
1871     /** This method should only be called for leaf task. */
cleanUpRemovedTask(Task task, boolean killProcess, boolean removeFromRecents)1872     private void cleanUpRemovedTask(Task task, boolean killProcess, boolean removeFromRecents) {
1873         if (removeFromRecents) {
1874             mRecentTasks.remove(task);
1875         }
1876         final Intent baseIntent = task.getBaseIntent();
1877         final ComponentName component = baseIntent != null ? baseIntent.getComponent() : null;
1878         if (component == null) {
1879             Slog.w(TAG, "No component for base intent of task: " + task);
1880             return;
1881         }
1882 
1883         // Find any running services associated with this app and stop if needed.
1884         final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::cleanUpServices,
1885                 mService.mAmInternal, task.mUserId, component, new Intent(baseIntent));
1886         mService.mH.sendMessage(msg);
1887 
1888         if (!killProcess) {
1889             return;
1890         }
1891         // Give a chance for the client to handle Activity#onStop(). The timeout waits for
1892         // onDestroy because the client defers to report completion of stopped, the callback from
1893         // DestroyActivityItem may be called first.
1894         final ActivityRecord top = task.getTopMostActivity();
1895         if (top != null && top.finishing && !top.mAppStopped && top.lastVisibleTime > 0
1896                 && !task.mKillProcessesOnDestroyed && top.hasProcess()) {
1897             task.mKillProcessesOnDestroyed = true;
1898             mHandler.sendMessageDelayed(
1899                     mHandler.obtainMessage(KILL_TASK_PROCESSES_TIMEOUT_MSG, task),
1900                     KILL_TASK_PROCESSES_TIMEOUT_MS);
1901             return;
1902         }
1903         killTaskProcessesIfPossible(task);
1904     }
1905 
killTaskProcessesOnDestroyedIfNeeded(Task task)1906     void killTaskProcessesOnDestroyedIfNeeded(Task task) {
1907         if (task == null || !task.mKillProcessesOnDestroyed) return;
1908         mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task);
1909         killTaskProcessesIfPossible(task);
1910     }
1911 
1912     /** Kills the processes in the task if it doesn't contain perceptible components. */
killTaskProcessesIfPossible(Task task)1913     private void killTaskProcessesIfPossible(Task task) {
1914         task.mKillProcessesOnDestroyed = false;
1915         final String pkg = task.getBasePackageName();
1916         ArrayList<Object> procsToKill = null;
1917         ArrayMap<String, SparseArray<WindowProcessController>> pmap =
1918                 mService.mProcessNames.getMap();
1919         for (int i = 0; i < pmap.size(); i++) {
1920 
1921             SparseArray<WindowProcessController> uids = pmap.valueAt(i);
1922             for (int j = 0; j < uids.size(); j++) {
1923                 WindowProcessController proc = uids.valueAt(j);
1924                 if (proc.mUserId != task.mUserId) {
1925                     // Don't kill process for a different user.
1926                     continue;
1927                 }
1928                 if (proc == mService.mHomeProcess) {
1929                     // Don't kill the home process along with tasks from the same package.
1930                     continue;
1931                 }
1932                 if (!proc.containsPackage(pkg)) {
1933                     // Don't kill process that is not associated with this task.
1934                     continue;
1935                 }
1936 
1937                 if (!proc.shouldKillProcessForRemovedTask(task)) {
1938                     // Don't kill process(es) that has an activity in a different task that is also
1939                     // in recents, or has an activity not stopped.
1940                     return;
1941                 }
1942 
1943                 if (proc.hasForegroundServices()) {
1944                     // Don't kill process(es) with foreground service.
1945                     return;
1946                 }
1947 
1948                 if (procsToKill == null) {
1949                     procsToKill = new ArrayList<>();
1950                 }
1951                 // Add process to kill list.
1952                 procsToKill.add(proc);
1953             }
1954         }
1955         if (procsToKill == null) return;
1956 
1957         // Kill the running processes. Post on handle since we don't want to hold the service lock
1958         // while calling into AM.
1959         final Message m = PooledLambda.obtainMessage(
1960                 ActivityManagerInternal::killProcessesForRemovedTask, mService.mAmInternal,
1961                 procsToKill);
1962         mService.mH.sendMessage(m);
1963     }
1964 
1965     /**
1966      * Called to restore the state of the task into the root task that it's supposed to go into.
1967      *
1968      * @param task The recent task to be restored.
1969      * @param aOptions The activity options to use for restoration.
1970      * @param onTop If the root task for the task should be the topmost on the display.
1971      * @return true if the task has been restored successfully.
1972      */
restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop)1973     boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) {
1974         final Task rootTask =
1975                 mRootWindowContainer.getOrCreateRootTask(null, aOptions, task, onTop);
1976         final WindowContainer parent = task.getParent();
1977 
1978         if (parent == rootTask || task == rootTask) {
1979             // Nothing else to do since it is already restored in the right root task.
1980             return true;
1981         }
1982 
1983         if (parent != null) {
1984             // Task has already been restored once. Just re-parent it to the new root task.
1985             task.reparent(rootTask, POSITION_TOP, true /*moveParents*/, "restoreRecentTaskLocked");
1986             return true;
1987         }
1988 
1989         rootTask.addChild(task, onTop, true /* showForAllUsers */);
1990         if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
1991                 "Added restored task=" + task + " to root task=" + rootTask);
1992         return true;
1993     }
1994 
1995     @Override
onRecentTaskAdded(Task task)1996     public void onRecentTaskAdded(Task task) {
1997         task.touchActiveTime();
1998     }
1999 
2000     @Override
onRecentTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess)2001     public void onRecentTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess) {
2002         if (wasTrimmed) {
2003             // Task was trimmed from the recent tasks list -- remove the active task record as well
2004             // since the user won't really be able to go back to it
2005             removeTaskById(task.mTaskId, killProcess, false /* removeFromRecents */,
2006                     "recent-task-trimmed", SYSTEM_UID);
2007         }
2008         task.removedFromRecents();
2009     }
2010 
2011     /**
2012      * Returns the reparent target root task, creating the root task if necessary.  This call
2013      * also enforces the various checks on tasks that are going to be reparented from one root
2014      * task to another.
2015      */
2016     // TODO: Look into changing users to this method to DisplayContent.resolveWindowingMode()
getReparentTargetRootTask(Task task, Task rootTask, boolean toTop)2017     Task getReparentTargetRootTask(Task task, Task rootTask, boolean toTop) {
2018         final Task prevRootTask = task.getRootTask();
2019         final int rootTaskId = rootTask.mTaskId;
2020         final boolean inMultiWindowMode = rootTask.inMultiWindowMode();
2021 
2022         // Check that we aren't reparenting to the same root task that the task is already in
2023         if (prevRootTask != null && prevRootTask.mTaskId == rootTaskId) {
2024             Slog.w(TAG, "Can not reparent to same root task, task=" + task
2025                     + " already in rootTaskId=" + rootTaskId);
2026             return prevRootTask;
2027         }
2028 
2029         // Ensure that we aren't trying to move into a multi-window root task without multi-window
2030         // support
2031         if (inMultiWindowMode && !mService.mSupportsMultiWindow) {
2032             throw new IllegalArgumentException("Device doesn't support multi-window, can not"
2033                     + " reparent task=" + task + " to root-task=" + rootTask);
2034         }
2035 
2036         // Ensure that we're not moving a task to a dynamic root task if device doesn't support
2037         // multi-display.
2038         if (rootTask.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) {
2039             throw new IllegalArgumentException("Device doesn't support multi-display, can not"
2040                     + " reparent task=" + task + " to rootTaskId=" + rootTaskId);
2041         }
2042 
2043         // Ensure that we aren't trying to move into a freeform root task without freeform support
2044         if (rootTask.getWindowingMode() == WINDOWING_MODE_FREEFORM
2045                 && !mService.mSupportsFreeformWindowManagement) {
2046             throw new IllegalArgumentException("Device doesn't support freeform, can not reparent"
2047                     + " task=" + task);
2048         }
2049 
2050         if (rootTask.inPinnedWindowingMode()) {
2051             throw new IllegalArgumentException("No support to reparent to PIP, task=" + task);
2052         }
2053 
2054         // Leave the task in its current root task or a fullscreen root task if it isn't
2055         // resizeable and the preferred root task is in multi-window mode.
2056         if (inMultiWindowMode
2057                 && !task.supportsMultiWindowInDisplayArea(rootTask.getDisplayArea())) {
2058             Slog.w(TAG, "Can not move unresizeable task=" + task + " to multi-window root task="
2059                     + rootTask + " Moving to a fullscreen root task instead.");
2060             if (prevRootTask != null) {
2061                 return prevRootTask;
2062             }
2063             rootTask = rootTask.getDisplayArea().createRootTask(
2064                     WINDOWING_MODE_FULLSCREEN, rootTask.getActivityType(), toTop);
2065         }
2066         return rootTask;
2067     }
2068 
goingToSleepLocked()2069     void goingToSleepLocked() {
2070         scheduleSleepTimeout();
2071         if (!mGoingToSleepWakeLock.isHeld()) {
2072             mGoingToSleepWakeLock.acquire();
2073             if (mLaunchingActivityWakeLock.isHeld()) {
2074                 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
2075                     throw new IllegalStateException("Calling must be system uid");
2076                 }
2077                 mLaunchingActivityWakeLock.release();
2078                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2079             }
2080         }
2081 
2082         mRootWindowContainer.applySleepTokens(false /* applyToRootTasks */);
2083 
2084         checkReadyForSleepLocked(true /* allowDelay */);
2085     }
2086 
shutdownLocked(int timeout)2087     boolean shutdownLocked(int timeout) {
2088         goingToSleepLocked();
2089 
2090         boolean timedout = false;
2091         final long endTime = System.currentTimeMillis() + timeout;
2092         while (true) {
2093             if (!mRootWindowContainer.putTasksToSleep(
2094                     true /* allowDelay */, true /* shuttingDown */)) {
2095                 long timeRemaining = endTime - System.currentTimeMillis();
2096                 if (timeRemaining > 0) {
2097                     try {
2098                         mService.mGlobalLock.wait(timeRemaining);
2099                     } catch (InterruptedException e) {
2100                     }
2101                 } else {
2102                     Slog.w(TAG, "Activity manager shutdown timed out");
2103                     timedout = true;
2104                     break;
2105                 }
2106             } else {
2107                 break;
2108             }
2109         }
2110 
2111         // Force checkReadyForSleep to complete.
2112         checkReadyForSleepLocked(false /* allowDelay */);
2113 
2114         return timedout;
2115     }
2116 
comeOutOfSleepIfNeededLocked()2117     void comeOutOfSleepIfNeededLocked() {
2118         removeSleepTimeouts();
2119         if (mGoingToSleepWakeLock.isHeld()) {
2120             mGoingToSleepWakeLock.release();
2121         }
2122     }
2123 
checkReadyForSleepLocked(boolean allowDelay)2124     void checkReadyForSleepLocked(boolean allowDelay) {
2125         if (!mService.isSleepingOrShuttingDownLocked()) {
2126             // Do not care.
2127             return;
2128         }
2129 
2130         if (!mRootWindowContainer.putTasksToSleep(
2131                 allowDelay, false /* shuttingDown */)) {
2132             return;
2133         }
2134 
2135         // End power mode launch before going sleep
2136         mService.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_ALL);
2137 
2138         // Rank task layers to make sure the {@link Task#mLayerRank} is updated.
2139         mRootWindowContainer.rankTaskLayers();
2140 
2141         removeSleepTimeouts();
2142 
2143         if (mGoingToSleepWakeLock.isHeld()) {
2144             mGoingToSleepWakeLock.release();
2145         }
2146         if (mService.mShuttingDown) {
2147             mService.mGlobalLock.notifyAll();
2148         }
2149     }
2150 
reportResumedActivityLocked(ActivityRecord r)2151     boolean reportResumedActivityLocked(ActivityRecord r) {
2152         // A resumed activity cannot be stopping. remove from list
2153         mStoppingActivities.remove(r);
2154 
2155         final Task rootTask = r.getRootTask();
2156         if (rootTask.getDisplayArea().allResumedActivitiesComplete()) {
2157             mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2158             // Make sure activity & window visibility should be identical
2159             // for all displays in this stage.
2160             mRootWindowContainer.executeAppTransitionForAllDisplay();
2161             return true;
2162         }
2163         return false;
2164     }
2165 
2166     // Called when WindowManager has finished animating the launchingBehind activity to the back.
handleLaunchTaskBehindCompleteLocked(ActivityRecord r)2167     private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2168         final Task task = r.getTask();
2169         final Task rootTask = task.getRootTask();
2170 
2171         mRecentTasks.add(task);
2172         mService.getTaskChangeNotificationController().notifyTaskStackChanged();
2173         rootTask.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2174 
2175         // When launching tasks behind, update the last active time of the top task after the new
2176         // task has been shown briefly
2177         final ActivityRecord top = rootTask.getTopNonFinishingActivity();
2178         if (top != null) {
2179             top.getTask().touchActiveTime();
2180         }
2181     }
2182 
scheduleLaunchTaskBehindComplete(IBinder token)2183     void scheduleLaunchTaskBehindComplete(IBinder token) {
2184         mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2185     }
2186 
2187     /**
2188      * Processes the activities to be stopped or destroyed. This should be called when the resumed
2189      * activities are idle or drawn.
2190      */
processStoppingAndFinishingActivities(ActivityRecord launchedActivity, boolean processPausingActivities, String reason)2191     void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
2192             boolean processPausingActivities, String reason) {
2193         // Stop any activities that are scheduled to do so but have been waiting for the transition
2194         // animation to finish.
2195         boolean displaySwapping = false;
2196         ArrayList<ActivityRecord> readyToStopActivities = null;
2197         for (int i = 0; i < mStoppingActivities.size(); i++) {
2198             final ActivityRecord s = mStoppingActivities.get(i);
2199             // Activity in a force hidden task should not be counted as animating, i.e., we want to
2200             // send onStop before any configuration change when removing pip transition is ongoing.
2201             final boolean animating = s.isInTransition()
2202                     && s.getTask() != null && !s.getTask().isForceHidden();
2203             displaySwapping |= s.isDisplaySleepingAndSwapping();
2204             ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
2205                     + "finishing=%s", s, s.nowVisible, animating, s.finishing);
2206             if ((!animating && !displaySwapping) || mService.mShuttingDown
2207                     || s.getRootTask().isForceHiddenForPinnedTask()) {
2208                 if (!processPausingActivities && s.isState(PAUSING)) {
2209                     // Defer processing pausing activities in this iteration and reschedule
2210                     // a delayed idle to reprocess it again
2211                     removeIdleTimeoutForActivity(launchedActivity);
2212                     scheduleIdleTimeout(launchedActivity);
2213                     continue;
2214                 }
2215 
2216                 ProtoLog.v(WM_DEBUG_STATES, "Ready to stop: %s", s);
2217                 if (readyToStopActivities == null) {
2218                     readyToStopActivities = new ArrayList<>();
2219                 }
2220                 readyToStopActivities.add(s);
2221 
2222                 mStoppingActivities.remove(i);
2223                 i--;
2224             }
2225         }
2226 
2227         // Stopping activities are deferred processing if the display is swapping. Check again
2228         // later to ensure the stopping activities can be stopped after display swapped.
2229         if (displaySwapping) {
2230             mHandler.postDelayed(() -> {
2231                 synchronized (mService.mGlobalLock) {
2232                     scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
2233                 }
2234             }, SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS);
2235         }
2236 
2237         final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
2238         for (int i = 0; i < numReadyStops; i++) {
2239             final ActivityRecord r = readyToStopActivities.get(i);
2240             if (r.isInHistory()) {
2241                 if (r.finishing) {
2242                     // TODO(b/137329632): Wait for idle of the right activity, not just any.
2243                     r.destroyIfPossible(reason);
2244                 } else {
2245                     r.stopIfPossible();
2246                 }
2247             }
2248         }
2249 
2250         final int numFinishingActivities = mFinishingActivities.size();
2251         if (numFinishingActivities == 0) {
2252             return;
2253         }
2254 
2255         // Finish any activities that are scheduled to do so but have been waiting for the next one
2256         // to start.
2257         final ArrayList<ActivityRecord> finishingActivities = new ArrayList<>(mFinishingActivities);
2258         mFinishingActivities.clear();
2259         for (int i = 0; i < numFinishingActivities; i++) {
2260             final ActivityRecord r = finishingActivities.get(i);
2261             if (r.isInHistory()) {
2262                 r.destroyImmediately("finish-" + reason);
2263             }
2264         }
2265     }
2266 
removeHistoryRecords(WindowProcessController app)2267     void removeHistoryRecords(WindowProcessController app) {
2268         removeHistoryRecords(mStoppingActivities, app, "mStoppingActivities");
2269         removeHistoryRecords(mFinishingActivities, app, "mFinishingActivities");
2270         removeHistoryRecords(mNoHistoryActivities, app, "mNoHistoryActivities");
2271     }
2272 
removeHistoryRecords(ArrayList<ActivityRecord> list, WindowProcessController app, String listName)2273     private void removeHistoryRecords(ArrayList<ActivityRecord> list, WindowProcessController app,
2274             String listName) {
2275         int i = list.size();
2276         if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
2277                 "Removing app " + this + " from list " + listName + " with " + i + " entries");
2278         while (i > 0) {
2279             i--;
2280             ActivityRecord r = list.get(i);
2281             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r);
2282             if (r.app == app) {
2283                 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!");
2284                 list.remove(i);
2285                 r.removeTimeouts();
2286             }
2287         }
2288     }
2289 
dump(PrintWriter pw, String prefix)2290     public void dump(PrintWriter pw, String prefix) {
2291         pw.println();
2292         pw.println("ActivityTaskSupervisor state:");
2293         mRootWindowContainer.dump(pw, prefix, true /* dumpAll */);
2294         getKeyguardController().dump(pw, prefix);
2295         mService.getLockTaskController().dump(pw, prefix);
2296         pw.print(prefix);
2297         pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
2298         pw.println(prefix + "mUserRootTaskInFront=" + mRootWindowContainer.mUserRootTaskInFront);
2299         pw.println(prefix + "mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
2300         pw.print(prefix); pw.print("isHomeRecentsComponent=");
2301         pw.println(mRecentTasks.isRecentsComponentHomeActivity(mRootWindowContainer.mCurrentUser));
2302         if (!mWaitingActivityLaunched.isEmpty()) {
2303             pw.println(prefix + "mWaitingActivityLaunched=");
2304             for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
2305                 mWaitingActivityLaunched.get(i).dump(pw, prefix + "  ");
2306             }
2307         }
2308         pw.println(prefix + "mNoHistoryActivities=" + mNoHistoryActivities);
2309         pw.println();
2310     }
2311 
printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, boolean needSep, String prefix, Runnable header)2312     static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2313             boolean needSep, String prefix, Runnable header) {
2314         return printThisActivity(pw, activity, dumpPackage, INVALID_DISPLAY, needSep, prefix,
2315                 header);
2316     }
2317 
printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, int displayIdFilter, boolean needSep, String prefix, Runnable header)2318     static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2319             int displayIdFilter, boolean needSep, String prefix, Runnable header) {
2320         if (activity != null && (displayIdFilter == INVALID_DISPLAY
2321                 || displayIdFilter == activity.getDisplayId())) {
2322             if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2323                 if (needSep) {
2324                     pw.println();
2325                 }
2326                 if (header != null) {
2327                     header.run();
2328                 }
2329                 pw.print(prefix);
2330                 pw.println(activity);
2331                 return true;
2332             }
2333         }
2334         return false;
2335     }
2336 
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)2337     static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2338             String prefix, String label, boolean complete, boolean brief, boolean client,
2339             String dumpPackage, boolean needNL, Runnable header, Task lastTask) {
2340         boolean printed = false;
2341         for (int i = list.size() - 1; i >= 0; i--) {
2342             final ActivityRecord r = list.get(i);
2343             ActivityRecord.dumpActivity(fd, pw, i, r, prefix, label, complete, brief,
2344                     client, dumpPackage, needNL, header, lastTask);
2345             lastTask = r.getTask();
2346             header = null;
2347             needNL = client && r.attachedToProcess();
2348         }
2349         return printed;
2350     }
2351 
scheduleIdleTimeout(ActivityRecord next)2352     void scheduleIdleTimeout(ActivityRecord next) {
2353         if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdleTimeout: Callers=" + Debug.getCallers(4));
2354         Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2355         mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2356     }
2357 
scheduleIdle()2358     final void scheduleIdle() {
2359         if (!mHandler.hasMessages(IDLE_NOW_MSG)) {
2360             if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdle: Callers=" + Debug.getCallers(4));
2361             mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2362         }
2363     }
2364 
2365     /**
2366      * Updates the record of top resumed activity when it changes and handles reporting of the
2367      * state changes to previous and new top activities. It will immediately dispatch top resumed
2368      * state loss message to previous top activity (if haven't done it already). After the previous
2369      * activity releases the top state and reports back, message about acquiring top state will be
2370      * sent to the new top resumed activity.
2371      */
updateTopResumedActivityIfNeeded(String reason)2372     void updateTopResumedActivityIfNeeded(String reason) {
2373         final ActivityRecord prevTopActivity = mTopResumedActivity;
2374         final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
2375         if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) {
2376             if (topRootTask == null) {
2377                 // There's no focused task and there won't have any resumed activity either.
2378                 scheduleTopResumedActivityStateLossIfNeeded();
2379             }
2380             if (mService.isSleepingLocked()) {
2381                 // There won't be a next resumed activity. The top process should still be updated
2382                 // according to the current top focused activity.
2383                 mService.updateTopApp(null /* topResumedActivity */);
2384             }
2385             return;
2386         }
2387 
2388         // Ask previous activity to release the top state.
2389         scheduleTopResumedActivityStateLossIfNeeded();
2390 
2391         // Update the current top activity.
2392         mTopResumedActivity = topRootTask.getTopResumedActivity();
2393         // Update process state if there is no activity state change (e.g. focus change between
2394         // multi-window mode activities) to make sure that the current top has top oom-adj.
2395         // If the previous top is null, there should be activity state change from it, Then the
2396         // process state should also have been updated so no need to update again.
2397         if (mTopResumedActivity != null && prevTopActivity != null) {
2398             if (mTopResumedActivity.app != null) {
2399                 mTopResumedActivity.app.addToPendingTop();
2400             }
2401             mService.updateOomAdj();
2402         }
2403         // Update the last resumed activity and focused app when the top resumed activity changed
2404         // because the new top resumed activity might be already resumed and thus won't have
2405         // activity state change to update the records to AMS.
2406         if (mTopResumedActivity != null) {
2407             mService.setLastResumedActivityUncheckLocked(mTopResumedActivity, reason);
2408         }
2409         scheduleTopResumedActivityStateIfNeeded();
2410 
2411         mService.updateTopApp(mTopResumedActivity);
2412     }
2413 
2414     /** Schedule current top resumed activity state loss */
scheduleTopResumedActivityStateLossIfNeeded()2415     private void scheduleTopResumedActivityStateLossIfNeeded() {
2416         if (mTopResumedActivity == null) {
2417             return;
2418         }
2419 
2420         // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
2421         // before the prevTopActivity one hasn't reported back yet. So server never sent the top
2422         // resumed state change message to prevTopActivity.
2423         if (!mTopResumedActivityWaitingForPrev
2424                 && mTopResumedActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
2425             scheduleTopResumedStateLossTimeout(mTopResumedActivity);
2426             mTopResumedActivityWaitingForPrev = true;
2427             mTopResumedActivity = null;
2428         }
2429     }
2430 
2431     /** Schedule top resumed state change if previous top activity already reported back. */
scheduleTopResumedActivityStateIfNeeded()2432     private void scheduleTopResumedActivityStateIfNeeded() {
2433         if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) {
2434             mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */);
2435         }
2436     }
2437 
2438     /**
2439      * Limit the time given to the app to report handling of the state loss.
2440      */
scheduleTopResumedStateLossTimeout(ActivityRecord r)2441     private void scheduleTopResumedStateLossTimeout(ActivityRecord r) {
2442         final Message msg = mHandler.obtainMessage(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG);
2443         msg.obj = r;
2444         r.topResumedStateLossTime = SystemClock.uptimeMillis();
2445         mHandler.sendMessageDelayed(msg, TOP_RESUMED_STATE_LOSS_TIMEOUT);
2446         ProtoLog.v(WM_DEBUG_STATES, "Waiting for top state to be released by %s", r);
2447     }
2448 
2449     /**
2450      * Handle a loss of top resumed state by an activity - update internal state and inform next top
2451      * activity if needed.
2452      */
handleTopResumedStateReleased(boolean timeout)2453     void handleTopResumedStateReleased(boolean timeout) {
2454         ProtoLog.v(WM_DEBUG_STATES, "Top resumed state released %s",
2455                     (timeout ? "(due to timeout)" : "(transition complete)"));
2456 
2457         mHandler.removeMessages(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG);
2458         if (!mTopResumedActivityWaitingForPrev) {
2459             // Top resumed activity state loss already handled.
2460             return;
2461         }
2462         mTopResumedActivityWaitingForPrev = false;
2463         scheduleTopResumedActivityStateIfNeeded();
2464     }
2465 
removeIdleTimeoutForActivity(ActivityRecord r)2466     void removeIdleTimeoutForActivity(ActivityRecord r) {
2467         if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
2468                 + Debug.getCallers(4));
2469         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2470     }
2471 
scheduleResumeTopActivities()2472     final void scheduleResumeTopActivities() {
2473         if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2474             mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2475         }
2476     }
2477 
scheduleProcessStoppingAndFinishingActivitiesIfNeeded()2478     void scheduleProcessStoppingAndFinishingActivitiesIfNeeded() {
2479         if (mStoppingActivities.isEmpty() && mFinishingActivities.isEmpty()) {
2480             return;
2481         }
2482         if (mRootWindowContainer.allResumedActivitiesIdle()) {
2483             scheduleIdle();
2484             return;
2485         }
2486         if (!mHandler.hasMessages(PROCESS_STOPPING_AND_FINISHING_MSG)
2487                 && mRootWindowContainer.allResumedActivitiesVisible()) {
2488             mHandler.sendEmptyMessage(PROCESS_STOPPING_AND_FINISHING_MSG);
2489         }
2490     }
2491 
removeSleepTimeouts()2492     void removeSleepTimeouts() {
2493         mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2494     }
2495 
scheduleSleepTimeout()2496     final void scheduleSleepTimeout() {
2497         removeSleepTimeouts();
2498         mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2499     }
2500 
hasScheduledRestartTimeouts(ActivityRecord r)2501     boolean hasScheduledRestartTimeouts(ActivityRecord r) {
2502         return mHandler.hasMessages(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r);
2503     }
2504 
removeRestartTimeouts(ActivityRecord r)2505     void removeRestartTimeouts(ActivityRecord r) {
2506         mHandler.removeMessages(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r);
2507     }
2508 
scheduleRestartTimeout(ActivityRecord r)2509     final void scheduleRestartTimeout(ActivityRecord r) {
2510         removeRestartTimeouts(r);
2511         mHandler.sendMessageDelayed(mHandler.obtainMessage(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r),
2512                 WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION);
2513     }
2514 
handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask)2515     void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode,
2516             TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask) {
2517         handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredTaskDisplayArea,
2518                 actualRootTask, false /* forceNonResizable */);
2519     }
2520 
handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask, boolean forceNonResizable)2521     void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode,
2522             TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask,
2523             boolean forceNonResizable) {
2524         final boolean isSecondaryDisplayPreferred = preferredTaskDisplayArea != null
2525                 && preferredTaskDisplayArea.getDisplayId() != DEFAULT_DISPLAY;
2526         if (!task.isActivityTypeStandardOrUndefined()) {
2527             return;
2528         }
2529 
2530         // Handle incorrect launch/move to secondary display if needed.
2531         if (isSecondaryDisplayPreferred) {
2532             if (!task.canBeLaunchedOnDisplay(task.getDisplayId())) {
2533                 throw new IllegalStateException("Task resolved to incompatible display");
2534             }
2535 
2536             final DisplayContent preferredDisplay = preferredTaskDisplayArea.mDisplayContent;
2537             if (preferredDisplay != task.getDisplayContent()) {
2538                 Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplay.mDisplayId);
2539                 // Display a warning toast that we failed to put a task on a secondary display.
2540                 mService.getTaskChangeNotificationController()
2541                         .notifyActivityLaunchOnSecondaryDisplayFailed(task.getTaskInfo(),
2542                                 preferredDisplay.mDisplayId);
2543             } else if (!forceNonResizable) {
2544                 handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY);
2545             }
2546             // The information about not support secondary display should already be notified, we
2547             // don't want to show another message on default display about split-screen. And it may
2548             // be the case that a resizable activity is launched on a non-resizable task.
2549             return;
2550         }
2551 
2552         if (!forceNonResizable) {
2553             handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
2554         }
2555     }
2556 
2557     /** Notifies that the top activity of the task is forced to be resizeable. */
handleForcedResizableTaskIfNeeded(Task task, int reason)2558     private void handleForcedResizableTaskIfNeeded(Task task, int reason) {
2559         final ActivityRecord topActivity = task.getTopNonFinishingActivity();
2560         if (topActivity == null || topActivity.noDisplay
2561                 || !topActivity.canForceResizeNonResizable(task.getWindowingMode())) {
2562             return;
2563         }
2564         mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
2565                 task.mTaskId, reason, topActivity.info.applicationInfo.packageName);
2566     }
2567 
scheduleUpdateMultiWindowMode(Task task)2568     void scheduleUpdateMultiWindowMode(Task task) {
2569         task.forAllActivities(r -> {
2570             if (r.attachedToProcess()) {
2571                 mMultiWindowModeChangedActivities.add(r);
2572             }
2573         });
2574 
2575         if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
2576             mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
2577         }
2578     }
2579 
scheduleUpdatePictureInPictureModeIfNeeded(Task task, Task prevRootTask)2580     void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Task prevRootTask) {
2581         final Task rootTask = task.getRootTask();
2582         if ((prevRootTask == null || (prevRootTask != rootTask
2583                 && !prevRootTask.inPinnedWindowingMode() && !rootTask.inPinnedWindowingMode()))) {
2584             return;
2585         }
2586 
2587         scheduleUpdatePictureInPictureModeIfNeeded(task, rootTask.getRequestedOverrideBounds());
2588     }
2589 
scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds)2590     void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds) {
2591         task.forAllActivities(r -> {
2592             if (!r.attachedToProcess()) return;
2593             mPipModeChangedActivities.add(r);
2594             // If we are scheduling pip change, then remove this activity from multi-window
2595             // change list as the processing of pip change will make sure multi-window changed
2596             // message is processed in the right order relative to pip changed.
2597             mMultiWindowModeChangedActivities.remove(r);
2598         });
2599 
2600         mPipModeChangedTargetRootTaskBounds = targetRootTaskBounds;
2601 
2602         if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
2603             mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
2604         }
2605     }
2606 
wakeUp(String reason)2607     void wakeUp(String reason) {
2608         mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_APPLICATION,
2609                 "android.server.am:TURN_ON:" + reason);
2610     }
2611 
2612     /** Starts a batch of visibility updates. */
beginActivityVisibilityUpdate()2613     void beginActivityVisibilityUpdate() {
2614         if (mVisibilityTransactionDepth == 0) {
2615             getKeyguardController().updateVisibility();
2616         }
2617         mVisibilityTransactionDepth++;
2618     }
2619 
2620     /** Ends a batch of visibility updates. */
endActivityVisibilityUpdate()2621     void endActivityVisibilityUpdate() {
2622         mVisibilityTransactionDepth--;
2623         if (mVisibilityTransactionDepth == 0) {
2624             computeProcessActivityStateBatch();
2625         }
2626     }
2627 
2628     /** Returns {@code true} if the caller is on the path to update visibility. */
inActivityVisibilityUpdate()2629     boolean inActivityVisibilityUpdate() {
2630         return mVisibilityTransactionDepth > 0;
2631     }
2632 
setDeferRootVisibilityUpdate(boolean deferUpdate)2633     void setDeferRootVisibilityUpdate(boolean deferUpdate) {
2634         mDeferRootVisibilityUpdate = deferUpdate;
2635     }
2636 
isRootVisibilityUpdateDeferred()2637     boolean isRootVisibilityUpdateDeferred() {
2638         return mDeferRootVisibilityUpdate;
2639     }
2640 
2641     /**
2642      * Called when the state or visibility of an attached activity is changed.
2643      *
2644      * @param wpc The process who owns the activity.
2645      * @param forceBatch Whether to put the changed record to a pending list. If the caller is not
2646      *                   in the path of visibility update ({@link #inActivityVisibilityUpdate}), it
2647      *                   must call {@link #computeProcessActivityStateBatch} manually.
2648      */
onProcessActivityStateChanged(WindowProcessController wpc, boolean forceBatch)2649     void onProcessActivityStateChanged(WindowProcessController wpc, boolean forceBatch) {
2650         if (forceBatch || inActivityVisibilityUpdate()) {
2651             if (!mActivityStateChangedProcs.contains(wpc)) {
2652                 mActivityStateChangedProcs.add(wpc);
2653             }
2654             return;
2655         }
2656         wpc.computeProcessActivityState();
2657     }
2658 
computeProcessActivityStateBatch()2659     void computeProcessActivityStateBatch() {
2660         if (mActivityStateChangedProcs.isEmpty()) {
2661             return;
2662         }
2663         for (int i = mActivityStateChangedProcs.size() - 1; i >= 0; i--) {
2664             mActivityStateChangedProcs.get(i).computeProcessActivityState();
2665         }
2666         mActivityStateChangedProcs.clear();
2667     }
2668 
2669     /**
2670      * Begin deferring resume to avoid duplicate resumes in one pass.
2671      */
beginDeferResume()2672     void beginDeferResume() {
2673         mDeferResumeCount++;
2674     }
2675 
2676     /**
2677      * End deferring resume and determine if resume can be called.
2678      */
endDeferResume()2679     void endDeferResume() {
2680         mDeferResumeCount--;
2681     }
2682 
2683     /** @return True if resume can be called. */
readyToResume()2684     boolean readyToResume() {
2685         return mDeferResumeCount == 0;
2686     }
2687 
2688     private final class ActivityTaskSupervisorHandler extends Handler {
2689 
ActivityTaskSupervisorHandler(Looper looper)2690         ActivityTaskSupervisorHandler(Looper looper) {
2691             super(looper);
2692         }
2693 
2694         @Override
handleMessage(Message msg)2695         public void handleMessage(Message msg) {
2696             synchronized (mService.mGlobalLock) {
2697                 if (handleMessageInner(msg)) {
2698                     return;
2699                 }
2700             }
2701             // The cases that some invocations cannot be locked by WM.
2702             switch (msg.what) {
2703                 case RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG: {
2704                     final ActivityRecord r = (ActivityRecord) msg.obj;
2705                     String processName = null;
2706                     int uid = 0;
2707                     synchronized (mService.mGlobalLock) {
2708                         if (r.attachedToProcess() && r.isState(RESTARTING_PROCESS)) {
2709                             processName = r.app.mName;
2710                             uid = r.app.mUid;
2711                         }
2712                     }
2713                     if (processName != null) {
2714                         mService.mAmInternal.killProcess(processName, uid,
2715                                 "restartActivityProcessTimeout");
2716                     }
2717                 } break;
2718             }
2719         }
2720 
activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout)2721         private void activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout) {
2722             activityIdleInternal(idleActivity, fromTimeout,
2723                     fromTimeout /* processPausingActivities */, null /* config */);
2724         }
2725 
2726         /**
2727          * Handles the message with lock held.
2728          *
2729          * @return {@code true} if the message is handled.
2730          */
handleMessageInner(Message msg)2731         private boolean handleMessageInner(Message msg) {
2732             switch (msg.what) {
2733                 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
2734                     for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
2735                         final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
2736                         r.updateMultiWindowMode();
2737                     }
2738                 } break;
2739                 case REPORT_PIP_MODE_CHANGED_MSG: {
2740                     for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
2741                         final ActivityRecord r = mPipModeChangedActivities.remove(i);
2742                         r.updatePictureInPictureMode(mPipModeChangedTargetRootTaskBounds,
2743                                 false /* forceUpdate */);
2744                     }
2745                 } break;
2746                 case IDLE_TIMEOUT_MSG: {
2747                     if (DEBUG_IDLE) Slog.d(TAG_IDLE,
2748                             "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2749                     // We don't at this point know if the activity is fullscreen, so we need to be
2750                     // conservative and assume it isn't.
2751                     activityIdleFromMessage((ActivityRecord) msg.obj, true /* fromTimeout */);
2752                 } break;
2753                 case IDLE_NOW_MSG: {
2754                     if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2755                     activityIdleFromMessage((ActivityRecord) msg.obj, false /* fromTimeout */);
2756                 } break;
2757                 case RESUME_TOP_ACTIVITY_MSG: {
2758                     mRootWindowContainer.resumeFocusedTasksTopActivities();
2759                 } break;
2760                 case SLEEP_TIMEOUT_MSG: {
2761                     if (mService.isSleepingOrShuttingDownLocked()) {
2762                         Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2763                         checkReadyForSleepLocked(false /* allowDelay */);
2764                     }
2765                 } break;
2766                 case LAUNCH_TIMEOUT_MSG: {
2767                     if (mLaunchingActivityWakeLock.isHeld()) {
2768                         Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2769                         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
2770                             throw new IllegalStateException("Calling must be system uid");
2771                         }
2772                         mLaunchingActivityWakeLock.release();
2773                     }
2774                 } break;
2775                 case PROCESS_STOPPING_AND_FINISHING_MSG: {
2776                     processStoppingAndFinishingActivities(null /* launchedActivity */,
2777                             false /* processPausingActivities */, "transit");
2778                 } break;
2779                 case KILL_TASK_PROCESSES_TIMEOUT_MSG: {
2780                     final Task task = (Task) msg.obj;
2781                     if (task.mKillProcessesOnDestroyed) {
2782                         Slog.i(TAG, "Destroy timeout of remove-task, attempt to kill " + task);
2783                         killTaskProcessesIfPossible(task);
2784                     }
2785                 } break;
2786                 case LAUNCH_TASK_BEHIND_COMPLETE: {
2787                     final ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2788                     if (r != null) {
2789                         handleLaunchTaskBehindCompleteLocked(r);
2790                     }
2791                 } break;
2792                 case START_HOME_MSG: {
2793                     mHandler.removeMessages(START_HOME_MSG);
2794 
2795                     // Start home activities on displays with no activities.
2796                     mRootWindowContainer.startHomeOnEmptyDisplays((String) msg.obj);
2797                 } break;
2798                 case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: {
2799                     final ActivityRecord r = (ActivityRecord) msg.obj;
2800                     Slog.w(TAG, "Activity top resumed state loss timeout for " + r);
2801                     if (r.hasProcess()) {
2802                         mService.logAppTooSlow(r.app, r.topResumedStateLossTime,
2803                                 "top state loss for " + r);
2804                     }
2805                     handleTopResumedStateReleased(true /* timeout */);
2806                 } break;
2807                 default:
2808                     return false;
2809             }
2810             return true;
2811         }
2812     }
2813 
2814     /**
2815      * Start the given task from the recent tasks. Do not hold WM global lock when calling this
2816      * method to avoid potential deadlock or permission deny by UriGrantsManager when resolving
2817      * activity (see {@link ActivityStarter.Request#resolveActivity} and
2818      * {@link com.android.server.am.ContentProviderHelper#checkContentProviderUriPermission}).
2819      *
2820      * @return The result code of starter.
2821      */
startActivityFromRecents(int callingPid, int callingUid, int taskId, SafeActivityOptions options)2822     int startActivityFromRecents(int callingPid, int callingUid, int taskId,
2823             SafeActivityOptions options) {
2824         final Task task;
2825         final int taskCallingUid;
2826         final String callingPackage;
2827         final String callingFeatureId;
2828         final Intent intent;
2829         final int userId;
2830         final ActivityOptions activityOptions = options != null
2831                 ? options.getOptions(this)
2832                 : null;
2833         boolean moveHomeTaskForward = true;
2834         synchronized (mService.mGlobalLock) {
2835             final boolean isCallerRecents = mRecentTasks.isCallerRecents(callingUid);
2836             int activityType = ACTIVITY_TYPE_UNDEFINED;
2837             if (activityOptions != null) {
2838                 activityType = activityOptions.getLaunchActivityType();
2839                 if (activityOptions.freezeRecentTasksReordering() && (isCallerRecents
2840                         || ActivityTaskManagerService.checkPermission(MANAGE_ACTIVITY_TASKS,
2841                                 callingPid, callingUid) == PERMISSION_GRANTED)) {
2842                     mRecentTasks.setFreezeTaskListReordering();
2843                 }
2844                 if (activityOptions.getLaunchRootTask() != null) {
2845                     // Don't move home activity forward if there is a launch root set.
2846                     moveHomeTaskForward = false;
2847                 }
2848             }
2849             if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) {
2850                 throw new IllegalArgumentException("startActivityFromRecents: Task "
2851                         + taskId + " can't be launch in the home/recents root task.");
2852             }
2853 
2854             boolean shouldStartActivity = false;
2855             mService.deferWindowLayout();
2856             try {
2857                 task = mRootWindowContainer.anyTaskForId(taskId,
2858                         MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, activityOptions, ON_TOP);
2859                 if (task == null) {
2860                     mWindowManager.executeAppTransition();
2861                     throw new IllegalArgumentException(
2862                             "startActivityFromRecents: Task " + taskId + " not found.");
2863                 }
2864 
2865                 if (moveHomeTaskForward) {
2866                     // We always want to return to the home activity instead of the recents
2867                     // activity from whatever is started from the recents activity, so move
2868                     // the home root task forward.
2869                     // TODO (b/115289124): Multi-display supports for recents.
2870                     mRootWindowContainer.getDefaultTaskDisplayArea().moveHomeRootTaskToFront(
2871                             "startActivityFromRecents");
2872                 }
2873 
2874                 // If the user must confirm credentials (e.g. when first launching a work
2875                 // app and the Work Challenge is present) let startActivityInPackage handle
2876                 // the intercepting.
2877                 if (!mService.mAmInternal.shouldConfirmCredentials(task.mUserId)
2878                         && task.getRootActivity() != null) {
2879                     final ActivityRecord targetActivity = task.getTopNonFinishingActivity();
2880 
2881                     mRootWindowContainer.startPowerModeLaunchIfNeeded(
2882                             true /* forceSend */, targetActivity);
2883                     final LaunchingState launchingState =
2884                             mActivityMetricsLogger.notifyActivityLaunching(task.intent,
2885                                     // Recents always has a new launching state (not combinable).
2886                                     null /* caller */, isCallerRecents ? INVALID_UID : callingUid);
2887                     try {
2888                         mService.moveTaskToFrontLocked(null /* appThread */,
2889                                 null /* callingPackage */, task.mTaskId, 0, options);
2890                         // Apply options to prevent pendingOptions be taken when scheduling
2891                         // activity lifecycle transaction to make sure the override pending app
2892                         // transition will be applied immediately.
2893                         if (activityOptions != null
2894                                 && activityOptions.getAnimationType() == ANIM_REMOTE_ANIMATION) {
2895                             targetActivity.mPendingRemoteAnimation =
2896                                     activityOptions.getRemoteAnimationAdapter();
2897                         }
2898                         targetActivity.applyOptionsAnimation();
2899                         if (activityOptions != null && activityOptions.getLaunchCookie() != null) {
2900                             targetActivity.mLaunchCookie = activityOptions.getLaunchCookie();
2901                         }
2902                     } finally {
2903                         mActivityMetricsLogger.notifyActivityLaunched(launchingState,
2904                                 START_TASK_TO_FRONT, false /* newActivityCreated */,
2905                                 targetActivity, activityOptions);
2906                     }
2907 
2908                     mService.getActivityStartController().postStartActivityProcessingForLastStarter(
2909                             task.getTopNonFinishingActivity(), ActivityManager.START_TASK_TO_FRONT,
2910                             task.getRootTask());
2911 
2912                     // As it doesn't go to ActivityStarter.executeRequest() path, we need to resume
2913                     // app switching here also.
2914                     mService.resumeAppSwitches();
2915                     return ActivityManager.START_TASK_TO_FRONT;
2916                 }
2917                 // The task is empty or needs to show the confirmation for credential.
2918                 shouldStartActivity = true;
2919             } finally {
2920                 if (!shouldStartActivity) {
2921                     mService.continueWindowLayout();
2922                 }
2923             }
2924             taskCallingUid = task.mCallingUid;
2925             callingPackage = task.mCallingPackage;
2926             callingFeatureId = task.mCallingFeatureId;
2927             intent = task.intent;
2928             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
2929             userId = task.mUserId;
2930         }
2931         // ActivityStarter will acquire the lock where the places need, so execute the request
2932         // outside of the lock.
2933         try {
2934             // We need to temporarily disable the explicit intent filter matching enforcement
2935             // because Task does not store the resolved type of the intent data, causing filter
2936             // mismatch in certain cases. (b/240373119)
2937             PackageManagerServiceUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(true);
2938             return mService.getActivityStartController().startActivityInPackage(taskCallingUid,
2939                     callingPid, callingUid, callingPackage, callingFeatureId, intent, null, null,
2940                     null, 0, 0, options, userId, task, "startActivityFromRecents",
2941                     false /* validateIncomingUser */, null /* originatingPendingIntent */,
2942                     BackgroundStartPrivileges.NONE);
2943         } finally {
2944             PackageManagerServiceUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(false);
2945             synchronized (mService.mGlobalLock) {
2946                 mService.continueWindowLayout();
2947             }
2948         }
2949     }
2950 
2951     /** The helper to get the top opaque activity of a container. */
2952     static class OpaqueActivityHelper implements Predicate<ActivityRecord> {
2953         private ActivityRecord mStarting;
2954         private boolean mIncludeInvisibleAndFinishing;
2955 
getOpaqueActivity(@onNull WindowContainer<?> container)2956         ActivityRecord getOpaqueActivity(@NonNull WindowContainer<?> container) {
2957             mIncludeInvisibleAndFinishing = true;
2958             return container.getActivity(this,
2959                     true /* traverseTopToBottom */, null /* boundary */);
2960         }
2961 
getVisibleOpaqueActivity(@onNull WindowContainer<?> container, @Nullable ActivityRecord starting)2962         ActivityRecord getVisibleOpaqueActivity(@NonNull WindowContainer<?> container,
2963                 @Nullable ActivityRecord starting) {
2964             mStarting = starting;
2965             mIncludeInvisibleAndFinishing = false;
2966             final ActivityRecord opaque = container.getActivity(this,
2967                     true /* traverseTopToBottom */, null /* boundary */);
2968             mStarting = null;
2969             return opaque;
2970         }
2971 
2972         @Override
test(ActivityRecord r)2973         public boolean test(ActivityRecord r) {
2974             if (!mIncludeInvisibleAndFinishing && !r.visibleIgnoringKeyguard && r != mStarting) {
2975                 // Ignore invisible activities that are not the currently starting activity
2976                 // (about to be visible).
2977                 return false;
2978             }
2979             return r.occludesParent(mIncludeInvisibleAndFinishing /* includingFinishing */);
2980         }
2981     }
2982 
2983     /**
2984      * Fills the info that needs to iterate all activities of task, such as the number of
2985      * non-finishing activities and collecting launch cookies.
2986      */
2987     static class TaskInfoHelper implements Consumer<ActivityRecord> {
2988         private TaskInfo mInfo;
2989         private ActivityRecord mTopRunning;
2990 
fillAndReturnTop(Task task, TaskInfo info)2991         ActivityRecord fillAndReturnTop(Task task, TaskInfo info) {
2992             info.numActivities = 0;
2993             info.baseActivity = null;
2994             mInfo = info;
2995             task.forAllActivities(this);
2996             final ActivityRecord top = mTopRunning;
2997             mTopRunning = null;
2998             mInfo = null;
2999             return top;
3000         }
3001 
3002         @Override
accept(ActivityRecord r)3003         public void accept(ActivityRecord r) {
3004             if (r.mLaunchCookie != null) {
3005                 mInfo.addLaunchCookie(r.mLaunchCookie);
3006             }
3007             if (r.finishing) {
3008                 return;
3009             }
3010             mInfo.numActivities++;
3011             mInfo.baseActivity = r.mActivityComponent;
3012             if (mTopRunning == null) {
3013                 mTopRunning = r;
3014             }
3015         }
3016     }
3017 
3018     /**
3019      * Internal container to store a match qualifier alongside a WaitResult.
3020      */
3021     private static class WaitInfo {
3022         final WaitResult mResult;
3023         final ComponentName mTargetComponent;
3024         /**
3025          * The target component may not be the final drawn activity. The launching state is managed
3026          * by {@link ActivityMetricsLogger} that can track consecutive launching sequence.
3027          */
3028         final LaunchingState mLaunchingState;
3029 
WaitInfo(WaitResult result, ComponentName component, LaunchingState launchingState)3030         WaitInfo(WaitResult result, ComponentName component, LaunchingState launchingState) {
3031             mResult = result;
3032             mTargetComponent = component;
3033             mLaunchingState = launchingState;
3034         }
3035 
matches(ActivityRecord r)3036         boolean matches(ActivityRecord r) {
3037             if (!mLaunchingState.hasActiveTransitionInfo()) {
3038                 return mTargetComponent.equals(r.mActivityComponent);
3039             }
3040             return mLaunchingState.contains(r);
3041         }
3042 
dump(PrintWriter pw, String prefix)3043         void dump(PrintWriter pw, String prefix) {
3044             pw.println(prefix + "WaitInfo:");
3045             pw.println(prefix + "  mTargetComponent=" + mTargetComponent);
3046             pw.println(prefix + "  mResult=");
3047             mResult.dump(pw, prefix + "    ");
3048         }
3049     }
3050 }
3051