1 /*
2  * Copyright (C) 2016 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.app.ActivityTaskManager.INVALID_TASK_ID;
20 import static android.app.KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
23 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
24 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
25 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
26 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
27 import static android.content.res.Configuration.EMPTY;
28 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
29 import static android.view.Display.DEFAULT_DISPLAY;
30 import static android.view.Display.INVALID_DISPLAY;
31 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
32 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
33 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
34 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING;
35 import static android.view.WindowManager.TRANSIT_NONE;
36 import static android.view.WindowManager.TRANSIT_PIP;
37 import static android.view.WindowManager.TRANSIT_SLEEP;
38 import static android.view.WindowManager.TRANSIT_TO_BACK;
39 import static android.view.WindowManager.TRANSIT_WAKE;
40 
41 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
42 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
43 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
44 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
45 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
46 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
47 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
48 import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
49 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
50 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
51 import static com.android.server.wm.ActivityRecord.State.FINISHING;
52 import static com.android.server.wm.ActivityRecord.State.PAUSED;
53 import static com.android.server.wm.ActivityRecord.State.RESUMED;
54 import static com.android.server.wm.ActivityRecord.State.STOPPED;
55 import static com.android.server.wm.ActivityRecord.State.STOPPING;
56 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
57 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK;
58 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
59 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
60 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
61 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
62 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
63 import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
64 import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;
65 import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
66 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
67 import static com.android.server.wm.ActivityTaskSupervisor.dumpHistoryList;
68 import static com.android.server.wm.ActivityTaskSupervisor.printThisActivity;
69 import static com.android.server.wm.KeyguardController.KEYGUARD_SLEEP_TOKEN_TAG;
70 import static com.android.server.wm.RootWindowContainerProto.IS_HOME_RECENTS_COMPONENT;
71 import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER;
72 import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
73 import static com.android.server.wm.Task.REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
74 import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
75 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
76 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
77 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
78 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
79 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
80 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
81 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
82 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
83 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
84 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
85 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
86 
87 import static java.lang.Integer.MAX_VALUE;
88 
89 import android.annotation.IntDef;
90 import android.annotation.NonNull;
91 import android.annotation.Nullable;
92 import android.annotation.UserIdInt;
93 import android.app.ActivityManager;
94 import android.app.ActivityOptions;
95 import android.app.ActivityTaskManager.RootTaskInfo;
96 import android.app.AppGlobals;
97 import android.app.WindowConfiguration;
98 import android.content.ComponentName;
99 import android.content.Context;
100 import android.content.Intent;
101 import android.content.pm.ActivityInfo;
102 import android.content.pm.ApplicationInfo;
103 import android.content.pm.ResolveInfo;
104 import android.content.pm.UserProperties;
105 import android.content.res.Configuration;
106 import android.graphics.Rect;
107 import android.hardware.display.DisplayManager;
108 import android.hardware.display.DisplayManagerInternal;
109 import android.hardware.power.Mode;
110 import android.net.Uri;
111 import android.os.Binder;
112 import android.os.Debug;
113 import android.os.FactoryTest;
114 import android.os.Handler;
115 import android.os.IBinder;
116 import android.os.Looper;
117 import android.os.Message;
118 import android.os.PowerManager;
119 import android.os.RemoteException;
120 import android.os.SystemClock;
121 import android.os.Trace;
122 import android.os.UserHandle;
123 import android.os.storage.StorageManager;
124 import android.provider.Settings;
125 import android.service.voice.IVoiceInteractionSession;
126 import android.util.ArrayMap;
127 import android.util.ArraySet;
128 import android.util.IntArray;
129 import android.util.Pair;
130 import android.util.Slog;
131 import android.util.SparseArray;
132 import android.util.SparseIntArray;
133 import android.util.TimeUtils;
134 import android.util.proto.ProtoOutputStream;
135 import android.view.Display;
136 import android.view.DisplayInfo;
137 import android.view.SurfaceControl;
138 import android.view.WindowManager;
139 import android.window.TaskFragmentAnimationParams;
140 import android.window.WindowContainerToken;
141 
142 import com.android.internal.annotations.VisibleForTesting;
143 import com.android.internal.app.ResolverActivity;
144 import com.android.internal.protolog.common.ProtoLog;
145 import com.android.internal.util.function.pooled.PooledLambda;
146 import com.android.internal.util.function.pooled.PooledPredicate;
147 import com.android.server.LocalServices;
148 import com.android.server.am.ActivityManagerService;
149 import com.android.server.am.AppTimeTracker;
150 import com.android.server.am.UserState;
151 import com.android.server.pm.UserManagerInternal;
152 import com.android.server.policy.PermissionPolicyInternal;
153 import com.android.server.policy.WindowManagerPolicy;
154 import com.android.server.utils.Slogf;
155 import com.android.window.flags.Flags;
156 
157 import java.io.FileDescriptor;
158 import java.io.PrintWriter;
159 import java.lang.annotation.Retention;
160 import java.lang.annotation.RetentionPolicy;
161 import java.util.ArrayList;
162 import java.util.Collections;
163 import java.util.List;
164 import java.util.Objects;
165 import java.util.Set;
166 import java.util.function.Consumer;
167 import java.util.function.Predicate;
168 
169 /** Root {@link WindowContainer} for the device. */
170 class RootWindowContainer extends WindowContainer<DisplayContent>
171         implements DisplayManager.DisplayListener {
172     private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
173 
174     private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
175     private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
176     private static final int MSG_SEND_SLEEP_TRANSITION = 3;
177     private static final int PINNED_TASK_ABORT_TIMEOUT = 1000;
178 
179     static final String TAG_TASKS = TAG + POSTFIX_TASKS;
180     static final String TAG_STATES = TAG + POSTFIX_STATES;
181     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
182 
183     private static final long SLEEP_TRANSITION_WAIT_MILLIS = 1000L;
184 
185     private Object mLastWindowFreezeSource = null;
186     private float mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
187     private long mUserActivityTimeout = -1;
188     private boolean mUpdateRotation = false;
189     // Only set while traversing the default display based on its content.
190     // Affects the behavior of mirroring on secondary displays.
191     private boolean mObscureApplicationContentOnSecondaryDisplays = false;
192 
193     private boolean mSustainedPerformanceModeEnabled = false;
194     private boolean mSustainedPerformanceModeCurrent = false;
195 
196     // During an orientation change, we track whether all windows have rendered
197     // at the new orientation, and this will be false from changing orientation until that occurs.
198     // For seamless rotation cases this always stays true, as the windows complete their orientation
199     // changes 1 by 1 without disturbing global state.
200     boolean mOrientationChangeComplete = true;
201     boolean mWallpaperActionPending = false;
202 
203     private final Handler mHandler;
204 
205     private String mCloseSystemDialogsReason;
206 
207     // The ID of the display which is responsible for receiving display-unspecified key and pointer
208     // events.
209     private int mTopFocusedDisplayId = INVALID_DISPLAY;
210 
211     // Map from the PID to the top most app which has a focused window of the process.
212     final ArrayMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new ArrayMap<>();
213 
214     // The tag for the token to put root tasks on the displays to sleep.
215     private static final String DISPLAY_OFF_SLEEP_TOKEN_TAG = "Display-off";
216 
217     /** The token acquirer to put root tasks on the displays to sleep */
218     final ActivityTaskManagerInternal.SleepTokenAcquirer mDisplayOffTokenAcquirer;
219 
220     /**
221      * The modes which affect which tasks are returned when calling
222      * {@link RootWindowContainer#anyTaskForId(int)}.
223      */
224     @Retention(RetentionPolicy.SOURCE)
225     @IntDef({
226             MATCH_ATTACHED_TASK_ONLY,
227             MATCH_ATTACHED_TASK_OR_RECENT_TASKS,
228             MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE
229     })
230     public @interface AnyTaskForIdMatchTaskMode {
231     }
232 
233     // Match only tasks that are attached to the hierarchy
234     static final int MATCH_ATTACHED_TASK_ONLY = 0;
235     // Match either attached tasks, or in the recent tasks if the tasks are detached
236     static final int MATCH_ATTACHED_TASK_OR_RECENT_TASKS = 1;
237     // Match either attached tasks, or in the recent tasks, restoring it to the provided task id
238     static final int MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE = 2;
239 
240     ActivityTaskManagerService mService;
241     ActivityTaskSupervisor mTaskSupervisor;
242     WindowManagerService mWindowManager;
243     DisplayManager mDisplayManager;
244     private DisplayManagerInternal mDisplayManagerInternal;
245     @NonNull
246     private final DeviceStateController mDeviceStateController;
247     @NonNull
248     private final DisplayRotationCoordinator mDisplayRotationCoordinator;
249 
250     /** Reference to default display so we can quickly look it up. */
251     private DisplayContent mDefaultDisplay;
252     private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
253     private final SparseArray<SurfaceControl.Transaction> mDisplayTransactions =
254             new SparseArray<>();
255 
256     /** The current user */
257     int mCurrentUser;
258     /** Root task id of the front root task when user switched, indexed by userId. */
259     SparseIntArray mUserRootTaskInFront = new SparseIntArray(2);
260 
261     /**
262      * A list of tokens that cause the top activity to be put to sleep.
263      * They are used by components that may hide and block interaction with underlying
264      * activities.
265      */
266     final SparseArray<SleepToken> mSleepTokens = new SparseArray<>();
267 
268     // Whether tasks have moved and we need to rank the tasks before next OOM scoring
269     private boolean mTaskLayersChanged = true;
270     private int mTmpTaskLayerRank;
271     private final RankTaskLayersRunnable mRankTaskLayersRunnable = new RankTaskLayersRunnable();
272 
273     private String mDestroyAllActivitiesReason;
274     private final Runnable mDestroyAllActivitiesRunnable = new Runnable() {
275         @Override
276         public void run() {
277             synchronized (mService.mGlobalLock) {
278                 try {
279                     mTaskSupervisor.beginDeferResume();
280                     forAllActivities(r -> {
281                         if (r.finishing || !r.isDestroyable()) return;
282                         if (DEBUG_SWITCH) {
283                             Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState()
284                                     + " resumed=" + r.getTask().getTopResumedActivity()
285                                     + " pausing=" + r.getTask().getTopPausingActivity()
286                                     + " for reason " + mDestroyAllActivitiesReason);
287                         }
288                         r.destroyImmediately(mDestroyAllActivitiesReason);
289                     });
290                 } finally {
291                     mTaskSupervisor.endDeferResume();
292                     resumeFocusedTasksTopActivities();
293                 }
294             }
295         }
296 
297     };
298 
299     // TODO: b/335866033 Remove the abort PiP on timeout once PiP2 flag is on.
300     @Nullable private Runnable mMaybeAbortPipEnterRunnable = null;
301 
302     private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
303 
304     static class FindTaskResult implements Predicate<Task> {
305         ActivityRecord mIdealRecord;
306         ActivityRecord mCandidateRecord;
307 
308         private int mActivityType;
309         private String mTaskAffinity;
310         private Intent mIntent;
311         private ActivityInfo mInfo;
312         private ComponentName cls;
313         private int userId;
314         private boolean isDocument;
315         private Uri documentData;
316 
317         // determines whether to include bubbled tasks. defaults to true to preserve previous
318         // behavior.
319         private boolean mIncludeLaunchedFromBubble = true;
320 
init(int activityType, String taskAffinity, Intent intent, ActivityInfo info, boolean includeLaunchedFromBubble)321         void init(int activityType, String taskAffinity, Intent intent, ActivityInfo info,
322                 boolean includeLaunchedFromBubble) {
323             mActivityType = activityType;
324             mTaskAffinity = taskAffinity;
325             mIntent = intent;
326             mInfo = info;
327             mIdealRecord = null;
328             mCandidateRecord = null;
329             mIncludeLaunchedFromBubble = includeLaunchedFromBubble;
330         }
331 
332         /**
333          * Returns the top activity in any existing task matching the given Intent in the input
334          * result. Returns null if no such task is found.
335          */
process(WindowContainer parent)336         void process(WindowContainer parent) {
337             cls = mIntent.getComponent();
338             if (mInfo.targetActivity != null) {
339                 cls = new ComponentName(mInfo.packageName, mInfo.targetActivity);
340             }
341             userId = UserHandle.getUserId(mInfo.applicationInfo.uid);
342             isDocument = mIntent != null & mIntent.isDocument();
343             // If documentData is non-null then it must match the existing task data.
344             documentData = isDocument ? mIntent.getData() : null;
345 
346             ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s in %s", mInfo,
347                     parent);
348             parent.forAllLeafTasks(this);
349         }
350 
351         @Override
test(Task task)352         public boolean test(Task task) {
353             if (!ConfigurationContainer.isCompatibleActivityType(mActivityType,
354                     task.getActivityType())) {
355                 ProtoLog.d(WM_DEBUG_TASKS, "Skipping task: (mismatch activity/task) %s", task);
356                 return false;
357             }
358 
359             if (task.voiceSession != null) {
360                 // We never match voice sessions; those always run independently.
361                 ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: voice session", task);
362                 return false;
363             }
364             if (task.mUserId != userId) {
365                 // Looking for a different task.
366                 ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: different user", task);
367                 return false;
368             }
369 
370             // Overlays should not be considered as the task's logical top activity.
371             final ActivityRecord r = task.getTopNonFinishingActivity(
372                     false /* includeOverlays */, mIncludeLaunchedFromBubble);
373 
374             if (r == null || r.finishing || r.mUserId != userId
375                     || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
376                 ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch root %s", task, r);
377                 return false;
378             }
379             if (!ConfigurationContainer.isCompatibleActivityType(r.getActivityType(),
380                     mActivityType)) {
381                 ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch activity type", task);
382                 return false;
383             }
384 
385             final Intent taskIntent = task.intent;
386             final Intent affinityIntent = task.affinityIntent;
387             final boolean taskIsDocument;
388             final Uri taskDocumentData;
389             if (taskIntent != null && taskIntent.isDocument()) {
390                 taskIsDocument = true;
391                 taskDocumentData = taskIntent.getData();
392             } else if (affinityIntent != null && affinityIntent.isDocument()) {
393                 taskIsDocument = true;
394                 taskDocumentData = affinityIntent.getData();
395             } else {
396                 taskIsDocument = false;
397                 taskDocumentData = null;
398             }
399 
400             ProtoLog.d(WM_DEBUG_TASKS, "Comparing existing cls=%s /aff=%s to new cls=%s /aff=%s",
401                     (task.realActivity != null ? task.realActivity.flattenToShortString() : ""),
402                     task.rootAffinity, mIntent.getComponent().flattenToShortString(),
403                     mTaskAffinity);
404             // TODO Refactor to remove duplications. Check if logic can be simplified.
405             if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
406                     && Objects.equals(documentData, taskDocumentData)) {
407                 ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!");
408                 //dump();
409                 ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", mIntent, r.intent);
410                 mIdealRecord = r;
411                 return true;
412             } else if (affinityIntent != null && affinityIntent.getComponent() != null
413                     && affinityIntent.getComponent().compareTo(cls) == 0 &&
414                     Objects.equals(documentData, taskDocumentData)) {
415                 ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!");
416                 ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", mIntent, r.intent);
417                 mIdealRecord = r;
418                 return true;
419             } else if (!isDocument && !taskIsDocument
420                     && mIdealRecord == null && mCandidateRecord == null
421                     && task.rootAffinity != null) {
422                 if (task.rootAffinity.equals(mTaskAffinity)
423                         && task.isSameRequiredDisplayCategory(mInfo)) {
424                     ProtoLog.d(WM_DEBUG_TASKS, "Found matching affinity candidate!");
425                     // It is possible for multiple tasks to have the same root affinity especially
426                     // if they are in separate root tasks. We save off this candidate, but keep
427                     // looking to see if there is a better candidate.
428                     mCandidateRecord = r;
429                 }
430             } else {
431                 ProtoLog.d(WM_DEBUG_TASKS, "Not a match: %s", task);
432             }
433 
434             return false;
435         }
436     }
437 
438     private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
439         if (w.mHasSurface) {
440             try {
441                 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason);
442             } catch (RemoteException e) {
443             }
444         }
445     };
446 
RootWindowContainer(WindowManagerService service)447     RootWindowContainer(WindowManagerService service) {
448         super(service);
449         mHandler = new MyHandler(service.mH.getLooper());
450         mService = service.mAtmService;
451         mTaskSupervisor = mService.mTaskSupervisor;
452         mTaskSupervisor.mRootWindowContainer = this;
453         mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl(DISPLAY_OFF_SLEEP_TOKEN_TAG);
454         mDeviceStateController = new DeviceStateController(service.mContext, service.mGlobalLock);
455         mDisplayRotationCoordinator = new DisplayRotationCoordinator();
456     }
457 
458     /**
459      * Updates the children's focused window and the top focused display if needed.
460      */
updateFocusedWindowLocked(int mode, boolean updateInputWindows)461     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
462         mTopFocusedAppByProcess.clear();
463         boolean changed = false;
464         int topFocusedDisplayId = INVALID_DISPLAY;
465         // Go through the children in z-order starting at the top-most
466         for (int i = mChildren.size() - 1; i >= 0; --i) {
467             final DisplayContent dc = mChildren.get(i);
468             changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
469             final WindowState newFocus = dc.mCurrentFocus;
470             if (newFocus != null) {
471                 final int pidOfNewFocus = newFocus.mSession.mPid;
472                 if (mTopFocusedAppByProcess.get(pidOfNewFocus) == null) {
473                     mTopFocusedAppByProcess.put(pidOfNewFocus, newFocus.mActivityRecord);
474                 }
475                 if (topFocusedDisplayId == INVALID_DISPLAY) {
476                     topFocusedDisplayId = dc.getDisplayId();
477                 }
478             } else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) {
479                 // The top-most display that has a focused app should still be the top focused
480                 // display even when the app window is not ready yet (process not attached or
481                 // window not added yet).
482                 topFocusedDisplayId = dc.getDisplayId();
483             }
484         }
485         if (topFocusedDisplayId == INVALID_DISPLAY) {
486             topFocusedDisplayId = DEFAULT_DISPLAY;
487         }
488         if (mTopFocusedDisplayId != topFocusedDisplayId) {
489             mTopFocusedDisplayId = topFocusedDisplayId;
490             mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
491             mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId);
492             mWmService.mAccessibilityController.setFocusedDisplay(topFocusedDisplayId);
493             ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d", topFocusedDisplayId);
494         }
495         return changed;
496     }
497 
getTopFocusedDisplayContent()498     DisplayContent getTopFocusedDisplayContent() {
499         final DisplayContent dc = getDisplayContent(mTopFocusedDisplayId);
500         return dc != null ? dc : getDisplayContent(DEFAULT_DISPLAY);
501     }
502 
503     @Override
isOnTop()504     boolean isOnTop() {
505         // Considered always on top
506         return true;
507     }
508 
509     @Override
onChildPositionChanged(WindowContainer child)510     void onChildPositionChanged(WindowContainer child) {
511         mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
512                 !mWmService.mPerDisplayFocusEnabled /* updateInputWindows */);
513         mTaskSupervisor.updateTopResumedActivityIfNeeded("onChildPositionChanged");
514     }
515 
516     @Override
isAttached()517     boolean isAttached() {
518         return true;
519     }
520 
521     /**
522      * Called when DisplayWindowSettings values may change.
523      */
onSettingsRetrieved()524     void onSettingsRetrieved() {
525         final int numDisplays = mChildren.size();
526         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
527             final DisplayContent displayContent = mChildren.get(displayNdx);
528             final boolean changed = mWmService.mDisplayWindowSettings.updateSettingsForDisplay(
529                     displayContent);
530             if (!changed) {
531                 continue;
532             }
533 
534             displayContent.reconfigureDisplayLocked();
535 
536             // We need to update global configuration as well if config of default display has
537             // changed. Do it inline because ATMS#retrieveSettings() will soon update the
538             // configuration inline, which will overwrite the new windowing mode.
539             if (displayContent.isDefaultDisplay) {
540                 final Configuration newConfig = mWmService.computeNewConfiguration(
541                         displayContent.getDisplayId());
542                 mWmService.mAtmService.updateConfigurationLocked(newConfig, null /* starting */,
543                         false /* initLocale */);
544             }
545         }
546     }
547 
isLayoutNeeded()548     boolean isLayoutNeeded() {
549         final int numDisplays = mChildren.size();
550         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
551             final DisplayContent displayContent = mChildren.get(displayNdx);
552             if (displayContent.isLayoutNeeded()) {
553                 return true;
554             }
555         }
556         return false;
557     }
558 
getWindowsByName(ArrayList<WindowState> output, String name)559     void getWindowsByName(ArrayList<WindowState> output, String name) {
560         int objectId = 0;
561         // See if this is an object ID.
562         try {
563             objectId = Integer.parseInt(name, 16);
564             name = null;
565         } catch (RuntimeException e) {
566         }
567 
568         getWindowsByName(output, name, objectId);
569     }
570 
getWindowsByName(ArrayList<WindowState> output, String name, int objectId)571     private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
572         forAllWindows((w) -> {
573             if (name != null) {
574                 if (w.mAttrs.getTitle().toString().contains(name)) {
575                     output.add(w);
576                 }
577             } else if (System.identityHashCode(w) == objectId) {
578                 output.add(w);
579             }
580         }, true /* traverseTopToBottom */);
581     }
582 
583     /** Returns the window token for the input binder if it exist in the system. */
getWindowToken(IBinder binder)584     WindowToken getWindowToken(IBinder binder) {
585         for (int i = mChildren.size() - 1; i >= 0; --i) {
586             final DisplayContent dc = mChildren.get(i);
587             final WindowToken wtoken = dc.getWindowToken(binder);
588             if (wtoken != null) {
589                 return wtoken;
590             }
591         }
592         return null;
593     }
594 
595     /** Returns the display object the input window token is currently mapped on. */
getWindowTokenDisplay(WindowToken token)596     DisplayContent getWindowTokenDisplay(WindowToken token) {
597         if (token == null) {
598             return null;
599         }
600 
601         for (int i = mChildren.size() - 1; i >= 0; --i) {
602             final DisplayContent dc = mChildren.get(i);
603             final WindowToken current = dc.getWindowToken(token.token);
604             if (current == token) {
605                 return dc;
606             }
607         }
608 
609         return null;
610     }
611 
612     @Override
dispatchConfigurationToChild(DisplayContent child, Configuration config)613     void dispatchConfigurationToChild(DisplayContent child, Configuration config) {
614         if (child.isDefaultDisplay) {
615             // The global configuration is also the override configuration of default display.
616             child.performDisplayOverrideConfigUpdate(config);
617         } else {
618             child.onConfigurationChanged(config);
619         }
620     }
621 
refreshSecureSurfaceState()622     void refreshSecureSurfaceState() {
623         forAllWindows(w -> {
624             w.setSecureLocked(w.isSecureLocked());
625         }, true /* traverseTopToBottom */);
626     }
627 
updateHiddenWhileSuspendedState(final ArraySet<String> packages, final boolean suspended)628     void updateHiddenWhileSuspendedState(final ArraySet<String> packages, final boolean suspended) {
629         forAllWindows((w) -> {
630             if (packages.contains(w.getOwningPackage())) {
631                 w.setHiddenWhileSuspended(suspended);
632             }
633         }, false);
634     }
635 
updateAppOpsState()636     void updateAppOpsState() {
637         forAllWindows((w) -> {
638             w.updateAppOpsState();
639         }, false /* traverseTopToBottom */);
640     }
641 
canShowStrictModeViolation(int pid)642     boolean canShowStrictModeViolation(int pid) {
643         final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisible());
644         return win != null;
645     }
646 
closeSystemDialogs(String reason)647     void closeSystemDialogs(String reason) {
648         mCloseSystemDialogsReason = reason;
649         forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
650     }
651 
hasPendingLayoutChanges(WindowAnimator animator)652     boolean hasPendingLayoutChanges(WindowAnimator animator) {
653         boolean hasChanges = false;
654 
655         final int count = mChildren.size();
656         for (int i = 0; i < count; ++i) {
657             final int pendingChanges = mChildren.get(i).pendingLayoutChanges;
658             if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
659                 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
660             }
661             if (pendingChanges != 0) {
662                 hasChanges = true;
663             }
664         }
665 
666         return hasChanges;
667     }
668 
reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation, boolean secure)669     boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
670             boolean secure) {
671         final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
672         boolean leakedSurface = false;
673         boolean killedApps = false;
674         EventLogTags.writeWmNoSurfaceMemory(winAnimator.mWin.toString(),
675                 winAnimator.mSession.mPid, operation);
676         final long callingIdentity = Binder.clearCallingIdentity();
677         try {
678             // There was some problem...first, do a validity check of the window list to make sure
679             // we haven't left any dangling surfaces around.
680 
681             Slog.i(TAG_WM, "Out of memory for surface!  Looking for leaks...");
682             final int numDisplays = mChildren.size();
683             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
684                 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
685             }
686 
687             if (!leakedSurface) {
688                 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
689                 final SparseIntArray pidCandidates = new SparseIntArray();
690                 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
691                     mChildren.get(displayNdx).forAllWindows((w) -> {
692                         if (mWmService.mForceRemoves.contains(w)) {
693                             return;
694                         }
695                         final WindowStateAnimator wsa = w.mWinAnimator;
696                         if (wsa.mSurfaceController != null) {
697                             pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
698                         }
699                     }, false /* traverseTopToBottom */);
700 
701                     if (pidCandidates.size() > 0) {
702                         int[] pids = new int[pidCandidates.size()];
703                         for (int i = 0; i < pids.length; i++) {
704                             pids[i] = pidCandidates.keyAt(i);
705                         }
706                         try {
707                             if (mWmService.mActivityManager.killPids(pids, "Free memory", secure)) {
708                                 killedApps = true;
709                             }
710                         } catch (RemoteException e) {
711                         }
712                     }
713                 }
714             }
715 
716             if (leakedSurface || killedApps) {
717                 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
718                 // app to request another one.
719                 Slog.w(TAG_WM,
720                         "Looks like we have reclaimed some memory, clearing surface for retry.");
721                 if (surfaceController != null) {
722                     ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
723                             "SURFACE RECOVER DESTROY: %s", winAnimator.mWin);
724                     SurfaceControl.Transaction t = mWmService.mTransactionFactory.get();
725                     winAnimator.destroySurface(t);
726                     t.apply();
727                     if (winAnimator.mWin.mActivityRecord != null) {
728                         winAnimator.mWin.mActivityRecord.removeStartingWindow();
729                     }
730                 }
731 
732                 try {
733                     winAnimator.mWin.mClient.dispatchGetNewSurface();
734                 } catch (RemoteException e) {
735                 }
736             }
737         } finally {
738             Binder.restoreCallingIdentity(callingIdentity);
739         }
740 
741         return leakedSurface || killedApps;
742     }
743 
744     /**
745      * This method should only be called from {@link WindowSurfacePlacer}. Otherwise the recursion
746      * check and {@link WindowSurfacePlacer#isInLayout()} won't take effect.
747      */
performSurfacePlacement()748     void performSurfacePlacement() {
749         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
750         try {
751             performSurfacePlacementNoTrace();
752         } finally {
753             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
754         }
755     }
756 
757     // "Something has changed!  Let's make it correct now."
758     // TODO: Super long method that should be broken down...
performSurfacePlacementNoTrace()759     void performSurfacePlacementNoTrace() {
760         if (DEBUG_WINDOW_TRACE) {
761             Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
762                     + Debug.getCallers(3));
763         }
764 
765         int i;
766 
767         if (mWmService.mFocusMayChange) {
768             mWmService.mFocusMayChange = false;
769             mWmService.updateFocusedWindowLocked(
770                     UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
771         }
772 
773         mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
774         mUserActivityTimeout = -1;
775         mObscureApplicationContentOnSecondaryDisplays = false;
776         mSustainedPerformanceModeCurrent = false;
777         mWmService.mTransactionSequence++;
778 
779         // TODO(multi-display): recents animation & wallpaper need support multi-display.
780         final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked();
781         final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
782 
783         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
784         try {
785             applySurfaceChangesTransaction();
786         } catch (RuntimeException e) {
787             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
788         } finally {
789             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
790         }
791 
792         if (Flags.bundleClientTransactionFlag()) {
793             // mWmService.mResizingWindows is populated in #applySurfaceChangesTransaction()
794             handleResizingWindows();
795 
796             // Called after #handleResizingWindows to include WindowStateResizeItem if any.
797             mWmService.mAtmService.getLifecycleManager().dispatchPendingTransactions();
798         }
799 
800         // Send any pending task-info changes that were queued-up during a layout deferment
801         mWmService.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
802         mWmService.mAtmService.mTaskFragmentOrganizerController.dispatchPendingEvents();
803         mWmService.mSyncEngine.onSurfacePlacement();
804 
805         checkAppTransitionReady(surfacePlacer);
806 
807         // Defer starting the recents animation until the wallpaper has drawn
808         final RecentsAnimationController recentsAnimationController =
809                 mWmService.getRecentsAnimationController();
810         if (recentsAnimationController != null) {
811             recentsAnimationController.checkAnimationReady(defaultDisplay.mWallpaperController);
812         }
813         mWmService.mAtmService.mBackNavigationController
814                 .checkAnimationReady(defaultDisplay.mWallpaperController);
815 
816         for (int displayNdx = 0; displayNdx < mChildren.size(); ++displayNdx) {
817             final DisplayContent displayContent = mChildren.get(displayNdx);
818             if (displayContent.mWallpaperMayChange) {
819                 ProtoLog.v(WM_DEBUG_WALLPAPER, "Wallpaper may change!  Adjusting");
820                 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
821                 if (DEBUG_LAYOUT_REPEATS) {
822                     surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
823                             displayContent.pendingLayoutChanges);
824                 }
825             }
826         }
827 
828         if (mWmService.mFocusMayChange) {
829             mWmService.mFocusMayChange = false;
830             mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
831                     false /*updateInputWindows*/);
832         }
833 
834         if (isLayoutNeeded()) {
835             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
836             if (DEBUG_LAYOUT_REPEATS) {
837                 surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
838                         defaultDisplay.pendingLayoutChanges);
839             }
840         }
841 
842         if (!Flags.bundleClientTransactionFlag()) {
843             handleResizingWindows();
844         }
845         clearFrameChangingWindows();
846 
847         if (mWmService.mDisplayFrozen) {
848             ProtoLog.v(WM_DEBUG_ORIENTATION,
849                     "With display frozen, orientationChangeComplete=%b",
850                     mOrientationChangeComplete);
851         }
852         if (mOrientationChangeComplete) {
853             if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
854                 mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
855                 mWmService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
856                 mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
857             }
858             mWmService.stopFreezingDisplayLocked();
859         }
860 
861         // Destroy the surface of any windows that are no longer visible.
862         i = mWmService.mDestroySurface.size();
863         if (i > 0) {
864             do {
865                 i--;
866                 WindowState win = mWmService.mDestroySurface.get(i);
867                 win.mDestroying = false;
868                 final DisplayContent displayContent = win.getDisplayContent();
869                 if (displayContent.mInputMethodWindow == win) {
870                     displayContent.setInputMethodWindowLocked(null);
871                 }
872                 if (displayContent.mWallpaperController.isWallpaperTarget(win)) {
873                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
874                 }
875                 win.destroySurfaceUnchecked();
876             } while (i > 0);
877             mWmService.mDestroySurface.clear();
878         }
879 
880         for (int displayNdx = 0; displayNdx < mChildren.size(); ++displayNdx) {
881             final DisplayContent displayContent = mChildren.get(displayNdx);
882             if (displayContent.pendingLayoutChanges != 0) {
883                 displayContent.setLayoutNeeded();
884             }
885         }
886 
887         if (!mWmService.mDisplayFrozen) {
888             final float brightnessOverride = mScreenBrightnessOverride < PowerManager.BRIGHTNESS_MIN
889                     || mScreenBrightnessOverride > PowerManager.BRIGHTNESS_MAX
890                     ? PowerManager.BRIGHTNESS_INVALID_FLOAT : mScreenBrightnessOverride;
891             int brightnessFloatAsIntBits = Float.floatToIntBits(brightnessOverride);
892             // Post these on a handler such that we don't call into power manager service while
893             // holding the window manager lock to avoid lock contention with power manager lock.
894             mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightnessFloatAsIntBits,
895                     0).sendToTarget();
896             mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
897         }
898 
899         if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
900             mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
901             mWmService.mPowerManagerInternal.setPowerMode(
902                     Mode.SUSTAINED_PERFORMANCE,
903                     mSustainedPerformanceModeEnabled);
904         }
905 
906         if (mUpdateRotation) {
907             ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation");
908             mUpdateRotation = updateRotationUnchecked();
909         }
910 
911         if (!mWmService.mWaitingForDrawnCallbacks.isEmpty()
912                 || (mOrientationChangeComplete && !isLayoutNeeded()
913                 && !mUpdateRotation)) {
914             mWmService.checkDrawnWindowsLocked();
915         }
916 
917         forAllDisplays(dc -> {
918             dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
919             dc.updateSystemGestureExclusion();
920             dc.updateKeepClearAreas();
921         });
922 
923         // Check to see if we are now in a state where the screen should
924         // be enabled, because the window obscured flags have changed.
925         mWmService.enableScreenIfNeededLocked();
926 
927         mWmService.scheduleAnimationLocked();
928 
929         if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit");
930     }
931 
checkAppTransitionReady(WindowSurfacePlacer surfacePlacer)932     private void checkAppTransitionReady(WindowSurfacePlacer surfacePlacer) {
933         // Trace all displays app transition by Z-order for pending layout change.
934         for (int i = mChildren.size() - 1; i >= 0; --i) {
935             final DisplayContent curDisplay = mChildren.get(i);
936 
937             // If we are ready to perform an app transition, check through all of the app tokens
938             // to be shown and see if they are ready to go.
939             if (curDisplay.mAppTransition.isReady()) {
940                 // handleAppTransitionReady may modify curDisplay.pendingLayoutChanges.
941                 curDisplay.mAppTransitionController.handleAppTransitionReady();
942                 if (DEBUG_LAYOUT_REPEATS) {
943                     surfacePlacer.debugLayoutRepeats("after handleAppTransitionReady",
944                             curDisplay.pendingLayoutChanges);
945                 }
946             }
947 
948             if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppTransitioning()) {
949                 // We have finished the animation of an app transition. To do this, we have
950                 // delayed a lot of operations like showing and hiding apps, moving apps in
951                 // Z-order, etc.
952                 // The app token list reflects the correct Z-order, but the window list may now
953                 // be out of sync with it. So here we will just rebuild the entire app window
954                 // list. Fun!
955                 curDisplay.handleAnimatingStoppedAndTransition();
956                 if (DEBUG_LAYOUT_REPEATS) {
957                     surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
958                             curDisplay.pendingLayoutChanges);
959                 }
960             }
961         }
962     }
963 
applySurfaceChangesTransaction()964     private void applySurfaceChangesTransaction() {
965         // TODO(multi-display): Support these features on secondary screens.
966         final DisplayContent defaultDc = mDefaultDisplay;
967         final DisplayInfo defaultInfo = defaultDc.getDisplayInfo();
968         final int defaultDw = defaultInfo.logicalWidth;
969         final int defaultDh = defaultInfo.logicalHeight;
970         final SurfaceControl.Transaction t = defaultDc.getSyncTransaction();
971         if (mWmService.mWatermark != null) {
972             mWmService.mWatermark.positionSurface(defaultDw, defaultDh, t);
973         }
974         if (mWmService.mStrictModeFlash != null) {
975             mWmService.mStrictModeFlash.positionSurface(defaultDw, defaultDh, t);
976         }
977         if (mWmService.mEmulatorDisplayOverlay != null) {
978             mWmService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
979                     defaultDc.getRotation(), t);
980         }
981 
982         final int count = mChildren.size();
983         for (int j = 0; j < count; ++j) {
984             final DisplayContent dc = mChildren.get(j);
985             dc.applySurfaceChangesTransaction();
986             mDisplayTransactions.append(dc.mDisplayId, dc.getSyncTransaction());
987         }
988 
989         // Give the display manager a chance to adjust properties like display rotation if it needs
990         // to.
991         mWmService.mDisplayManagerInternal.performTraversal(t, mDisplayTransactions);
992         mDisplayTransactions.clear();
993     }
994 
995     /**
996      * Handles resizing windows during surface placement.
997      */
handleResizingWindows()998     private void handleResizingWindows() {
999         for (int i = mWmService.mResizingWindows.size() - 1; i >= 0; i--) {
1000             WindowState win = mWmService.mResizingWindows.get(i);
1001             if (win.mAppFreezing || win.getDisplayContent().mWaitingForConfig) {
1002                 // Don't remove this window until rotation has completed and is not waiting for the
1003                 // complete configuration.
1004                 continue;
1005             }
1006             win.reportResized();
1007             mWmService.mResizingWindows.remove(i);
1008         }
1009     }
1010 
1011     /**
1012      * Clears frame changing windows after handling moving and resizing windows.
1013      */
clearFrameChangingWindows()1014     private void clearFrameChangingWindows() {
1015         final ArrayList<WindowState> frameChangingWindows = mWmService.mFrameChangingWindows;
1016         for (int i = frameChangingWindows.size() - 1; i >= 0; i--) {
1017             frameChangingWindows.get(i).updateLastFrames();
1018         }
1019         frameChangingWindows.clear();
1020     }
1021 
1022     /**
1023      * @param w        WindowState this method is applied to.
1024      * @param obscured True if there is a window on top of this obscuring the display.
1025      * @param syswin   System window?
1026      * @return True when the display contains content to show the user. When false, the display
1027      * manager may choose to mirror or blank the display.
1028      */
handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin)1029     boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
1030         final boolean onScreen = w.isOnScreen();
1031         boolean displayHasContent = false;
1032 
1033         ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
1034                 "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w"
1035                         + ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",
1036                 w, w.mHasSurface, onScreen, w.isDisplayed(), w.mAttrs.userActivityTimeout);
1037         if (!onScreen) {
1038             return false;
1039         }
1040         if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
1041             mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1042             ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "mUserActivityTimeout set to %d",
1043                     mUserActivityTimeout);
1044         }
1045         if (w.isDrawn() || (w.mActivityRecord != null && w.mActivityRecord.firstWindowDrawn
1046                 && w.mActivityRecord.isVisibleRequested())) {
1047             if (!syswin && w.mAttrs.screenBrightness >= 0
1048                     && Float.isNaN(mScreenBrightnessOverride)) {
1049                 mScreenBrightnessOverride = w.mAttrs.screenBrightness;
1050             }
1051 
1052             // This function assumes that the contents of the default display are processed first
1053             // before secondary displays.
1054             final DisplayContent displayContent = w.getDisplayContent();
1055             if (displayContent != null && displayContent.isDefaultDisplay) {
1056                 // While a dream or keyguard is showing, obscure ordinary application content on
1057                 // secondary displays (by forcibly enabling mirroring unless there is other content
1058                 // we want to show) but still allow opaque keyguard dialogs to be shown.
1059                 if (w.isDreamWindow() || mWmService.mPolicy.isKeyguardShowing()) {
1060                     mObscureApplicationContentOnSecondaryDisplays = true;
1061                 }
1062                 displayHasContent = true;
1063             } else if (displayContent != null &&
1064                     (!mObscureApplicationContentOnSecondaryDisplays
1065                             || displayContent.isKeyguardAlwaysUnlocked()
1066                             || (obscured && w.mAttrs.type == TYPE_KEYGUARD_DIALOG))) {
1067                 // Allow full screen keyguard presentation dialogs to be seen, or simply ignore the
1068                 // keyguard if this display is always unlocked.
1069                 displayHasContent = true;
1070             }
1071             if ((w.mAttrs.privateFlags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1072                 mSustainedPerformanceModeCurrent = true;
1073             }
1074         }
1075 
1076         return displayHasContent;
1077     }
1078 
updateRotationUnchecked()1079     boolean updateRotationUnchecked() {
1080         boolean changed = false;
1081         for (int i = mChildren.size() - 1; i >= 0; i--) {
1082             if (mChildren.get(i).getDisplayRotation().updateRotationAndSendNewConfigIfChanged()) {
1083                 changed = true;
1084             }
1085         }
1086         return changed;
1087     }
1088 
copyAnimToLayoutParams()1089     boolean copyAnimToLayoutParams() {
1090         boolean doRequest = false;
1091 
1092         final int bulkUpdateParams = mWmService.mAnimator.mBulkUpdateParams;
1093         if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1094             mUpdateRotation = true;
1095             doRequest = true;
1096         }
1097         if (mOrientationChangeComplete) {
1098             mLastWindowFreezeSource = mWmService.mAnimator.mLastWindowFreezeSource;
1099             if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1100                 doRequest = true;
1101             }
1102         }
1103 
1104         if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1105             mWallpaperActionPending = true;
1106         }
1107 
1108         return doRequest;
1109     }
1110 
1111     private final class MyHandler extends Handler {
1112 
MyHandler(Looper looper)1113         public MyHandler(Looper looper) {
1114             super(looper);
1115         }
1116 
1117         @Override
handleMessage(Message msg)1118         public void handleMessage(Message msg) {
1119             switch (msg.what) {
1120                 case SET_SCREEN_BRIGHTNESS_OVERRIDE:
1121                     mWmService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
1122                             Float.intBitsToFloat(msg.arg1));
1123                     break;
1124                 case SET_USER_ACTIVITY_TIMEOUT:
1125                     mWmService.mPowerManagerInternal.
1126                             setUserActivityTimeoutOverrideFromWindowManager((Long) msg.obj);
1127                     break;
1128                 case MSG_SEND_SLEEP_TRANSITION:
1129                     synchronized (mService.mGlobalLock) {
1130                         sendSleepTransition((DisplayContent) msg.obj);
1131                     }
1132                     break;
1133                 default:
1134                     break;
1135             }
1136         }
1137     }
1138 
dumpDisplayContents(PrintWriter pw)1139     void dumpDisplayContents(PrintWriter pw) {
1140         pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
1141         if (mWmService.mDisplayReady) {
1142             final int count = mChildren.size();
1143             for (int i = 0; i < count; ++i) {
1144                 final DisplayContent displayContent = mChildren.get(i);
1145                 displayContent.dump(pw, "  ", true /* dumpAll */);
1146             }
1147         } else {
1148             pw.println("  NO DISPLAY");
1149         }
1150     }
1151 
dumpTopFocusedDisplayId(PrintWriter pw)1152     void dumpTopFocusedDisplayId(PrintWriter pw) {
1153         pw.print("  mTopFocusedDisplayId=");
1154         pw.println(mTopFocusedDisplayId);
1155     }
1156 
dumpLayoutNeededDisplayIds(PrintWriter pw)1157     void dumpLayoutNeededDisplayIds(PrintWriter pw) {
1158         if (!isLayoutNeeded()) {
1159             return;
1160         }
1161         pw.print("  mLayoutNeeded on displays=");
1162         final int count = mChildren.size();
1163         for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
1164             final DisplayContent displayContent = mChildren.get(displayNdx);
1165             if (displayContent.isLayoutNeeded()) {
1166                 pw.print(displayContent.getDisplayId());
1167             }
1168         }
1169         pw.println();
1170     }
1171 
dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows)1172     void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
1173         final int[] index = new int[1];
1174         forAllWindows((w) -> {
1175             if (windows == null || windows.contains(w)) {
1176                 pw.println("  Window #" + index[0] + " " + w + ":");
1177                 w.dump(pw, "    ", dumpAll || windows != null);
1178                 index[0] = index[0] + 1;
1179             }
1180         }, true /* traverseTopToBottom */);
1181     }
1182 
dumpTokens(PrintWriter pw, boolean dumpAll)1183     void dumpTokens(PrintWriter pw, boolean dumpAll) {
1184         pw.println("  All tokens:");
1185         for (int i = mChildren.size() - 1; i >= 0; --i) {
1186             mChildren.get(i).dumpTokens(pw, dumpAll);
1187         }
1188     }
1189 
1190     @Override
dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTraceLogLevel int logLevel)1191     public void dumpDebug(ProtoOutputStream proto, long fieldId,
1192             @WindowTraceLogLevel int logLevel) {
1193         if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
1194             return;
1195         }
1196 
1197         final long token = proto.start(fieldId);
1198         super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
1199 
1200         mTaskSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
1201         proto.write(IS_HOME_RECENTS_COMPONENT,
1202                 mTaskSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
1203         proto.end(token);
1204     }
1205 
1206     @Override
getName()1207     String getName() {
1208         return "ROOT";
1209     }
1210 
1211     @Override
removeChild(DisplayContent dc)1212     protected void removeChild(DisplayContent dc) {
1213         super.removeChild(dc);
1214         if (mTopFocusedDisplayId == dc.getDisplayId()) {
1215             mWmService.updateFocusedWindowLocked(
1216                     UPDATE_FOCUS_NORMAL, true /* updateInputWindows */);
1217         }
1218     }
1219 
1220     /**
1221      * For all display at or below this call the callback.
1222      *
1223      * @param callback Callback to be called for every display.
1224      */
forAllDisplays(Consumer<DisplayContent> callback)1225     void forAllDisplays(Consumer<DisplayContent> callback) {
1226         for (int i = mChildren.size() - 1; i >= 0; --i) {
1227             callback.accept(mChildren.get(i));
1228         }
1229     }
1230 
forAllDisplayPolicies(Consumer<DisplayPolicy> callback)1231     void forAllDisplayPolicies(Consumer<DisplayPolicy> callback) {
1232         for (int i = mChildren.size() - 1; i >= 0; --i) {
1233             callback.accept(mChildren.get(i).getDisplayPolicy());
1234         }
1235     }
1236 
1237     /**
1238      * Get current topmost focused IME window in system.
1239      * Will look on all displays in current Z-order.
1240      */
getCurrentInputMethodWindow()1241     WindowState getCurrentInputMethodWindow() {
1242         for (int i = mChildren.size() - 1; i >= 0; --i) {
1243             final DisplayContent displayContent = mChildren.get(i);
1244             if (displayContent.mInputMethodWindow != null) {
1245                 return displayContent.mInputMethodWindow;
1246             }
1247         }
1248         return null;
1249     }
1250 
getDisplayContextsWithNonToastVisibleWindows(int pid, List<Context> outContexts)1251     void getDisplayContextsWithNonToastVisibleWindows(int pid, List<Context> outContexts) {
1252         if (outContexts == null) {
1253             return;
1254         }
1255         for (int i = mChildren.size() - 1; i >= 0; --i) {
1256             DisplayContent dc = mChildren.get(i);
1257             if (dc.getWindow(w -> pid == w.mSession.mPid && w.isVisibleNow()
1258                     && w.mAttrs.type != WindowManager.LayoutParams.TYPE_TOAST) != null) {
1259                 outContexts.add(dc.getDisplayUiContext());
1260             }
1261         }
1262     }
1263 
1264     @Nullable
getDisplayUiContext(int displayId)1265     Context getDisplayUiContext(int displayId) {
1266         return getDisplayContent(displayId) != null
1267                 ? getDisplayContent(displayId).getDisplayUiContext() : null;
1268     }
1269 
setWindowManager(WindowManagerService wm)1270     void setWindowManager(WindowManagerService wm) {
1271         mWindowManager = wm;
1272         mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
1273         mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
1274         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
1275 
1276         final Display[] displays = mDisplayManager.getDisplays();
1277         for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
1278             final Display display = displays[displayNdx];
1279             final DisplayContent displayContent =
1280                     new DisplayContent(display, this, mDeviceStateController);
1281             addChild(displayContent, POSITION_BOTTOM);
1282             if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
1283                 mDefaultDisplay = displayContent;
1284             }
1285         }
1286 
1287         final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();
1288         defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
1289         positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent,
1290                 false /* includingParents */);
1291     }
1292 
1293     /**
1294      * Called just before display manager has applied the device state to the displays
1295      * @param deviceState device state as defined by
1296      *        {@link android.hardware.devicestate.DeviceStateManager}
1297      */
onDisplayManagerReceivedDeviceState(int deviceState)1298     void onDisplayManagerReceivedDeviceState(int deviceState) {
1299         mDeviceStateController.onDeviceStateReceivedByDisplayManager(deviceState);
1300     }
1301 
1302     // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
getDefaultDisplay()1303     DisplayContent getDefaultDisplay() {
1304         return mDefaultDisplay;
1305     }
1306 
1307     @NonNull
getDisplayRotationCoordinator()1308     DisplayRotationCoordinator getDisplayRotationCoordinator() {
1309         return mDisplayRotationCoordinator;
1310     }
1311 
1312     /**
1313      * Get the default display area on the device dedicated to app windows. This one should be used
1314      * only as a fallback location for activity launches when no target display area is specified,
1315      * or for cases when multi-instance is not supported yet (like Split-screen, Freeform, PiP or
1316      * Recents).
1317      */
getDefaultTaskDisplayArea()1318     TaskDisplayArea getDefaultTaskDisplayArea() {
1319         return mDefaultDisplay.getDefaultTaskDisplayArea();
1320     }
1321 
1322     /**
1323      * Get an existing instance of {@link DisplayContent} that has the given uniqueId. Unique ID is
1324      * defined in {@link DisplayInfo#uniqueId}.
1325      *
1326      * @param uniqueId the unique ID of the display
1327      * @return the {@link DisplayContent} or {@code null} if nothing is found.
1328      */
getDisplayContent(String uniqueId)1329     DisplayContent getDisplayContent(String uniqueId) {
1330         for (int i = getChildCount() - 1; i >= 0; --i) {
1331             final DisplayContent display = getChildAt(i);
1332             final boolean isValid = display.mDisplay.isValid();
1333             if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
1334                 return display;
1335             }
1336         }
1337 
1338         return null;
1339     }
1340 
1341     // TODO: Look into consolidating with getDisplayContentOrCreate()
getDisplayContent(int displayId)1342     DisplayContent getDisplayContent(int displayId) {
1343         for (int i = getChildCount() - 1; i >= 0; --i) {
1344             final DisplayContent displayContent = getChildAt(i);
1345             if (displayContent.mDisplayId == displayId) {
1346                 return displayContent;
1347             }
1348         }
1349         return null;
1350     }
1351 
1352     /**
1353      * Get an existing instance of {@link DisplayContent} or create new if there is a
1354      * corresponding record in display manager.
1355      */
1356     // TODO: Look into consolidating with getDisplayContent()
1357     @Nullable
getDisplayContentOrCreate(int displayId)1358     DisplayContent getDisplayContentOrCreate(int displayId) {
1359         DisplayContent displayContent = getDisplayContent(displayId);
1360         if (displayContent != null) {
1361             return displayContent;
1362         }
1363         if (mDisplayManager == null) {
1364             // The system isn't fully initialized yet.
1365             return null;
1366         }
1367         final Display display = mDisplayManager.getDisplay(displayId);
1368         if (display == null) {
1369             // The display is not registered in DisplayManager.
1370             return null;
1371         }
1372         // The display hasn't been added to ActivityManager yet, create a new record now.
1373         displayContent = new DisplayContent(display, this, mDeviceStateController);
1374         addChild(displayContent, POSITION_BOTTOM);
1375         return displayContent;
1376     }
1377 
getDefaultDisplayHomeActivityForUser(int userId)1378     ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
1379         return getDefaultTaskDisplayArea().getHomeActivityForUser(userId);
1380     }
1381 
startHomeOnAllDisplays(int userId, String reason)1382     boolean startHomeOnAllDisplays(int userId, String reason) {
1383         boolean homeStarted = false;
1384         for (int i = getChildCount() - 1; i >= 0; i--) {
1385             final int displayId = getChildAt(i).mDisplayId;
1386             homeStarted |= startHomeOnDisplay(userId, reason, displayId);
1387         }
1388         return homeStarted;
1389     }
1390 
startHomeOnEmptyDisplays(String reason)1391     void startHomeOnEmptyDisplays(String reason) {
1392         forAllTaskDisplayAreas(taskDisplayArea -> {
1393             if (taskDisplayArea.topRunningActivity() == null) {
1394                 int userId = mWmService.getUserAssignedToDisplay(taskDisplayArea.getDisplayId());
1395                 startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
1396                         false /* allowInstrumenting */, false /* fromHomeKey */);
1397             }
1398         });
1399     }
1400 
startHomeOnDisplay(int userId, String reason, int displayId)1401     boolean startHomeOnDisplay(int userId, String reason, int displayId) {
1402         return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
1403                 false /* fromHomeKey */);
1404     }
1405 
startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey)1406     boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
1407             boolean fromHomeKey) {
1408         // Fallback to top focused display or default display if the displayId is invalid.
1409         if (displayId == INVALID_DISPLAY) {
1410             final Task rootTask = getTopDisplayFocusedRootTask();
1411             displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY;
1412         }
1413 
1414         final DisplayContent display = getDisplayContent(displayId);
1415         return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
1416                         result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
1417                                 allowInstrumenting, fromHomeKey),
1418                 false /* initValue */);
1419     }
1420 
1421     /**
1422      * This starts home activity on display areas that can have system decorations based on
1423      * displayId - default display area always uses primary home component.
1424      * For secondary display areas, the home activity must have category SECONDARY_HOME and then
1425      * resolves according to the priorities listed below.
1426      * - If default home is not set, always use the secondary home defined in the config.
1427      * - Use currently selected primary home activity.
1428      * - Use the activity in the same package as currently selected primary home activity.
1429      * If there are multiple activities matched, use first one.
1430      * - Use the secondary home defined in the config.
1431      */
startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting, boolean fromHomeKey)1432     boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
1433             boolean allowInstrumenting, boolean fromHomeKey) {
1434         // Fallback to top focused display area if the provided one is invalid.
1435         if (taskDisplayArea == null) {
1436             final Task rootTask = getTopDisplayFocusedRootTask();
1437             taskDisplayArea = rootTask != null ? rootTask.getDisplayArea()
1438                     : getDefaultTaskDisplayArea();
1439         }
1440 
1441         Intent homeIntent = null;
1442         ActivityInfo aInfo = null;
1443         if (taskDisplayArea == getDefaultTaskDisplayArea()
1444                 || mWmService.shouldPlacePrimaryHomeOnDisplay(
1445                         taskDisplayArea.getDisplayId(), userId)) {
1446             homeIntent = mService.getHomeIntent();
1447             aInfo = resolveHomeActivity(userId, homeIntent);
1448         } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
1449             Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
1450             aInfo = info.first;
1451             homeIntent = info.second;
1452         }
1453 
1454         if (aInfo == null || homeIntent == null) {
1455             return false;
1456         }
1457 
1458         if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
1459             return false;
1460         }
1461 
1462         if (mService.mAmInternal.shouldDelayHomeLaunch(userId)) {
1463             Slog.d(TAG, "ThemeHomeDelay: Home launch was deferred with user " + userId);
1464             return false;
1465         }
1466 
1467         // Updates the home component of the intent.
1468         homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
1469         homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
1470         // Updates the extra information of the intent.
1471         if (fromHomeKey) {
1472             homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
1473             if (mWindowManager.getRecentsAnimationController() != null) {
1474                 mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart();
1475             }
1476         }
1477         homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason);
1478 
1479         // Update the reason for ANR debugging to verify if the user activity is the one that
1480         // actually launched.
1481         final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
1482                 aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
1483         mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
1484                 taskDisplayArea);
1485         return true;
1486     }
1487 
1488     /**
1489      * This resolves the home activity info.
1490      *
1491      * @return the home activity info if any.
1492      */
1493     @VisibleForTesting
resolveHomeActivity(int userId, Intent homeIntent)1494     ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
1495         final int flags = ActivityManagerService.STOCK_PM_FLAGS;
1496         final ComponentName comp = homeIntent.getComponent();
1497         ActivityInfo aInfo = null;
1498         try {
1499             if (comp != null) {
1500                 // Factory test.
1501                 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
1502             } else {
1503                 final String resolvedType =
1504                         homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
1505                 final ResolveInfo info = mTaskSupervisor.resolveIntent(homeIntent, resolvedType,
1506                         userId, flags, Binder.getCallingUid(), Binder.getCallingPid());
1507                 if (info != null) {
1508                     aInfo = info.activityInfo;
1509                 }
1510             }
1511         } catch (RemoteException e) {
1512             // ignore
1513         }
1514 
1515         if (aInfo == null) {
1516             Slogf.wtf(TAG, new Exception(), "No home screen found for %s and user %d", homeIntent,
1517                     userId);
1518             return null;
1519         }
1520 
1521         aInfo = new ActivityInfo(aInfo);
1522         aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
1523         return aInfo;
1524     }
1525 
1526     @VisibleForTesting
resolveSecondaryHomeActivity(int userId, @NonNull TaskDisplayArea taskDisplayArea)1527     Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId,
1528             @NonNull TaskDisplayArea taskDisplayArea) {
1529         if (taskDisplayArea == getDefaultTaskDisplayArea()) {
1530             throw new IllegalArgumentException(
1531                     "resolveSecondaryHomeActivity: Should not be default task container");
1532         }
1533 
1534         Intent homeIntent = mService.getHomeIntent();
1535         ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
1536         boolean lookForSecondaryHomeActivityInPrimaryHomePackage = aInfo != null;
1537 
1538         if (android.companion.virtual.flags.Flags.vdmCustomHome()) {
1539             // Resolve the externally set home activity for this display, if any. If it is unset or
1540             // we fail to resolve it, fallback to the default secondary home activity.
1541             final ComponentName customHomeComponent =
1542                     taskDisplayArea.getDisplayContent() != null
1543                             ? taskDisplayArea.getDisplayContent().getCustomHomeComponent()
1544                             : null;
1545             if (customHomeComponent != null) {
1546                 homeIntent.setComponent(customHomeComponent);
1547                 ActivityInfo customHomeActivityInfo = resolveHomeActivity(userId, homeIntent);
1548                 if (customHomeActivityInfo != null) {
1549                     aInfo = customHomeActivityInfo;
1550                     lookForSecondaryHomeActivityInPrimaryHomePackage = false;
1551                 }
1552             }
1553         }
1554 
1555         if (lookForSecondaryHomeActivityInPrimaryHomePackage) {
1556             // Resolve activities in the same package as currently selected primary home activity.
1557             if (ResolverActivity.class.getName().equals(aInfo.name)) {
1558                 // Always fallback to secondary home component if default home is not set.
1559                 aInfo = null;
1560             } else {
1561                 // Look for secondary home activities in the currently selected default home
1562                 // package.
1563                 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
1564                 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
1565                 final int size = resolutions.size();
1566                 final String targetName = aInfo.name;
1567                 aInfo = null;
1568                 for (int i = 0; i < size; i++) {
1569                     ResolveInfo resolveInfo = resolutions.get(i);
1570                     // We need to traverse all resolutions to check if the currently selected
1571                     // default home activity is present.
1572                     if (resolveInfo.activityInfo.name.equals(targetName)) {
1573                         aInfo = resolveInfo.activityInfo;
1574                         break;
1575                     }
1576                 }
1577                 if (aInfo == null && size > 0) {
1578                     // First one is the best.
1579                     aInfo = resolutions.get(0).activityInfo;
1580                 }
1581             }
1582         }
1583 
1584         if (aInfo != null) {
1585             if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea,
1586                     false /* allowInstrumenting */)) {
1587                 aInfo = null;
1588             }
1589         }
1590 
1591         // Fallback to secondary home component.
1592         if (aInfo == null) {
1593             homeIntent = mService.getSecondaryHomeIntent(null);
1594             aInfo = resolveHomeActivity(userId, homeIntent);
1595         }
1596         return Pair.create(aInfo, homeIntent);
1597     }
1598 
1599     /**
1600      * Retrieve all activities that match the given intent.
1601      * The list should already ordered from best to worst matched.
1602      * {@link android.content.pm.PackageManager#queryIntentActivities}
1603      */
1604     @VisibleForTesting
resolveActivities(int userId, Intent homeIntent)1605     List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
1606         List<ResolveInfo> resolutions;
1607         try {
1608             final String resolvedType =
1609                     homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
1610             resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
1611                     resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
1612 
1613         } catch (RemoteException e) {
1614             resolutions = new ArrayList<>();
1615         }
1616         return resolutions;
1617     }
1618 
resumeHomeActivity(ActivityRecord prev, String reason, TaskDisplayArea taskDisplayArea)1619     boolean resumeHomeActivity(ActivityRecord prev, String reason,
1620             TaskDisplayArea taskDisplayArea) {
1621         if (!mService.isBooting() && !mService.isBooted()) {
1622             // Not ready yet!
1623             return false;
1624         }
1625 
1626         if (taskDisplayArea == null) {
1627             taskDisplayArea = getDefaultTaskDisplayArea();
1628         }
1629 
1630         final ActivityRecord r = taskDisplayArea.getHomeActivity();
1631         final String myReason = reason + " resumeHomeActivity";
1632 
1633         // Only resume home activity if isn't finishing.
1634         if (r != null && !r.finishing) {
1635             r.moveFocusableActivityToTop(myReason);
1636             return resumeFocusedTasksTopActivities(r.getRootTask(), prev, null);
1637         }
1638         int userId = mWmService.getUserAssignedToDisplay(taskDisplayArea.getDisplayId());
1639         return startHomeOnTaskDisplayArea(userId, myReason, taskDisplayArea,
1640                 false /* allowInstrumenting */, false /* fromHomeKey */);
1641     }
1642 
1643     /**
1644      * Check if the display is valid for primary home activity.
1645      *
1646      * @param displayId The target display ID
1647      * @return {@code true} if allowed to launch, {@code false} otherwise.
1648      */
shouldPlacePrimaryHomeOnDisplay(int displayId)1649     boolean shouldPlacePrimaryHomeOnDisplay(int displayId) {
1650         // No restrictions to default display, vr 2d display or main display for visible users.
1651         return displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
1652                 && (displayId == mService.mVr2dDisplayId
1653                 || mWmService.shouldPlacePrimaryHomeOnDisplay(displayId)));
1654     }
1655 
1656     /**
1657      * Check if the display area is valid for secondary home activity.
1658      *
1659      * @param taskDisplayArea The target display area.
1660      * @return {@code true} if allow to launch, {@code false} otherwise.
1661      */
shouldPlaceSecondaryHomeOnDisplayArea(TaskDisplayArea taskDisplayArea)1662     boolean shouldPlaceSecondaryHomeOnDisplayArea(TaskDisplayArea taskDisplayArea) {
1663         if (getDefaultTaskDisplayArea() == taskDisplayArea) {
1664             throw new IllegalArgumentException(
1665                     "shouldPlaceSecondaryHomeOnDisplay: Should not be on default task container");
1666         } else if (taskDisplayArea == null) {
1667             return false;
1668         }
1669 
1670         if (!taskDisplayArea.canHostHomeTask()) {
1671             // Can't launch home on a TaskDisplayArea that does not support root home task
1672             return false;
1673         }
1674 
1675         if (taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) {
1676             // Can't launch home on secondary display if device does not support multi-display.
1677             return false;
1678         }
1679 
1680         final boolean deviceProvisioned = Settings.Global.getInt(
1681                 mService.mContext.getContentResolver(),
1682                 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1683         if (!deviceProvisioned) {
1684             // Can't launch home on secondary display areas before device is provisioned.
1685             return false;
1686         }
1687 
1688         if (!StorageManager.isCeStorageUnlocked(mCurrentUser)) {
1689             // Can't launch home on secondary display areas if CE storage is still locked.
1690             return false;
1691         }
1692 
1693         final DisplayContent display = taskDisplayArea.getDisplayContent();
1694         if (display == null || display.isRemoved() || !display.isHomeSupported()) {
1695             // Can't launch home on display that doesn't support home.
1696             return false;
1697         }
1698 
1699         return true;
1700     }
1701 
1702     /**
1703      * Check if home activity start should be allowed on a {@link TaskDisplayArea}.
1704      *
1705      * @param homeInfo           {@code ActivityInfo} of the home activity that is going to be
1706      *                           launched.
1707      * @param taskDisplayArea    The target display area.
1708      * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
1709      * @return {@code true} if allow to launch, {@code false} otherwise.
1710      */
canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting)1711     boolean canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea,
1712             boolean allowInstrumenting) {
1713         if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
1714                 && mService.mTopAction == null) {
1715             // We are running in factory test mode, but unable to find the factory test app, so
1716             // just sit around displaying the error message and don't try to start anything.
1717             return false;
1718         }
1719 
1720         final WindowProcessController app =
1721                 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
1722         if (!allowInstrumenting && app != null && app.isInstrumenting()) {
1723             // Don't do this if the home app is currently being instrumented.
1724             return false;
1725         }
1726 
1727         if (taskDisplayArea != null && !taskDisplayArea.canHostHomeTask()) {
1728             return false;
1729         }
1730 
1731         final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId()
1732                 : INVALID_DISPLAY;
1733         if (shouldPlacePrimaryHomeOnDisplay(displayId)) {
1734             return true;
1735         }
1736 
1737         if (!shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
1738             return false;
1739         }
1740 
1741         final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
1742                 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
1743         if (!supportMultipleInstance) {
1744             // Can't launch home on secondary displays if it requested to be single instance.
1745             return false;
1746         }
1747 
1748         return true;
1749     }
1750 
1751     /**
1752      * Ensure all activities visibility, update orientation and configuration.
1753      *
1754      * @param starting                  The currently starting activity or {@code null} if there is
1755      *                                  none.
1756      * @param displayContent            The display where the operation is executed.
1757      * @param deferResume               Whether to defer resume while updating config.
1758      */
ensureVisibilityAndConfig(@ullable ActivityRecord starting, @NonNull DisplayContent displayContent, boolean deferResume)1759     void ensureVisibilityAndConfig(@Nullable ActivityRecord starting,
1760             @NonNull DisplayContent displayContent, boolean deferResume) {
1761         // First ensure visibility without updating the config just yet. We need this to know what
1762         // activities are affecting configuration now.
1763         // Passing null here for 'starting' param value, so that visibility of actual starting
1764         // activity will be properly updated.
1765         ensureActivitiesVisible(null /* starting */, false /* notifyClients */);
1766 
1767         // Force-update the orientation from the WindowManager, since we need the true configuration
1768         // to send to the client now.
1769         final Configuration config =
1770                 displayContent.updateOrientation(starting, true /* forceUpdate */);
1771         // Visibilities may change so let the starting activity have a chance to report. Can't do it
1772         // when visibility is changed in each AppWindowToken because it may trigger wrong
1773         // configuration push because the visibility of some activities may not be updated yet.
1774         if (starting != null) {
1775             starting.reportDescendantOrientationChangeIfNeeded();
1776         }
1777 
1778         // Update the configuration of the activities on the display.
1779         displayContent.updateDisplayOverrideConfigurationLocked(config, starting, deferResume);
1780     }
1781 
1782     /**
1783      * @return a list of pairs, containing activities and their task id which are the top ones in
1784      * each visible root task. The first entry will be the focused activity.
1785      *
1786      * <p>NOTE: If the top activity is in the split screen, the other activities in the same split
1787      * screen will also be returned.
1788      */
getTopVisibleActivities()1789     List<ActivityAssistInfo> getTopVisibleActivities() {
1790         final ArrayList<ActivityAssistInfo> topVisibleActivities = new ArrayList<>();
1791         final ArrayList<ActivityAssistInfo> activityAssistInfos = new ArrayList<>();
1792         final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
1793         // Traverse all displays.
1794         forAllRootTasks(rootTask -> {
1795             // Get top activity from a visible root task and add it to the list.
1796             if (rootTask.shouldBeVisible(null /* starting */)) {
1797                 final ActivityRecord top = rootTask.getTopNonFinishingActivity();
1798                 if (top != null) {
1799                     activityAssistInfos.clear();
1800                     activityAssistInfos.add(new ActivityAssistInfo(top));
1801                     // Check if the activity on the split screen.
1802                     final Task adjacentTask = top.getTask().getAdjacentTask();
1803                     if (adjacentTask != null) {
1804                         final ActivityRecord adjacentActivityRecord =
1805                                 adjacentTask.getTopNonFinishingActivity();
1806                         if (adjacentActivityRecord != null) {
1807                             activityAssistInfos.add(new ActivityAssistInfo(adjacentActivityRecord));
1808                         }
1809                     }
1810                     if (rootTask == topFocusedRootTask) {
1811                         topVisibleActivities.addAll(0, activityAssistInfos);
1812                     } else {
1813                         topVisibleActivities.addAll(activityAssistInfos);
1814                     }
1815                 }
1816             }
1817         });
1818         return topVisibleActivities;
1819     }
1820 
1821     @Nullable
getTopDisplayFocusedRootTask()1822     Task getTopDisplayFocusedRootTask() {
1823         for (int i = getChildCount() - 1; i >= 0; --i) {
1824             final Task focusedRootTask = getChildAt(i).getFocusedRootTask();
1825             if (focusedRootTask != null) {
1826                 return focusedRootTask;
1827             }
1828         }
1829         return null;
1830     }
1831 
1832     @Nullable
getTopResumedActivity()1833     ActivityRecord getTopResumedActivity() {
1834         final Task focusedRootTask = getTopDisplayFocusedRootTask();
1835         if (focusedRootTask == null) {
1836             return null;
1837         }
1838         final ActivityRecord resumedActivity = focusedRootTask.getTopResumedActivity();
1839         if (resumedActivity != null && resumedActivity.app != null) {
1840             return resumedActivity;
1841         }
1842         // The top focused root task might not have a resumed activity yet - look on all displays in
1843         // focus order.
1844         return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedActivity);
1845     }
1846 
isTopDisplayFocusedRootTask(Task task)1847     boolean isTopDisplayFocusedRootTask(Task task) {
1848         return task != null && task == getTopDisplayFocusedRootTask();
1849     }
1850 
attachApplication(WindowProcessController app)1851     boolean attachApplication(WindowProcessController app) throws RemoteException {
1852         final ArrayList<ActivityRecord> activities = mService.mStartingProcessActivities;
1853         RemoteException remoteException = null;
1854         boolean hasActivityStarted = false;
1855         for (int i = activities.size() - 1; i >= 0; i--) {
1856             final ActivityRecord r = activities.get(i);
1857             if (app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
1858                 // The attaching process does not match the starting activity.
1859                 continue;
1860             }
1861             // Consume the pending record.
1862             activities.remove(i);
1863             final TaskFragment tf = r.getTaskFragment();
1864             if (tf == null || r.finishing || r.app != null
1865                     // Ignore keyguard because the app may use show-when-locked when creating.
1866                     || !r.shouldBeVisible(true /* ignoringKeyguard */)
1867                     || !r.showToCurrentUser()) {
1868                 continue;
1869             }
1870             try {
1871                 final boolean canResume = r.isFocusable() && r == tf.topRunningActivity();
1872                 if (mTaskSupervisor.realStartActivityLocked(r, app, canResume,
1873                         true /* checkConfig */)) {
1874                     hasActivityStarted = true;
1875                 }
1876             } catch (RemoteException e) {
1877                 Slog.w(TAG, "Exception in new process when starting " + r, e);
1878                 remoteException = e;
1879             }
1880         }
1881         if (remoteException != null) {
1882             throw remoteException;
1883         }
1884         return hasActivityStarted;
1885     }
1886 
1887     /**
1888      * Make sure that all activities that need to be visible in the system actually are and update
1889      * their configuration.
1890      */
ensureActivitiesVisible()1891     void ensureActivitiesVisible() {
1892         ensureActivitiesVisible(null /* starting */);
1893     }
1894 
ensureActivitiesVisible(ActivityRecord starting)1895     void ensureActivitiesVisible(ActivityRecord starting) {
1896         ensureActivitiesVisible(starting, true /* notifyClients */);
1897     }
1898 
1899     /**
1900      * @see #ensureActivitiesVisible()
1901      */
ensureActivitiesVisible(ActivityRecord starting, boolean notifyClients)1902     void ensureActivitiesVisible(ActivityRecord starting, boolean notifyClients) {
1903         if (mTaskSupervisor.inActivityVisibilityUpdate()
1904                 || mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
1905             // Don't do recursive work.
1906             return;
1907         }
1908         mTaskSupervisor.beginActivityVisibilityUpdate();
1909         try {
1910             // First the front root tasks. In case any are not fullscreen and are in front of home.
1911             for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
1912                 final DisplayContent display = getChildAt(displayNdx);
1913                 display.ensureActivitiesVisible(starting, notifyClients);
1914             }
1915         } finally {
1916             mTaskSupervisor.endActivityVisibilityUpdate();
1917         }
1918     }
1919 
switchUser(int userId, UserState uss)1920     boolean switchUser(int userId, UserState uss) {
1921         final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
1922         final int focusRootTaskId = topFocusedRootTask != null
1923                 ? topFocusedRootTask.getRootTaskId() : INVALID_TASK_ID;
1924         // Also dismiss the pinned root task whenever we switch users. Removing the pinned root task
1925         // will also cause all tasks to be moved to the fullscreen root task at a position that is
1926         // appropriate.
1927         removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED);
1928 
1929         mUserRootTaskInFront.put(mCurrentUser, focusRootTaskId);
1930         mCurrentUser = userId;
1931 
1932         mTaskSupervisor.mStartingUsers.add(uss);
1933         forAllRootTasks(rootTask -> {
1934             rootTask.switchUser(userId);
1935         });
1936 
1937 
1938         if (topFocusedRootTask != null && isAlwaysVisibleUser(topFocusedRootTask.mUserId)) {
1939             Slog.i(TAG, "Persisting top task because it belongs to an always-visible user");
1940             // For a normal user-switch, we will restore the new user's task. But if the pre-switch
1941             // top task is an always-visible (Communal) one, keep it even after the switch.
1942             mUserRootTaskInFront.put(mCurrentUser, focusRootTaskId);
1943         }
1944 
1945         final int restoreRootTaskId = mUserRootTaskInFront.get(userId);
1946         Task rootTask = getRootTask(restoreRootTaskId);
1947         if (rootTask == null) {
1948             rootTask = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
1949         }
1950         final boolean homeInFront = rootTask.isActivityTypeHome();
1951         if (rootTask.isOnHomeDisplay()) {
1952             rootTask.moveToFront("switchUserOnHomeDisplay");
1953         } else {
1954             // Root task was moved to another display while user was swapped out.
1955             resumeHomeActivity(null, "switchUserOnOtherDisplay", getDefaultTaskDisplayArea());
1956         }
1957         return homeInFront;
1958     }
1959 
1960     /** Returns whether the given user is to be always-visible (e.g. a communal profile). */
isAlwaysVisibleUser(@serIdInt int userId)1961     private boolean isAlwaysVisibleUser(@UserIdInt int userId) {
1962         final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
1963         final UserProperties properties = umi.getUserProperties(userId);
1964         return properties != null && properties.getAlwaysVisible();
1965     }
1966 
removeUser(int userId)1967     void removeUser(int userId) {
1968         mUserRootTaskInFront.delete(userId);
1969     }
1970 
1971     /**
1972      * Update the last used root task id for non-current user (current user's last
1973      * used root task is the focused root task)
1974      */
updateUserRootTask(int userId, Task rootTask)1975     void updateUserRootTask(int userId, Task rootTask) {
1976         if (userId != mCurrentUser) {
1977             if (rootTask == null) {
1978                 rootTask = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
1979             }
1980 
1981             mUserRootTaskInFront.put(userId, rootTask.getRootTaskId());
1982         }
1983     }
1984 
1985     /**
1986      * Move root task with all its existing content to specified task display area.
1987      *
1988      * @param rootTaskId      Id of root task to move.
1989      * @param taskDisplayArea The task display area to move root task to.
1990      * @param onTop           Indicates whether container should be place on top or on bottom.
1991      */
moveRootTaskToTaskDisplayArea(int rootTaskId, TaskDisplayArea taskDisplayArea, boolean onTop)1992     void moveRootTaskToTaskDisplayArea(int rootTaskId, TaskDisplayArea taskDisplayArea,
1993             boolean onTop) {
1994         final Task rootTask = getRootTask(rootTaskId);
1995         if (rootTask == null) {
1996             throw new IllegalArgumentException("moveRootTaskToTaskDisplayArea: Unknown rootTaskId="
1997                     + rootTaskId);
1998         }
1999 
2000         final TaskDisplayArea currentTaskDisplayArea = rootTask.getDisplayArea();
2001         if (currentTaskDisplayArea == null) {
2002             throw new IllegalStateException("moveRootTaskToTaskDisplayArea: rootTask=" + rootTask
2003                     + " is not attached to any task display area.");
2004         }
2005 
2006         if (taskDisplayArea == null) {
2007             throw new IllegalArgumentException(
2008                     "moveRootTaskToTaskDisplayArea: Unknown taskDisplayArea=" + taskDisplayArea);
2009         }
2010 
2011         if (currentTaskDisplayArea == taskDisplayArea) {
2012             throw new IllegalArgumentException("Trying to move rootTask=" + rootTask
2013                     + " to its current taskDisplayArea=" + taskDisplayArea);
2014         }
2015         rootTask.reparent(taskDisplayArea, onTop);
2016 
2017         // Resume focusable root task after reparenting to another display area.
2018         rootTask.resumeNextFocusAfterReparent();
2019 
2020         // TODO(multi-display): resize rootTasks properly if moved from split-screen.
2021     }
2022 
2023     /**
2024      * Move root task with all its existing content to specified display.
2025      *
2026      * @param rootTaskId Id of root task to move.
2027      * @param displayId  Id of display to move root task to.
2028      * @param onTop      Indicates whether container should be place on top or on bottom.
2029      */
moveRootTaskToDisplay(int rootTaskId, int displayId, boolean onTop)2030     void moveRootTaskToDisplay(int rootTaskId, int displayId, boolean onTop) {
2031         final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
2032         if (displayContent == null) {
2033             throw new IllegalArgumentException("moveRootTaskToDisplay: Unknown displayId="
2034                     + displayId);
2035         }
2036 
2037         moveRootTaskToTaskDisplayArea(rootTaskId, displayContent.getDefaultTaskDisplayArea(),
2038                 onTop);
2039     }
2040 
moveActivityToPinnedRootTask(@onNull ActivityRecord r, @Nullable ActivityRecord launchIntoPipHostActivity, String reason)2041     void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
2042             @Nullable ActivityRecord launchIntoPipHostActivity, String reason) {
2043         moveActivityToPinnedRootTask(r, launchIntoPipHostActivity, reason, null /* transition */);
2044     }
2045 
moveActivityToPinnedRootTask(@onNull ActivityRecord r, @Nullable ActivityRecord launchIntoPipHostActivity, String reason, @Nullable Transition transition)2046     void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
2047             @Nullable ActivityRecord launchIntoPipHostActivity, String reason,
2048             @Nullable Transition transition) {
2049         moveActivityToPinnedRootTask(r, launchIntoPipHostActivity, reason, transition,
2050                 null /* bounds */);
2051     }
2052 
moveActivityToPinnedRootTask(@onNull ActivityRecord r, @Nullable ActivityRecord launchIntoPipHostActivity, String reason, @Nullable Transition transition, @Nullable Rect bounds)2053     void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
2054             @Nullable ActivityRecord launchIntoPipHostActivity, String reason,
2055             @Nullable Transition transition, @Nullable Rect bounds) {
2056         final TaskDisplayArea taskDisplayArea = r.getDisplayArea();
2057         final Task task = r.getTask();
2058         final Task rootTask;
2059 
2060         Transition newTransition = transition;
2061         // Create a transition now (if not provided) to collect the current pinned Task dismiss.
2062         // Only do the create here as the Task (trigger) to enter PIP is not ready yet.
2063         final TransitionController transitionController = task.mTransitionController;
2064         if (newTransition == null && !transitionController.isCollecting()
2065                 && transitionController.getTransitionPlayer() != null) {
2066             newTransition = transitionController.createTransition(TRANSIT_PIP);
2067         }
2068 
2069         transitionController.deferTransitionReady();
2070         Transition.ReadyCondition pipChangesApplied = new Transition.ReadyCondition("movedToPip");
2071         transitionController.waitFor(pipChangesApplied);
2072         mService.deferWindowLayout();
2073         boolean localVisibilityDeferred = false;
2074         // If the caller is from WindowOrganizerController, it should be already deferred.
2075         if (!mTaskSupervisor.isRootVisibilityUpdateDeferred()) {
2076             mTaskSupervisor.setDeferRootVisibilityUpdate(true);
2077             localVisibilityDeferred = true;
2078         }
2079         try {
2080             // This will change the root pinned task's windowing mode to its original mode, ensuring
2081             // we only have one root task that is in pinned mode.
2082             final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask();
2083             if (rootPinnedTask != null) {
2084                 transitionController.collect(rootPinnedTask);
2085                 // The new ActivityRecord should replace the existing PiP, so it's more desirable
2086                 // that the old PiP disappears instead of turning to full-screen at the same time,
2087                 // as the Task#dismissPip is trying to do.
2088                 removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED);
2089             }
2090 
2091             // Set a transition to ensure that we don't immediately try and update the visibility
2092             // of the activity entering PIP
2093             r.getDisplayContent().prepareAppTransition(TRANSIT_NONE);
2094 
2095             transitionController.collect(task);
2096 
2097             // Defer the windowing mode change until after the transition to prevent the activity
2098             // from doing work and changing the activity visuals while animating
2099             // TODO(task-org): Figure-out more structured way to do this long term.
2100             if (!isPip2ExperimentEnabled()) {
2101                 r.setWindowingMode(r.getWindowingMode());
2102             }
2103 
2104             final TaskFragment organizedTf = r.getOrganizedTaskFragment();
2105             final TaskFragment taskFragment = r.getTaskFragment();
2106             final boolean singleActivity = task.getNonFinishingActivityCount() == 1;
2107             if (singleActivity) {
2108                 rootTask = task;
2109 
2110                 // Apply the last recents animation leash transform to the task entering PIP
2111                 rootTask.maybeApplyLastRecentsAnimationTransaction();
2112 
2113                 if (rootTask.getParent() != taskDisplayArea) {
2114                     // root task is nested, but pinned tasks need to be direct children of their
2115                     // display area, so reparent.
2116                     rootTask.reparent(taskDisplayArea, true /* onTop */);
2117                 }
2118 
2119                 rootTask.forAllTaskFragments(tf -> {
2120                     if (!tf.isOrganizedTaskFragment()) {
2121                         return;
2122                     }
2123                     tf.resetAdjacentTaskFragment();
2124                     tf.setCompanionTaskFragment(null /* companionTaskFragment */);
2125                     tf.setAnimationParams(TaskFragmentAnimationParams.DEFAULT);
2126                     if (tf.getTopNonFinishingActivity() != null) {
2127                         // When the Task is entering picture-in-picture, we should clear all
2128                         // override from the client organizer, so the PIP activity can get the
2129                         // correct config from the Task, and prevent conflict with the
2130                         // PipTaskOrganizer. TaskFragmentOrganizer may have requested relative
2131                         // bounds, so reset the relative bounds before update configuration.
2132                         tf.setRelativeEmbeddedBounds(new Rect());
2133                         tf.updateRequestedOverrideConfiguration(EMPTY);
2134                     }
2135                 });
2136             } else {
2137                 // In the case of multiple activities, we will create a new task for it and then
2138                 // move the PIP activity into the task. Note that we explicitly defer the task
2139                 // appear being sent in this case and mark this newly created task to been visible.
2140                 rootTask = new Task.Builder(mService)
2141                         .setActivityType(r.getActivityType())
2142                         .setOnTop(true)
2143                         .setActivityInfo(r.info)
2144                         .setParent(taskDisplayArea)
2145                         .setIntent(r.intent)
2146                         .setDeferTaskAppear(true)
2147                         .setHasBeenVisible(true)
2148                         // In case the activity is in system split screen, or Activity Embedding
2149                         // split, we need to animate the PIP Task from the original TaskFragment
2150                         // bounds, so also setting the windowing mode, otherwise the bounds may
2151                         // be reset to fullscreen.
2152                         .setWindowingMode(taskFragment.getWindowingMode())
2153                         .build();
2154                 // Establish bi-directional link between the original and pinned task.
2155                 r.setLastParentBeforePip(launchIntoPipHostActivity);
2156                 // It's possible the task entering PIP is in freeform, so save the last
2157                 // non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore
2158                 // to its previous freeform bounds.
2159                 rootTask.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds);
2160                 // When creating a new Task for PiP, set its initial bounds as the TaskFragment in
2161                 // case the activity is embedded, so that it can be animated to PiP window from the
2162                 // current bounds.
2163                 // Use Task#setBoundsUnchecked to skip checking windowing mode as the windowing mode
2164                 // will be updated later after this is collected in transition.
2165                 rootTask.setBoundsUnchecked(taskFragment.getBounds());
2166                 // The exit-PIP activity resumes early for seamless transition. In certain
2167                 // scenarios, this introduces unintended addition to recents. To address this,
2168                 // we mark the root task for automatic removal from recents. This ensures that
2169                 // after the pinned activity reparents to its original task, the root task is
2170                 // automatically removed from the recents list.
2171                 rootTask.autoRemoveRecents = true;
2172 
2173                 // Move the last recents animation transaction from original task to the new one.
2174                 if (task.mLastRecentsAnimationTransaction != null) {
2175                     rootTask.setLastRecentsAnimationTransaction(
2176                             task.mLastRecentsAnimationTransaction,
2177                             task.mLastRecentsAnimationOverlay);
2178                     task.clearLastRecentsAnimationTransaction(false /* forceRemoveOverlay */);
2179                 } else {
2180                     // Reset the original task surface
2181                     task.resetSurfaceControlTransforms();
2182                 }
2183 
2184                 // The organized TaskFragment is becoming empty because this activity is reparented
2185                 // to a new PIP Task. In this case, we should notify the organizer about why the
2186                 // TaskFragment becomes empty.
2187                 if (organizedTf != null && organizedTf.getNonFinishingActivityCount() == 1
2188                         && organizedTf.getTopNonFinishingActivity() == r) {
2189                     organizedTf.mClearedTaskFragmentForPip = true;
2190                 }
2191 
2192                 if (isPip2ExperimentEnabled()) {
2193                     transitionController.collectExistenceChange(rootTask);
2194                 } else {
2195                     transitionController.collect(rootTask);
2196                 }
2197 
2198                 if (transitionController.isShellTransitionsEnabled()) {
2199                     // set mode NOW so that when we reparent the activity, it won't be resumed.
2200                     // During recents animations, the original task is "occluded" by launcher but
2201                     // it wasn't paused (due to transient-launch). If we reparent to the (top) task
2202                     // now, it will take focus briefly which confuses the RecentTasks tracker.
2203                     rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
2204                 }
2205                 // Temporarily disable focus when reparenting to avoid intermediate focus change
2206                 // (because the task is on top and the activity is resumed), which could cause the
2207                 // task to be added in recents task list unexpectedly.
2208                 rootTask.setFocusable(false);
2209                 // There are multiple activities in the task and moving the top activity should
2210                 // reveal/leave the other activities in their original task.
2211                 // On the other hand, ActivityRecord#onParentChanged takes care of setting the
2212                 // up-to-dated root pinned task information on this newly created root task.
2213                 r.reparent(rootTask, MAX_VALUE, reason);
2214                 rootTask.setFocusable(true);
2215 
2216                 // Ensure the leash of new task is in sync with its current bounds after reparent.
2217                 rootTask.maybeApplyLastRecentsAnimationTransaction();
2218 
2219                 // In the case of this activity entering PIP due to it being moved to the back,
2220                 // the old activity would have a TRANSIT_TASK_TO_BACK transition that needs to be
2221                 // ran. But, since its visibility did not change (note how it was STOPPED/not
2222                 // visible, and with it now at the back stack, it remains not visible), the logic to
2223                 // add the transition is automatically skipped. We then add this activity manually
2224                 // to the list of apps being closed, and request its transition to be ran.
2225                 final ActivityRecord oldTopActivity = task.getTopMostActivity();
2226                 if (oldTopActivity != null && oldTopActivity.isState(STOPPED)
2227                         && task.getDisplayContent().mAppTransition.containsTransitRequest(
2228                         TRANSIT_TO_BACK)) {
2229                     task.getDisplayContent().mClosingApps.add(oldTopActivity);
2230                     oldTopActivity.mRequestForceTransition = true;
2231                 }
2232             }
2233 
2234             // TODO(remove-legacy-transit): Move this to the `singleActivity` case when removing
2235             //                              legacy transit.
2236             rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
2237             if (isPip2ExperimentEnabled() && bounds != null) {
2238                 // set the final pip bounds in advance if pip2 is enabled
2239                 rootTask.setBounds(bounds);
2240             }
2241 
2242             // Set the launch bounds for launch-into-pip Activity on the root task.
2243             if (r.getOptions() != null && r.getOptions().isLaunchIntoPip()) {
2244                 // Record the snapshot now, it will be later fetched for content-pip animation.
2245                 // We do this early in the process to make sure the right snapshot is used for
2246                 // entering content-pip animation.
2247                 mWindowManager.mTaskSnapshotController.recordSnapshot(task);
2248                 rootTask.setBounds(r.pictureInPictureArgs.getSourceRectHint());
2249             }
2250             rootTask.setDeferTaskAppear(false);
2251 
2252             if (!isPip2ExperimentEnabled()) {
2253                 // After setting this, it is not expected to change activity configuration until the
2254                 // transition animation is finished. So the activity can keep consistent appearance
2255                 // when animating.
2256                 r.mWaitForEnteringPinnedMode = true;
2257             }
2258             // Reset the state that indicates it can enter PiP while pausing after we've moved it
2259             // to the root pinned task
2260             r.supportsEnterPipOnTaskSwitch = false;
2261 
2262             if (organizedTf != null && organizedTf.mClearedTaskFragmentForPip
2263                     && organizedTf.isTaskVisibleRequested()) {
2264                 // Dispatch the pending info to TaskFragmentOrganizer before PIP animation.
2265                 // Otherwise, it will keep waiting for the empty TaskFragment to be non-empty.
2266                 mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
2267                         organizedTf);
2268             }
2269         } finally {
2270             mService.continueWindowLayout();
2271             try {
2272                 if (localVisibilityDeferred) {
2273                     mTaskSupervisor.setDeferRootVisibilityUpdate(false);
2274                     ensureActivitiesVisible();
2275                 }
2276             } finally {
2277                 transitionController.continueTransitionReady();
2278                 pipChangesApplied.meet();
2279             }
2280         }
2281 
2282         if (newTransition != null) {
2283             // Request at end since we want task-organizer events from ensureActivitiesVisible
2284             // to be recognized.
2285             transitionController.requestStartTransition(newTransition, rootTask,
2286                     null /* remoteTransition */, null /* displayChange */);
2287             // A new transition was created just for this operations. Since the operation is
2288             // complete, mark it as ready.
2289             newTransition.setReady(rootTask, true /* ready */);
2290         }
2291 
2292         resumeFocusedTasksTopActivities();
2293 
2294         notifyActivityPipModeChanged(r.getTask(), r);
2295 
2296         if (!isPip2ExperimentEnabled()) {
2297             // TODO: b/335866033 Remove the abort PiP on timeout once PiP2 flag is on.
2298             // Set up a timeout callback to potentially abort PiP enter if in an inconsistent state.
2299             scheduleTimeoutAbortPipEnter(rootTask);
2300         }
2301     }
2302 
scheduleTimeoutAbortPipEnter(Task rootTask)2303     private void scheduleTimeoutAbortPipEnter(Task rootTask) {
2304         if (mMaybeAbortPipEnterRunnable != null) {
2305             // If there is an abort enter PiP check pending already remove it and abort
2306             // immediately since we are trying to enter PiP in an inconsistent state
2307             mHandler.removeCallbacks(mMaybeAbortPipEnterRunnable);
2308             mMaybeAbortPipEnterRunnable.run();
2309         }
2310         // Snapshot a throwable early on to display the callstack upon abort later on timeout.
2311         final Throwable enterPipThrowable = new Throwable();
2312         // Set up a timeout to potentially roll back the task change to PINNED mode
2313         // by aborting PiP.
2314         mMaybeAbortPipEnterRunnable = new Runnable() {
2315             @Override
2316             public void run() {
2317                 synchronized (mService.mGlobalLock) {
2318                     if (mTransitionController.inTransition()) {
2319                         // If this task is a part an active transition aborting PiP might break
2320                         // it; so run the timeout callback directly once idle.
2321 
2322                         final Runnable expectedMaybeAbortAtTimeout = mMaybeAbortPipEnterRunnable;
2323                         mTransitionController.mStateValidators.add(() -> {
2324                             // If a second PiP transition comes in, it runs the abort runnable for
2325                             // the first transition pre-emptively, so we need to avoid calling
2326                             // the same runnable twice when validating states.
2327                             if (expectedMaybeAbortAtTimeout != mMaybeAbortPipEnterRunnable) return;
2328                             mMaybeAbortPipEnterRunnable = null;
2329                             run();
2330                         });
2331                         return;
2332                     } else {
2333                         mMaybeAbortPipEnterRunnable = null;
2334                     }
2335                     mService.deferWindowLayout();
2336                     final ActivityRecord top = rootTask.getTopMostActivity();
2337                     final ActivityManager.RunningTaskInfo beforeTaskInfo =
2338                             rootTask.getTaskInfo();
2339                     if (top != null && !top.inPinnedWindowingMode()
2340                             && rootTask.abortPipEnter(top)) {
2341                         Slog.wtf(TAG, "Enter PiP was aborted via a scheduled timeout"
2342                                         + "task_state_before=" + beforeTaskInfo
2343                                         + "task_state_after=" + rootTask.getTaskInfo(),
2344                                 enterPipThrowable);
2345                     }
2346                     mService.continueWindowLayout();
2347                 }
2348             }
2349         };
2350         mHandler.postDelayed(mMaybeAbortPipEnterRunnable, PINNED_TASK_ABORT_TIMEOUT);
2351         Slog.d(TAG, "a delayed check for potentially aborting PiP if "
2352                 + "in a wrong state is scheduled.");
2353     }
2354 
2355 
2356     /**
2357      * Notifies when an activity enters or leaves PIP mode.
2358      *
2359      * @param task the task of {@param r}
2360      * @param r indicates the activity currently in PIP, can be null to indicate no activity is
2361      *          currently in PIP mode.
2362      */
notifyActivityPipModeChanged(@onNull Task task, @Nullable ActivityRecord r)2363     void notifyActivityPipModeChanged(@NonNull Task task, @Nullable ActivityRecord r) {
2364         final boolean inPip = r != null;
2365         if (inPip) {
2366             mService.getTaskChangeNotificationController().notifyActivityPinned(r);
2367         } else {
2368             mService.getTaskChangeNotificationController().notifyActivityUnpinned();
2369         }
2370         mWindowManager.mPolicy.setPipVisibilityLw(inPip);
2371         if (task.getSurfaceControl() != null) {
2372             mWmService.mTransactionFactory.get()
2373                     .setTrustedOverlay(task.getSurfaceControl(), inPip)
2374                     .apply();
2375         }
2376     }
2377 
executeAppTransitionForAllDisplay()2378     void executeAppTransitionForAllDisplay() {
2379         for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2380             final DisplayContent display = getChildAt(displayNdx);
2381             display.mDisplayContent.executeAppTransition();
2382         }
2383     }
2384 
2385     @Nullable
findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea, boolean includeLaunchedFromBubble)2386     ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea,
2387             boolean includeLaunchedFromBubble) {
2388         return findTask(r.getActivityType(), r.taskAffinity, r.intent, r.info,
2389                 preferredTaskDisplayArea, includeLaunchedFromBubble);
2390     }
2391 
2392     @Nullable
findTask(int activityType, String taskAffinity, Intent intent, ActivityInfo info, TaskDisplayArea preferredTaskDisplayArea, boolean includeLaunchedFromBubble)2393     ActivityRecord findTask(int activityType, String taskAffinity, Intent intent, ActivityInfo info,
2394             TaskDisplayArea preferredTaskDisplayArea, boolean includeLaunchedFromBubble) {
2395         ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of type=%s, taskAffinity=%s, intent=%s"
2396                         + ", info=%s, preferredTDA=%s, includeLaunchedFromBubble=%b", activityType,
2397                 taskAffinity, intent, info, preferredTaskDisplayArea, includeLaunchedFromBubble);
2398         mTmpFindTaskResult.init(activityType, taskAffinity, intent, info,
2399                 includeLaunchedFromBubble);
2400 
2401         // Looking up task on preferred display area first
2402         ActivityRecord candidateActivity = null;
2403         if (preferredTaskDisplayArea != null) {
2404             mTmpFindTaskResult.process(preferredTaskDisplayArea);
2405             if (mTmpFindTaskResult.mIdealRecord != null) {
2406                 return mTmpFindTaskResult.mIdealRecord;
2407             } else if (mTmpFindTaskResult.mCandidateRecord != null) {
2408                 candidateActivity = mTmpFindTaskResult.mCandidateRecord;
2409             }
2410         }
2411 
2412         final ActivityRecord idealMatchActivity = getItemFromTaskDisplayAreas(taskDisplayArea -> {
2413             if (taskDisplayArea == preferredTaskDisplayArea) {
2414                 return null;
2415             }
2416 
2417             mTmpFindTaskResult.process(taskDisplayArea);
2418             if (mTmpFindTaskResult.mIdealRecord != null) {
2419                 return mTmpFindTaskResult.mIdealRecord;
2420             }
2421             return null;
2422         });
2423         if (idealMatchActivity != null) {
2424             return idealMatchActivity;
2425         }
2426 
2427         if (WM_DEBUG_TASKS.isEnabled() && candidateActivity == null) {
2428             ProtoLog.d(WM_DEBUG_TASKS, "No task found");
2429         }
2430         return candidateActivity;
2431     }
2432 
2433     /**
2434      * Finish the topmost activities in all leaf tasks that belong to the crashed app.
2435      *
2436      * @param app    The app that crashed.
2437      * @param reason Reason to perform this action.
2438      * @return The finished task which was on top or visible, otherwise {@code null} if the crashed
2439      *         app doesn't have activity in visible task.
2440      */
2441     @Nullable
finishTopCrashedActivities(WindowProcessController app, String reason)2442     Task finishTopCrashedActivities(WindowProcessController app, String reason) {
2443         Task focusedRootTask = getTopDisplayFocusedRootTask();
2444         final Task[] finishedTask = new Task[1];
2445         forAllLeafTasks(leafTask -> {
2446             final boolean recordTopOrVisible = finishedTask[0] == null
2447                     && (focusedRootTask == leafTask.getRootTask() || leafTask.isVisibleRequested());
2448             final Task t = leafTask.finishTopCrashedActivityLocked(app, reason);
2449             if (recordTopOrVisible) {
2450                 finishedTask[0] = t;
2451             }
2452         }, true);
2453         return finishedTask[0];
2454     }
2455 
ensureVisibilityOnVisibleActivityDiedOrCrashed(String reason)2456     void ensureVisibilityOnVisibleActivityDiedOrCrashed(String reason) {
2457         final Task topTask = getTopDisplayFocusedRootTask();
2458         if (topTask != null && topTask.topRunningActivity(true /* focusableOnly */) == null) {
2459             // Move the next focusable task to front.
2460             topTask.adjustFocusToNextFocusableTask(reason);
2461         }
2462         if (!resumeFocusedTasksTopActivities()) {
2463             // It may be nothing to resume because there are pausing activities or all the top
2464             // activities are resumed. Then it still needs to make sure all visible activities are
2465             // running in case the tasks were reordered or there are non-top visible activities.
2466             ensureActivitiesVisible();
2467         }
2468     }
2469 
resumeFocusedTasksTopActivities()2470     boolean resumeFocusedTasksTopActivities() {
2471         return resumeFocusedTasksTopActivities(null, null, null);
2472     }
2473 
resumeFocusedTasksTopActivities( Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions)2474     boolean resumeFocusedTasksTopActivities(
2475             Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) {
2476         return resumeFocusedTasksTopActivities(targetRootTask, target, targetOptions,
2477                 false /* deferPause */);
2478     }
2479 
resumeFocusedTasksTopActivities( Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions, boolean deferPause)2480     boolean resumeFocusedTasksTopActivities(
2481             Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
2482             boolean deferPause) {
2483         if (!mTaskSupervisor.readyToResume()) {
2484             return false;
2485         }
2486 
2487         boolean result = false;
2488         if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
2489                 || getTopDisplayFocusedRootTask() == targetRootTask)) {
2490             result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
2491                     deferPause);
2492         }
2493 
2494         for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2495             final DisplayContent display = getChildAt(displayNdx);
2496             final boolean curResult = result;
2497             boolean[] resumedOnDisplay = new boolean[1];
2498             final ActivityRecord topOfDisplay = display.topRunningActivity();
2499             display.forAllRootTasks(rootTask -> {
2500                 final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
2501                 if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
2502                     return;
2503                 }
2504                 if (rootTask == targetRootTask) {
2505                     // Simply update the result for targetRootTask because the targetRootTask
2506                     // had already resumed in above. We don't want to resume it again,
2507                     // especially in some cases, it would cause a second launch failure
2508                     // if app process was dead.
2509                     resumedOnDisplay[0] |= curResult;
2510                     return;
2511                 }
2512                 if (topRunningActivity.isState(RESUMED) && topRunningActivity == topOfDisplay) {
2513                     // Kick off any lingering app transitions form the MoveTaskToFront operation,
2514                     // but only consider the top activity on that display.
2515                     rootTask.executeAppTransition(targetOptions);
2516                 } else {
2517                     resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
2518                 }
2519             });
2520             result |= resumedOnDisplay[0];
2521             if (!resumedOnDisplay[0]) {
2522                 // In cases when there are no valid activities (e.g. device just booted or launcher
2523                 // crashed) it's possible that nothing was resumed on a display. Requesting resume
2524                 // of top activity in focused root task explicitly will make sure that at least home
2525                 // activity is started and resumed, and no recursion occurs.
2526                 final Task focusedRoot = display.getFocusedRootTask();
2527                 if (focusedRoot != null) {
2528                     result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
2529                 } else if (targetRootTask == null) {
2530                     result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
2531                             display.getDefaultTaskDisplayArea());
2532                 }
2533             }
2534         }
2535 
2536         return result;
2537     }
2538 
sendSleepTransition(final DisplayContent display)2539     void sendSleepTransition(final DisplayContent display) {
2540         // We don't actually care about collecting anything here. We really just want
2541         // this as a signal to the transition-player.
2542         final Transition transition = new Transition(TRANSIT_SLEEP, 0 /* flags */,
2543                 display.mTransitionController, mWmService.mSyncEngine);
2544         final TransitionController.OnStartCollect sendSleepTransition = (deferred) -> {
2545             if (deferred && !display.shouldSleep()) {
2546                 transition.abort();
2547             } else {
2548                 display.mTransitionController.requestStartTransition(transition,
2549                         null /* trigger */, null /* remote */, null /* display */);
2550                 // Force playing immediately so that unrelated ops can't be collected.
2551                 transition.playNow();
2552             }
2553         };
2554         if (!display.mTransitionController.isCollecting()) {
2555             // Since this bypasses sync, submit directly ignoring whether sync-engine
2556             // is active.
2557             if (mWindowManager.mSyncEngine.hasActiveSync()) {
2558                 Slog.w(TAG, "Ongoing sync outside of a transition.");
2559             }
2560             display.mTransitionController.moveToCollecting(transition);
2561             sendSleepTransition.onCollectStarted(false /* deferred */);
2562         } else {
2563             display.mTransitionController.startCollectOrQueue(transition,
2564                     sendSleepTransition);
2565         }
2566     }
2567 
applySleepTokens(boolean applyToRootTasks)2568     void applySleepTokens(boolean applyToRootTasks) {
2569         boolean scheduledSleepTransition = false;
2570 
2571         for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2572             // Set the sleeping state of the display.
2573             final DisplayContent display = getChildAt(displayNdx);
2574             final boolean displayShouldSleep = display.shouldSleep();
2575             if (displayShouldSleep == display.isSleeping()) {
2576                 continue;
2577             }
2578             final boolean wasSleeping = display.isSleeping();
2579             display.setIsSleeping(displayShouldSleep);
2580 
2581             if (display.mTransitionController.isShellTransitionsEnabled()
2582                     && !scheduledSleepTransition
2583                     // Only care if there are actual sleep tokens.
2584                     && displayShouldSleep && !display.mAllSleepTokens.isEmpty()) {
2585                 scheduledSleepTransition = true;
2586 
2587                 if (!mHandler.hasMessages(MSG_SEND_SLEEP_TRANSITION)) {
2588                     mHandler.sendMessageDelayed(
2589                             mHandler.obtainMessage(MSG_SEND_SLEEP_TRANSITION, display),
2590                             SLEEP_TRANSITION_WAIT_MILLIS);
2591                 }
2592             }
2593 
2594             if (!applyToRootTasks) {
2595                 continue;
2596             }
2597 
2598             // Prepare transition before resume top activity, so it can be collected.
2599             if (!displayShouldSleep && display.mTransitionController.isShellTransitionsEnabled()
2600                     && !display.mTransitionController.isCollecting()) {
2601                 // Use NONE if keyguard is not showing.
2602                 int transit = TRANSIT_NONE;
2603                 Task startTask = null;
2604                 int flags = 0;
2605                 if (display.isKeyguardOccluded()) {
2606                     startTask = display.getTaskOccludingKeyguard();
2607                     flags = TRANSIT_FLAG_KEYGUARD_OCCLUDING;
2608                     transit = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
2609                 }
2610                 if (wasSleeping) {
2611                     transit = TRANSIT_WAKE;
2612                 }
2613                 display.mTransitionController.requestStartTransition(
2614                         display.mTransitionController.createTransition(transit, flags),
2615                         startTask, null /* remoteTransition */, null /* displayChange */);
2616             }
2617             // Set the sleeping state of the root tasks on the display.
2618             display.forAllRootTasks(rootTask -> {
2619                 if (displayShouldSleep) {
2620                     rootTask.goToSleepIfPossible(false /* shuttingDown */);
2621                 } else {
2622                     rootTask.forAllLeafTasksAndLeafTaskFragments(
2623                             taskFragment -> taskFragment.awakeFromSleeping(),
2624                             true /* traverseTopToBottom */);
2625                     if (rootTask.isFocusedRootTaskOnDisplay()
2626                             && !mTaskSupervisor.getKeyguardController()
2627                             .isKeyguardOrAodShowing(display.mDisplayId)) {
2628                         // If the keyguard is unlocked - resume immediately.
2629                         // It is possible that the display will not be awake at the time we
2630                         // process the keyguard going away, which can happen before the sleep
2631                         // token is released. As a result, it is important we resume the
2632                         // activity here.
2633                         rootTask.resumeTopActivityUncheckedLocked(null, null);
2634                     }
2635                     // The visibility update must not be called before resuming the top, so the
2636                     // display orientation can be updated first if needed. Otherwise there may
2637                     // have redundant configuration changes due to apply outdated display
2638                     // orientation (from keyguard) to activity.
2639                     rootTask.ensureActivitiesVisible(null /* starting */);
2640                 }
2641             });
2642         }
2643 
2644         if (!scheduledSleepTransition) {
2645             mHandler.removeMessages(MSG_SEND_SLEEP_TRANSITION);
2646         }
2647     }
2648 
getRootTask(int rooTaskId)2649     protected Task getRootTask(int rooTaskId) {
2650         for (int i = getChildCount() - 1; i >= 0; --i) {
2651             final Task rootTask = getChildAt(i).getRootTask(rooTaskId);
2652             if (rootTask != null) {
2653                 return rootTask;
2654             }
2655         }
2656         return null;
2657     }
2658 
2659     /** @see DisplayContent#getRootTask(int, int) */
getRootTask(int windowingMode, int activityType)2660     Task getRootTask(int windowingMode, int activityType) {
2661         for (int i = getChildCount() - 1; i >= 0; --i) {
2662             final Task rootTask = getChildAt(i).getRootTask(windowingMode, activityType);
2663             if (rootTask != null) {
2664                 return rootTask;
2665             }
2666         }
2667         return null;
2668     }
2669 
getRootTask(int windowingMode, int activityType, int displayId)2670     private Task getRootTask(int windowingMode, int activityType,
2671             int displayId) {
2672         DisplayContent display = getDisplayContent(displayId);
2673         if (display == null) {
2674             return null;
2675         }
2676         return display.getRootTask(windowingMode, activityType);
2677     }
2678 
getRootTaskInfo(Task task)2679     private RootTaskInfo getRootTaskInfo(Task task) {
2680         RootTaskInfo info = new RootTaskInfo();
2681         task.fillTaskInfo(info);
2682 
2683         final DisplayContent displayContent = task.getDisplayContent();
2684         if (displayContent == null) {
2685             // A task might be not attached to a display.
2686             info.position = -1;
2687         } else {
2688             // Find the task z-order among all root tasks on the display from bottom to top.
2689             final int[] taskIndex = new int[1];
2690             final boolean[] hasFound = new boolean[1];
2691             displayContent.forAllRootTasks(rootTask -> {
2692                 if (task == rootTask) {
2693                     hasFound[0] = true;
2694                     return true;
2695                 }
2696                 taskIndex[0]++;
2697                 return false;
2698             }, false /* traverseTopToBottom */);
2699             info.position = hasFound[0] ? taskIndex[0] : -1;
2700         }
2701         info.visible = task.shouldBeVisible(null);
2702         task.getBounds(info.bounds);
2703 
2704         final int numTasks = task.getDescendantTaskCount();
2705         info.childTaskIds = new int[numTasks];
2706         info.childTaskNames = new String[numTasks];
2707         info.childTaskBounds = new Rect[numTasks];
2708         info.childTaskUserIds = new int[numTasks];
2709         final int[] currentIndex = {0};
2710 
2711         task.forAllLeafTasks(t -> {
2712             int i = currentIndex[0];
2713             info.childTaskIds[i] = t.mTaskId;
2714             info.childTaskNames[i] = t.origActivity != null ? t.origActivity.flattenToString()
2715                     : t.realActivity != null ? t.realActivity.flattenToString()
2716                     : t.getTopNonFinishingActivity() != null
2717                     ? t.getTopNonFinishingActivity().packageName : "unknown";
2718             info.childTaskBounds[i] = t.mAtmService.getTaskBounds(t.mTaskId);
2719             info.childTaskUserIds[i] = t.mUserId;
2720             currentIndex[0] = ++i;
2721         }, false /* traverseTopToBottom */);
2722 
2723         final ActivityRecord top = task.topRunningActivity();
2724         info.topActivity = top != null ? top.intent.getComponent() : null;
2725         return info;
2726     }
2727 
getRootTaskInfo(int taskId)2728     RootTaskInfo getRootTaskInfo(int taskId) {
2729         Task task = getRootTask(taskId);
2730         if (task != null) {
2731             return getRootTaskInfo(task);
2732         }
2733         return null;
2734     }
2735 
getRootTaskInfo(int windowingMode, int activityType)2736     RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) {
2737         final Task rootTask = getRootTask(windowingMode, activityType);
2738         return (rootTask != null) ? getRootTaskInfo(rootTask) : null;
2739     }
2740 
getRootTaskInfo(int windowingMode, int activityType, int displayId)2741     RootTaskInfo getRootTaskInfo(int windowingMode, int activityType, int displayId) {
2742         final Task rootTask = getRootTask(windowingMode, activityType, displayId);
2743         return (rootTask != null) ? getRootTaskInfo(rootTask) : null;
2744     }
2745 
2746     /** If displayId == INVALID_DISPLAY, this will get root task infos on all displays */
getAllRootTaskInfos(int displayId)2747     ArrayList<RootTaskInfo> getAllRootTaskInfos(int displayId) {
2748         final ArrayList<RootTaskInfo> list = new ArrayList<>();
2749         if (displayId == INVALID_DISPLAY) {
2750             forAllRootTasks(rootTask -> {
2751                 list.add(getRootTaskInfo(rootTask));
2752             });
2753             return list;
2754         }
2755         final DisplayContent display = getDisplayContent(displayId);
2756         if (display == null) {
2757             return list;
2758         }
2759         display.forAllRootTasks(rootTask -> {
2760             list.add(getRootTaskInfo(rootTask));
2761         });
2762         return list;
2763     }
2764 
2765     @Override
onDisplayAdded(int displayId)2766     public void onDisplayAdded(int displayId) {
2767         if (DEBUG_ROOT_TASK) Slog.v(TAG, "Display added displayId=" + displayId);
2768         synchronized (mService.mGlobalLock) {
2769             final DisplayContent display = getDisplayContentOrCreate(displayId);
2770             if (display == null) {
2771                 return;
2772             }
2773             // Do not start home before booting, or it may accidentally finish booting before it
2774             // starts. Instead, we expect home activities to be launched when the system is ready
2775             // (ActivityManagerService#systemReady).
2776             if (mService.isBooted() || mService.isBooting()) {
2777                 startSystemDecorations(display);
2778             }
2779             // Drop any cached DisplayInfos associated with this display id - the values are now
2780             // out of date given this display added event.
2781             mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
2782         }
2783     }
2784 
startSystemDecorations(final DisplayContent displayContent)2785     private void startSystemDecorations(final DisplayContent displayContent) {
2786         startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
2787         displayContent.getDisplayPolicy().notifyDisplayReady();
2788     }
2789 
2790     @Override
onDisplayRemoved(int displayId)2791     public void onDisplayRemoved(int displayId) {
2792         if (DEBUG_ROOT_TASK) Slog.v(TAG, "Display removed displayId=" + displayId);
2793         if (displayId == DEFAULT_DISPLAY) {
2794             throw new IllegalArgumentException("Can't remove the primary display.");
2795         }
2796 
2797         synchronized (mService.mGlobalLock) {
2798             final DisplayContent displayContent = getDisplayContent(displayId);
2799             if (displayContent == null) {
2800                 return;
2801             }
2802             displayContent.remove();
2803             mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
2804         }
2805     }
2806 
2807     @Override
onDisplayChanged(int displayId)2808     public void onDisplayChanged(int displayId) {
2809         if (DEBUG_ROOT_TASK) Slog.v(TAG, "Display changed displayId=" + displayId);
2810         synchronized (mService.mGlobalLock) {
2811             final DisplayContent displayContent = getDisplayContent(displayId);
2812             if (displayContent != null) {
2813                 displayContent.requestDisplayUpdate(() -> clearDisplayInfoCaches(displayId));
2814             } else {
2815                 clearDisplayInfoCaches(displayId);
2816             }
2817         }
2818     }
2819 
clearDisplayInfoCaches(int displayId)2820     private void clearDisplayInfoCaches(int displayId) {
2821         // Drop any cached DisplayInfos associated with this display id - the values are now
2822         // out of date given this display changed event.
2823         mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
2824         updateDisplayImePolicyCache();
2825     }
2826 
updateDisplayImePolicyCache()2827     void updateDisplayImePolicyCache() {
2828         ArrayMap<Integer, Integer> displayImePolicyMap = new ArrayMap<>();
2829         forAllDisplays(dc -> displayImePolicyMap.put(dc.getDisplayId(), dc.getImePolicy()));
2830         mWmService.mDisplayImePolicyCache = Collections.unmodifiableMap(displayImePolicyMap);
2831     }
2832 
2833     /** Update lists of UIDs that are present on displays and have access to them. */
updateUIDsPresentOnDisplay()2834     void updateUIDsPresentOnDisplay() {
2835         mDisplayAccessUIDs.clear();
2836         for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2837             final DisplayContent displayContent = getChildAt(displayNdx);
2838             // Only bother calculating the allowlist for private displays
2839             if (displayContent.isPrivate()) {
2840                 mDisplayAccessUIDs.append(
2841                         displayContent.mDisplayId, displayContent.getPresentUIDs());
2842             }
2843         }
2844         // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
2845         mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
2846     }
2847 
prepareForShutdown()2848     void prepareForShutdown() {
2849         for (int i = 0; i < getChildCount(); i++) {
2850             createSleepToken("shutdown", getChildAt(i).mDisplayId);
2851         }
2852     }
2853 
createSleepToken(String tag, int displayId)2854     SleepToken createSleepToken(String tag, int displayId) {
2855         return createSleepToken(tag, displayId, false /* isSwappingDisplay */);
2856     }
2857 
createSleepToken(String tag, int displayId, boolean isSwappingDisplay)2858     SleepToken createSleepToken(String tag, int displayId, boolean isSwappingDisplay) {
2859         final DisplayContent display = getDisplayContent(displayId);
2860         if (display == null) {
2861             throw new IllegalArgumentException("Invalid display: " + displayId);
2862         }
2863 
2864         final int tokenKey = makeSleepTokenKey(tag, displayId);
2865         SleepToken token = mSleepTokens.get(tokenKey);
2866         if (token == null) {
2867             token = new SleepToken(tag, displayId, isSwappingDisplay);
2868             mSleepTokens.put(tokenKey, token);
2869             display.mAllSleepTokens.add(token);
2870             ProtoLog.d(WM_DEBUG_STATES, "Create sleep token: tag=%s, displayId=%d", tag, displayId);
2871         } else {
2872             throw new RuntimeException("Create the same sleep token twice: " + token);
2873         }
2874         if (isSwappingDisplay) {
2875             display.mWallpaperController.onDisplaySwitchStarted();
2876         }
2877         return token;
2878     }
2879 
removeSleepToken(SleepToken token)2880     void removeSleepToken(SleepToken token) {
2881         if (!mSleepTokens.contains(token.mHashKey)) {
2882             Slog.d(TAG, "Remove non-exist sleep token: " + token + " from " + Debug.getCallers(6));
2883         }
2884         mSleepTokens.remove(token.mHashKey);
2885         final DisplayContent display = getDisplayContent(token.mDisplayId);
2886         if (display == null) {
2887             Slog.d(TAG, "Remove sleep token for non-existing display: " + token + " from "
2888                     + Debug.getCallers(6));
2889             return;
2890         }
2891 
2892         ProtoLog.d(WM_DEBUG_STATES, "Remove sleep token: tag=%s, displayId=%d", token.mTag,
2893                 token.mDisplayId);
2894         display.mAllSleepTokens.remove(token);
2895         if (display.mAllSleepTokens.isEmpty()) {
2896             mService.updateSleepIfNeededLocked();
2897             // Assuming no lock screen is set and a user launches an activity, turns off the screen
2898             // and turn on the screen again, then the launched activity should be displayed on the
2899             // screen without app transition animation. When the screen turns on, both keyguard
2900             // sleep token and display off sleep token are removed, but the order is
2901             // non-deterministic.
2902             // Note: Display#mSkipAppTransitionAnimation will be ignored when keyguard related
2903             // transition exists, so this affects only when no lock screen is set. Otherwise
2904             // keyguard going away animation will be played.
2905             // See also AppTransitionController#getTransitCompatType for more details.
2906             if ((!mTaskSupervisor.getKeyguardController().isKeyguardOccluded(display.mDisplayId)
2907                     && token.mTag.equals(KEYGUARD_SLEEP_TOKEN_TAG))
2908                     || token.mTag.equals(DISPLAY_OFF_SLEEP_TOKEN_TAG)) {
2909                 display.mSkipAppTransitionAnimation = true;
2910             }
2911         }
2912     }
2913 
addStartingWindowsForVisibleActivities()2914     void addStartingWindowsForVisibleActivities() {
2915         final ArrayList<Task> addedTasks = new ArrayList<>();
2916         forAllActivities((r) -> {
2917             final Task task = r.getTask();
2918             if (r.isVisibleRequested() && r.mStartingData == null && !addedTasks.contains(task)) {
2919                 r.showStartingWindow(true /*taskSwitch*/);
2920                 addedTasks.add(task);
2921             }
2922         });
2923     }
2924 
invalidateTaskLayers()2925     void invalidateTaskLayers() {
2926         if (!mTaskLayersChanged) {
2927             mTaskLayersChanged = true;
2928             mService.mH.post(mRankTaskLayersRunnable);
2929         }
2930     }
2931 
2932     /** Generate oom-score-adjustment rank for all tasks in the system based on z-order. */
rankTaskLayers()2933     void rankTaskLayers() {
2934         if (mTaskLayersChanged) {
2935             mTaskLayersChanged = false;
2936             mService.mH.removeCallbacks(mRankTaskLayersRunnable);
2937         }
2938         mTmpTaskLayerRank = 0;
2939         // Only rank for leaf tasks because the score of activity is based on immediate parent.
2940         forAllLeafTasks(task -> {
2941             final int oldRank = task.mLayerRank;
2942             final ActivityRecord r = task.topRunningActivityLocked();
2943             if (r != null && r.isVisibleRequested()) {
2944                 task.mLayerRank = ++mTmpTaskLayerRank;
2945             } else {
2946                 task.mLayerRank = Task.LAYER_RANK_INVISIBLE;
2947             }
2948             if (task.mLayerRank != oldRank) {
2949                 task.forAllActivities(activity -> {
2950                     if (activity.hasProcess()) {
2951                         mTaskSupervisor.onProcessActivityStateChanged(activity.app,
2952                                 true /* forceBatch */);
2953                     }
2954                 });
2955             }
2956         }, true /* traverseTopToBottom */);
2957 
2958         if (!mTaskSupervisor.inActivityVisibilityUpdate()) {
2959             mTaskSupervisor.computeProcessActivityStateBatch();
2960         }
2961     }
2962 
clearOtherAppTimeTrackers(AppTimeTracker except)2963     void clearOtherAppTimeTrackers(AppTimeTracker except) {
2964         forAllActivities(r -> {
2965             if (r.appTimeTracker != except) {
2966                 r.appTimeTracker = null;
2967             }
2968         });
2969     }
2970 
scheduleDestroyAllActivities(String reason)2971     void scheduleDestroyAllActivities(String reason) {
2972         mDestroyAllActivitiesReason = reason;
2973         mService.mH.post(mDestroyAllActivitiesRunnable);
2974     }
2975 
removeAllMaybeAbortPipEnterRunnable()2976     void removeAllMaybeAbortPipEnterRunnable() {
2977         if (mMaybeAbortPipEnterRunnable == null) {
2978             return;
2979         }
2980         mHandler.removeCallbacks(mMaybeAbortPipEnterRunnable);
2981         mMaybeAbortPipEnterRunnable = null;
2982     }
2983 
2984     // Tries to put all activity tasks to sleep. Returns true if all tasks were
2985     // successfully put to sleep.
putTasksToSleep(boolean allowDelay, boolean shuttingDown)2986     boolean putTasksToSleep(boolean allowDelay, boolean shuttingDown) {
2987         final boolean[] result = {true};
2988         forAllRootTasks(task -> {
2989             if (allowDelay) {
2990                 result[0] &= task.goToSleepIfPossible(shuttingDown);
2991             } else {
2992                 task.ensureActivitiesVisible(null /* starting */);
2993             }
2994         });
2995         return result[0];
2996     }
2997 
findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters)2998     ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
2999         ComponentName cls = intent.getComponent();
3000         if (info.targetActivity != null) {
3001             cls = new ComponentName(info.packageName, info.targetActivity);
3002         }
3003         final int userId = UserHandle.getUserId(info.applicationInfo.uid);
3004 
3005         final PooledPredicate p = PooledLambda.obtainPredicate(
3006                 RootWindowContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
3007                 userId, compareIntentFilters, intent, cls);
3008         final ActivityRecord r = getActivity(p);
3009         p.recycle();
3010         return r;
3011     }
3012 
matchesActivity(ActivityRecord r, int userId, boolean compareIntentFilters, Intent intent, ComponentName cls)3013     private static boolean matchesActivity(ActivityRecord r, int userId,
3014             boolean compareIntentFilters, Intent intent, ComponentName cls) {
3015         if (!r.canBeTopRunning() || r.mUserId != userId) return false;
3016 
3017         if (compareIntentFilters) {
3018             if (r.intent.filterEquals(intent)) {
3019                 return true;
3020             }
3021         } else {
3022             // Compare the target component instead of intent component so we don't miss if the
3023             // activity uses alias.
3024             if (r.mActivityComponent.equals(cls)) {
3025                 return true;
3026             }
3027         }
3028         return false;
3029     }
3030 
hasAwakeDisplay()3031     boolean hasAwakeDisplay() {
3032         for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3033             final DisplayContent display = getChildAt(displayNdx);
3034             if (!display.shouldSleep()) {
3035                 return true;
3036             }
3037         }
3038         return false;
3039     }
3040 
getOrCreateRootTask(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop)3041     Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
3042             @Nullable Task candidateTask, boolean onTop) {
3043         return getOrCreateRootTask(r, options, candidateTask, null /* sourceTask */, onTop,
3044                 null /* launchParams */, 0 /* launchFlags */);
3045     }
3046 
3047     /**
3048      * Returns the right root task to use for launching factoring in all the input parameters.
3049      *
3050      * @param r              The activity we are trying to launch. Can be null.
3051      * @param options        The activity options used to the launch. Can be null.
3052      * @param candidateTask  The possible task the activity might be launched in. Can be null.
3053      * @param sourceTask     The task requesting to start activity. Can be null.
3054      * @param launchParams   The resolved launch params to use.
3055      * @param launchFlags    The launch flags for this launch.
3056      * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
3057      * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
3058      * @return The root task to use for the launch.
3059      */
getOrCreateRootTask(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, @Nullable Task sourceTask, boolean onTop, @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags)3060     Task getOrCreateRootTask(@Nullable ActivityRecord r,
3061             @Nullable ActivityOptions options, @Nullable Task candidateTask,
3062             @Nullable Task sourceTask, boolean onTop,
3063             @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags) {
3064         // First preference goes to the launch root task set in the activity options.
3065         if (options != null) {
3066             final Task candidateRoot = Task.fromWindowContainerToken(options.getLaunchRootTask());
3067             if (candidateRoot != null && canLaunchOnDisplay(r, candidateRoot)) {
3068                 return candidateRoot;
3069             }
3070         }
3071 
3072         // Next preference goes to the task id set in the activity options.
3073         if (options != null) {
3074             final int candidateTaskId = options.getLaunchTaskId();
3075             if (candidateTaskId != INVALID_TASK_ID) {
3076                 // Temporarily set the task id to invalid in case in re-entry.
3077                 options.setLaunchTaskId(INVALID_TASK_ID);
3078                 final Task task = anyTaskForId(candidateTaskId,
3079                         MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
3080                 options.setLaunchTaskId(candidateTaskId);
3081                 if (canLaunchOnDisplay(r, task)) {
3082                     return task.getRootTask();
3083                 }
3084             }
3085         }
3086 
3087         // Next preference goes to the TaskDisplayArea candidate from launchParams
3088         // or activity options.
3089         TaskDisplayArea taskDisplayArea = null;
3090         if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
3091             taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
3092         } else if (options != null) {
3093             final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
3094             taskDisplayArea = daToken != null
3095                     ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;
3096             if (taskDisplayArea == null) {
3097                 final int launchDisplayId = options.getLaunchDisplayId();
3098                 if (launchDisplayId != INVALID_DISPLAY) {
3099                     final DisplayContent displayContent = getDisplayContent(launchDisplayId);
3100                     if (displayContent != null) {
3101                         taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
3102                     }
3103                 }
3104             }
3105         }
3106 
3107         final int activityType = resolveActivityType(r, options, candidateTask);
3108         if (taskDisplayArea != null) {
3109             if (canLaunchOnDisplay(r, taskDisplayArea.getDisplayId())) {
3110                 return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
3111                         sourceTask, launchParams, launchFlags, activityType, onTop);
3112             } else {
3113                 taskDisplayArea = null;
3114             }
3115         }
3116 
3117         // Give preference to the root task and display of the input task and activity if they
3118         // match the mode we want to launch into.
3119         Task rootTask = null;
3120         if (candidateTask != null) {
3121             rootTask = candidateTask.getRootTask();
3122         }
3123         if (rootTask == null && r != null) {
3124             rootTask = r.getRootTask();
3125         }
3126         int windowingMode = launchParams != null ? launchParams.mWindowingMode
3127                 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
3128         if (rootTask != null) {
3129             taskDisplayArea = rootTask.getDisplayArea();
3130             if (taskDisplayArea != null
3131                     && canLaunchOnDisplay(r, taskDisplayArea.mDisplayContent.mDisplayId)) {
3132                 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
3133                     windowingMode = taskDisplayArea.resolveWindowingMode(r, options, candidateTask);
3134                 }
3135                 // Always allow organized tasks that created by organizer since the activity type
3136                 // of an organized task is decided by the activity type of its top child, which
3137                 // could be incompatible with the given windowing mode and activity type.
3138                 if (rootTask.isCompatible(windowingMode, activityType)
3139                         || rootTask.mCreatedByOrganizer) {
3140                     return rootTask;
3141                 }
3142             } else {
3143                 taskDisplayArea = null;
3144             }
3145 
3146         }
3147 
3148         // Falling back to default task container
3149         if (taskDisplayArea == null) {
3150             taskDisplayArea = getDefaultTaskDisplayArea();
3151         }
3152         return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, sourceTask,
3153                 launchParams, launchFlags, activityType, onTop);
3154     }
3155 
canLaunchOnDisplay(ActivityRecord r, Task task)3156     private boolean canLaunchOnDisplay(ActivityRecord r, Task task) {
3157         if (task == null) {
3158             Slog.w(TAG, "canLaunchOnDisplay(), invalid task: " + task);
3159             return false;
3160         }
3161 
3162         if (!task.isAttached()) {
3163             Slog.w(TAG, "canLaunchOnDisplay(), Task is not attached: " + task);
3164             return false;
3165         }
3166 
3167         return canLaunchOnDisplay(r, task.getTaskDisplayArea().getDisplayId());
3168     }
3169 
3170     /** @return true if activity record is null or can be launched on provided display. */
canLaunchOnDisplay(ActivityRecord r, int displayId)3171     private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
3172         if (r == null) {
3173             return true;
3174         }
3175         if (!r.canBeLaunchedOnDisplay(displayId)) {
3176             Slog.w(TAG, "Not allow to launch " + r + " on display " + displayId);
3177             return false;
3178         }
3179         return true;
3180     }
3181 
resolveActivityType(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task task)3182     int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
3183             @Nullable Task task) {
3184         // Preference is given to the activity type for the activity then the task since the type
3185         // once set shouldn't change.
3186         int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
3187         if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
3188             activityType = task.getActivityType();
3189         }
3190         if (activityType != ACTIVITY_TYPE_UNDEFINED) {
3191             return activityType;
3192         }
3193         if (options != null) {
3194             activityType = options.getLaunchActivityType();
3195         }
3196         return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
3197     }
3198 
3199     /**
3200      * Get next focusable root task in the system. This will search through the root task on the
3201      * same display as the current focused root task, looking for a focusable and visible root task,
3202      * different from the target root task. If no valid candidates will be found, it will then go
3203      * through all displays and root tasks in last-focused order.
3204      *
3205      * @param currentFocus  The root task that previously had focus.
3206      * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
3207      *                      candidate.
3208      * @return Next focusable {@link Task}, {@code null} if not found.
3209      */
getNextFocusableRootTask(@onNull Task currentFocus, boolean ignoreCurrent)3210     Task getNextFocusableRootTask(@NonNull Task currentFocus, boolean ignoreCurrent) {
3211         // First look for next focusable root task on the same display
3212         TaskDisplayArea preferredDisplayArea = currentFocus.getDisplayArea();
3213         if (preferredDisplayArea == null) {
3214             // Root task is currently detached because it is being removed. Use the previous
3215             // display it was on.
3216             preferredDisplayArea = getDisplayContent(currentFocus.mPrevDisplayId)
3217                     .getDefaultTaskDisplayArea();
3218         }
3219         final Task preferredFocusableRootTask = preferredDisplayArea.getNextFocusableRootTask(
3220                 currentFocus, ignoreCurrent);
3221         if (preferredFocusableRootTask != null) {
3222             return preferredFocusableRootTask;
3223         }
3224 
3225         if (preferredDisplayArea.mDisplayContent.isHomeSupported()) {
3226             // Stop looking for focusable root task on other displays because the preferred display
3227             // supports home. Home activity would be launched on the same display if no focusable
3228             // root task found.
3229             return null;
3230         }
3231 
3232         // Now look through all displays
3233         for (int i = getChildCount() - 1; i >= 0; --i) {
3234             final DisplayContent display = getChildAt(i);
3235             if (display == preferredDisplayArea.mDisplayContent) {
3236                 // We've already checked this one
3237                 continue;
3238             }
3239             final Task nextFocusableRootTask = display.getDefaultTaskDisplayArea()
3240                     .getNextFocusableRootTask(currentFocus, ignoreCurrent);
3241             if (nextFocusableRootTask != null) {
3242                 return nextFocusableRootTask;
3243             }
3244         }
3245 
3246         return null;
3247     }
3248 
closeSystemDialogActivities(String reason)3249     void closeSystemDialogActivities(String reason) {
3250         forAllActivities((r) -> {
3251             if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0
3252                     || shouldCloseAssistant(r, reason)) {
3253                 r.finishIfPossible(reason, true /* oomAdj */);
3254             }
3255         });
3256     }
3257 
3258     /**
3259      * Returns {@code true} if {@code uid} has a visible window that's above the window of type
3260      * {@link WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE} and {@code uid} is not owner of
3261      * the window of type {@link WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}.
3262      *
3263      * If there is no window with type {@link WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE},
3264      * it returns {@code false}.
3265      */
hasVisibleWindowAboveButDoesNotOwnNotificationShade(int uid)3266     boolean hasVisibleWindowAboveButDoesNotOwnNotificationShade(int uid) {
3267         boolean[] visibleWindowFound = {false};
3268         // We only return true if we found the notification shade (ie. window of type
3269         // TYPE_NOTIFICATION_SHADE). Usually, it should always be there, but if for some reason
3270         // it isn't, we should better be on the safe side and return false for this.
3271         return forAllWindows(w -> {
3272             if (w.mOwnerUid == uid && w.isVisible()) {
3273                 visibleWindowFound[0] = true;
3274             }
3275             if (w.mAttrs.type == TYPE_NOTIFICATION_SHADE) {
3276                 return visibleWindowFound[0] && w.mOwnerUid != uid;
3277             }
3278             return false;
3279         }, true /* traverseTopToBottom */);
3280     }
3281 
3282     private boolean shouldCloseAssistant(ActivityRecord r, String reason) {
3283         if (!r.isActivityTypeAssistant()) return false;
3284         if (reason == SYSTEM_DIALOG_REASON_ASSIST) return false;
3285         // When the assistant is configured to be on top of the dream, it will have higher z-order
3286         // than other activities. If it is also opaque, it will prevent other activities from
3287         // starting. We want to close the assistant on closeSystemDialogs to allow other activities
3288         // to start, e.g. on home button press.
3289         return mWmService.mAssistantOnTopOfDream;
3290     }
3291 
3292     FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
3293             new FinishDisabledPackageActivitiesHelper();
3294 
3295     class FinishDisabledPackageActivitiesHelper implements Predicate<ActivityRecord> {
3296         private String mPackageName;
3297         private Set<String> mFilterByClasses;
3298         private boolean mDoit;
3299         private boolean mEvenPersistent;
3300         private int mUserId;
3301         private boolean mOnlyRemoveNoProcess;
3302         private Task mLastTask;
3303         private final ArrayList<ActivityRecord> mCollectedActivities = new ArrayList<>();
3304 
3305         private void reset(String packageName, Set<String> filterByClasses,
3306                 boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) {
3307             mPackageName = packageName;
3308             mFilterByClasses = filterByClasses;
3309             mDoit = doit;
3310             mEvenPersistent = evenPersistent;
3311             mUserId = userId;
3312             mOnlyRemoveNoProcess = onlyRemoveNoProcess;
3313             mLastTask = null;
3314         }
3315 
3316         boolean process(String packageName, Set<String> filterByClasses,
3317                 boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) {
3318             reset(packageName, filterByClasses, doit, evenPersistent, userId, onlyRemoveNoProcess);
3319             forAllActivities(this);
3320 
3321             boolean didSomething = false;
3322             final int size = mCollectedActivities.size();
3323             // Keep the finishing order from top to bottom.
3324             for (int i = 0; i < size; i++) {
3325                 final ActivityRecord r = mCollectedActivities.get(i);
3326                 if (mOnlyRemoveNoProcess) {
3327                     if (!r.hasProcess()) {
3328                         didSomething = true;
3329                         Slog.i(TAG, "  Force removing " + r);
3330                         r.cleanUp(false /* cleanServices */, false /* setState */);
3331                         r.removeFromHistory("force-stop");
3332                     }
3333                 } else {
3334                     didSomething = true;
3335                     Slog.i(TAG, "  Force finishing " + r);
3336                     r.finishIfPossible("force-stop", true /* oomAdj */);
3337                 }
3338             }
3339             mCollectedActivities.clear();
3340 
3341             return didSomething;
3342         }
3343 
3344         @Override
3345         public boolean test(ActivityRecord r) {
3346             final boolean sameComponent =
3347                     (r.packageName.equals(mPackageName) && (mFilterByClasses == null
3348                             || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
3349                             || (mPackageName == null && r.mUserId == mUserId);
3350             final boolean noProcess = !r.hasProcess();
3351             if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
3352                     && (sameComponent || r.getTask() == mLastTask)
3353                     && (noProcess || mEvenPersistent || !r.app.isPersistent())) {
3354                 if (!mDoit) {
3355                     if (r.finishing) {
3356                         // If this activity is just finishing, then it is not
3357                         // interesting as far as something to stop.
3358                         return false;
3359                     }
3360                     return true;
3361                 }
3362                 mCollectedActivities.add(r);
3363                 mLastTask = r.getTask();
3364             }
3365 
3366             return false;
3367         }
3368     }
3369 
3370     /** @return true if some activity was finished (or would have finished if doit were true). */
3371     boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
3372             boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) {
3373         return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
3374                 evenPersistent, userId, onlyRemoveNoProcess);
3375     }
3376 
3377     void updateActivityApplicationInfo(ApplicationInfo aInfo) {
3378         final String packageName = aInfo.packageName;
3379         final int userId = UserHandle.getUserId(aInfo.uid);
3380         forAllActivities(r -> {
3381             if (r.mUserId == userId && packageName.equals(r.packageName)) {
3382                 r.updateApplicationInfo(aInfo);
3383             }
3384         });
3385     }
3386 
3387     void updateActivityApplicationInfo(int userId,
3388             ArrayMap<String, ApplicationInfo> applicationInfoByPackage) {
3389         forAllActivities(r -> {
3390             if (r.mUserId != userId) {
3391                 return;
3392             }
3393 
3394             final ApplicationInfo aInfo = applicationInfoByPackage.get(r.packageName);
3395             if (aInfo != null) {
3396                 r.updateApplicationInfo(aInfo);
3397             }
3398         });
3399     }
3400 
3401     void finishVoiceTask(IVoiceInteractionSession session) {
3402         final IBinder binder = session.asBinder();
3403         forAllLeafTasks(t -> t.finishIfVoiceTask(binder), true /* traverseTopToBottom */);
3404     }
3405 
3406     /**
3407      * Removes root tasks in the input windowing modes from the system if they are of activity type
3408      * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
3409      */
3410     void removeRootTasksInWindowingModes(int... windowingModes) {
3411         for (int i = getChildCount() - 1; i >= 0; --i) {
3412             getChildAt(i).removeRootTasksInWindowingModes(windowingModes);
3413         }
3414     }
3415 
3416     void removeRootTasksWithActivityTypes(int... activityTypes) {
3417         for (int i = getChildCount() - 1; i >= 0; --i) {
3418             getChildAt(i).removeRootTasksWithActivityTypes(activityTypes);
3419         }
3420     }
3421 
3422     ActivityRecord topRunningActivity() {
3423         for (int i = getChildCount() - 1; i >= 0; --i) {
3424             final ActivityRecord topActivity = getChildAt(i).topRunningActivity();
3425             if (topActivity != null) {
3426                 return topActivity;
3427             }
3428         }
3429         return null;
3430     }
3431 
3432     boolean allResumedActivitiesIdle() {
3433         for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3434             // TODO(b/117135575): Check resumed activities on all visible root tasks.
3435             final DisplayContent display = getChildAt(displayNdx);
3436             if (display.isSleeping()) {
3437                 // No resumed activities while display is sleeping.
3438                 continue;
3439             }
3440 
3441             // If the focused root task is not null or not empty, there should have some activities
3442             // resuming or resumed. Make sure these activities are idle.
3443             final Task rootTask = display.getFocusedRootTask();
3444             if (rootTask == null || !rootTask.hasActivity()) {
3445                 continue;
3446             }
3447             final ActivityRecord resumedActivity = rootTask.getTopResumedActivity();
3448             if (resumedActivity == null || !resumedActivity.idle) {
3449                 ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: rootTask=%d %s "
3450                         + "not idle", rootTask.getRootTaskId(), resumedActivity);
3451                 return false;
3452             }
3453             if (mTransitionController.isTransientLaunch(resumedActivity)) {
3454                 // Not idle if the transient transition animation is running.
3455                 return false;
3456             }
3457         }
3458         // End power mode launch when idle.
3459         mService.endPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY);
3460         return true;
3461     }
3462 
3463     boolean allResumedActivitiesVisible() {
3464         boolean[] foundResumed = {false};
3465         final boolean foundInvisibleResumedActivity = forAllRootTasks(rootTask -> {
3466             final ActivityRecord r = rootTask.getTopResumedActivity();
3467             if (r != null) {
3468                 if (!r.nowVisible) {
3469                     return true;
3470                 }
3471                 foundResumed[0] = true;
3472             }
3473             return false;
3474         });
3475         if (foundInvisibleResumedActivity) {
3476             return false;
3477         }
3478         return foundResumed[0];
3479     }
3480 
3481     boolean allPausedActivitiesComplete() {
3482         boolean[] pausing = {true};
3483         final boolean hasActivityNotCompleted = forAllLeafTasks(task -> {
3484             final ActivityRecord r = task.getTopPausingActivity();
3485             if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) {
3486                 ProtoLog.d(WM_DEBUG_STATES, "allPausedActivitiesComplete: "
3487                         + "r=%s state=%s", r, r.getState());
3488                 if (WM_DEBUG_STATES.isEnabled()) {
3489                     pausing[0] = false;
3490                 } else {
3491                     return true;
3492                 }
3493             }
3494             return false;
3495         });
3496         if (hasActivityNotCompleted) {
3497             return false;
3498         }
3499         return pausing[0];
3500     }
3501 
3502     /**
3503      * Find all tasks containing {@param userId} and intercept them with an activity
3504      * to block out the contents and possibly start a credential-confirming intent.
3505      *
3506      * @param userId user handle for the locked managed profile.
3507      */
3508     void lockAllProfileTasks(@UserIdInt int userId) {
3509         forAllLeafTasks(task -> {
3510             final ActivityRecord top = task.topRunningActivity();
3511             if (top != null && !top.finishing
3512                     && ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER.equals(top.intent.getAction())
3513                     && top.packageName.equals(
3514                             mService.getSysUiServiceComponentLocked().getPackageName())) {
3515                 // Do nothing since the task is already secure by sysui.
3516                 return;
3517             }
3518 
3519             if (task.getActivity(activity -> !activity.finishing && activity.mUserId == userId)
3520                     != null) {
3521                 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
3522                         task.getTaskInfo(), userId);
3523             }
3524         }, true /* traverseTopToBottom */);
3525     }
3526 
3527     Task anyTaskForId(int id) {
3528         return anyTaskForId(id, MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE);
3529     }
3530 
3531     Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode) {
3532         return anyTaskForId(id, matchMode, null, !ON_TOP);
3533     }
3534 
3535     /**
3536      * Returns a {@link Task} for the input id if available. {@code null} otherwise.
3537      *
3538      * @param id        Id of the task we would like returned.
3539      * @param matchMode The mode to match the given task id in.
3540      * @param aOptions  The activity options to use for restoration. Can be null.
3541      * @param onTop     If the root task for the task should be the topmost on the display.
3542      */
3543     Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode,
3544             @Nullable ActivityOptions aOptions, boolean onTop) {
3545         // If options are set, ensure that we are attempting to actually restore a task
3546         if (matchMode != MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
3547             throw new IllegalArgumentException("Should not specify activity options for non-restore"
3548                     + " lookup");
3549         }
3550 
3551         final PooledPredicate p = PooledLambda.obtainPredicate(
3552                 Task::isTaskId, PooledLambda.__(Task.class), id);
3553         Task task = getTask(p);
3554         p.recycle();
3555 
3556         if (task != null) {
3557             if (aOptions != null) {
3558                 // Resolve the root task the task should be placed in now based on options
3559                 // and reparent if needed.
3560                 // TODO(b/229927851) For split-screen, setLaunchRootTask is no longer the "root"
3561                 // task, consider to rename methods like "parentTask" instead of "rootTask".
3562                 final Task targetRootTask =
3563                         getOrCreateRootTask(null, aOptions, task, onTop);
3564                 // When launch with ActivityOptions#getLaunchRootTask, the "root task" just mean the
3565                 // parent of current launch, not the "root task" in hierarchy.
3566                 if (targetRootTask != null && task.getRootTask() != targetRootTask
3567                         && task.getParent() != targetRootTask) {
3568                     final int reparentMode = onTop
3569                             ? REPARENT_MOVE_ROOT_TASK_TO_FRONT : REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
3570                     task.reparent(targetRootTask, onTop, reparentMode, ANIMATE, DEFER_RESUME,
3571                             "anyTaskForId");
3572                 }
3573             }
3574             return task;
3575         }
3576 
3577         // If we are matching root task tasks only, return now
3578         if (matchMode == MATCH_ATTACHED_TASK_ONLY) {
3579             return null;
3580         }
3581 
3582         // Otherwise, check the recent tasks and return if we find it there and we are not restoring
3583         // the task from recents
3584         if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
3585         task = mTaskSupervisor.mRecentTasks.getTask(id);
3586 
3587         if (task == null) {
3588             if (DEBUG_RECENTS) {
3589                 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
3590             }
3591 
3592             return null;
3593         }
3594 
3595         if (matchMode == MATCH_ATTACHED_TASK_OR_RECENT_TASKS) {
3596             return task;
3597         }
3598 
3599         // Implicitly, this case is MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE
3600         if (!mTaskSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
3601             if (DEBUG_RECENTS) {
3602                 Slog.w(TAG_RECENTS,
3603                         "Couldn't restore task id=" + id + " found in recents");
3604             }
3605             return null;
3606         }
3607         if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
3608         return task;
3609     }
3610 
3611     @VisibleForTesting
3612     void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
3613             int flags, int callingUid, ArraySet<Integer> profileIds, int displayId) {
3614         WindowContainer root = this;
3615         if (displayId != INVALID_DISPLAY) {
3616             root = getDisplayContent(displayId);
3617             if (root == null) {
3618                 return;
3619             }
3620         }
3621         mTaskSupervisor.getRunningTasks().getTasks(maxNum, list, flags, mService.getRecentTasks(),
3622                 root, callingUid, profileIds);
3623     }
3624 
3625     void startPowerModeLaunchIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
3626         if (!forceSend && targetActivity != null && targetActivity.app != null) {
3627             // Set power mode when the activity's process is different than the current top resumed
3628             // activity on all display areas, or if there are no resumed activities in the system.
3629             boolean[] noResumedActivities = {true};
3630             boolean[] allFocusedProcessesDiffer = {true};
3631             forAllTaskDisplayAreas(taskDisplayArea -> {
3632                 final ActivityRecord resumedActivity = taskDisplayArea.getFocusedActivity();
3633                 final WindowProcessController resumedActivityProcess =
3634                         resumedActivity == null ? null : resumedActivity.app;
3635 
3636                 noResumedActivities[0] &= resumedActivityProcess == null;
3637                 if (resumedActivityProcess != null) {
3638                     allFocusedProcessesDiffer[0] &=
3639                             !resumedActivityProcess.equals(targetActivity.app);
3640                 }
3641             });
3642             if (!noResumedActivities[0] && !allFocusedProcessesDiffer[0]) {
3643                 // All focused activities are resumed and the process of the target activity is
3644                 // the same as them, e.g. delivering new intent to the current top.
3645                 return;
3646             }
3647         }
3648 
3649         int reason = ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY;
3650         // If the activity is launching while keyguard is locked (including occluded), the activity
3651         // may be visible until its first relayout is done (e.g. apply show-when-lock flag). To
3652         // avoid power mode from being cleared before that, add a special reason to consider whether
3653         // the unknown visibility is resolved. The case from SystemUI is excluded because it should
3654         // rely on keyguard-going-away.
3655         final boolean isKeyguardLocked = (targetActivity != null)
3656                 ? targetActivity.isKeyguardLocked() : mDefaultDisplay.isKeyguardLocked();
3657         if (isKeyguardLocked && targetActivity != null
3658                 && !targetActivity.isLaunchSourceType(ActivityRecord.LAUNCH_SOURCE_TYPE_SYSTEMUI)) {
3659             final ActivityOptions opts = targetActivity.getOptions();
3660             if (opts == null || opts.getSourceInfo() == null
3661                     || opts.getSourceInfo().type != ActivityOptions.SourceInfo.TYPE_LOCKSCREEN) {
3662                 reason |= ActivityTaskManagerService.POWER_MODE_REASON_UNKNOWN_VISIBILITY;
3663             }
3664         }
3665         mService.startPowerMode(reason);
3666     }
3667 
3668     /**
3669      * Iterate over all task fragments, to see if there exists one that meets the
3670      * PermissionPolicyService's criteria to show a permission dialog.
3671      */
3672     public int getTaskToShowPermissionDialogOn(String pkgName, int uid) {
3673         PermissionPolicyInternal pPi = mService.getPermissionPolicyInternal();
3674         if (pPi == null) {
3675             return INVALID_TASK_ID;
3676         }
3677 
3678         final int[] validTaskId = {INVALID_TASK_ID};
3679         forAllLeafTaskFragments(fragment -> {
3680             ActivityRecord record = fragment.getActivity((r) -> {
3681                 // skip hidden (or about to hide) apps, or the permission dialog
3682                 return r.canBeTopRunning() && r.isVisibleRequested()
3683                         && !pPi.isIntentToPermissionDialog(r.intent);
3684             });
3685             if (record != null && record.isUid(uid)
3686                     && Objects.equals(pkgName, record.packageName)
3687                     && pPi.shouldShowNotificationDialogForTask(record.getTask().getTaskInfo(),
3688                     pkgName, record.launchedFromPackage, record.intent, record.getName())) {
3689                 validTaskId[0] = record.getTask().mTaskId;
3690                 return true;
3691             }
3692             return false;
3693         });
3694 
3695         return validTaskId[0];
3696     }
3697 
3698     /**
3699      * Dumps the activities matching the given {@param name} in the either the focused root task
3700      * or all visible root tasks if {@param dumpVisibleRootTasksOnly} is true.
3701      */
3702     ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleRootTasksOnly,
3703             boolean dumpFocusedRootTaskOnly, @UserIdInt int userId) {
3704         if (dumpFocusedRootTaskOnly) {
3705             final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
3706             if (topFocusedRootTask != null) {
3707                 return topFocusedRootTask.getDumpActivitiesLocked(name, userId);
3708             } else {
3709                 return new ArrayList<>();
3710             }
3711         } else {
3712             final RecentTasks recentTasks = mWindowManager.mAtmService.getRecentTasks();
3713             final int recentsComponentUid = recentTasks != null
3714                     ? recentTasks.getRecentsComponentUid()
3715                     : -1;
3716             final ArrayList<ActivityRecord> activities = new ArrayList<>();
3717             forAllLeafTasks(task -> {
3718                 final boolean isRecents = (task.effectiveUid == recentsComponentUid);
3719                 if (!dumpVisibleRootTasksOnly || task.shouldBeVisible(null) || isRecents) {
3720                     activities.addAll(task.getDumpActivitiesLocked(name, userId));
3721                 }
3722                 return false;
3723             });
3724             return activities;
3725         }
3726     }
3727 
3728     @Override
3729     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
3730         super.dump(pw, prefix, dumpAll);
3731         pw.print(prefix);
3732         pw.println("topDisplayFocusedRootTask=" + getTopDisplayFocusedRootTask());
3733         for (int i = getChildCount() - 1; i >= 0; --i) {
3734             final DisplayContent display = getChildAt(i);
3735             display.dump(pw, prefix, dumpAll);
3736         }
3737     }
3738 
3739     /**
3740      * Dump all connected displays' configurations.
3741      *
3742      * @param prefix Prefix to apply to each line of the dump.
3743      */
3744     void dumpDisplayConfigs(PrintWriter pw, String prefix) {
3745         pw.print(prefix);
3746         pw.println("Display override configurations:");
3747         final int displayCount = getChildCount();
3748         for (int i = 0; i < displayCount; i++) {
3749             final DisplayContent displayContent = getChildAt(i);
3750             pw.print(prefix);
3751             pw.print("  ");
3752             pw.print(displayContent.mDisplayId);
3753             pw.print(": ");
3754             pw.println(displayContent.getRequestedOverrideConfiguration());
3755         }
3756     }
3757 
3758     boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
3759             String dumpPackage, int displayIdFilter) {
3760         boolean[] printed = {false};
3761         boolean[] needSep = {false};
3762         for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3763             DisplayContent displayContent = getChildAt(displayNdx);
3764             if (printed[0]) {
3765                 pw.println();
3766             }
3767             if (displayIdFilter != Display.INVALID_DISPLAY
3768                     && displayContent.mDisplayId != displayIdFilter) {
3769                 continue;
3770             }
3771             pw.print("Display #");
3772             pw.print(displayContent.mDisplayId);
3773             pw.println(" (activities from top to bottom):");
3774             displayContent.forAllRootTasks(rootTask -> {
3775                 if (needSep[0]) {
3776                     pw.println();
3777                 }
3778                 needSep[0] = rootTask.dump(fd, pw, dumpAll, dumpClient, dumpPackage, false);
3779                 printed[0] |= needSep[0];
3780             });
3781             displayContent.forAllTaskDisplayAreas(taskDisplayArea -> {
3782                 printed[0] |= printThisActivity(pw, taskDisplayArea.getFocusedActivity(),
3783                         dumpPackage, needSep[0], "    Resumed: ", () ->
3784                                 pw.println("  Resumed activities in task display areas"
3785                                         + " (from top to bottom):"));
3786             });
3787         }
3788 
3789         printed[0] |= dumpHistoryList(fd, pw, mTaskSupervisor.mFinishingActivities, "  ",
3790                 "Fin", false, !dumpAll,
3791                 false, dumpPackage, true,
3792                 () -> pw.println("  Activities waiting to finish:"), null);
3793         printed[0] |= dumpHistoryList(fd, pw, mTaskSupervisor.mStoppingActivities, "  ",
3794                 "Stop", false, !dumpAll,
3795                 false, dumpPackage, true,
3796                 () -> pw.println("  Activities waiting to stop:"), null);
3797 
3798         return printed[0];
3799     }
3800 
3801     private static int makeSleepTokenKey(String tag, int displayId) {
3802         final String tokenKey = tag + displayId;
3803         return tokenKey.hashCode();
3804     }
3805 
3806     static final class SleepToken {
3807         private final String mTag;
3808         private final long mAcquireTime;
3809         private final int mDisplayId;
3810         private final boolean mIsSwappingDisplay;
3811         final int mHashKey;
3812 
3813         // The display could remain in sleep after the physical display swapped, adding a 1
3814         // seconds display swap timeout to prevent activities staying in PAUSED state.
3815         // Otherwise, the sleep token should be removed once display turns back on after swapped.
3816         private static final long DISPLAY_SWAP_TIMEOUT = 1000;
3817 
3818         SleepToken(String tag, int displayId, boolean isSwappingDisplay) {
3819             mTag = tag;
3820             mDisplayId = displayId;
3821             mAcquireTime = SystemClock.uptimeMillis();
3822             mIsSwappingDisplay = isSwappingDisplay;
3823             mHashKey = makeSleepTokenKey(mTag, mDisplayId);
3824         }
3825 
3826         public boolean isDisplaySwapping() {
3827             long now = SystemClock.uptimeMillis();
3828             if (now - mAcquireTime > DISPLAY_SWAP_TIMEOUT) {
3829                 return false;
3830             }
3831             return mIsSwappingDisplay;
3832         }
3833 
3834         @Override
3835         public String toString() {
3836             return "{\"" + mTag + "\", display " + mDisplayId
3837                     + (mIsSwappingDisplay ? " is swapping " : "")
3838                     + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
3839         }
3840 
3841         void writeTagToProto(ProtoOutputStream proto, long fieldId) {
3842             proto.write(fieldId, mTag);
3843         }
3844     }
3845 
3846     private class RankTaskLayersRunnable implements Runnable {
3847         @Override
3848         public void run() {
3849             synchronized (mService.mGlobalLock) {
3850                 if (mTaskLayersChanged) {
3851                     mTaskLayersChanged = false;
3852                     rankTaskLayers();
3853                 }
3854             }
3855         }
3856     }
3857 }
3858