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