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