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