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