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