blob: 2d30b737b274643fac3abc18f43890326c26d7e5 [file] [log] [blame]
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001/*
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
17package com.android.server.wm;
18
Louis Chang149d5c82019-12-30 09:47:39 +080019import static android.app.ActivityTaskManager.INVALID_TASK_ID;
20import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
Galia Peycheva45f48d32020-02-20 15:39:10 +010021import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
Louis Chang149d5c82019-12-30 09:47:39 +080022import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
23import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
24import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
25import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Louis Chang149d5c82019-12-30 09:47:39 +080026import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
27import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
28import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
29import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
30import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
31import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
32import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Jorim Jaggi4981f152019-03-26 18:58:45 +010033import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
wilsonshihab672942018-08-06 15:42:07 +080034import static android.view.Display.DEFAULT_DISPLAY;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080035import static android.view.Display.INVALID_DISPLAY;
wilsonshihab672942018-08-06 15:42:07 +080036import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
wilsonshihab672942018-08-06 15:42:07 +080037import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
wilsonshihab672942018-08-06 15:42:07 +080038import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
Louis Chang149d5c82019-12-30 09:47:39 +080039import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
Winson Chung8b5d23a2020-04-06 19:23:23 -070040import static android.view.WindowManager.TRANSIT_NONE;
Louis Chang149d5c82019-12-30 09:47:39 +080041import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
wilsonshihab672942018-08-06 15:42:07 +080042
Galia Peycheva72d581e2020-06-12 10:06:40 +020043import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
wilsonshihab672942018-08-06 15:42:07 +080044import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
45import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Chris Li74f622a2020-04-19 18:57:35 -070046import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
Louis Chang149d5c82019-12-30 09:47:39 +080047import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
48import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
49import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
50import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
51import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
52import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
53import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
54import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
55import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
56import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
57import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
58import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
59import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
60import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
61import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
62import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
63import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
64import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
65import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
Adrian Roosb125e0b2019-10-02 14:55:14 +020066import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
67import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
68import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
69import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
70import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
lumark04bceb92020-03-07 00:03:33 +080071import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
Wale Ogunwalef342f062020-01-27 07:34:13 -080072import static com.android.server.wm.RootWindowContainerProto.IS_HOME_RECENTS_COMPONENT;
73import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER;
74import static com.android.server.wm.RootWindowContainerProto.PENDING_ACTIVITIES;
wilsonshihab672942018-08-06 15:42:07 +080075import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
Louis Chang149d5c82019-12-30 09:47:39 +080076import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
77import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
wilsonshihab672942018-08-06 15:42:07 +080078import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
wilsonshihab672942018-08-06 15:42:07 +080079import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
80import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
81import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
wilsonshihab672942018-08-06 15:42:07 +080082import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
83import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
wilsonshihab672942018-08-06 15:42:07 +080084import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080085import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
wilsonshihab672942018-08-06 15:42:07 +080086import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
87import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
88import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
wilsonshihab672942018-08-06 15:42:07 +080089import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
90import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
91import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
wilsonshihab672942018-08-06 15:42:07 +080092
Louis Chang149d5c82019-12-30 09:47:39 +080093import static java.lang.Integer.MAX_VALUE;
94
95import android.annotation.IntDef;
Evan Roskye747c3e2018-10-30 20:06:41 -070096import android.annotation.NonNull;
Charles Chen173ae782019-11-11 20:39:02 +080097import android.annotation.Nullable;
Louis Chang149d5c82019-12-30 09:47:39 +080098import android.annotation.UserIdInt;
99import android.app.ActivityManager;
100import android.app.ActivityOptions;
101import android.app.AppGlobals;
102import android.app.WindowConfiguration;
103import android.content.ComponentName;
Charles Chen173ae782019-11-11 20:39:02 +0800104import android.content.Context;
Louis Chang149d5c82019-12-30 09:47:39 +0800105import android.content.Intent;
106import android.content.pm.ActivityInfo;
107import android.content.pm.ApplicationInfo;
108import android.content.pm.ResolveInfo;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700109import android.content.res.Configuration;
Louis Chang149d5c82019-12-30 09:47:39 +0800110import android.content.res.Resources;
111import android.graphics.Rect;
112import android.hardware.display.DisplayManager;
113import android.hardware.display.DisplayManagerInternal;
Ruchi Kandoi0d434042016-10-03 09:12:02 -0700114import android.hardware.power.V1_0.PowerHint;
Louis Chang149d5c82019-12-30 09:47:39 +0800115import android.net.Uri;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700116import android.os.Binder;
117import android.os.Debug;
Louis Chang149d5c82019-12-30 09:47:39 +0800118import android.os.FactoryTest;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200119import android.os.Handler;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700120import android.os.IBinder;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200121import android.os.Looper;
122import android.os.Message;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700123import android.os.PowerManager;
124import android.os.RemoteException;
Louis Chang149d5c82019-12-30 09:47:39 +0800125import android.os.SystemClock;
Jorim Jaggi4981f152019-03-26 18:58:45 +0100126import android.os.Trace;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700127import android.os.UserHandle;
Louis Chang149d5c82019-12-30 09:47:39 +0800128import android.os.storage.StorageManager;
129import android.provider.Settings;
130import android.service.voice.IVoiceInteractionSession;
David Stevensf833ba92017-03-16 19:00:20 -0700131import android.util.ArraySet;
Louis Chang149d5c82019-12-30 09:47:39 +0800132import android.util.DisplayMetrics;
133import android.util.IntArray;
134import android.util.Pair;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700135import android.util.Slog;
Louis Chang149d5c82019-12-30 09:47:39 +0800136import android.util.SparseArray;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700137import android.util.SparseIntArray;
Louis Chang149d5c82019-12-30 09:47:39 +0800138import android.util.TimeUtils;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700139import android.util.proto.ProtoOutputStream;
Louis Chang149d5c82019-12-30 09:47:39 +0800140import android.view.Display;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700141import android.view.DisplayInfo;
Robert Carrae606b42018-02-15 15:36:23 -0800142import android.view.SurfaceControl;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700143import android.view.WindowManager;
Andrii Kulian1cfcae82020-04-10 12:44:38 -0700144import android.window.WindowContainerToken;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200145
Louis Chang149d5c82019-12-30 09:47:39 +0800146import com.android.internal.annotations.VisibleForTesting;
147import com.android.internal.app.ResolverActivity;
148import com.android.internal.util.function.pooled.PooledConsumer;
149import com.android.internal.util.function.pooled.PooledFunction;
Charles Chen173ae782019-11-11 20:39:02 +0800150import com.android.internal.util.function.pooled.PooledLambda;
151import com.android.internal.util.function.pooled.PooledPredicate;
Louis Chang149d5c82019-12-30 09:47:39 +0800152import com.android.server.LocalServices;
153import com.android.server.am.ActivityManagerService;
154import com.android.server.am.AppTimeTracker;
155import com.android.server.am.UserState;
156import com.android.server.policy.WindowManagerPolicy;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200157import com.android.server.protolog.common.ProtoLog;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700158
Louis Chang149d5c82019-12-30 09:47:39 +0800159import java.io.FileDescriptor;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700160import java.io.PrintWriter;
Louis Chang149d5c82019-12-30 09:47:39 +0800161import java.lang.annotation.Retention;
162import java.lang.annotation.RetentionPolicy;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700163import java.util.ArrayList;
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800164import java.util.HashMap;
Charles Chen173ae782019-11-11 20:39:02 +0800165import java.util.List;
Louis Chang149d5c82019-12-30 09:47:39 +0800166import java.util.Objects;
167import java.util.Set;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800168import java.util.function.Consumer;
Louis Chang149d5c82019-12-30 09:47:39 +0800169import java.util.function.Function;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700170
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700171/** Root {@link WindowContainer} for the device. */
Louis Chang149d5c82019-12-30 09:47:39 +0800172class RootWindowContainer extends WindowContainer<DisplayContent>
173 implements DisplayManager.DisplayListener {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700174 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
175
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200176 private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
177 private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
Louis Chang149d5c82019-12-30 09:47:39 +0800178 static final String TAG_TASKS = TAG + POSTFIX_TASKS;
179 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
180 static final String TAG_STATES = TAG + POSTFIX_STATES;
181 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200182
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700183 private Object mLastWindowFreezeSource = null;
184 private Session mHoldScreen = null;
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100185 private float mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700186 private long mUserActivityTimeout = -1;
187 private boolean mUpdateRotation = false;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700188 // Following variables are for debugging screen wakelock only.
189 // Last window that requires screen wakelock
190 WindowState mHoldScreenWindow = null;
191 // Last window that obscures all windows below
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700192 WindowState mObscuringWindow = null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700193 // Only set while traversing the default display based on its content.
194 // Affects the behavior of mirroring on secondary displays.
195 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
196
197 private boolean mSustainedPerformanceModeEnabled = false;
198 private boolean mSustainedPerformanceModeCurrent = false;
199
Robert Carr11c26c22016-09-23 12:40:27 -0700200 // During an orientation change, we track whether all windows have rendered
201 // at the new orientation, and this will be false from changing orientation until that occurs.
202 // For seamless rotation cases this always stays true, as the windows complete their orientation
203 // changes 1 by 1 without disturbing global state.
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700204 boolean mOrientationChangeComplete = true;
205 boolean mWallpaperActionPending = false;
206
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200207 private final Handler mHandler;
208
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800209 private String mCloseSystemDialogsReason;
Robert Carrae606b42018-02-15 15:36:23 -0800210
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800211 // The ID of the display which is responsible for receiving display-unspecified key and pointer
212 // events.
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800213 private int mTopFocusedDisplayId = INVALID_DISPLAY;
214
215 // Map from the PID to the top most app which has a focused window of the process.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700216 final HashMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new HashMap<>();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800217
Tiger Huang7c610aa2018-10-27 00:01:01 +0800218 // Only a separate transaction until we separate the apply surface changes
Robert Carrae606b42018-02-15 15:36:23 -0800219 // transaction from the global transaction.
Vishnu Nair33197392019-08-30 10:29:37 -0700220 private final SurfaceControl.Transaction mDisplayTransaction;
Robert Carrae606b42018-02-15 15:36:23 -0800221
Louis Chang149d5c82019-12-30 09:47:39 +0800222 /**
223 * The modes which affect which tasks are returned when calling
224 * {@link RootWindowContainer#anyTaskForId(int)}.
225 */
226 @Retention(RetentionPolicy.SOURCE)
227 @IntDef({
228 MATCH_TASK_IN_STACKS_ONLY,
229 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
230 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
231 })
232 public @interface AnyTaskForIdMatchTaskMode {}
233 // Match only tasks in the current stacks
234 static final int MATCH_TASK_IN_STACKS_ONLY = 0;
235 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
236 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
237 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
238 // provided stack id
239 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
240
241 ActivityTaskManagerService mService;
242 ActivityStackSupervisor mStackSupervisor;
243 WindowManagerService mWindowManager;
244 DisplayManager mDisplayManager;
245 private DisplayManagerInternal mDisplayManagerInternal;
246
247 /** Reference to default display so we can quickly look it up. */
248 private DisplayContent mDefaultDisplay;
249 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
250
251 /** The current user */
252 int mCurrentUser;
253 /** Stack id of the front stack when user switched, indexed by userId. */
254 SparseIntArray mUserStackInFront = new SparseIntArray(2);
255
256 /**
257 * A list of tokens that cause the top activity to be put to sleep.
258 * They are used by components that may hide and block interaction with underlying
259 * activities.
260 */
261 final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
262
Louis Chang149d5c82019-12-30 09:47:39 +0800263 /** Set when a power hint has started, but not ended. */
264 private boolean mPowerHintSent;
265
Louis Chang149d5c82019-12-30 09:47:39 +0800266 // The default minimal size that will be used if the activity doesn't specify its minimal size.
267 // It will be calculated when the default display gets added.
268 int mDefaultMinSizeOfResizeableTaskDp = -1;
269
270 // Whether tasks have moved and we need to rank the tasks before next OOM scoring
271 private boolean mTaskLayersChanged = true;
272 private int mTmpTaskLayerRank;
273
274 private boolean mTmpBoolean;
275 private RemoteException mTmpRemoteException;
276
277 private String mDestroyAllActivitiesReason;
278 private final Runnable mDestroyAllActivitiesRunnable = new Runnable() {
279 @Override
280 public void run() {
281 synchronized (mService.mGlobalLock) {
282 try {
283 mStackSupervisor.beginDeferResume();
284
285 final PooledConsumer c = PooledLambda.obtainConsumer(
286 RootWindowContainer::destroyActivity, RootWindowContainer.this,
287 PooledLambda.__(ActivityRecord.class));
288 forAllActivities(c);
289 c.recycle();
290 } finally {
291 mStackSupervisor.endDeferResume();
292 resumeFocusedStacksTopActivities();
293 }
294 }
295 }
296
297 };
298
299 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
300 static class FindTaskResult implements Function<Task, Boolean> {
301 ActivityRecord mRecord;
302 boolean mIdealMatch;
303
304 private ActivityRecord mTarget;
305 private Intent intent;
306 private ActivityInfo info;
307 private ComponentName cls;
308 private int userId;
309 private boolean isDocument;
310 private Uri documentData;
311
312 /**
313 * Returns the top activity in any existing task matching the given Intent in the input
314 * result. Returns null if no such task is found.
315 */
316 void process(ActivityRecord target, ActivityStack parent) {
317 mTarget = target;
318
319 intent = target.intent;
320 info = target.info;
321 cls = intent.getComponent();
322 if (info.targetActivity != null) {
323 cls = new ComponentName(info.packageName, info.targetActivity);
324 }
325 userId = UserHandle.getUserId(info.applicationInfo.uid);
326 isDocument = intent != null & intent.isDocument();
327 // If documentData is non-null then it must match the existing task data.
328 documentData = isDocument ? intent.getData() : null;
329
330 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
Louis Chang87ca32e2020-05-14 13:40:16 +0800331 parent.forAllLeafTasks(this);
Louis Chang149d5c82019-12-30 09:47:39 +0800332 }
333
334 void clear() {
335 mRecord = null;
336 mIdealMatch = false;
337 }
338
339 void setTo(FindTaskResult result) {
340 mRecord = result.mRecord;
341 mIdealMatch = result.mIdealMatch;
342 }
343
344 @Override
345 public Boolean apply(Task task) {
346 if (task.voiceSession != null) {
347 // We never match voice sessions; those always run independently.
348 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
349 return false;
350 }
351 if (task.mUserId != userId) {
352 // Looking for a different task.
353 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
354 return false;
355 }
356
357 // Overlays should not be considered as the task's logical top activity.
358 final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
359 if (r == null || r.finishing || r.mUserId != userId
360 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
361 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
362 return false;
363 }
364 if (!r.hasCompatibleActivityType(mTarget)) {
365 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
366 return false;
367 }
368
369 final Intent taskIntent = task.intent;
370 final Intent affinityIntent = task.affinityIntent;
371 final boolean taskIsDocument;
372 final Uri taskDocumentData;
373 if (taskIntent != null && taskIntent.isDocument()) {
374 taskIsDocument = true;
375 taskDocumentData = taskIntent.getData();
376 } else if (affinityIntent != null && affinityIntent.isDocument()) {
377 taskIsDocument = true;
378 taskDocumentData = affinityIntent.getData();
379 } else {
380 taskIsDocument = false;
381 taskDocumentData = null;
382 }
383
384 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
385 + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
386 + "/aff=" + r.getTask().rootAffinity + " to new cls="
387 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
388 // TODO Refactor to remove duplications. Check if logic can be simplified.
389 if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
390 && Objects.equals(documentData, taskDocumentData)) {
391 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
392 //dump();
393 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
394 "For Intent " + intent + " bringing to top: " + r.intent);
395 mRecord = r;
396 mIdealMatch = true;
397 return true;
398 } else if (affinityIntent != null && affinityIntent.getComponent() != null
399 && affinityIntent.getComponent().compareTo(cls) == 0 &&
400 Objects.equals(documentData, taskDocumentData)) {
401 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
402 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
403 "For Intent " + intent + " bringing to top: " + r.intent);
404 mRecord = r;
405 mIdealMatch = true;
406 return true;
407 } else if (!isDocument && !taskIsDocument
408 && mRecord == null && task.rootAffinity != null) {
409 if (task.rootAffinity.equals(mTarget.taskAffinity)) {
410 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
411 // It is possible for multiple tasks to have the same root affinity especially
412 // if they are in separate stacks. We save off this candidate, but keep looking
413 // to see if there is a better candidate.
414 mRecord = r;
415 mIdealMatch = false;
416 }
417 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
418
419 return false;
420 }
421 }
422
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800423 private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
424 if (w.mHasSurface) {
425 try {
426 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason);
427 } catch (RemoteException e) {
428 }
429 }
430 };
431
432 private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700433 final ActivityRecord activity = w.mActivityRecord;
434 if (activity != null) {
435 activity.removeReplacedWindowIfNeeded(w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800436 }
437 };
438
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700439 RootWindowContainer(WindowManagerService service) {
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100440 super(service);
Vishnu Nair33197392019-08-30 10:29:37 -0700441 mDisplayTransaction = service.mTransactionFactory.get();
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200442 mHandler = new MyHandler(service.mH.getLooper());
Louis Chang149d5c82019-12-30 09:47:39 +0800443 mService = service.mAtmService;
444 mStackSupervisor = mService.mStackSupervisor;
445 mStackSupervisor.mRootWindowContainer = this;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700446 }
447
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800448 boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800449 mTopFocusedAppByProcess.clear();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800450 boolean changed = false;
451 int topFocusedDisplayId = INVALID_DISPLAY;
lumark6f13d20b2018-10-19 14:38:15 +0800452 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700453 final DisplayContent dc = mChildren.get(i);
Louis Changa9350fe2019-04-25 17:14:20 +0800454 changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800455 final WindowState newFocus = dc.mCurrentFocus;
456 if (newFocus != null) {
457 final int pidOfNewFocus = newFocus.mSession.mPid;
458 if (mTopFocusedAppByProcess.get(pidOfNewFocus) == null) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700459 mTopFocusedAppByProcess.put(pidOfNewFocus, newFocus.mActivityRecord);
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800460 }
461 if (topFocusedDisplayId == INVALID_DISPLAY) {
462 topFocusedDisplayId = dc.getDisplayId();
463 }
Louis Changa9350fe2019-04-25 17:14:20 +0800464 } else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) {
465 // The top-most display that has a focused app should still be the top focused
466 // display even when the app window is not ready yet (process not attached or
467 // window not added yet).
468 topFocusedDisplayId = dc.getDisplayId();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700469 }
470 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800471 if (topFocusedDisplayId == INVALID_DISPLAY) {
472 topFocusedDisplayId = DEFAULT_DISPLAY;
473 }
474 if (mTopFocusedDisplayId != topFocusedDisplayId) {
475 mTopFocusedDisplayId = topFocusedDisplayId;
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800476 mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
Tiger Huangdc7356a2018-12-17 16:15:35 +0800477 mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId);
Adrian Roosb125e0b2019-10-02 14:55:14 +0200478 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d",
479 topFocusedDisplayId);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800480 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800481 return changed;
482 }
483
484 DisplayContent getTopFocusedDisplayContent() {
Charles Chen37848f32019-02-27 19:27:45 +0800485 final DisplayContent dc = getDisplayContent(mTopFocusedDisplayId);
486 return dc != null ? dc : getDisplayContent(DEFAULT_DISPLAY);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800487 }
488
489 @Override
lumarkd0b5c8f2019-09-29 11:30:37 +0800490 boolean isOnTop() {
491 // Considered always on top
492 return true;
493 }
494
495 @Override
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200496 void onChildPositionChanged(WindowContainer child) {
Tiger Huangfc90c132018-12-20 18:53:47 +0800497 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
498 !mWmService.mPerDisplayFocusEnabled /* updateInputWindows */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700499 }
500
Garfield Tanb5910b42019-03-14 14:50:59 -0700501 /**
502 * Called when DisplayWindowSettings values may change.
503 */
504 void onSettingsRetrieved() {
505 final int numDisplays = mChildren.size();
506 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
507 final DisplayContent displayContent = mChildren.get(displayNdx);
508 final boolean changed = mWmService.mDisplayWindowSettings.updateSettingsForDisplay(
509 displayContent);
510 if (!changed) {
511 continue;
512 }
513
Shivam Agrawal6472e0e2019-07-03 16:27:49 -0700514 displayContent.reconfigureDisplayLocked();
Garfield Tanb5910b42019-03-14 14:50:59 -0700515
516 // We need to update global configuration as well if config of default display has
517 // changed. Do it inline because ATMS#retrieveSettings() will soon update the
518 // configuration inline, which will overwrite the new windowing mode.
519 if (displayContent.isDefaultDisplay) {
520 final Configuration newConfig = mWmService.computeNewConfiguration(
521 displayContent.getDisplayId());
522 mWmService.mAtmService.updateConfigurationLocked(newConfig, null /* starting */,
523 false /* initLocale */);
524 }
525 }
526 }
527
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700528 boolean isLayoutNeeded() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700529 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700530 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700531 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700532 if (displayContent.isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700533 return true;
534 }
535 }
536 return false;
537 }
538
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000539 void getWindowsByName(ArrayList<WindowState> output, String name) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700540 int objectId = 0;
541 // See if this is an object ID.
542 try {
543 objectId = Integer.parseInt(name, 16);
544 name = null;
545 } catch (RuntimeException e) {
546 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800547
548 getWindowsByName(output, name, objectId);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700549 }
550
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000551 private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800552 forAllWindows((w) -> {
553 if (name != null) {
554 if (w.mAttrs.getTitle().toString().contains(name)) {
555 output.add(w);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700556 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800557 } else if (System.identityHashCode(w) == objectId) {
558 output.add(w);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700559 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800560 }, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700561 }
562
Wale Ogunwale02319a62016-09-26 15:21:22 -0700563 /**
Charles Chen173ae782019-11-11 20:39:02 +0800564 * Returns {@code true} if the callingUid has any non-toast window currently visible to the
565 * user. Also ignores {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_STARTING},
566 * since those windows don't belong to apps.
567 * @see WindowState#isNonToastOrStarting()
Michal Karpinskia606a292019-01-12 17:29:52 +0000568 */
569 boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
Charles Chen173ae782019-11-11 20:39:02 +0800570 final PooledPredicate p = PooledLambda.obtainPredicate(
571 WindowState::isNonToastWindowVisibleForUid,
572 PooledLambda.__(WindowState.class), callingUid);
573
574 final WindowState w = getWindow(p);
575 p.recycle();
576 return w != null;
Michal Karpinskia606a292019-01-12 17:29:52 +0000577 }
578
579 /**
Wale Ogunwale02319a62016-09-26 15:21:22 -0700580 * Returns the app window token for the input binder if it exist in the system.
581 * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
582 * AppWindowToken represents an activity which can only exist on one display.
583 */
Garfield Tane8d84ab2019-10-11 09:49:40 -0700584 ActivityRecord getActivityRecord(IBinder binder) {
Wale Ogunwale02319a62016-09-26 15:21:22 -0700585 for (int i = mChildren.size() - 1; i >= 0; --i) {
586 final DisplayContent dc = mChildren.get(i);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700587 final ActivityRecord activity = dc.getActivityRecord(binder);
588 if (activity != null) {
589 return activity;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700590 }
591 }
592 return null;
593 }
594
wilsonshihab672942018-08-06 15:42:07 +0800595 /** Returns the window token for the input binder if it exist in the system. */
596 WindowToken getWindowToken(IBinder binder) {
597 for (int i = mChildren.size() - 1; i >= 0; --i) {
598 final DisplayContent dc = mChildren.get(i);
599 final WindowToken wtoken = dc.getWindowToken(binder);
600 if (wtoken != null) {
601 return wtoken;
602 }
603 }
604 return null;
605 }
606
Wale Ogunwale02319a62016-09-26 15:21:22 -0700607 /** Returns the display object the input window token is currently mapped on. */
608 DisplayContent getWindowTokenDisplay(WindowToken token) {
609 if (token == null) {
610 return null;
611 }
612
613 for (int i = mChildren.size() - 1; i >= 0; --i) {
614 final DisplayContent dc = mChildren.get(i);
615 final WindowToken current = dc.getWindowToken(token.token);
616 if (current == token) {
617 return dc;
618 }
619 }
620
621 return null;
622 }
623
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700624 /**
Evan Roskye747c3e2018-10-30 20:06:41 -0700625 * Set new display override config. If called for the default display, global configuration
626 * will also be updated.
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700627 */
Evan Roskye747c3e2018-10-30 20:06:41 -0700628 void setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration,
629 @NonNull DisplayContent displayContent) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700630
Evan Roskydfe3da72018-10-26 17:21:06 -0700631 final Configuration currentConfig = displayContent.getRequestedOverrideConfiguration();
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700632 final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
633 if (!configChanged) {
Evan Roskye747c3e2018-10-30 20:06:41 -0700634 return;
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700635 }
Bryce Leeaea60d22018-01-31 14:42:15 -0800636
Evan Roskydfe3da72018-10-26 17:21:06 -0700637 displayContent.onRequestedOverrideConfigurationChanged(newConfiguration);
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700638
Evan Roskye747c3e2018-10-30 20:06:41 -0700639 if (displayContent.getDisplayId() == DEFAULT_DISPLAY) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700640 // Override configuration of the default display duplicates global config. In this case
641 // we also want to update the global config.
Evan Roskye747c3e2018-10-30 20:06:41 -0700642 setGlobalConfigurationIfNeeded(newConfiguration);
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700643 }
644 }
645
Evan Roskye747c3e2018-10-30 20:06:41 -0700646 private void setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
Andrii Kulian441e4492016-09-29 15:25:00 -0700647 final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
648 if (!configChanged) {
Bryce Leeaea60d22018-01-31 14:42:15 -0800649 return;
Andrii Kulian441e4492016-09-29 15:25:00 -0700650 }
651 onConfigurationChanged(newConfiguration);
Andrii Kulian441e4492016-09-29 15:25:00 -0700652 }
653
654 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700655 public void onConfigurationChanged(Configuration newParentConfig) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700656 prepareFreezingTaskBounds();
Andrii Kulian441e4492016-09-29 15:25:00 -0700657 super.onConfigurationChanged(newParentConfig);
Andrii Kulian441e4492016-09-29 15:25:00 -0700658 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700659
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700660 private void prepareFreezingTaskBounds() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700661 for (int i = mChildren.size() - 1; i >= 0; i--) {
662 mChildren.get(i).prepareFreezingTaskBounds();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700663 }
664 }
665
Alex Johnston302c1fe2020-06-18 20:00:51 +0100666 void setSecureSurfaceState(int userId) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800667 forAllWindows((w) -> {
wilsonshihd0fc2ca2020-03-18 22:41:55 +0800668 if (w.mHasSurface && userId == w.mShowUserId) {
Alex Johnston302c1fe2020-06-18 20:00:51 +0100669 w.mWinAnimator.setSecureLocked(w.isSecureLocked());
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700670 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800671 }, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700672 }
673
Suprabh Shukla69c71422018-04-02 18:39:01 -0700674 void updateHiddenWhileSuspendedState(final ArraySet<String> packages, final boolean suspended) {
675 forAllWindows((w) -> {
676 if (packages.contains(w.getOwningPackage())) {
677 w.setHiddenWhileSuspended(suspended);
678 }
679 }, false);
680 }
681
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700682 void updateAppOpsState() {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800683 forAllWindows((w) -> {
Svet Ganovf7b47252018-02-26 11:11:27 -0800684 w.updateAppOpsState();
Wale Ogunwaled1880962016-11-08 10:31:59 -0800685 }, false /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700686 }
687
688 boolean canShowStrictModeViolation(int pid) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800689 final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
690 return win != null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700691 }
692
693 void closeSystemDialogs(String reason) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800694 mCloseSystemDialogsReason = reason;
695 forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700696 }
697
698 void removeReplacedWindows() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200699 ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION removeReplacedWindows");
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800700 mWmService.openSurfaceTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700701 try {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800702 forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700703 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800704 mWmService.closeSurfaceTransaction("removeReplacedWindows");
Adrian Roosb125e0b2019-10-02 14:55:14 +0200705 ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION removeReplacedWindows");
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700706 }
707 }
708
709 boolean hasPendingLayoutChanges(WindowAnimator animator) {
710 boolean hasChanges = false;
711
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700712 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700713 for (int i = 0; i < count; ++i) {
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800714 final int pendingChanges = mChildren.get(i).pendingLayoutChanges;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700715 if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
716 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
717 }
718 if (pendingChanges != 0) {
719 hasChanges = true;
720 }
721 }
722
723 return hasChanges;
724 }
725
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700726 boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
727 boolean secure) {
728 final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
729 boolean leakedSurface = false;
730 boolean killedApps = false;
Jeff Changd136e772019-11-05 20:33:52 +0800731 EventLogTags.writeWmNoSurfaceMemory(winAnimator.mWin.toString(),
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700732 winAnimator.mSession.mPid, operation);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700733 final long callingIdentity = Binder.clearCallingIdentity();
734 try {
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700735 // There was some problem...first, do a sanity check of the window list to make sure
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700736 // we haven't left any dangling surfaces around.
737
738 Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700739 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700740 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700741 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700742 }
743
744 if (!leakedSurface) {
745 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700746 final SparseIntArray pidCandidates = new SparseIntArray();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700747 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800748 mChildren.get(displayNdx).forAllWindows((w) -> {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800749 if (mWmService.mForceRemoves.contains(w)) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800750 return;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700751 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800752 final WindowStateAnimator wsa = w.mWinAnimator;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700753 if (wsa.mSurfaceController != null) {
754 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
755 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800756 }, false /* traverseTopToBottom */);
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700757
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700758 if (pidCandidates.size() > 0) {
759 int[] pids = new int[pidCandidates.size()];
760 for (int i = 0; i < pids.length; i++) {
761 pids[i] = pidCandidates.keyAt(i);
762 }
763 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800764 if (mWmService.mActivityManager.killPids(pids, "Free memory", secure)) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700765 killedApps = true;
766 }
767 } catch (RemoteException e) {
768 }
769 }
770 }
771 }
772
773 if (leakedSurface || killedApps) {
774 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
775 // app to request another one.
776 Slog.w(TAG_WM,
777 "Looks like we have reclaimed some memory, clearing surface for retry.");
778 if (surfaceController != null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200779 ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
780 "SURFACE RECOVER DESTROY: %s", winAnimator.mWin);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700781 winAnimator.destroySurface();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700782 if (winAnimator.mWin.mActivityRecord != null) {
783 winAnimator.mWin.mActivityRecord.removeStartingWindow();
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800784 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700785 }
786
787 try {
788 winAnimator.mWin.mClient.dispatchGetNewSurface();
789 } catch (RemoteException e) {
790 }
791 }
792 } finally {
793 Binder.restoreCallingIdentity(callingIdentity);
794 }
795
796 return leakedSurface || killedApps;
797 }
798
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800799 void performSurfacePlacement() {
Jorim Jaggi4981f152019-03-26 18:58:45 +0100800 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
801 try {
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800802 performSurfacePlacementNoTrace();
Jorim Jaggi4981f152019-03-26 18:58:45 +0100803 } finally {
804 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
805 }
806 }
807
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700808 // "Something has changed! Let's make it correct now."
809 // TODO: Super crazy long method that should be broken down...
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800810 void performSurfacePlacementNoTrace() {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700811 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
812 + Debug.getCallers(3));
813
814 int i;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700815
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800816 if (mWmService.mFocusMayChange) {
817 mWmService.mFocusMayChange = false;
Jorim Jaggi4981f152019-03-26 18:58:45 +0100818 mWmService.updateFocusedWindowLocked(
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700819 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
820 }
821
822 // Initialize state of exiting tokens.
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700823 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700824 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700825 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800826 displayContent.setExitingTokensHasVisible(false);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700827 }
828
829 mHoldScreen = null;
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100830 mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700831 mUserActivityTimeout = -1;
832 mObscureApplicationContentOnSecondaryDisplays = false;
833 mSustainedPerformanceModeCurrent = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800834 mWmService.mTransactionSequence++;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700835
lumark588a3e82018-07-20 18:53:54 +0800836 // TODO(multi-display): recents animation & wallpaper need support multi-display.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800837 final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked();
838 final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700839
840 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
841 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Jorim Jaggi4981f152019-03-26 18:58:45 +0100842 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800843 mWmService.openSurfaceTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700844 try {
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800845 applySurfaceChangesTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700846 } catch (RuntimeException e) {
847 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
848 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800849 mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
Jorim Jaggi4981f152019-03-26 18:58:45 +0100850 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700851 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
852 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
853 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800854 mWmService.mAnimator.executeAfterPrepareSurfacesRunnables();
Chavi Weingarten16d0d072018-02-12 23:50:28 +0000855
lumark588a3e82018-07-20 18:53:54 +0800856 checkAppTransitionReady(surfacePlacer);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700857
Winson Chunge2d72172018-01-25 17:46:20 +0000858 // Defer starting the recents animation until the wallpaper has drawn
859 final RecentsAnimationController recentsAnimationController =
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800860 mWmService.getRecentsAnimationController();
Winson Chunge2d72172018-01-25 17:46:20 +0000861 if (recentsAnimationController != null) {
wilsonshihc32538e2018-11-07 17:27:34 +0800862 recentsAnimationController.checkAnimationReady(defaultDisplay.mWallpaperController);
Winson Chunge2d72172018-01-25 17:46:20 +0000863 }
864
wilsonshihc32538e2018-11-07 17:27:34 +0800865 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
866 final DisplayContent displayContent = mChildren.get(displayNdx);
867 if (displayContent.mWallpaperMayChange) {
868 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
869 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
870 if (DEBUG_LAYOUT_REPEATS) {
871 surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
872 displayContent.pendingLayoutChanges);
873 }
874 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700875 }
876
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800877 if (mWmService.mFocusMayChange) {
878 mWmService.mFocusMayChange = false;
Jorim Jaggi4981f152019-03-26 18:58:45 +0100879 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
880 false /*updateInputWindows*/);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700881 }
882
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700883 if (isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700884 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
885 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
886 defaultDisplay.pendingLayoutChanges);
887 }
888
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800889 handleResizingWindows();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700890
Adrian Roosb125e0b2019-10-02 14:55:14 +0200891 if (mWmService.mDisplayFrozen) {
892 ProtoLog.v(WM_DEBUG_ORIENTATION,
893 "With display frozen, orientationChangeComplete=%b",
894 mOrientationChangeComplete);
895 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700896 if (mOrientationChangeComplete) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800897 if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
898 mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
899 mWmService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
900 mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700901 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800902 mWmService.stopFreezingDisplayLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700903 }
904
905 // Destroy the surface of any windows that are no longer visible.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800906 i = mWmService.mDestroySurface.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700907 if (i > 0) {
908 do {
909 i--;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800910 WindowState win = mWmService.mDestroySurface.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700911 win.mDestroying = false;
lumark90120a82018-08-15 00:33:03 +0800912 final DisplayContent displayContent = win.getDisplayContent();
913 if (displayContent.mInputMethodWindow == win) {
914 displayContent.setInputMethodWindowLocked(null);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700915 }
lumark90120a82018-08-15 00:33:03 +0800916 if (displayContent.mWallpaperController.isWallpaperTarget(win)) {
wilsonshihc32538e2018-11-07 17:27:34 +0800917 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700918 }
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200919 win.destroySurfaceUnchecked();
Robert Carrfa8edf82018-04-19 12:38:47 -0700920 win.mWinAnimator.destroyPreservedSurfaceLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700921 } while (i > 0);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800922 mWmService.mDestroySurface.clear();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700923 }
924
925 // Time to remove any exiting tokens?
926 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700927 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800928 displayContent.removeExistingTokensIfPossible();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700929 }
930
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700931 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700932 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700933 if (displayContent.pendingLayoutChanges != 0) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700934 displayContent.setLayoutNeeded();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700935 }
936 }
937
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800938 mWmService.setHoldScreenLocked(mHoldScreen);
939 if (!mWmService.mDisplayFrozen) {
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100940 final float brightnessOverride = mScreenBrightnessOverride < PowerManager.BRIGHTNESS_MIN
941 || mScreenBrightnessOverride > PowerManager.BRIGHTNESS_MAX
942 ? PowerManager.BRIGHTNESS_INVALID_FLOAT : mScreenBrightnessOverride;
943 int brightnessFloatAsIntBits = Float.floatToIntBits(brightnessOverride);
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200944 // Post these on a handler such that we don't call into power manager service while
945 // holding the window manager lock to avoid lock contention with power manager lock.
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100946 mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightnessFloatAsIntBits,
947 0).sendToTarget();
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200948 mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700949 }
950
951 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
952 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800953 mWmService.mPowerManagerInternal.powerHint(
Ruchi Kandoi0d434042016-10-03 09:12:02 -0700954 PowerHint.SUSTAINED_PERFORMANCE,
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700955 (mSustainedPerformanceModeEnabled ? 1 : 0));
956 }
957
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700958 if (mUpdateRotation) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200959 ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation");
Riddle Hsu654a6f92018-07-13 22:59:36 +0800960 mUpdateRotation = updateRotationUnchecked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700961 }
962
Yunfan Chen87b5a242019-10-01 17:53:59 +0900963 if (!mWmService.mWaitingForDrawnCallbacks.isEmpty()
lumark588a3e82018-07-20 18:53:54 +0800964 || (mOrientationChangeComplete && !isLayoutNeeded()
Jorim Jaggi4981f152019-03-26 18:58:45 +0100965 && !mUpdateRotation)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800966 mWmService.checkDrawnWindowsLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700967 }
968
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800969 final int N = mWmService.mPendingRemove.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700970 if (N > 0) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800971 if (mWmService.mPendingRemoveTmp.length < N) {
972 mWmService.mPendingRemoveTmp = new WindowState[N + 10];
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700973 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800974 mWmService.mPendingRemove.toArray(mWmService.mPendingRemoveTmp);
975 mWmService.mPendingRemove.clear();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700976 ArrayList<DisplayContent> displayList = new ArrayList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700977 for (i = 0; i < N; i++) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800978 final WindowState w = mWmService.mPendingRemoveTmp[i];
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700979 w.removeImmediately();
980 final DisplayContent displayContent = w.getDisplayContent();
981 if (displayContent != null && !displayList.contains(displayContent)) {
982 displayList.add(displayContent);
983 }
984 }
985
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700986 for (int j = displayList.size() - 1; j >= 0; --j) {
987 final DisplayContent dc = displayList.get(j);
988 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700989 }
990 }
991
992 // Remove all deferred displays stacks, tasks, and activities.
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700993 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
994 mChildren.get(displayNdx).checkCompleteDeferredRemoval();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700995 }
996
Jorim Jaggi4981f152019-03-26 18:58:45 +0100997 forAllDisplays(dc -> {
998 dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
999 dc.updateSystemGestureExclusion();
1000 dc.updateTouchExcludeRegion();
1001 });
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001002
1003 // Check to see if we are now in a state where the screen should
1004 // be enabled, because the window obscured flags have changed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001005 mWmService.enableScreenIfNeededLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001006
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001007 mWmService.scheduleAnimationLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001008
Evan Rosky0037e5f2019-11-05 10:26:24 -08001009 // Send any pending task-info changes that were queued-up during a layout deferment
1010 mWmService.mAtmService.mTaskOrganizerController.dispatchPendingTaskInfoChanges();
1011
Evan Rosky73a7fe92019-11-18 18:28:01 -08001012 if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit");
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001013 }
1014
lumark588a3e82018-07-20 18:53:54 +08001015 private void checkAppTransitionReady(WindowSurfacePlacer surfacePlacer) {
1016 // Trace all displays app transition by Z-order for pending layout change.
1017 for (int i = mChildren.size() - 1; i >= 0; --i) {
1018 final DisplayContent curDisplay = mChildren.get(i);
1019
1020 // If we are ready to perform an app transition, check through all of the app tokens
1021 // to be shown and see if they are ready to go.
1022 if (curDisplay.mAppTransition.isReady()) {
1023 // handleAppTransitionReady may modify curDisplay.pendingLayoutChanges.
1024 curDisplay.mAppTransitionController.handleAppTransitionReady();
1025 if (DEBUG_LAYOUT_REPEATS) {
1026 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReady",
1027 curDisplay.pendingLayoutChanges);
1028 }
1029 }
1030
lumark9bca6b42019-10-17 18:35:22 +08001031 if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppTransitioning()) {
lumark588a3e82018-07-20 18:53:54 +08001032 // We have finished the animation of an app transition. To do this, we have
1033 // delayed a lot of operations like showing and hiding apps, moving apps in
1034 // Z-order, etc.
1035 // The app token list reflects the correct Z-order, but the window list may now
1036 // be out of sync with it. So here we will just rebuild the entire app window
1037 // list. Fun!
1038 curDisplay.handleAnimatingStoppedAndTransition();
1039 if (DEBUG_LAYOUT_REPEATS) {
1040 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
1041 curDisplay.pendingLayoutChanges);
1042 }
1043 }
1044 }
1045 }
1046
Riddle Hsu72d6dc32020-03-25 22:58:00 +08001047 private void applySurfaceChangesTransaction() {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001048 mHoldScreenWindow = null;
Wale Ogunwaled4a00a02016-10-10 11:29:17 -07001049 mObscuringWindow = null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001050
Andrii Kulian8ee72852017-03-10 10:36:45 -08001051 // TODO(multi-display): Support these features on secondary screens.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001052 final DisplayContent defaultDc = mWmService.getDefaultDisplayContentLocked();
lumark588a3e82018-07-20 18:53:54 +08001053 final DisplayInfo defaultInfo = defaultDc.getDisplayInfo();
1054 final int defaultDw = defaultInfo.logicalWidth;
1055 final int defaultDh = defaultInfo.logicalHeight;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001056 if (mWmService.mWatermark != null) {
chaviw619da692019-06-10 15:39:40 -07001057 mWmService.mWatermark.positionSurface(defaultDw, defaultDh, mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001058 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001059 if (mWmService.mStrictModeFlash != null) {
chaviw619da692019-06-10 15:39:40 -07001060 mWmService.mStrictModeFlash.positionSurface(defaultDw, defaultDh, mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001061 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001062 if (mWmService.mEmulatorDisplayOverlay != null) {
1063 mWmService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
chaviw619da692019-06-10 15:39:40 -07001064 mWmService.getDefaultDisplayRotation(), mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001065 }
1066
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001067 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001068 for (int j = 0; j < count; ++j) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001069 final DisplayContent dc = mChildren.get(j);
Riddle Hsu72d6dc32020-03-25 22:58:00 +08001070 dc.applySurfaceChangesTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001071 }
1072
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001073 // Give the display manager a chance to adjust properties like display rotation if it needs
1074 // to.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001075 mWmService.mDisplayManagerInternal.performTraversal(mDisplayTransaction);
Robert Carrae606b42018-02-15 15:36:23 -08001076 SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001077 }
1078
1079 /**
David Stevensf833ba92017-03-16 19:00:20 -07001080 * Handles resizing windows during surface placement.
David Stevensf833ba92017-03-16 19:00:20 -07001081 */
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001082 private void handleResizingWindows() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001083 for (int i = mWmService.mResizingWindows.size() - 1; i >= 0; i--) {
1084 WindowState win = mWmService.mResizingWindows.get(i);
Louis Changc3f29da2018-12-10 18:09:06 +08001085 if (win.mAppFreezing || win.getDisplayContent().mWaitingForConfig) {
1086 // Don't remove this window until rotation has completed and is not waiting for the
1087 // complete configuration.
David Stevensf833ba92017-03-16 19:00:20 -07001088 continue;
1089 }
1090 win.reportResized();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001091 mWmService.mResizingWindows.remove(i);
David Stevensf833ba92017-03-16 19:00:20 -07001092 }
David Stevensf833ba92017-03-16 19:00:20 -07001093 }
1094
1095 /**
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001096 * @param w WindowState this method is applied to.
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001097 * @param obscured True if there is a window on top of this obscuring the display.
1098 * @param syswin System window?
1099 * @return True when the display contains content to show the user. When false, the display
1100 * manager may choose to mirror or blank the display.
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001101 */
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001102 boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001103 final WindowManager.LayoutParams attrs = w.mAttrs;
1104 final int attrFlags = attrs.flags;
Aaron Whyte8cbdf042018-01-23 12:06:02 -08001105 final boolean onScreen = w.isOnScreen();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001106 final boolean canBeSeen = w.isDisplayedLw();
1107 final int privateflags = attrs.privateFlags;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001108 boolean displayHasContent = false;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001109
Adrian Roosb125e0b2019-10-02 14:55:14 +02001110 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
1111 "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w"
1112 + ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",
1113 w, w.mHasSurface, onScreen, w.isDisplayedLw(), w.mAttrs.userActivityTimeout);
Aaron Whyte8cbdf042018-01-23 12:06:02 -08001114 if (w.mHasSurface && onScreen) {
1115 if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
1116 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
Adrian Roosb125e0b2019-10-02 14:55:14 +02001117 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "mUserActivityTimeout set to %d",
1118 mUserActivityTimeout);
Aaron Whyte8cbdf042018-01-23 12:06:02 -08001119 }
1120 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001121 if (w.mHasSurface && canBeSeen) {
1122 if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
1123 mHoldScreen = w.mSession;
1124 mHoldScreenWindow = w;
Adrian Roosb125e0b2019-10-02 14:55:14 +02001125 } else if (w == mWmService.mLastWakeLockHoldingWindow) {
1126 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
1127 "handleNotObscuredLocked: %s was holding screen wakelock but no longer "
1128 + "has FLAG_KEEP_SCREEN_ON!!! called by%s",
1129 w, Debug.getCallers(10));
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001130 }
Fiona Campbell29dce0f2020-04-03 17:24:45 +01001131 if (!syswin && w.mAttrs.screenBrightness >= 0
1132 && Float.isNaN(mScreenBrightnessOverride)) {
1133 mScreenBrightnessOverride = w.mAttrs.screenBrightness;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001134 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001135
1136 final int type = attrs.type;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001137 // This function assumes that the contents of the default display are processed first
1138 // before secondary displays.
1139 final DisplayContent displayContent = w.getDisplayContent();
1140 if (displayContent != null && displayContent.isDefaultDisplay) {
1141 // While a dream or keyguard is showing, obscure ordinary application content on
1142 // secondary displays (by forcibly enabling mirroring unless there is other content
1143 // we want to show) but still allow opaque keyguard dialogs to be shown.
Galia Peycheva70b55712020-03-16 18:31:34 +01001144 if (w.isDreamWindow() || mWmService.mPolicy.isKeyguardShowing()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001145 mObscureApplicationContentOnSecondaryDisplays = true;
1146 }
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001147 displayHasContent = true;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001148 } else if (displayContent != null &&
1149 (!mObscureApplicationContentOnSecondaryDisplays
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001150 || (obscured && type == TYPE_KEYGUARD_DIALOG))) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001151 // Allow full screen keyguard presentation dialogs to be seen.
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001152 displayHasContent = true;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001153 }
1154 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1155 mSustainedPerformanceModeCurrent = true;
1156 }
1157 }
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001158
1159 return displayHasContent;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001160 }
1161
Riddle Hsu654a6f92018-07-13 22:59:36 +08001162 boolean updateRotationUnchecked() {
1163 boolean changed = false;
1164 for (int i = mChildren.size() - 1; i >= 0; i--) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001165 if (mChildren.get(i).getDisplayRotation().updateRotationAndSendNewConfigIfChanged()) {
Riddle Hsu654a6f92018-07-13 22:59:36 +08001166 changed = true;
Riddle Hsu654a6f92018-07-13 22:59:36 +08001167 }
1168 }
1169 return changed;
1170 }
1171
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001172 boolean copyAnimToLayoutParams() {
1173 boolean doRequest = false;
1174
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001175 final int bulkUpdateParams = mWmService.mAnimator.mBulkUpdateParams;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001176 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1177 mUpdateRotation = true;
1178 doRequest = true;
1179 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001180 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1181 mOrientationChangeComplete = false;
1182 } else {
1183 mOrientationChangeComplete = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001184 mLastWindowFreezeSource = mWmService.mAnimator.mLastWindowFreezeSource;
1185 if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001186 doRequest = true;
1187 }
1188 }
chaviw042059d2018-01-11 11:24:08 -08001189
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001190 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1191 mWallpaperActionPending = true;
1192 }
1193
1194 return doRequest;
1195 }
1196
Jorim Jaggi86c39f92017-05-02 18:02:46 +02001197 private final class MyHandler extends Handler {
1198
1199 public MyHandler(Looper looper) {
1200 super(looper);
1201 }
1202
1203 @Override
1204 public void handleMessage(Message msg) {
1205 switch (msg.what) {
1206 case SET_SCREEN_BRIGHTNESS_OVERRIDE:
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001207 mWmService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
Fiona Campbell29dce0f2020-04-03 17:24:45 +01001208 Float.intBitsToFloat(msg.arg1));
Jorim Jaggi86c39f92017-05-02 18:02:46 +02001209 break;
1210 case SET_USER_ACTIVITY_TIMEOUT:
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001211 mWmService.mPowerManagerInternal.
1212 setUserActivityTimeoutOverrideFromWindowManager((Long) msg.obj);
Jorim Jaggi86c39f92017-05-02 18:02:46 +02001213 break;
1214 default:
1215 break;
1216 }
1217 }
1218 }
1219
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001220 void dumpDisplayContents(PrintWriter pw) {
1221 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001222 if (mWmService.mDisplayReady) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001223 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001224 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001225 final DisplayContent displayContent = mChildren.get(i);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001226 displayContent.dump(pw, " ", true /* dumpAll */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001227 }
1228 } else {
1229 pw.println(" NO DISPLAY");
1230 }
1231 }
1232
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001233 void dumpTopFocusedDisplayId(PrintWriter pw) {
1234 pw.print(" mTopFocusedDisplayId="); pw.println(mTopFocusedDisplayId);
1235 }
1236
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001237 void dumpLayoutNeededDisplayIds(PrintWriter pw) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001238 if (!isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001239 return;
1240 }
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001241 pw.print(" mLayoutNeeded on displays=");
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001242 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001243 for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001244 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001245 if (displayContent.isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001246 pw.print(displayContent.getDisplayId());
1247 }
1248 }
1249 pw.println();
1250 }
1251
1252 void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
Wale Ogunwaled1880962016-11-08 10:31:59 -08001253 final int[] index = new int[1];
1254 forAllWindows((w) -> {
1255 if (windows == null || windows.contains(w)) {
1256 pw.println(" Window #" + index[0] + " " + w + ":");
1257 w.dump(pw, " ", dumpAll || windows != null);
1258 index[0] = index[0] + 1;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001259 }
Wale Ogunwaled1880962016-11-08 10:31:59 -08001260 }, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001261 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001262
Wale Ogunwale02319a62016-09-26 15:21:22 -07001263 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1264 pw.println(" All tokens:");
1265 for (int i = mChildren.size() - 1; i >= 0; --i) {
1266 mChildren.get(i).dumpTokens(pw, dumpAll);
1267 }
1268 }
1269
Wale Ogunwalef342f062020-01-27 07:34:13 -08001270 @Override
1271 public void dumpDebug(ProtoOutputStream proto, long fieldId,
Nataniel Borges023ecb52019-01-16 14:15:43 -08001272 @WindowTraceLogLevel int logLevel) {
1273 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
1274 return;
1275 }
1276
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001277 final long token = proto.start(fieldId);
Jeffrey Huangcb782852019-12-05 11:28:11 -08001278 super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
Wale Ogunwalef342f062020-01-27 07:34:13 -08001279
1280 mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
1281 proto.write(IS_HOME_RECENTS_COMPONENT,
1282 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
1283 mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
1284
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001285 proto.end(token);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001286 }
1287
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001288 @Override
1289 String getName() {
1290 return "ROOT";
1291 }
Robert Carrb1579c82017-09-05 14:54:47 -07001292
1293 @Override
1294 void scheduleAnimation() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001295 mWmService.scheduleAnimationLocked();
Robert Carrb1579c82017-09-05 14:54:47 -07001296 }
Arthur Hung95b38a92018-07-20 18:56:12 +08001297
Charles Chen37848f32019-02-27 19:27:45 +08001298 @Override
1299 protected void removeChild(DisplayContent dc) {
1300 super.removeChild(dc);
1301 if (mTopFocusedDisplayId == dc.getDisplayId()) {
1302 mWmService.updateFocusedWindowLocked(
1303 UPDATE_FOCUS_NORMAL, true /* updateInputWindows */);
1304 }
1305 }
1306
Arthur Hung95b38a92018-07-20 18:56:12 +08001307 /**
1308 * For all display at or below this call the callback.
1309 *
1310 * @param callback Callback to be called for every display.
1311 */
1312 void forAllDisplays(Consumer<DisplayContent> callback) {
1313 for (int i = mChildren.size() - 1; i >= 0; --i) {
1314 callback.accept(mChildren.get(i));
1315 }
1316 }
lumark90120a82018-08-15 00:33:03 +08001317
Tiger Huang7c610aa2018-10-27 00:01:01 +08001318 void forAllDisplayPolicies(Consumer<DisplayPolicy> callback) {
1319 for (int i = mChildren.size() - 1; i >= 0; --i) {
1320 callback.accept(mChildren.get(i).getDisplayPolicy());
1321 }
1322 }
1323
lumark90120a82018-08-15 00:33:03 +08001324 /**
1325 * Get current topmost focused IME window in system.
1326 * Will look on all displays in current Z-order.
1327 */
1328 WindowState getCurrentInputMethodWindow() {
1329 for (int i = mChildren.size() - 1; i >= 0; --i) {
1330 final DisplayContent displayContent = mChildren.get(i);
1331 if (displayContent.mInputMethodWindow != null) {
1332 return displayContent.mInputMethodWindow;
1333 }
1334 }
1335 return null;
1336 }
Charles Chen173ae782019-11-11 20:39:02 +08001337
1338 void getDisplayContextsWithNonToastVisibleWindows(int pid, List<Context> outContexts) {
1339 if (outContexts == null) {
1340 return;
1341 }
1342 for (int i = mChildren.size() - 1; i >= 0; --i) {
1343 DisplayContent dc = mChildren.get(i);
1344 if (dc.isAnyNonToastWindowVisibleForPid(pid)) {
1345 outContexts.add(dc.getDisplayUiContext());
1346 }
1347 }
1348 }
1349
1350 @Nullable Context getDisplayUiContext(int displayId) {
1351 return getDisplayContent(displayId) != null
1352 ? getDisplayContent(displayId).getDisplayUiContext() : null;
1353 }
Louis Chang149d5c82019-12-30 09:47:39 +08001354
1355 void setWindowManager(WindowManagerService wm) {
1356 mWindowManager = wm;
1357 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
1358 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
1359 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
1360
1361 final Display[] displays = mDisplayManager.getDisplays();
1362 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
1363 final Display display = displays[displayNdx];
1364 final DisplayContent displayContent = new DisplayContent(display, this);
Garfield Tanfbd233a2019-12-26 12:39:25 -08001365 addChild(displayContent, POSITION_BOTTOM);
Louis Chang149d5c82019-12-30 09:47:39 +08001366 if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
1367 mDefaultDisplay = displayContent;
1368 }
1369 }
1370 calculateDefaultMinimalSizeOfResizeableTasks();
1371
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001372 final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();
Chris Lif95a7762020-04-14 20:03:47 -07001373 defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001374 positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent,
1375 false /* includingParents */);
Louis Chang149d5c82019-12-30 09:47:39 +08001376 }
1377
1378 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
1379 DisplayContent getDefaultDisplay() {
1380 return mDefaultDisplay;
1381 }
1382
1383 /**
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001384 * Get the default display area on the device dedicated to app windows. This one should be used
1385 * only as a fallback location for activity launches when no target display area is specified,
1386 * or for cases when multi-instance is not supported yet (like Split-screen, Freeform, PiP or
1387 * Recents).
1388 */
1389 TaskDisplayArea getDefaultTaskDisplayArea() {
1390 return mDefaultDisplay.getDefaultTaskDisplayArea();
1391 }
1392
1393 /**
Louis Chang149d5c82019-12-30 09:47:39 +08001394 * Get an existing instance of {@link DisplayContent} that has the given uniqueId. Unique ID is
1395 * defined in {@link DisplayInfo#uniqueId}.
1396 *
1397 * @param uniqueId the unique ID of the display
1398 * @return the {@link DisplayContent} or {@code null} if nothing is found.
1399 */
1400 DisplayContent getDisplayContent(String uniqueId) {
1401 for (int i = getChildCount() - 1; i >= 0; --i) {
1402 final DisplayContent display = getChildAt(i);
1403 final boolean isValid = display.mDisplay.isValid();
1404 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
1405 return display;
1406 }
1407 }
1408
1409 return null;
1410 }
1411
1412 // TODO: Look into consolidating with getDisplayContentOrCreate()
1413 DisplayContent getDisplayContent(int displayId) {
1414 for (int i = getChildCount() - 1; i >= 0; --i) {
1415 final DisplayContent displayContent = getChildAt(i);
1416 if (displayContent.mDisplayId == displayId) {
1417 return displayContent;
1418 }
1419 }
1420 return null;
1421 }
1422
1423 /**
1424 * Get an existing instance of {@link DisplayContent} or create new if there is a
1425 * corresponding record in display manager.
1426 */
1427 // TODO: Look into consolidating with getDisplayContent()
1428 @Nullable DisplayContent getDisplayContentOrCreate(int displayId) {
1429 DisplayContent displayContent = getDisplayContent(displayId);
1430 if (displayContent != null) {
1431 return displayContent;
1432 }
1433 if (mDisplayManager == null) {
1434 // The system isn't fully initialized yet.
1435 return null;
1436 }
1437 final Display display = mDisplayManager.getDisplay(displayId);
1438 if (display == null) {
1439 // The display is not registered in DisplayManager.
1440 return null;
1441 }
1442 // The display hasn't been added to ActivityManager yet, create a new record now.
1443 displayContent = new DisplayContent(display, this);
Garfield Tanfbd233a2019-12-26 12:39:25 -08001444 addChild(displayContent, POSITION_BOTTOM);
Louis Chang149d5c82019-12-30 09:47:39 +08001445 return displayContent;
1446 }
1447
Louis Chang149d5c82019-12-30 09:47:39 +08001448 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001449 return getDefaultTaskDisplayArea().getHomeActivityForUser(userId);
Louis Chang149d5c82019-12-30 09:47:39 +08001450 }
1451
1452 boolean startHomeOnAllDisplays(int userId, String reason) {
1453 boolean homeStarted = false;
1454 for (int i = getChildCount() - 1; i >= 0; i--) {
1455 final int displayId = getChildAt(i).mDisplayId;
1456 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
1457 }
1458 return homeStarted;
1459 }
1460
1461 void startHomeOnEmptyDisplays(String reason) {
1462 for (int i = getChildCount() - 1; i >= 0; i--) {
1463 final DisplayContent display = getChildAt(i);
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001464 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1465 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
1466 if (taskDisplayArea.topRunningActivity() == null) {
1467 startHomeOnTaskDisplayArea(mCurrentUser, reason, taskDisplayArea,
1468 false /* allowInstrumenting */, false /* fromHomeKey */);
1469 }
Louis Chang149d5c82019-12-30 09:47:39 +08001470 }
1471 }
1472 }
1473
1474 boolean startHomeOnDisplay(int userId, String reason, int displayId) {
1475 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
1476 false /* fromHomeKey */);
1477 }
1478
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001479 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
1480 boolean fromHomeKey) {
1481 // Fallback to top focused display or default display if the displayId is invalid.
1482 if (displayId == INVALID_DISPLAY) {
1483 final ActivityStack stack = getTopDisplayFocusedStack();
1484 displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
1485 }
1486
1487 final DisplayContent display = getDisplayContent(displayId);
1488 boolean result = false;
1489 for (int tcNdx = display.getTaskDisplayAreaCount() - 1; tcNdx >= 0; --tcNdx) {
1490 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tcNdx);
1491 result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
1492 allowInstrumenting, fromHomeKey);
1493 }
1494 return result;
1495 }
1496
Louis Chang149d5c82019-12-30 09:47:39 +08001497 /**
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001498 * This starts home activity on display areas that can have system decorations based on
1499 * displayId - default display area always uses primary home component.
1500 * For secondary display areas, the home activity must have category SECONDARY_HOME and then
1501 * resolves according to the priorities listed below.
Louis Chang149d5c82019-12-30 09:47:39 +08001502 * - If default home is not set, always use the secondary home defined in the config.
1503 * - Use currently selected primary home activity.
1504 * - Use the activity in the same package as currently selected primary home activity.
1505 * If there are multiple activities matched, use first one.
1506 * - Use the secondary home defined in the config.
1507 */
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001508 boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
1509 boolean allowInstrumenting, boolean fromHomeKey) {
1510 // Fallback to top focused display area if the provided one is invalid.
1511 if (taskDisplayArea == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08001512 final ActivityStack stack = getTopDisplayFocusedStack();
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001513 taskDisplayArea = stack != null ? stack.getDisplayArea()
1514 : getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08001515 }
1516
1517 Intent homeIntent = null;
1518 ActivityInfo aInfo = null;
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001519 if (taskDisplayArea == getDefaultTaskDisplayArea()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001520 homeIntent = mService.getHomeIntent();
1521 aInfo = resolveHomeActivity(userId, homeIntent);
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001522 } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001523 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
Louis Chang149d5c82019-12-30 09:47:39 +08001524 aInfo = info.first;
1525 homeIntent = info.second;
1526 }
1527 if (aInfo == null || homeIntent == null) {
1528 return false;
1529 }
1530
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001531 if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
Louis Chang149d5c82019-12-30 09:47:39 +08001532 return false;
1533 }
1534
1535 // Updates the home component of the intent.
1536 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
1537 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
1538 // Updates the extra information of the intent.
1539 if (fromHomeKey) {
1540 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
lumark04bceb92020-03-07 00:03:33 +08001541 mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity");
Louis Chang149d5c82019-12-30 09:47:39 +08001542 }
1543 // Update the reason for ANR debugging to verify if the user activity is the one that
1544 // actually launched.
1545 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001546 aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
Louis Chang149d5c82019-12-30 09:47:39 +08001547 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001548 taskDisplayArea);
Louis Chang149d5c82019-12-30 09:47:39 +08001549 return true;
1550 }
1551
1552 /**
1553 * This resolves the home activity info.
1554 * @return the home activity info if any.
1555 */
1556 @VisibleForTesting
1557 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
1558 final int flags = ActivityManagerService.STOCK_PM_FLAGS;
1559 final ComponentName comp = homeIntent.getComponent();
1560 ActivityInfo aInfo = null;
1561 try {
1562 if (comp != null) {
1563 // Factory test.
1564 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
1565 } else {
1566 final String resolvedType =
1567 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
1568 final ResolveInfo info = AppGlobals.getPackageManager()
1569 .resolveIntent(homeIntent, resolvedType, flags, userId);
1570 if (info != null) {
1571 aInfo = info.activityInfo;
1572 }
1573 }
1574 } catch (RemoteException e) {
1575 // ignore
1576 }
1577
1578 if (aInfo == null) {
1579 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
1580 return null;
1581 }
1582
1583 aInfo = new ActivityInfo(aInfo);
1584 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
1585 return aInfo;
1586 }
1587
1588 @VisibleForTesting
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001589 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId,
1590 @NonNull TaskDisplayArea taskDisplayArea) {
1591 if (taskDisplayArea == getDefaultTaskDisplayArea()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001592 throw new IllegalArgumentException(
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001593 "resolveSecondaryHomeActivity: Should not be default task container");
Louis Chang149d5c82019-12-30 09:47:39 +08001594 }
1595 // Resolve activities in the same package as currently selected primary home activity.
1596 Intent homeIntent = mService.getHomeIntent();
1597 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
1598 if (aInfo != null) {
1599 if (ResolverActivity.class.getName().equals(aInfo.name)) {
1600 // Always fallback to secondary home component if default home is not set.
1601 aInfo = null;
1602 } else {
1603 // Look for secondary home activities in the currently selected default home
1604 // package.
1605 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
1606 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
1607 final int size = resolutions.size();
1608 final String targetName = aInfo.name;
1609 aInfo = null;
1610 for (int i = 0; i < size; i++) {
1611 ResolveInfo resolveInfo = resolutions.get(i);
1612 // We need to traverse all resolutions to check if the currently selected
1613 // default home activity is present.
1614 if (resolveInfo.activityInfo.name.equals(targetName)) {
1615 aInfo = resolveInfo.activityInfo;
1616 break;
1617 }
1618 }
1619 if (aInfo == null && size > 0) {
1620 // First one is the best.
1621 aInfo = resolutions.get(0).activityInfo;
1622 }
1623 }
1624 }
1625
1626 if (aInfo != null) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001627 if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, false /* allowInstrumenting */)) {
Louis Chang149d5c82019-12-30 09:47:39 +08001628 aInfo = null;
1629 }
1630 }
1631
1632 // Fallback to secondary home component.
1633 if (aInfo == null) {
1634 homeIntent = mService.getSecondaryHomeIntent(null);
1635 aInfo = resolveHomeActivity(userId, homeIntent);
1636 }
1637 return Pair.create(aInfo, homeIntent);
1638 }
1639
1640 /**
1641 * Retrieve all activities that match the given intent.
1642 * The list should already ordered from best to worst matched.
1643 * {@link android.content.pm.PackageManager#queryIntentActivities}
1644 */
1645 @VisibleForTesting
1646 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
1647 List<ResolveInfo> resolutions;
1648 try {
1649 final String resolvedType =
1650 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
1651 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
1652 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
1653
1654 } catch (RemoteException e) {
1655 resolutions = new ArrayList<>();
1656 }
1657 return resolutions;
1658 }
1659
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001660 boolean resumeHomeActivity(ActivityRecord prev, String reason,
1661 TaskDisplayArea taskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08001662 if (!mService.isBooting() && !mService.isBooted()) {
1663 // Not ready yet!
1664 return false;
1665 }
1666
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001667 if (taskDisplayArea == null) {
1668 taskDisplayArea = getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08001669 }
1670
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001671 final ActivityRecord r = taskDisplayArea.getHomeActivity();
Louis Chang149d5c82019-12-30 09:47:39 +08001672 final String myReason = reason + " resumeHomeActivity";
1673
1674 // Only resume home activity if isn't finishing.
1675 if (r != null && !r.finishing) {
1676 r.moveFocusableActivityToTop(myReason);
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08001677 return resumeFocusedStacksTopActivities(r.getRootTask(), prev, null);
Louis Chang149d5c82019-12-30 09:47:39 +08001678 }
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001679 return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
1680 false /* allowInstrumenting */, false /* fromHomeKey */);
Louis Chang149d5c82019-12-30 09:47:39 +08001681 }
1682
1683 /**
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001684 * Check if the display area is valid for secondary home activity.
1685 * @param taskDisplayArea The target display area.
Louis Chang149d5c82019-12-30 09:47:39 +08001686 * @return {@code true} if allow to launch, {@code false} otherwise.
1687 */
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001688 boolean shouldPlaceSecondaryHomeOnDisplayArea(TaskDisplayArea taskDisplayArea) {
1689 if (getDefaultTaskDisplayArea() == taskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08001690 throw new IllegalArgumentException(
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001691 "shouldPlaceSecondaryHomeOnDisplay: Should not be on default task container");
1692 } else if (taskDisplayArea == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08001693 return false;
1694 }
1695
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001696 if (taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) {
Louis Chang149d5c82019-12-30 09:47:39 +08001697 // Can't launch home on secondary display if device does not support multi-display.
1698 return false;
1699 }
1700
1701 final boolean deviceProvisioned = Settings.Global.getInt(
1702 mService.mContext.getContentResolver(),
1703 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1704 if (!deviceProvisioned) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001705 // Can't launch home on secondary display areas before device is provisioned.
Louis Chang149d5c82019-12-30 09:47:39 +08001706 return false;
1707 }
1708
1709 if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001710 // Can't launch home on secondary display areas if device is still locked.
Louis Chang149d5c82019-12-30 09:47:39 +08001711 return false;
1712 }
1713
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001714 final DisplayContent display = taskDisplayArea.getDisplayContent();
Louis Chang149d5c82019-12-30 09:47:39 +08001715 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
1716 // Can't launch home on display that doesn't support system decorations.
1717 return false;
1718 }
1719
1720 return true;
1721 }
1722
1723 /**
1724 * Check if home activity start should be allowed on a display.
1725 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001726 * @param taskDisplayArea The target display area.
Louis Chang149d5c82019-12-30 09:47:39 +08001727 * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
1728 * @return {@code true} if allow to launch, {@code false} otherwise.
1729 */
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001730 boolean canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea,
Louis Chang149d5c82019-12-30 09:47:39 +08001731 boolean allowInstrumenting) {
1732 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
1733 && mService.mTopAction == null) {
1734 // We are running in factory test mode, but unable to find the factory test app, so
1735 // just sit around displaying the error message and don't try to start anything.
1736 return false;
1737 }
1738
1739 final WindowProcessController app =
1740 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
1741 if (!allowInstrumenting && app != null && app.isInstrumenting()) {
1742 // Don't do this if the home app is currently being instrumented.
1743 return false;
1744 }
1745
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001746 final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId()
1747 : INVALID_DISPLAY;
Louis Chang149d5c82019-12-30 09:47:39 +08001748 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
1749 && displayId == mService.mVr2dDisplayId)) {
1750 // No restrictions to default display or vr 2d display.
1751 return true;
1752 }
1753
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001754 if (!shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Louis Chang149d5c82019-12-30 09:47:39 +08001755 return false;
1756 }
1757
1758 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
1759 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
1760 if (!supportMultipleInstance) {
1761 // Can't launch home on secondary displays if it requested to be single instance.
1762 return false;
1763 }
1764
1765 return true;
1766 }
1767
1768 /**
1769 * Ensure all activities visibility, update orientation and configuration.
1770 *
1771 * @param starting The currently starting activity or {@code null} if there is none.
1772 * @param displayId The id of the display where operation is executed.
1773 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
1774 * {@code true} if config changed.
1775 * @param deferResume Whether to defer resume while updating config.
1776 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
1777 * because of configuration update.
1778 */
1779 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
1780 boolean markFrozenIfConfigChanged, boolean deferResume) {
1781 // First ensure visibility without updating the config just yet. We need this to know what
1782 // activities are affecting configuration now.
1783 // Passing null here for 'starting' param value, so that visibility of actual starting
1784 // activity will be properly updated.
1785 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
1786 false /* preserveWindows */, false /* notifyClients */);
1787
1788 if (displayId == INVALID_DISPLAY) {
1789 // The caller didn't provide a valid display id, skip updating config.
1790 return true;
1791 }
1792
1793 // Force-update the orientation from the WindowManager, since we need the true configuration
1794 // to send to the client now.
1795 final DisplayContent displayContent = getDisplayContent(displayId);
1796 Configuration config = null;
1797 if (displayContent != null) {
1798 config = displayContent.updateOrientation(
1799 getDisplayOverrideConfiguration(displayId),
1800 starting != null && starting.mayFreezeScreenLocked()
1801 ? starting.appToken : null,
1802 true /* forceUpdate */);
1803 }
1804 // Visibilities may change so let the starting activity have a chance to report. Can't do it
1805 // when visibility is changed in each AppWindowToken because it may trigger wrong
1806 // configuration push because the visibility of some activities may not be updated yet.
1807 if (starting != null) {
1808 starting.reportDescendantOrientationChangeIfNeeded();
1809 }
1810 if (starting != null && markFrozenIfConfigChanged && config != null) {
1811 starting.frozenBeforeDestroy = true;
1812 }
1813
1814 if (displayContent != null) {
1815 // Update the configuration of the activities on the display.
1816 return displayContent.updateDisplayOverrideConfigurationLocked(config, starting,
1817 deferResume, null /* result */);
1818 } else {
1819 return true;
1820 }
1821 }
1822
1823 /**
1824 * @return a list of activities which are the top ones in each visible stack. The first
1825 * entry will be the focused activity.
1826 */
1827 List<IBinder> getTopVisibleActivities() {
1828 final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
1829 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
1830 // Traverse all displays.
Andrii Kulianf9df4a82020-03-31 12:09:27 -07001831 for (int dNdx = getChildCount() - 1; dNdx >= 0; dNdx--) {
1832 final DisplayContent display = getChildAt(dNdx);
1833 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1834 final TaskDisplayArea taskDisplayArea =
1835 display.getTaskDisplayAreaAt(tdaNdx);
1836 // Traverse all stacks on a display area.
1837 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
1838 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
1839 // Get top activity from a visible stack and add it to the list.
1840 if (stack.shouldBeVisible(null /* starting */)) {
1841 final ActivityRecord top = stack.getTopNonFinishingActivity();
1842 if (top != null) {
1843 if (stack == topFocusedStack) {
1844 topActivityTokens.add(0, top.appToken);
1845 } else {
1846 topActivityTokens.add(top.appToken);
1847 }
Louis Chang149d5c82019-12-30 09:47:39 +08001848 }
1849 }
1850 }
1851 }
1852 }
1853 return topActivityTokens;
1854 }
1855
1856 ActivityStack getTopDisplayFocusedStack() {
1857 for (int i = getChildCount() - 1; i >= 0; --i) {
1858 final ActivityStack focusedStack = getChildAt(i).getFocusedStack();
1859 if (focusedStack != null) {
1860 return focusedStack;
1861 }
1862 }
1863 return null;
1864 }
1865
1866 ActivityRecord getTopResumedActivity() {
1867 final ActivityStack focusedStack = getTopDisplayFocusedStack();
1868 if (focusedStack == null) {
1869 return null;
1870 }
1871 final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
1872 if (resumedActivity != null && resumedActivity.app != null) {
1873 return resumedActivity;
1874 }
1875 // The top focused stack might not have a resumed activity yet - look on all displays in
1876 // focus order.
1877 for (int i = getChildCount() - 1; i >= 0; --i) {
1878 final DisplayContent display = getChildAt(i);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07001879 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1880 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
1881 final ActivityRecord resumedActivityOnTaskContainer = taskDisplayArea
1882 .getFocusedActivity();
1883 if (resumedActivityOnTaskContainer != null) {
1884 return resumedActivityOnTaskContainer;
1885 }
Louis Chang149d5c82019-12-30 09:47:39 +08001886 }
1887 }
1888 return null;
1889 }
1890
Louis Chang149d5c82019-12-30 09:47:39 +08001891 boolean isTopDisplayFocusedStack(ActivityStack stack) {
1892 return stack != null && stack == getTopDisplayFocusedStack();
1893 }
1894
1895 void updatePreviousProcess(ActivityRecord r) {
1896 // Now that this process has stopped, we may want to consider it to be the previous app to
1897 // try to keep around in case the user wants to return to it.
1898
1899 // First, found out what is currently the foreground app, so that we don't blow away the
1900 // previous app if this activity is being hosted by the process that is actually still the
1901 // foreground.
1902 WindowProcessController fgApp = null;
1903 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
1904 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07001905 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1906 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
1907 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
1908 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
1909 if (isTopDisplayFocusedStack(stack)) {
1910 final ActivityRecord resumedActivity = stack.getResumedActivity();
1911 if (resumedActivity != null) {
1912 fgApp = resumedActivity.app;
1913 } else if (stack.mPausingActivity != null) {
1914 fgApp = stack.mPausingActivity.app;
1915 }
1916 break;
Louis Chang149d5c82019-12-30 09:47:39 +08001917 }
Louis Chang149d5c82019-12-30 09:47:39 +08001918 }
1919 }
1920 }
1921
1922 // Now set this one as the previous process, only if that really makes sense to.
1923 if (r.hasProcess() && fgApp != null && r.app != fgApp
1924 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
1925 && r.app != mService.mHomeProcess) {
1926 mService.mPreviousProcess = r.app;
1927 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1928 }
1929 }
1930
1931 boolean attachApplication(WindowProcessController app) throws RemoteException {
1932 final String processName = app.mName;
1933 boolean didSomething = false;
1934 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
1935 final DisplayContent display = getChildAt(displayNdx);
1936 final ActivityStack stack = display.getFocusedStack();
1937 if (stack == null) {
1938 continue;
1939 }
1940
1941 mTmpRemoteException = null;
1942 mTmpBoolean = false; // Set to true if an activity was started.
1943 final PooledFunction c = PooledLambda.obtainFunction(
1944 RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
1945 PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
1946 stack.forAllActivities(c);
1947 c.recycle();
1948 if (mTmpRemoteException != null) {
1949 throw mTmpRemoteException;
1950 }
1951 didSomething |= mTmpBoolean;
1952 }
1953 if (!didSomething) {
1954 ensureActivitiesVisible(null, 0, false /* preserve_windows */);
1955 }
1956 return didSomething;
1957 }
1958
1959 private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
1960 WindowProcessController app, ActivityRecord top) {
1961 if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
1962 || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
1963 return false;
1964 }
1965
1966 try {
1967 if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
1968 true /*checkConfig*/)) {
1969 mTmpBoolean = true;
1970 }
1971 } catch (RemoteException e) {
1972 Slog.w(TAG, "Exception in new application when starting activity "
1973 + top.intent.getComponent().flattenToShortString(), e);
1974 mTmpRemoteException = e;
1975 return true;
1976 }
1977 return false;
1978 }
1979
1980 /**
1981 * Make sure that all activities that need to be visible in the system actually are and update
1982 * their configuration.
1983 */
1984 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
1985 boolean preserveWindows) {
1986 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
1987 }
1988
1989 /**
1990 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
1991 */
1992 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
1993 boolean preserveWindows, boolean notifyClients) {
Riddle Hsuf2ff25f2020-04-29 19:15:33 +08001994 if (mStackSupervisor.inActivityVisibilityUpdate()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001995 // Don't do recursive work.
1996 return;
1997 }
Louis Chang149d5c82019-12-30 09:47:39 +08001998
1999 try {
Riddle Hsuf2ff25f2020-04-29 19:15:33 +08002000 mStackSupervisor.beginActivityVisibilityUpdate();
Louis Chang149d5c82019-12-30 09:47:39 +08002001 // First the front stacks. In case any are not fullscreen and are in front of home.
2002 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2003 final DisplayContent display = getChildAt(displayNdx);
2004 display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
2005 notifyClients);
2006 }
2007 } finally {
Riddle Hsuf2ff25f2020-04-29 19:15:33 +08002008 mStackSupervisor.endActivityVisibilityUpdate();
Louis Chang149d5c82019-12-30 09:47:39 +08002009 }
2010 }
2011
2012 boolean switchUser(int userId, UserState uss) {
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08002013 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
2014 final int focusStackId = topFocusedStack != null
2015 ? topFocusedStack.getRootTaskId() : INVALID_TASK_ID;
Louis Chang149d5c82019-12-30 09:47:39 +08002016 // We dismiss the docked stack whenever we switch users.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002017 if (getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
2018 getDefaultTaskDisplayArea().onSplitScreenModeDismissed();
Louis Chang149d5c82019-12-30 09:47:39 +08002019 }
2020 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
2021 // also cause all tasks to be moved to the fullscreen stack at a position that is
2022 // appropriate.
2023 removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2024
2025 mUserStackInFront.put(mCurrentUser, focusStackId);
Louis Chang149d5c82019-12-30 09:47:39 +08002026 mCurrentUser = userId;
2027
2028 mStackSupervisor.mStartingUsers.add(uss);
2029 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2030 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002031 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2032 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2033 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2034 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2035 stack.switchUser(userId);
2036 }
Louis Chang149d5c82019-12-30 09:47:39 +08002037 }
2038 }
2039
Darryl L Johnson3388bd22019-12-19 17:38:41 -08002040 final int restoreStackId = mUserStackInFront.get(userId);
Louis Chang149d5c82019-12-30 09:47:39 +08002041 ActivityStack stack = getStack(restoreStackId);
2042 if (stack == null) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002043 stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
Louis Chang149d5c82019-12-30 09:47:39 +08002044 }
2045 final boolean homeInFront = stack.isActivityTypeHome();
2046 if (stack.isOnHomeDisplay()) {
2047 stack.moveToFront("switchUserOnHomeDisplay");
2048 } else {
2049 // Stack was moved to another display while user was swapped out.
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002050 resumeHomeActivity(null, "switchUserOnOtherDisplay", getDefaultTaskDisplayArea());
Louis Chang149d5c82019-12-30 09:47:39 +08002051 }
2052 return homeInFront;
2053 }
2054
2055 void removeUser(int userId) {
2056 mUserStackInFront.delete(userId);
2057 }
2058
2059 /**
2060 * Update the last used stack id for non-current user (current user's last
2061 * used stack is the focused stack)
2062 */
2063 void updateUserStack(int userId, ActivityStack stack) {
2064 if (userId != mCurrentUser) {
Darryl L Johnson3388bd22019-12-19 17:38:41 -08002065 if (stack == null) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002066 stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
Darryl L Johnson3388bd22019-12-19 17:38:41 -08002067 }
2068
2069 mUserStackInFront.put(userId, stack.getRootTaskId());
Louis Chang149d5c82019-12-30 09:47:39 +08002070 }
2071 }
2072
2073 /**
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002074 * Move stack with all its existing content to specified task display area.
2075 * @param stackId Id of stack to move.
2076 * @param taskDisplayArea The task display area to move stack to.
2077 * @param onTop Indicates whether container should be place on top or on bottom.
2078 */
2079 void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) {
2080 final ActivityStack stack = getStack(stackId);
2081 if (stack == null) {
2082 throw new IllegalArgumentException("moveStackToTaskDisplayArea: Unknown stackId="
2083 + stackId);
2084 }
2085
2086 final TaskDisplayArea currentTaskDisplayArea = stack.getDisplayArea();
2087 if (currentTaskDisplayArea == null) {
2088 throw new IllegalStateException("moveStackToTaskDisplayArea: stack=" + stack
2089 + " is not attached to any task display area.");
2090 }
2091
2092 if (taskDisplayArea == null) {
2093 throw new IllegalArgumentException(
2094 "moveStackToTaskDisplayArea: Unknown taskDisplayArea=" + taskDisplayArea);
2095 }
2096
2097 if (currentTaskDisplayArea == taskDisplayArea) {
2098 throw new IllegalArgumentException("Trying to move stack=" + stack
2099 + " to its current taskDisplayArea=" + taskDisplayArea);
2100 }
2101 stack.reparent(taskDisplayArea, onTop);
2102 // TODO(multi-display): resize stacks properly if moved from split-screen.
2103 }
2104
2105 /**
Louis Chang149d5c82019-12-30 09:47:39 +08002106 * Move stack with all its existing content to specified display.
2107 * @param stackId Id of stack to move.
2108 * @param displayId Id of display to move stack to.
2109 * @param onTop Indicates whether container should be place on top or on bottom.
2110 */
2111 void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
2112 final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
2113 if (displayContent == null) {
2114 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
2115 + displayId);
2116 }
Louis Chang149d5c82019-12-30 09:47:39 +08002117
2118 if (displayContent.isSingleTaskInstance() && displayContent.getStackCount() > 0) {
2119 // We don't allow moving stacks to single instance display that already has a child.
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002120 Slog.e(TAG, "Can not move stackId=" + stackId
Louis Chang149d5c82019-12-30 09:47:39 +08002121 + " to single task instance display=" + displayContent);
2122 return;
2123 }
2124
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002125 moveStackToTaskDisplayArea(stackId, displayContent.getDefaultTaskDisplayArea(), onTop);
Louis Chang149d5c82019-12-30 09:47:39 +08002126 }
2127
2128 boolean moveTopStackActivityToPinnedStack(int stackId) {
2129 final ActivityStack stack = getStack(stackId);
2130 if (stack == null) {
2131 throw new IllegalArgumentException(
2132 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
2133 }
2134
2135 final ActivityRecord r = stack.topRunningActivity();
2136 if (r == null) {
2137 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
2138 + " in stack=" + stack);
2139 return false;
2140 }
2141
2142 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
2143 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
2144 + " r=" + r);
2145 return false;
2146 }
2147
Hongwei Wange8e32862020-04-08 13:23:45 -07002148 moveActivityToPinnedStack(r, "moveTopActivityToPinnedStack");
Louis Chang149d5c82019-12-30 09:47:39 +08002149 return true;
2150 }
2151
Hongwei Wange8e32862020-04-08 13:23:45 -07002152 void moveActivityToPinnedStack(ActivityRecord r, String reason) {
Louis Chang149d5c82019-12-30 09:47:39 +08002153 mService.deferWindowLayout();
2154
Andrii Kulian86d676c2020-03-27 19:34:54 -07002155 final TaskDisplayArea taskDisplayArea = r.getDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08002156
2157 try {
2158 final Task task = r.getTask();
Andrii Kulian86d676c2020-03-27 19:34:54 -07002159 final ActivityStack pinnedStack = taskDisplayArea.getRootPinnedTask();
Winson Chung8b5d23a2020-04-06 19:23:23 -07002160
Louis Chang149d5c82019-12-30 09:47:39 +08002161 // This will change the pinned stack's windowing mode to its original mode, ensuring
2162 // we only have one stack that is in pinned mode.
2163 if (pinnedStack != null) {
2164 pinnedStack.dismissPip();
2165 }
2166
Winson Chung8b5d23a2020-04-06 19:23:23 -07002167 // Set a transition to ensure that we don't immediately try and update the visibility
2168 // of the activity entering PIP
2169 r.getDisplayContent().prepareAppTransition(TRANSIT_NONE, false);
Louis Chang149d5c82019-12-30 09:47:39 +08002170
Winson Chung8b5d23a2020-04-06 19:23:23 -07002171 final boolean singleActivity = task.getChildCount() == 1;
Louis Chang149d5c82019-12-30 09:47:39 +08002172 final ActivityStack stack;
2173 if (singleActivity) {
Evan Rosky2af969c2020-05-08 16:26:31 +00002174 stack = (ActivityStack) task;
Louis Chang149d5c82019-12-30 09:47:39 +08002175 } else {
Louis Changa009c762020-02-26 11:21:31 +08002176 // In the case of multiple activities, we will create a new task for it and then
2177 // move the PIP activity into the task.
Hongwei Wange8e32862020-04-08 13:23:45 -07002178 stack = taskDisplayArea.createStack(WINDOWING_MODE_UNDEFINED, r.getActivityType(),
Andrii Kulian86d676c2020-03-27 19:34:54 -07002179 ON_TOP, r.info, r.intent, false /* createdByOrganizer */);
Ben Lin13e125b2020-05-15 15:01:07 -07002180 // It's possible the task entering PIP is in freeform, so save the last
2181 // non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore
2182 // to its previous freeform bounds.
2183 stack.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds);
Louis Changa009c762020-02-26 11:21:31 +08002184
Louis Chang149d5c82019-12-30 09:47:39 +08002185 // There are multiple activities in the task and moving the top activity should
2186 // reveal/leave the other activities in their original task.
Hongwei Wange8e32862020-04-08 13:23:45 -07002187 // On the other hand, ActivityRecord#onParentChanged takes care of setting the
2188 // up-to-dated pinned stack information on this newly created stack.
2189 r.reparent(stack, MAX_VALUE, reason);
Louis Chang149d5c82019-12-30 09:47:39 +08002190 }
Hongwei Wang95c307f2020-05-27 11:31:40 -07002191 // The intermediate windowing mode to be set on the ActivityRecord later.
2192 // This needs to happen before the re-parenting, otherwise we will always set the
2193 // ActivityRecord to be fullscreen.
2194 final int intermediateWindowingMode = stack.getWindowingMode();
Evan Rosky2af969c2020-05-08 16:26:31 +00002195 if (stack.getParent() != taskDisplayArea) {
2196 // stack is nested, but pinned tasks need to be direct children of their
2197 // display area, so reparent.
2198 stack.reparent(taskDisplayArea, true /* onTop */);
2199 }
Winson Chungc4d4ee82020-05-05 12:51:06 -07002200 // Defer the windowing mode change until after the transition to prevent the activity
2201 // from doing work and changing the activity visuals while animating
2202 // TODO(task-org): Figure-out more structured way to do this long term.
Hongwei Wang95c307f2020-05-27 11:31:40 -07002203 r.setWindowingMode(intermediateWindowingMode);
Hongwei Wange8e32862020-04-08 13:23:45 -07002204 stack.setWindowingMode(WINDOWING_MODE_PINNED);
Louis Chang149d5c82019-12-30 09:47:39 +08002205
Louis Chang149d5c82019-12-30 09:47:39 +08002206 // Reset the state that indicates it can enter PiP while pausing after we've moved it
2207 // to the pinned stack
2208 r.supportsEnterPipOnTaskSwitch = false;
2209 } finally {
2210 mService.continueWindowLayout();
2211 }
2212
Louis Chang149d5c82019-12-30 09:47:39 +08002213 ensureActivitiesVisible(null, 0, false /* preserveWindows */);
2214 resumeFocusedStacksTopActivities();
2215
2216 mService.getTaskChangeNotificationController().notifyActivityPinned(r);
2217 }
2218
2219 void executeAppTransitionForAllDisplay() {
2220 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2221 final DisplayContent display = getChildAt(displayNdx);
2222 display.mDisplayContent.executeAppTransition();
2223 }
2224 }
2225
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002226 ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08002227 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
2228 mTmpFindTaskResult.clear();
2229
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002230 // Looking up task on preferred display area first
2231 if (preferredTaskDisplayArea != null) {
2232 preferredTaskDisplayArea.findTaskLocked(r, true /* isPreferredDisplay */,
2233 mTmpFindTaskResult);
Louis Chang149d5c82019-12-30 09:47:39 +08002234 if (mTmpFindTaskResult.mIdealMatch) {
2235 return mTmpFindTaskResult.mRecord;
2236 }
2237 }
2238
2239 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2240 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002241 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2242 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2243 if (taskDisplayArea == preferredTaskDisplayArea) {
2244 continue;
2245 }
Louis Chang149d5c82019-12-30 09:47:39 +08002246
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002247 taskDisplayArea.findTaskLocked(r, false /* isPreferredDisplay */,
2248 mTmpFindTaskResult);
2249 if (mTmpFindTaskResult.mIdealMatch) {
2250 return mTmpFindTaskResult.mRecord;
2251 }
Louis Chang149d5c82019-12-30 09:47:39 +08002252 }
2253 }
2254
2255 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
2256 return mTmpFindTaskResult.mRecord;
2257 }
2258
2259 /**
2260 * Finish the topmost activities in all stacks that belong to the crashed app.
2261 * @param app The app that crashed.
2262 * @param reason Reason to perform this action.
2263 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
2264 */
2265 int finishTopCrashedActivities(WindowProcessController app, String reason) {
2266 Task finishedTask = null;
2267 ActivityStack focusedStack = getTopDisplayFocusedStack();
2268 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2269 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002270 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2271 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2272 // It is possible that request to finish activity might also remove its task and
2273 // stack, so we need to be careful with indexes in the loop and check child count
2274 // every time.
Andrii Kulian5bb053b2020-04-08 17:04:33 -07002275 for (int stackNdx = 0; stackNdx < taskDisplayArea.getStackCount(); ++stackNdx) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002276 final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx);
2277 final Task t = stack.finishTopCrashedActivityLocked(app, reason);
2278 if (stack == focusedStack || finishedTask == null) {
2279 finishedTask = t;
2280 }
Louis Chang149d5c82019-12-30 09:47:39 +08002281 }
2282 }
2283 }
2284 return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
2285 }
2286
2287 boolean resumeFocusedStacksTopActivities() {
2288 return resumeFocusedStacksTopActivities(null, null, null);
2289 }
2290
2291 boolean resumeFocusedStacksTopActivities(
2292 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
2293
2294 if (!mStackSupervisor.readyToResume()) {
2295 return false;
2296 }
2297
2298 boolean result = false;
Andrii Kulian86d676c2020-03-27 19:34:54 -07002299 if (targetStack != null && (targetStack.isTopStackInDisplayArea()
Louis Chang149d5c82019-12-30 09:47:39 +08002300 || getTopDisplayFocusedStack() == targetStack)) {
2301 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
2302 }
2303
2304 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2305 boolean resumedOnDisplay = false;
2306 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002307 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2308 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2309 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2310 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2311 final ActivityRecord topRunningActivity = stack.topRunningActivity();
2312 if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
2313 continue;
2314 }
2315 if (stack == targetStack) {
2316 // Simply update the result for targetStack because the targetStack had
2317 // already resumed in above. We don't want to resume it again, especially in
2318 // some cases, it would cause a second launch failure if app process was
2319 // dead.
2320 resumedOnDisplay |= result;
2321 continue;
2322 }
2323 if (taskDisplayArea.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
2324 // Kick off any lingering app transitions form the MoveTaskToFront
2325 // operation, but only consider the top task and stack on that display.
2326 stack.executeAppTransition(targetOptions);
2327 } else {
2328 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
2329 }
Louis Chang149d5c82019-12-30 09:47:39 +08002330 }
2331 }
2332 if (!resumedOnDisplay) {
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 stack explicitly will make sure that at least home
2336 // activity is started and resumed, and no recursion occurs.
2337 final ActivityStack focusedStack = display.getFocusedStack();
2338 if (focusedStack != null) {
2339 result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Riddle Hsu7baffbb2020-03-05 22:48:24 +08002340 } else if (targetStack == null) {
2341 result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002342 display.getDefaultTaskDisplayArea());
Louis Chang149d5c82019-12-30 09:47:39 +08002343 }
2344 }
2345 }
2346
2347 return result;
2348 }
2349
2350 void applySleepTokens(boolean applyToStacks) {
2351 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2352 // Set the sleeping state of the display.
2353 final DisplayContent display = getChildAt(displayNdx);
2354 final boolean displayShouldSleep = display.shouldSleep();
2355 if (displayShouldSleep == display.isSleeping()) {
2356 continue;
2357 }
2358 display.setIsSleeping(displayShouldSleep);
2359
2360 if (!applyToStacks) {
2361 continue;
2362 }
2363
2364 // Set the sleeping state of the stacks on the display.
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002365 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2366 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2367 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2368 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2369 if (displayShouldSleep) {
2370 stack.goToSleepIfPossible(false /* shuttingDown */);
2371 } else {
2372 // When the display which can only contain one task turns on, start a
2373 // special transition.
2374 // {@link AppTransitionController#handleAppTransitionReady} later picks up
2375 // the transition, and schedules
2376 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
2377 // triggered after contents are drawn on the display.
2378 if (display.isSingleTaskInstance()) {
2379 display.mDisplayContent.prepareAppTransition(
2380 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
2381 }
2382 stack.awakeFromSleepingLocked();
2383 if (display.isSingleTaskInstance()) {
2384 display.executeAppTransition();
2385 }
2386 if (stack.isFocusedStackOnDisplay()
2387 && !mStackSupervisor.getKeyguardController()
2388 .isKeyguardOrAodShowing(display.mDisplayId)) {
2389 // If the keyguard is unlocked - resume immediately.
2390 // It is possible that the display will not be awake at the time we
2391 // process the keyguard going away, which can happen before the sleep
2392 // token is released. As a result, it is important we resume the
2393 // activity here.
2394 resumeFocusedStacksTopActivities();
2395 }
Louis Chang149d5c82019-12-30 09:47:39 +08002396 }
2397 }
2398 }
Louis Chang149d5c82019-12-30 09:47:39 +08002399 }
2400 }
2401
2402 protected ActivityStack getStack(int stackId) {
2403 for (int i = getChildCount() - 1; i >= 0; --i) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002404 final ActivityStack stack = getChildAt(i).getStack(stackId);
Louis Chang149d5c82019-12-30 09:47:39 +08002405 if (stack != null) {
2406 return stack;
2407 }
2408 }
2409 return null;
2410 }
2411
2412 /** @see DisplayContent#getStack(int, int) */
2413 ActivityStack getStack(int windowingMode, int activityType) {
2414 for (int i = getChildCount() - 1; i >= 0; --i) {
2415 final ActivityStack stack = getChildAt(i).getStack(windowingMode, activityType);
2416 if (stack != null) {
2417 return stack;
2418 }
2419 }
2420 return null;
2421 }
2422
2423 private ActivityStack getStack(int windowingMode, int activityType,
2424 int displayId) {
2425 DisplayContent display = getDisplayContent(displayId);
2426 if (display == null) {
2427 return null;
2428 }
2429 return display.getStack(windowingMode, activityType);
2430 }
2431
2432 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002433 final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08002434 ActivityManager.StackInfo info = new ActivityManager.StackInfo();
2435 stack.getBounds(info.bounds);
Andrii Kulian86d676c2020-03-27 19:34:54 -07002436 info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY;
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002437 info.stackId = stack.mTaskId;
Wale Ogunwaleadf116e2020-03-27 16:36:01 -07002438 info.stackToken = stack.mRemoteToken.toWindowContainerToken();
Louis Chang149d5c82019-12-30 09:47:39 +08002439 info.userId = stack.mCurrentUser;
2440 info.visible = stack.shouldBeVisible(null);
2441 // A stack might be not attached to a display.
Wale Ogunwale0db64ac2020-04-11 10:00:42 -07002442 // TODO: Can be removed since no one is using it.
Andrii Kulian86d676c2020-03-27 19:34:54 -07002443 info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(stack) : 0;
Louis Chang149d5c82019-12-30 09:47:39 +08002444 info.configuration.setTo(stack.getConfiguration());
2445
Wale Ogunwale8f93b642019-12-26 12:10:52 -08002446 final int numTasks = stack.getDescendantTaskCount();
Louis Chang149d5c82019-12-30 09:47:39 +08002447 info.taskIds = new int[numTasks];
2448 info.taskNames = new String[numTasks];
2449 info.taskBounds = new Rect[numTasks];
2450 info.taskUserIds = new int[numTasks];
Wale Ogunwale8f93b642019-12-26 12:10:52 -08002451 final int[] currentIndex = {0};
Louis Chang149d5c82019-12-30 09:47:39 +08002452
2453 final PooledConsumer c = PooledLambda.obtainConsumer(
2454 RootWindowContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
Wale Ogunwale8f93b642019-12-26 12:10:52 -08002455 currentIndex);
Wale Ogunwale0d465192020-01-23 19:14:44 -08002456 stack.forAllLeafTasks(c, false /* traverseTopToBottom */);
Louis Chang149d5c82019-12-30 09:47:39 +08002457 c.recycle();
2458
2459 final ActivityRecord top = stack.topRunningActivity();
2460 info.topActivity = top != null ? top.intent.getComponent() : null;
2461 return info;
2462 }
2463
2464 private static void processTaskForStackInfo(
2465 Task task, ActivityManager.StackInfo info, int[] currentIndex) {
2466 int i = currentIndex[0];
2467 info.taskIds[i] = task.mTaskId;
2468 info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2469 : task.realActivity != null ? task.realActivity.flattenToString()
2470 : task.getTopNonFinishingActivity() != null
2471 ? task.getTopNonFinishingActivity().packageName : "unknown";
2472 info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
2473 info.taskUserIds[i] = task.mUserId;
2474 currentIndex[0] = ++i;
2475 }
2476
2477 ActivityManager.StackInfo getStackInfo(int stackId) {
2478 ActivityStack stack = getStack(stackId);
2479 if (stack != null) {
2480 return getStackInfo(stack);
2481 }
2482 return null;
2483 }
2484
2485 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
2486 final ActivityStack stack = getStack(windowingMode, activityType);
2487 return (stack != null) ? getStackInfo(stack) : null;
2488 }
2489
2490 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) {
2491 final ActivityStack stack = getStack(windowingMode, activityType, displayId);
2492 return (stack != null) ? getStackInfo(stack) : null;
2493 }
2494
2495 /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */
2496 ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) {
2497 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
2498 if (displayId == INVALID_DISPLAY) {
2499 for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
2500 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002501 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2502 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2503 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2504 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2505 list.add(getStackInfo(stack));
2506 }
Louis Chang149d5c82019-12-30 09:47:39 +08002507 }
2508 }
2509 return list;
2510 }
2511 final DisplayContent display = getDisplayContent(displayId);
2512 if (display == null) {
2513 return list;
2514 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002515 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2516 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2517 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2518 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2519 list.add(getStackInfo(stack));
2520 }
Louis Chang149d5c82019-12-30 09:47:39 +08002521 }
2522 return list;
2523 }
2524
Louis Chang149d5c82019-12-30 09:47:39 +08002525 @Override
2526 public void onDisplayAdded(int displayId) {
2527 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
2528 synchronized (mService.mGlobalLock) {
2529 final DisplayContent display = getDisplayContentOrCreate(displayId);
2530 if (display == null) {
2531 return;
2532 }
2533 // Do not start home before booting, or it may accidentally finish booting before it
2534 // starts. Instead, we expect home activities to be launched when the system is ready
2535 // (ActivityManagerService#systemReady).
2536 if (mService.isBooted() || mService.isBooting()) {
2537 startSystemDecorations(display.mDisplayContent);
2538 }
2539 }
2540 }
2541
2542 private void startSystemDecorations(final DisplayContent displayContent) {
2543 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
2544 displayContent.getDisplayPolicy().notifyDisplayReady();
2545 }
2546
2547 @Override
2548 public void onDisplayRemoved(int displayId) {
2549 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
2550 if (displayId == DEFAULT_DISPLAY) {
2551 throw new IllegalArgumentException("Can't remove the primary display.");
2552 }
2553
2554 synchronized (mService.mGlobalLock) {
2555 final DisplayContent displayContent = getDisplayContent(displayId);
2556 if (displayContent == null) {
2557 return;
2558 }
2559
2560 displayContent.remove();
2561 }
2562 }
2563
2564 @Override
2565 public void onDisplayChanged(int displayId) {
2566 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
2567 synchronized (mService.mGlobalLock) {
2568 final DisplayContent displayContent = getDisplayContent(displayId);
2569 if (displayContent != null) {
2570 displayContent.onDisplayChanged();
2571 }
2572 }
2573 }
2574
2575 /** Update lists of UIDs that are present on displays and have access to them. */
2576 void updateUIDsPresentOnDisplay() {
2577 mDisplayAccessUIDs.clear();
2578 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2579 final DisplayContent displayContent = getChildAt(displayNdx);
2580 // Only bother calculating the whitelist for private displays
2581 if (displayContent.isPrivate()) {
2582 mDisplayAccessUIDs.append(
2583 displayContent.mDisplayId, displayContent.getPresentUIDs());
2584 }
2585 }
2586 // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
2587 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
2588 }
2589
2590 ActivityStack findStackBehind(ActivityStack stack) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002591 final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
2592 if (taskDisplayArea != null) {
2593 for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; i--) {
2594 if (taskDisplayArea.getStackAt(i) == stack && i > 0) {
2595 return taskDisplayArea.getStackAt(i - 1);
Louis Chang149d5c82019-12-30 09:47:39 +08002596 }
2597 }
2598 }
2599 throw new IllegalStateException("Failed to find a stack behind stack=" + stack
Andrii Kulian86d676c2020-03-27 19:34:54 -07002600 + " in=" + taskDisplayArea);
Louis Chang149d5c82019-12-30 09:47:39 +08002601 }
2602
2603 @Override
2604 void positionChildAt(int position, DisplayContent child, boolean includingParents) {
2605 super.positionChildAt(position, child, includingParents);
2606 mStackSupervisor.updateTopResumedActivityIfNeeded();
2607 }
2608
2609 Configuration getDisplayOverrideConfiguration(int displayId) {
2610 final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
2611 if (displayContent == null) {
2612 throw new IllegalArgumentException("No display found with id: " + displayId);
2613 }
2614
2615 return displayContent.getRequestedOverrideConfiguration();
2616 }
2617
2618 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
2619 final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
2620 if (displayContent == null) {
2621 throw new IllegalArgumentException("No display found with id: " + displayId);
2622 }
2623
2624 displayContent.onRequestedOverrideConfigurationChanged(overrideConfiguration);
2625 }
2626
2627 void prepareForShutdown() {
2628 for (int i = 0; i < getChildCount(); i++) {
2629 createSleepToken("shutdown", getChildAt(i).mDisplayId);
2630 }
2631 }
2632
2633 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
2634 final DisplayContent display = getDisplayContent(displayId);
2635 if (display == null) {
2636 throw new IllegalArgumentException("Invalid display: " + displayId);
2637 }
2638
2639 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
2640 mSleepTokens.add(token);
2641 display.mAllSleepTokens.add(token);
2642 return token;
2643 }
2644
2645 private void removeSleepToken(SleepTokenImpl token) {
2646 mSleepTokens.remove(token);
2647
2648 final DisplayContent display = getDisplayContent(token.mDisplayId);
2649 if (display != null) {
2650 display.mAllSleepTokens.remove(token);
2651 if (display.mAllSleepTokens.isEmpty()) {
2652 mService.updateSleepIfNeededLocked();
2653 }
2654 }
2655 }
2656
2657 void addStartingWindowsForVisibleActivities() {
2658 forAllActivities((r) -> {
2659 if (r.mVisibleRequested) {
2660 r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/);
2661 }
2662 });
2663 }
2664
2665 void invalidateTaskLayers() {
2666 mTaskLayersChanged = true;
2667 }
2668
2669 void rankTaskLayersIfNeeded() {
2670 if (!mTaskLayersChanged) {
2671 return;
2672 }
2673 mTaskLayersChanged = false;
2674 mTmpTaskLayerRank = 0;
2675 final PooledConsumer c = PooledLambda.obtainConsumer(
2676 RootWindowContainer::rankTaskLayerForActivity, this,
2677 PooledLambda.__(ActivityRecord.class));
2678 forAllActivities(c);
2679 c.recycle();
2680 }
2681
2682 private void rankTaskLayerForActivity(ActivityRecord r) {
2683 if (r.canBeTopRunning() && r.mVisibleRequested) {
2684 r.getTask().mLayerRank = ++mTmpTaskLayerRank;
2685 } else {
2686 r.getTask().mLayerRank = -1;
2687 }
2688 }
2689
2690 void clearOtherAppTimeTrackers(AppTimeTracker except) {
2691 final PooledConsumer c = PooledLambda.obtainConsumer(
2692 RootWindowContainer::clearOtherAppTimeTrackers,
2693 PooledLambda.__(ActivityRecord.class), except);
2694 forAllActivities(c);
2695 c.recycle();
2696 }
2697
2698 private static void clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except) {
2699 if (r.appTimeTracker != except) {
2700 r.appTimeTracker = null;
2701 }
2702 }
2703
2704 void scheduleDestroyAllActivities(String reason) {
2705 mDestroyAllActivitiesReason = reason;
2706 mService.mH.post(mDestroyAllActivitiesRunnable);
2707 }
2708
2709 private void destroyActivity(ActivityRecord r) {
2710 if (r.finishing || !r.isDestroyable()) return;
2711
2712 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState()
2713 + " resumed=" + r.getStack().mResumedActivity + " pausing="
2714 + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason);
2715
2716 r.destroyImmediately(true /* removeFromTask */, mDestroyAllActivitiesReason);
2717 }
2718
2719 // Tries to put all activity stacks to sleep. Returns true if all stacks were
2720 // successfully put to sleep.
2721 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
2722 boolean allSleep = true;
2723 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2724 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002725 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2726 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2727 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2728 // Stacks and activities could be removed while putting activities to sleep if
2729 // the app process was gone. This prevents us getting exception by accessing an
2730 // invalid stack index.
2731 if (sNdx >= taskDisplayArea.getStackCount()) {
2732 continue;
2733 }
2734 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2735 if (allowDelay) {
2736 allSleep &= stack.goToSleepIfPossible(shuttingDown);
2737 } else {
2738 stack.goToSleep();
2739 }
Louis Chang149d5c82019-12-30 09:47:39 +08002740 }
2741 }
2742 }
2743 return allSleep;
2744 }
2745
2746 void handleAppCrash(WindowProcessController app) {
2747 final PooledConsumer c = PooledLambda.obtainConsumer(
2748 RootWindowContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app);
2749 forAllActivities(c);
2750 c.recycle();
2751 }
2752
2753 private static void handleAppCrash(ActivityRecord r, WindowProcessController app) {
2754 if (r.app != app) return;
2755 Slog.w(TAG, " Force finishing activity "
2756 + r.intent.getComponent().flattenToShortString());
2757 r.app = null;
2758 r.getDisplay().mDisplayContent.prepareAppTransition(
2759 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
2760 r.destroyIfPossible("handleAppCrashed");
2761 }
2762
2763 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
2764 ComponentName cls = intent.getComponent();
2765 if (info.targetActivity != null) {
2766 cls = new ComponentName(info.packageName, info.targetActivity);
2767 }
2768 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
2769
2770 final PooledPredicate p = PooledLambda.obtainPredicate(
2771 RootWindowContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
2772 userId, compareIntentFilters, intent, cls);
2773 final ActivityRecord r = getActivity(p);
2774 p.recycle();
2775 return r;
2776 }
2777
2778 private static boolean matchesActivity(ActivityRecord r, int userId,
2779 boolean compareIntentFilters, Intent intent, ComponentName cls) {
2780 if (!r.canBeTopRunning() || r.mUserId != userId) return false;
2781
2782 if (compareIntentFilters) {
2783 if (r.intent.filterEquals(intent)) {
2784 return true;
2785 }
2786 } else {
Riddle Hsu8be3b9f2020-03-13 18:47:17 +08002787 // Compare the target component instead of intent component so we don't miss if the
2788 // activity uses alias.
2789 if (r.mActivityComponent.equals(cls)) {
Louis Chang149d5c82019-12-30 09:47:39 +08002790 return true;
2791 }
2792 }
2793 return false;
2794 }
2795
2796 boolean hasAwakeDisplay() {
2797 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2798 final DisplayContent display = getChildAt(displayNdx);
2799 if (!display.shouldSleep()) {
2800 return true;
2801 }
2802 }
2803 return false;
2804 }
2805
2806 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
2807 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
2808 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
2809 -1 /* no realCallingPid */, -1 /* no realCallingUid */);
2810 }
2811
2812 /**
2813 * Returns the right stack to use for launching factoring in all the input parameters.
2814 *
2815 * @param r The activity we are trying to launch. Can be null.
2816 * @param options The activity options used to the launch. Can be null.
2817 * @param candidateTask The possible task the activity might be launched in. Can be null.
2818 * @param launchParams The resolved launch params to use.
2819 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
2820 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
2821 *
2822 * @return The stack to use for the launch or INVALID_STACK_ID.
2823 */
2824 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
2825 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
2826 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
2827 int realCallingUid) {
2828 int taskId = INVALID_TASK_ID;
2829 int displayId = INVALID_DISPLAY;
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002830 TaskDisplayArea taskDisplayArea = null;
Louis Chang149d5c82019-12-30 09:47:39 +08002831
2832 // We give preference to the launch preference in activity options.
2833 if (options != null) {
2834 taskId = options.getLaunchTaskId();
2835 displayId = options.getLaunchDisplayId();
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002836 final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
2837 taskDisplayArea = daToken != null
2838 ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;
Louis Chang149d5c82019-12-30 09:47:39 +08002839 }
2840
2841 // First preference for stack goes to the task Id set in the activity options. Use the stack
2842 // associated with that if possible.
2843 if (taskId != INVALID_TASK_ID) {
2844 // Temporarily set the task id to invalid in case in re-entry.
2845 options.setLaunchTaskId(INVALID_TASK_ID);
2846 final Task task = anyTaskForId(taskId,
2847 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
2848 options.setLaunchTaskId(taskId);
2849 if (task != null) {
2850 return task.getStack();
2851 }
2852 }
2853
2854 final int activityType = resolveActivityType(r, options, candidateTask);
Louis Chang38430df2020-01-02 17:14:59 +08002855 ActivityStack stack = null;
Louis Chang149d5c82019-12-30 09:47:39 +08002856
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002857 // Next preference for stack goes to the taskDisplayArea candidate.
2858 if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
2859 taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
Louis Chang149d5c82019-12-30 09:47:39 +08002860 }
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002861
2862 if (taskDisplayArea == null && displayId != INVALID_DISPLAY) {
2863 final DisplayContent displayContent = getDisplayContent(displayId);
2864 if (displayContent != null) {
2865 taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08002866 }
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002867 }
2868
2869 if (taskDisplayArea != null) {
2870 final int tdaDisplayId = taskDisplayArea.getDisplayId();
2871 final boolean canLaunchOnDisplayFromStartRequest =
2872 realCallingPid != 0 && realCallingUid > 0 && r != null
2873 && mStackSupervisor.canPlaceEntityOnDisplay(tdaDisplayId,
2874 realCallingPid, realCallingUid, r.info);
2875 if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) {
2876 if (r != null) {
2877 final ActivityStack result = getValidLaunchStackInTaskDisplayArea(
2878 taskDisplayArea, r, candidateTask, options, launchParams);
2879 if (result != null) {
2880 return result;
2881 }
2882 }
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002883 // Falling back to default task container
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002884 taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002885 stack = taskDisplayArea.getOrCreateStack(r, options, candidateTask, activityType,
2886 onTop);
Louis Chang149d5c82019-12-30 09:47:39 +08002887 if (stack != null) {
2888 return stack;
2889 }
2890 }
2891 }
2892
2893 // Give preference to the stack and display of the input task and activity if they match the
2894 // mode we want to launch into.
Andrii Kulian86d676c2020-03-27 19:34:54 -07002895 TaskDisplayArea container = null;
Louis Chang149d5c82019-12-30 09:47:39 +08002896 if (candidateTask != null) {
2897 stack = candidateTask.getStack();
2898 }
2899 if (stack == null && r != null) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002900 stack = r.getRootTask();
Louis Chang149d5c82019-12-30 09:47:39 +08002901 }
Louis Changa009c762020-02-26 11:21:31 +08002902 int windowingMode = launchParams != null ? launchParams.mWindowingMode
2903 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Louis Chang149d5c82019-12-30 09:47:39 +08002904 if (stack != null) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002905 container = stack.getDisplayArea();
2906 if (container != null && canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
Louis Chang149d5c82019-12-30 09:47:39 +08002907 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002908 windowingMode = container.resolveWindowingMode(r, options, candidateTask,
2909 activityType);
Louis Chang149d5c82019-12-30 09:47:39 +08002910 }
Louis Changa009c762020-02-26 11:21:31 +08002911 // Always allow organized tasks that created by organizer since the activity type
2912 // of an organized task is decided by the activity type of its top child, which
2913 // could be incompatible with the given windowing mode and activity type.
2914 if (stack.isCompatible(windowingMode, activityType) || stack.mCreatedByOrganizer) {
Louis Chang149d5c82019-12-30 09:47:39 +08002915 return stack;
2916 }
2917 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
Andrii Kulian86d676c2020-03-27 19:34:54 -07002918 && container.getRootSplitScreenPrimaryTask() == stack
Louis Chang149d5c82019-12-30 09:47:39 +08002919 && candidateTask == stack.getTopMostTask()) {
2920 // This is a special case when we try to launch an activity that is currently on
2921 // top of split-screen primary stack, but is targeting split-screen secondary.
2922 // In this case we don't want to move it to another stack.
2923 // TODO(b/78788972): Remove after differentiating between preferred and required
2924 // launch options.
2925 return stack;
2926 }
2927 }
2928 }
2929
Andrii Kulian86d676c2020-03-27 19:34:54 -07002930 if (container == null
2931 || !canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002932 container = getDefaultTaskDisplayArea();
Louis Changa009c762020-02-26 11:21:31 +08002933 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002934 windowingMode = container.resolveWindowingMode(r, options, candidateTask,
2935 activityType);
Louis Changa009c762020-02-26 11:21:31 +08002936 }
Louis Chang149d5c82019-12-30 09:47:39 +08002937 }
2938
Andrii Kulian86d676c2020-03-27 19:34:54 -07002939 return container.getOrCreateStack(r, options, candidateTask, activityType, onTop);
Louis Chang149d5c82019-12-30 09:47:39 +08002940 }
2941
2942 /** @return true if activity record is null or can be launched on provided display. */
2943 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
2944 if (r == null) {
2945 return true;
2946 }
2947 return r.canBeLaunchedOnDisplay(displayId);
2948 }
2949
2950 /**
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002951 * Get a topmost stack on the display area, that is a valid launch stack for specified activity.
Louis Chang149d5c82019-12-30 09:47:39 +08002952 * If there is no such stack, new dynamic stack can be created.
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002953 * @param taskDisplayArea Target display area.
Louis Chang149d5c82019-12-30 09:47:39 +08002954 * @param r Activity that should be launched there.
2955 * @param candidateTask The possible task the activity might be put in.
2956 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
2957 */
Louis Changdd63da52020-03-24 14:49:49 +08002958 @VisibleForTesting
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002959 ActivityStack getValidLaunchStackInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea,
2960 @NonNull ActivityRecord r, @Nullable Task candidateTask,
2961 @Nullable ActivityOptions options,
Louis Chang149d5c82019-12-30 09:47:39 +08002962 @Nullable LaunchParamsController.LaunchParams launchParams) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002963 if (!r.canBeLaunchedOnDisplay(taskDisplayArea.getDisplayId())) {
Louis Chang149d5c82019-12-30 09:47:39 +08002964 return null;
2965 }
2966
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002967 // If {@code r} is already in target display area and its task is the same as the candidate
2968 // task, the intention should be getting a launch stack for the reusable activity, so we can
2969 // use the existing stack.
Louis Chang149d5c82019-12-30 09:47:39 +08002970 if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002971 // TODO(b/153920825): Fix incorrect evaluation of attached state
2972 final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null
2973 ? r.getTask().getDisplayArea() : r.getDisplayArea();
2974 if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08002975 return candidateTask.getStack();
2976 }
Louis Changdd63da52020-03-24 14:49:49 +08002977 // Or the candidate task is already a root task that can be reused by reparenting
2978 // it to the target display.
2979 if (candidateTask.isRootTask()) {
2980 final ActivityStack stack = candidateTask.getStack();
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002981 stack.reparent(taskDisplayArea, true /* onTop */);
Louis Changdd63da52020-03-24 14:49:49 +08002982 return stack;
2983 }
Louis Chang149d5c82019-12-30 09:47:39 +08002984 }
2985
2986 int windowingMode;
2987 if (launchParams != null) {
2988 // When launch params is not null, we always defer to its windowing mode. Sometimes
2989 // it could be unspecified, which indicates it should inherit windowing mode from
2990 // display.
2991 windowingMode = launchParams.mWindowingMode;
2992 } else {
2993 windowingMode = options != null ? options.getLaunchWindowingMode()
2994 : r.getWindowingMode();
2995 }
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002996 windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask,
2997 r.getActivityType());
Louis Chang149d5c82019-12-30 09:47:39 +08002998
2999 // Return the topmost valid stack on the display.
Andrii Kulian1cfcae82020-04-10 12:44:38 -07003000 for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; --i) {
3001 final ActivityStack stack = taskDisplayArea.getStackAt(i);
3002 if (isValidLaunchStack(stack, r, windowingMode)) {
3003 return stack;
Louis Chang149d5c82019-12-30 09:47:39 +08003004 }
3005 }
3006
Andrii Kulian1cfcae82020-04-10 12:44:38 -07003007 // If there is no valid stack on the secondary display area - check if new dynamic stack
3008 // will do.
3009 if (taskDisplayArea != getDisplayContent(taskDisplayArea.getDisplayId())
3010 .getDefaultTaskDisplayArea()) {
Louis Chang149d5c82019-12-30 09:47:39 +08003011 final int activityType =
3012 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
3013 ? options.getLaunchActivityType() : r.getActivityType();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07003014 return taskDisplayArea.createStack(windowingMode, activityType, true /*onTop*/);
Louis Chang149d5c82019-12-30 09:47:39 +08003015 }
3016
3017 return null;
3018 }
3019
Louis Chang149d5c82019-12-30 09:47:39 +08003020 // TODO: Can probably be consolidated into getLaunchStack()...
3021 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
3022 switch (stack.getActivityType()) {
3023 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
3024 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
3025 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
Galia Peycheva45f48d32020-02-20 15:39:10 +01003026 case ACTIVITY_TYPE_DREAM: return r.isActivityTypeDream();
Louis Chang149d5c82019-12-30 09:47:39 +08003027 }
Louis Changa009c762020-02-26 11:21:31 +08003028 if (stack.mCreatedByOrganizer) {
3029 // Don't launch directly into task created by organizer...but why can't we?
Evan Rosky0037e5f2019-11-05 10:26:24 -08003030 return false;
3031 }
Louis Chang149d5c82019-12-30 09:47:39 +08003032 // There is a 1-to-1 relationship between stack and task when not in
3033 // primary split-windowing mode.
3034 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
3035 && r.supportsSplitScreenWindowingMode()
3036 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
3037 || windowingMode == WINDOWING_MODE_UNDEFINED)) {
3038 return true;
3039 }
3040 return false;
3041 }
3042
3043 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
3044 @Nullable Task task) {
3045 // Preference is given to the activity type for the activity then the task since the type
3046 // once set shouldn't change.
3047 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
3048 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
3049 activityType = task.getActivityType();
3050 }
3051 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
3052 return activityType;
3053 }
3054 if (options != null) {
3055 activityType = options.getLaunchActivityType();
3056 }
3057 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
3058 }
3059
3060 /**
3061 * Get next focusable stack in the system. This will search through the stack on the same
3062 * display as the current focused stack, looking for a focusable and visible stack, different
3063 * from the target stack. If no valid candidates will be found, it will then go through all
3064 * displays and stacks in last-focused order.
3065 *
3066 * @param currentFocus The stack that previously had focus.
3067 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
3068 * candidate.
3069 * @return Next focusable {@link ActivityStack}, {@code null} if not found.
3070 */
3071 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
3072 boolean ignoreCurrent) {
3073 // First look for next focusable stack on the same display
Andrii Kulian86d676c2020-03-27 19:34:54 -07003074 TaskDisplayArea preferredDisplayArea = currentFocus.getDisplayArea();
3075 if (preferredDisplayArea == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08003076 // Stack is currently detached because it is being removed. Use the previous display it
3077 // was on.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07003078 preferredDisplayArea = getDisplayContent(currentFocus.mPrevDisplayId)
3079 .getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08003080 }
Andrii Kulian86d676c2020-03-27 19:34:54 -07003081 final ActivityStack preferredFocusableStack = preferredDisplayArea.getNextFocusableStack(
3082 currentFocus, ignoreCurrent);
Louis Chang149d5c82019-12-30 09:47:39 +08003083 if (preferredFocusableStack != null) {
3084 return preferredFocusableStack;
3085 }
Andrii Kulian86d676c2020-03-27 19:34:54 -07003086 if (preferredDisplayArea.mDisplayContent.supportsSystemDecorations()) {
Louis Chang149d5c82019-12-30 09:47:39 +08003087 // Stop looking for focusable stack on other displays because the preferred display
3088 // supports system decorations. Home activity would be launched on the same display if
3089 // no focusable stack found.
3090 return null;
3091 }
3092
3093 // Now look through all displays
3094 for (int i = getChildCount() - 1; i >= 0; --i) {
3095 final DisplayContent display = getChildAt(i);
Andrii Kulian86d676c2020-03-27 19:34:54 -07003096 if (display == preferredDisplayArea.mDisplayContent) {
Louis Chang149d5c82019-12-30 09:47:39 +08003097 // We've already checked this one
3098 continue;
3099 }
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07003100 final ActivityStack nextFocusableStack = display.getDefaultTaskDisplayArea()
Andrii Kulian9ea12da2020-03-27 17:16:38 -07003101 .getNextFocusableStack(currentFocus, ignoreCurrent);
Louis Chang149d5c82019-12-30 09:47:39 +08003102 if (nextFocusableStack != null) {
3103 return nextFocusableStack;
3104 }
3105 }
3106
3107 return null;
3108 }
3109
Louis Chang149d5c82019-12-30 09:47:39 +08003110 boolean handleAppDied(WindowProcessController app) {
3111 boolean hasVisibleActivities = false;
3112 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3113 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003114 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3115 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3116 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3117 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3118 hasVisibleActivities |= stack.handleAppDied(app);
3119 }
Louis Chang149d5c82019-12-30 09:47:39 +08003120 }
3121 }
3122 return hasVisibleActivities;
3123 }
3124
Galia Peycheva72d581e2020-06-12 10:06:40 +02003125 void closeSystemDialogActivities(String reason) {
Louis Chang149d5c82019-12-30 09:47:39 +08003126 forAllActivities((r) -> {
Galia Peycheva72d581e2020-06-12 10:06:40 +02003127 if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0
3128 || shouldCloseAssistant(r, reason)) {
3129 r.finishIfPossible(reason, true /* oomAdj */);
Louis Chang149d5c82019-12-30 09:47:39 +08003130 }
3131 });
3132 }
3133
Galia Peycheva72d581e2020-06-12 10:06:40 +02003134 private boolean shouldCloseAssistant(ActivityRecord r, String reason) {
3135 if (!r.isActivityTypeAssistant()) return false;
3136 if (reason == SYSTEM_DIALOG_REASON_ASSIST) return false;
3137 // When the assistant is configured to be on top of the dream, it will have higher z-order
3138 // than other activities. If it is also opaque, it will prevent other activities from
3139 // starting. We want to close the assistant on closeSystemDialogs to allow other activities
3140 // to start, e.g. on home button press.
3141 return mWmService.mAssistantOnTopOfDream;
3142 }
3143
Louis Chang149d5c82019-12-30 09:47:39 +08003144 FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
3145 new FinishDisabledPackageActivitiesHelper();
3146 class FinishDisabledPackageActivitiesHelper {
3147 private boolean mDidSomething;
3148 private String mPackageName;
3149 private Set<String> mFilterByClasses;
3150 private boolean mDoit;
3151 private boolean mEvenPersistent;
3152 private int mUserId;
3153 private Task mLastTask;
3154 private ComponentName mHomeActivity;
3155
3156 private void reset(String packageName, Set<String> filterByClasses,
3157 boolean doit, boolean evenPersistent, int userId) {
3158 mDidSomething = false;
3159 mPackageName = packageName;
3160 mFilterByClasses = filterByClasses;
3161 mDoit = doit;
3162 mEvenPersistent = evenPersistent;
3163 mUserId = userId;
3164 mLastTask = null;
3165 mHomeActivity = null;
3166 }
3167
3168 boolean process(String packageName, Set<String> filterByClasses,
3169 boolean doit, boolean evenPersistent, int userId) {
3170 reset(packageName, filterByClasses, doit, evenPersistent, userId);
3171
3172 final PooledFunction f = PooledLambda.obtainFunction(
3173 FinishDisabledPackageActivitiesHelper::processActivity, this,
3174 PooledLambda.__(ActivityRecord.class));
3175 forAllActivities(f);
3176 f.recycle();
3177 return mDidSomething;
3178 }
3179
3180 private boolean processActivity(ActivityRecord r) {
3181 final boolean sameComponent =
3182 (r.packageName.equals(mPackageName) && (mFilterByClasses == null
3183 || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
3184 || (mPackageName == null && r.mUserId == mUserId);
3185 if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
3186 && (sameComponent || r.getTask() == mLastTask)
3187 && (r.app == null || mEvenPersistent || !r.app.isPersistent())) {
3188 if (!mDoit) {
3189 if (r.finishing) {
3190 // If this activity is just finishing, then it is not
3191 // interesting as far as something to stop.
3192 return false;
3193 }
3194 return true;
3195 }
3196 if (r.isActivityTypeHome()) {
3197 if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) {
3198 Slog.i(TAG, "Skip force-stop again " + r);
3199 return false;
3200 } else {
3201 mHomeActivity = r.mActivityComponent;
3202 }
3203 }
3204 mDidSomething = true;
3205 Slog.i(TAG, " Force finishing activity " + r);
3206 mLastTask = r.getTask();
3207 r.finishIfPossible("force-stop", true);
3208 }
3209
3210 return false;
3211 }
3212 }
3213
3214 /** @return true if some activity was finished (or would have finished if doit were true). */
3215 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
3216 boolean doit, boolean evenPersistent, int userId) {
3217 return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
3218 evenPersistent, userId);
3219 }
3220
3221 void updateActivityApplicationInfo(ApplicationInfo aInfo) {
3222 final String packageName = aInfo.packageName;
3223 final int userId = UserHandle.getUserId(aInfo.uid);
3224 final PooledConsumer c = PooledLambda.obtainConsumer(
3225 RootWindowContainer::updateActivityApplicationInfo,
3226 PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName);
3227 forAllActivities(c);
3228 c.recycle();
3229 }
3230
3231 private static void updateActivityApplicationInfo(
3232 ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName) {
3233 if (r.mUserId == userId && packageName.equals(r.packageName)) {
3234 r.updateApplicationInfo(aInfo);
3235 }
3236 }
3237
3238 void finishVoiceTask(IVoiceInteractionSession session) {
3239 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3240 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003241 int numTaskContainers = display.getTaskDisplayAreaCount();
3242 for (int tdaNdx = 0; tdaNdx < numTaskContainers; tdaNdx++) {
3243 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3244 final int numStacks = display.getStackCount();
3245 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
3246 final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx);
3247 stack.finishVoiceTask(session);
3248 }
Louis Chang149d5c82019-12-30 09:47:39 +08003249 }
3250 }
3251 }
3252
3253 /**
3254 * Removes stacks in the input windowing modes from the system if they are of activity type
3255 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
3256 */
3257 void removeStacksInWindowingModes(int... windowingModes) {
3258 for (int i = getChildCount() - 1; i >= 0; --i) {
3259 getChildAt(i).removeStacksInWindowingModes(windowingModes);
3260 }
3261 }
3262
3263 void removeStacksWithActivityTypes(int... activityTypes) {
3264 for (int i = getChildCount() - 1; i >= 0; --i) {
3265 getChildAt(i).removeStacksWithActivityTypes(activityTypes);
3266 }
3267 }
3268
3269 ActivityRecord topRunningActivity() {
3270 for (int i = getChildCount() - 1; i >= 0; --i) {
3271 final ActivityRecord topActivity = getChildAt(i).topRunningActivity();
3272 if (topActivity != null) {
3273 return topActivity;
3274 }
3275 }
3276 return null;
3277 }
3278
3279 boolean allResumedActivitiesIdle() {
3280 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3281 // TODO(b/117135575): Check resumed activities on all visible stacks.
3282 final DisplayContent display = getChildAt(displayNdx);
3283 if (display.isSleeping()) {
3284 // No resumed activities while display is sleeping.
3285 continue;
3286 }
3287
3288 // If the focused stack is not null or not empty, there should have some activities
3289 // resuming or resumed. Make sure these activities are idle.
3290 final ActivityStack stack = display.getFocusedStack();
3291 if (stack == null || !stack.hasActivity()) {
3292 continue;
3293 }
3294 final ActivityRecord resumedActivity = stack.getResumedActivity();
3295 if (resumedActivity == null || !resumedActivity.idle) {
3296 if (DEBUG_STATES) {
3297 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08003298 + stack.getRootTaskId() + " " + resumedActivity + " not idle");
Louis Chang149d5c82019-12-30 09:47:39 +08003299 }
3300 return false;
3301 }
3302 }
3303 // Send launch end powerhint when idle
3304 sendPowerHintForLaunchEndIfNeeded();
3305 return true;
3306 }
3307
3308 boolean allResumedActivitiesVisible() {
3309 boolean foundResumed = false;
3310 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3311 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003312 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3313 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3314 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3315 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3316 final ActivityRecord r = stack.getResumedActivity();
3317 if (r != null) {
3318 if (!r.nowVisible) {
3319 return false;
3320 }
3321 foundResumed = true;
Louis Chang149d5c82019-12-30 09:47:39 +08003322 }
Louis Chang149d5c82019-12-30 09:47:39 +08003323 }
3324 }
3325 }
3326 return foundResumed;
3327 }
3328
3329 boolean allPausedActivitiesComplete() {
3330 boolean pausing = true;
3331 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3332 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003333 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3334 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3335 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3336 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3337 final ActivityRecord r = stack.mPausingActivity;
Chris Li74f622a2020-04-19 18:57:35 -07003338 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003339 if (DEBUG_STATES) {
3340 Slog.d(TAG_STATES, "allPausedActivitiesComplete: r=" + r
3341 + " state=" + r.getState());
3342 pausing = false;
3343 } else {
3344 return false;
3345 }
Louis Chang149d5c82019-12-30 09:47:39 +08003346 }
3347 }
3348 }
3349 }
3350 return pausing;
3351 }
3352
3353 /**
3354 * Find all visible task stacks containing {@param userId} and intercept them with an activity
3355 * to block out the contents and possibly start a credential-confirming intent.
3356 *
3357 * @param userId user handle for the locked managed profile.
3358 */
3359 void lockAllProfileTasks(@UserIdInt int userId) {
3360 mService.deferWindowLayout();
3361 try {
3362 final PooledConsumer c = PooledLambda.obtainConsumer(
3363 RootWindowContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class),
3364 userId);
Wale Ogunwale0d465192020-01-23 19:14:44 -08003365 forAllLeafTasks(c, true /* traverseTopToBottom */);
Louis Chang149d5c82019-12-30 09:47:39 +08003366 c.recycle();
3367 } finally {
3368 mService.continueWindowLayout();
3369 }
3370 }
3371
3372 /**
3373 * Detects whether we should show a lock screen in front of this task for a locked user.
3374 * <p>
3375 * We'll do this if either of the following holds:
3376 * <ul>
3377 * <li>The top activity explicitly belongs to {@param userId}.</li>
3378 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
3379 * </ul>
3380 *
3381 * @return {@code true} if the top activity looks like it belongs to {@param userId}.
3382 */
3383 private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
3384 // To handle the case that work app is in the task but just is not the top one.
3385 final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
3386 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
3387
3388 // Check the task for a top activity belonging to userId, or returning a
3389 // result to an activity belonging to userId. Example case: a document
3390 // picker for personal files, opened by a work app, should still get locked.
3391 if ((activityRecord != null && activityRecord.mUserId == userId)
3392 || (resultTo != null && resultTo.mUserId == userId)) {
3393 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
3394 task.mTaskId, userId);
3395 }
3396 }
3397
3398 void cancelInitializingActivities() {
3399 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3400 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003401 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3402 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3403 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3404 taskDisplayArea.getStackAt(sNdx).cancelInitializingActivities();
3405 }
Louis Chang149d5c82019-12-30 09:47:39 +08003406 }
3407 }
3408 }
3409
3410 Task anyTaskForId(int id) {
3411 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
3412 }
3413
3414 Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode) {
3415 return anyTaskForId(id, matchMode, null, !ON_TOP);
3416 }
3417
3418 /**
3419 * Returns a {@link Task} for the input id if available. {@code null} otherwise.
3420 * @param id Id of the task we would like returned.
3421 * @param matchMode The mode to match the given task id in.
3422 * @param aOptions The activity options to use for restoration. Can be null.
3423 * @param onTop If the stack for the task should be the topmost on the display.
3424 */
3425 Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode,
3426 @Nullable ActivityOptions aOptions, boolean onTop) {
3427 // If options are set, ensure that we are attempting to actually restore a task
3428 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
3429 throw new IllegalArgumentException("Should not specify activity options for non-restore"
3430 + " lookup");
3431 }
3432
3433 final PooledPredicate p = PooledLambda.obtainPredicate(
3434 Task::isTaskId, PooledLambda.__(Task.class), id);
3435 Task task = getTask(p);
3436 p.recycle();
3437
3438 if (task != null) {
3439 if (aOptions != null) {
3440 // Resolve the stack the task should be placed in now based on options
3441 // and reparent if needed.
3442 final ActivityStack launchStack =
3443 getLaunchStack(null, aOptions, task, onTop);
3444 if (launchStack != null && task.getStack() != launchStack) {
3445 final int reparentMode = onTop
3446 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
3447 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
3448 "anyTaskForId");
3449 }
3450 }
3451 return task;
3452 }
3453
3454 // If we are matching stack tasks only, return now
3455 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
3456 return null;
3457 }
3458
3459 // Otherwise, check the recent tasks and return if we find it there and we are not restoring
3460 // the task from recents
3461 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
3462 task = mStackSupervisor.mRecentTasks.getTask(id);
3463
3464 if (task == null) {
3465 if (DEBUG_RECENTS) {
3466 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
3467 }
3468
3469 return null;
3470 }
3471
3472 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
3473 return task;
3474 }
3475
3476 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
3477 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
3478 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
3479 "Couldn't restore task id=" + id + " found in recents");
3480 return null;
3481 }
3482 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
3483 return task;
3484 }
3485
3486 ActivityRecord isInAnyStack(IBinder token) {
Wale Ogunwale0d465192020-01-23 19:14:44 -08003487 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3488 return (r != null && r.isDescendantOf(this)) ? r : null;
Louis Chang149d5c82019-12-30 09:47:39 +08003489 }
3490
3491 @VisibleForTesting
3492 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
Winson Chunge5ab0172020-03-21 23:00:24 -07003493 boolean filterOnlyVisibleRecents, int callingUid, boolean allowed, boolean crossUser,
3494 ArraySet<Integer> profileIds) {
3495 mStackSupervisor.getRunningTasks().getTasks(maxNum, list, filterOnlyVisibleRecents, this,
3496 callingUid, allowed, crossUser, profileIds);
Louis Chang149d5c82019-12-30 09:47:39 +08003497 }
3498
3499 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
3500 boolean sendHint = forceSend;
3501
3502 if (!sendHint) {
3503 // Send power hint if we don't know what we're launching yet
3504 sendHint = targetActivity == null || targetActivity.app == null;
3505 }
3506
3507 if (!sendHint) { // targetActivity != null
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003508 // Send power hint when the activity's process is different than the current top resumed
3509 // activity on all display areas, or if there are no resumed activities in the system.
Louis Chang149d5c82019-12-30 09:47:39 +08003510 boolean noResumedActivities = true;
3511 boolean allFocusedProcessesDiffer = true;
3512 for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003513 final DisplayContent dc = getChildAt(displayNdx);
3514 for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3515 final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx);
3516 final ActivityRecord resumedActivity = taskDisplayArea.getFocusedActivity();
3517 final WindowProcessController resumedActivityProcess =
3518 resumedActivity == null ? null : resumedActivity.app;
Louis Chang149d5c82019-12-30 09:47:39 +08003519
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003520 noResumedActivities &= resumedActivityProcess == null;
3521 if (resumedActivityProcess != null) {
3522 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(
3523 targetActivity.app);
3524 }
Louis Chang149d5c82019-12-30 09:47:39 +08003525 }
3526 }
3527 sendHint = noResumedActivities || allFocusedProcessesDiffer;
3528 }
3529
3530 if (sendHint && mService.mPowerManagerInternal != null) {
3531 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
3532 mPowerHintSent = true;
3533 }
3534 }
3535
3536 void sendPowerHintForLaunchEndIfNeeded() {
3537 // Trigger launch power hint if activity is launched
3538 if (mPowerHintSent && mService.mPowerManagerInternal != null) {
3539 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
3540 mPowerHintSent = false;
3541 }
3542 }
3543
3544 private void calculateDefaultMinimalSizeOfResizeableTasks() {
3545 final Resources res = mService.mContext.getResources();
3546 final float minimalSize = res.getDimension(
3547 com.android.internal.R.dimen.default_minimal_size_resizable_task);
3548 final DisplayMetrics dm = res.getDisplayMetrics();
3549
3550 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
3551 }
3552
3553 /**
3554 * Dumps the activities matching the given {@param name} in the either the focused stack
3555 * or all visible stacks if {@param dumpVisibleStacks} is true.
3556 */
3557 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
3558 boolean dumpFocusedStackOnly) {
3559 if (dumpFocusedStackOnly) {
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08003560 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
3561 if (topFocusedStack != null) {
3562 return topFocusedStack.getDumpActivitiesLocked(name);
3563 } else {
3564 return new ArrayList<>();
3565 }
Louis Chang149d5c82019-12-30 09:47:39 +08003566 } else {
3567 ArrayList<ActivityRecord> activities = new ArrayList<>();
3568 int numDisplays = getChildCount();
3569 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
3570 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003571 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3572 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3573 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3574 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3575 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
3576 activities.addAll(stack.getDumpActivitiesLocked(name));
3577 }
Louis Chang149d5c82019-12-30 09:47:39 +08003578 }
3579 }
3580 }
3581 return activities;
3582 }
3583 }
3584
Riddle Hsu4f088b62020-06-05 00:44:26 +08003585 @Override
3586 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
3587 super.dump(pw, prefix, dumpAll);
Louis Chang149d5c82019-12-30 09:47:39 +08003588 pw.print(prefix);
3589 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
3590 for (int i = getChildCount() - 1; i >= 0; --i) {
3591 final DisplayContent display = getChildAt(i);
Riddle Hsu4f088b62020-06-05 00:44:26 +08003592 display.dump(pw, prefix, dumpAll);
Louis Chang149d5c82019-12-30 09:47:39 +08003593 }
Winson Chung268eccb2020-03-26 13:43:44 -07003594 pw.println();
Louis Chang149d5c82019-12-30 09:47:39 +08003595 }
3596
3597 /**
3598 * Dump all connected displays' configurations.
3599 * @param prefix Prefix to apply to each line of the dump.
3600 */
3601 void dumpDisplayConfigs(PrintWriter pw, String prefix) {
3602 pw.print(prefix); pw.println("Display override configurations:");
3603 final int displayCount = getChildCount();
3604 for (int i = 0; i < displayCount; i++) {
3605 final DisplayContent displayContent = getChildAt(i);
3606 pw.print(prefix); pw.print(" "); pw.print(displayContent.mDisplayId); pw.print(": ");
3607 pw.println(displayContent.getRequestedOverrideConfiguration());
3608 }
3609 }
3610
Louis Chang149d5c82019-12-30 09:47:39 +08003611 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
3612 String dumpPackage) {
3613 boolean printed = false;
3614 boolean needSep = false;
3615 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3616 DisplayContent displayContent = getChildAt(displayNdx);
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003617 if (printed) {
3618 pw.println();
3619 }
Louis Chang149d5c82019-12-30 09:47:39 +08003620 pw.print("Display #"); pw.print(displayContent.mDisplayId);
3621 pw.println(" (activities from top to bottom):");
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003622 for (int tdaNdx = displayContent.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3623 final TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(tdaNdx);
3624 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3625 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003626 if (needSep) {
3627 pw.println();
3628 }
3629 needSep = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, false);
3630 printed |= needSep;
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003631 }
Louis Chang149d5c82019-12-30 09:47:39 +08003632 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003633 for (int tdaNdx = displayContent.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3634 final TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(tdaNdx);
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003635 printed |= printThisActivity(pw, taskDisplayArea.getFocusedActivity(),
3636 dumpPackage, needSep, " Resumed: ", () -> {
3637 pw.println(" Resumed activities in task display areas"
3638 + " (from top to bottom):");
3639 });
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003640 }
Louis Chang149d5c82019-12-30 09:47:39 +08003641 }
3642
3643 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ",
3644 "Fin", false, !dumpAll,
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003645 false, dumpPackage, true,
3646 () -> { pw.println(" Activities waiting to finish:"); }, null);
Louis Chang149d5c82019-12-30 09:47:39 +08003647 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
3648 "Stop", false, !dumpAll,
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003649 false, dumpPackage, true,
3650 () -> { pw.println(" Activities waiting to stop:"); }, null);
Louis Chang149d5c82019-12-30 09:47:39 +08003651
3652 return printed;
3653 }
3654
Louis Chang149d5c82019-12-30 09:47:39 +08003655 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
3656 private final String mTag;
3657 private final long mAcquireTime;
3658 private final int mDisplayId;
3659
3660 public SleepTokenImpl(String tag, int displayId) {
3661 mTag = tag;
3662 mDisplayId = displayId;
3663 mAcquireTime = SystemClock.uptimeMillis();
3664 }
3665
3666 @Override
3667 public void release() {
3668 synchronized (mService.mGlobalLock) {
3669 removeSleepToken(this);
3670 }
3671 }
3672
3673 @Override
3674 public String toString() {
3675 return "{\"" + mTag + "\", display " + mDisplayId
3676 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
3677 }
3678 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07003679}