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