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