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