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