blob: 76403c24e652478cc2c95167dd9c1a6c0b6a4448 [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
wilsonshihab672942018-08-06 15:42:07 +080043import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
44import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Chris Li74f622a2020-04-19 18:57:35 -070045import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
Louis Chang149d5c82019-12-30 09:47:39 +080046import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
47import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
48import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
49import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
50import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
51import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
52import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
53import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
54import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
55import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
56import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
57import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
58import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
59import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
60import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
61import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
62import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
63import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
64import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
Adrian Roosb125e0b2019-10-02 14:55:14 +020065import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
66import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
67import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
68import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
69import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
lumark04bceb92020-03-07 00:03:33 +080070import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
Wale Ogunwalef342f062020-01-27 07:34:13 -080071import static com.android.server.wm.RootWindowContainerProto.IS_HOME_RECENTS_COMPONENT;
72import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER;
73import static com.android.server.wm.RootWindowContainerProto.PENDING_ACTIVITIES;
wilsonshihab672942018-08-06 15:42:07 +080074import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
Louis Chang149d5c82019-12-30 09:47:39 +080075import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
76import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
wilsonshihab672942018-08-06 15:42:07 +080077import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
wilsonshihab672942018-08-06 15:42:07 +080078import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
79import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
80import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
wilsonshihab672942018-08-06 15:42:07 +080081import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
82import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
wilsonshihab672942018-08-06 15:42:07 +080083import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080084import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
wilsonshihab672942018-08-06 15:42:07 +080085import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
86import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
87import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
wilsonshihab672942018-08-06 15:42:07 +080088import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
89import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
90import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
wilsonshihab672942018-08-06 15:42:07 +080091
Louis Chang149d5c82019-12-30 09:47:39 +080092import static java.lang.Integer.MAX_VALUE;
93
94import android.annotation.IntDef;
Evan Roskye747c3e2018-10-30 20:06:41 -070095import android.annotation.NonNull;
Charles Chen173ae782019-11-11 20:39:02 +080096import android.annotation.Nullable;
Louis Chang149d5c82019-12-30 09:47:39 +080097import android.annotation.UserIdInt;
98import android.app.ActivityManager;
99import android.app.ActivityOptions;
100import android.app.AppGlobals;
101import android.app.WindowConfiguration;
102import android.content.ComponentName;
Charles Chen173ae782019-11-11 20:39:02 +0800103import android.content.Context;
Louis Chang149d5c82019-12-30 09:47:39 +0800104import android.content.Intent;
105import android.content.pm.ActivityInfo;
106import android.content.pm.ApplicationInfo;
107import android.content.pm.ResolveInfo;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700108import android.content.res.Configuration;
Louis Chang149d5c82019-12-30 09:47:39 +0800109import android.content.res.Resources;
110import android.graphics.Rect;
111import android.hardware.display.DisplayManager;
112import android.hardware.display.DisplayManagerInternal;
Ruchi Kandoi0d434042016-10-03 09:12:02 -0700113import android.hardware.power.V1_0.PowerHint;
Louis Chang149d5c82019-12-30 09:47:39 +0800114import android.net.Uri;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700115import android.os.Binder;
116import android.os.Debug;
Louis Chang149d5c82019-12-30 09:47:39 +0800117import android.os.FactoryTest;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200118import android.os.Handler;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700119import android.os.IBinder;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200120import android.os.Looper;
121import android.os.Message;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700122import android.os.PowerManager;
123import android.os.RemoteException;
Louis Chang149d5c82019-12-30 09:47:39 +0800124import android.os.SystemClock;
Jorim Jaggi4981f152019-03-26 18:58:45 +0100125import android.os.Trace;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700126import android.os.UserHandle;
Louis Chang149d5c82019-12-30 09:47:39 +0800127import android.os.storage.StorageManager;
128import android.provider.Settings;
129import android.service.voice.IVoiceInteractionSession;
David Stevensf833ba92017-03-16 19:00:20 -0700130import android.util.ArraySet;
Louis Chang149d5c82019-12-30 09:47:39 +0800131import android.util.DisplayMetrics;
132import android.util.IntArray;
133import android.util.Pair;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700134import android.util.Slog;
Louis Chang149d5c82019-12-30 09:47:39 +0800135import android.util.SparseArray;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700136import android.util.SparseIntArray;
Louis Chang149d5c82019-12-30 09:47:39 +0800137import android.util.TimeUtils;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700138import android.util.proto.ProtoOutputStream;
Louis Chang149d5c82019-12-30 09:47:39 +0800139import android.view.Display;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700140import android.view.DisplayInfo;
Robert Carrae606b42018-02-15 15:36:23 -0800141import android.view.SurfaceControl;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700142import android.view.WindowManager;
Andrii Kulian1cfcae82020-04-10 12:44:38 -0700143import android.window.WindowContainerToken;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200144
Louis Chang149d5c82019-12-30 09:47:39 +0800145import com.android.internal.annotations.VisibleForTesting;
146import com.android.internal.app.ResolverActivity;
147import com.android.internal.util.function.pooled.PooledConsumer;
148import com.android.internal.util.function.pooled.PooledFunction;
Charles Chen173ae782019-11-11 20:39:02 +0800149import com.android.internal.util.function.pooled.PooledLambda;
150import com.android.internal.util.function.pooled.PooledPredicate;
Louis Chang149d5c82019-12-30 09:47:39 +0800151import com.android.server.LocalServices;
152import com.android.server.am.ActivityManagerService;
153import com.android.server.am.AppTimeTracker;
154import com.android.server.am.UserState;
155import com.android.server.policy.WindowManagerPolicy;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200156import com.android.server.protolog.common.ProtoLog;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700157
Louis Chang149d5c82019-12-30 09:47:39 +0800158import java.io.FileDescriptor;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700159import java.io.PrintWriter;
Louis Chang149d5c82019-12-30 09:47:39 +0800160import java.lang.annotation.Retention;
161import java.lang.annotation.RetentionPolicy;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700162import java.util.ArrayList;
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800163import java.util.HashMap;
Charles Chen173ae782019-11-11 20:39:02 +0800164import java.util.List;
Louis Chang149d5c82019-12-30 09:47:39 +0800165import java.util.Objects;
166import java.util.Set;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800167import java.util.function.Consumer;
Louis Chang149d5c82019-12-30 09:47:39 +0800168import java.util.function.Function;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700169
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700170/** Root {@link WindowContainer} for the device. */
Louis Chang149d5c82019-12-30 09:47:39 +0800171class RootWindowContainer extends WindowContainer<DisplayContent>
172 implements DisplayManager.DisplayListener {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700173 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
174
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200175 private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
176 private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
Louis Chang149d5c82019-12-30 09:47:39 +0800177 static final String TAG_TASKS = TAG + POSTFIX_TASKS;
178 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
179 static final String TAG_STATES = TAG + POSTFIX_STATES;
180 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200181
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700182 private Object mLastWindowFreezeSource = null;
183 private Session mHoldScreen = null;
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100184 private float mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700185 private long mUserActivityTimeout = -1;
186 private boolean mUpdateRotation = false;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700187 // Following variables are for debugging screen wakelock only.
188 // Last window that requires screen wakelock
189 WindowState mHoldScreenWindow = null;
190 // Last window that obscures all windows below
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700191 WindowState mObscuringWindow = null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700192 // Only set while traversing the default display based on its content.
193 // Affects the behavior of mirroring on secondary displays.
194 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
195
196 private boolean mSustainedPerformanceModeEnabled = false;
197 private boolean mSustainedPerformanceModeCurrent = false;
198
Robert Carr11c26c22016-09-23 12:40:27 -0700199 // During an orientation change, we track whether all windows have rendered
200 // at the new orientation, and this will be false from changing orientation until that occurs.
201 // For seamless rotation cases this always stays true, as the windows complete their orientation
202 // changes 1 by 1 without disturbing global state.
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700203 boolean mOrientationChangeComplete = true;
204 boolean mWallpaperActionPending = false;
205
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200206 private final Handler mHandler;
207
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800208 private String mCloseSystemDialogsReason;
Robert Carrae606b42018-02-15 15:36:23 -0800209
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800210 // The ID of the display which is responsible for receiving display-unspecified key and pointer
211 // events.
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800212 private int mTopFocusedDisplayId = INVALID_DISPLAY;
213
214 // Map from the PID to the top most app which has a focused window of the process.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700215 final HashMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new HashMap<>();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800216
Tiger Huang7c610aa2018-10-27 00:01:01 +0800217 // Only a separate transaction until we separate the apply surface changes
Robert Carrae606b42018-02-15 15:36:23 -0800218 // transaction from the global transaction.
Vishnu Nair33197392019-08-30 10:29:37 -0700219 private final SurfaceControl.Transaction mDisplayTransaction;
Robert Carrae606b42018-02-15 15:36:23 -0800220
Louis Chang149d5c82019-12-30 09:47:39 +0800221 /**
222 * The modes which affect which tasks are returned when calling
223 * {@link RootWindowContainer#anyTaskForId(int)}.
224 */
225 @Retention(RetentionPolicy.SOURCE)
226 @IntDef({
227 MATCH_TASK_IN_STACKS_ONLY,
228 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
229 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
230 })
231 public @interface AnyTaskForIdMatchTaskMode {}
232 // Match only tasks in the current stacks
233 static final int MATCH_TASK_IN_STACKS_ONLY = 0;
234 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
235 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
236 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
237 // provided stack id
238 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
239
240 ActivityTaskManagerService mService;
241 ActivityStackSupervisor mStackSupervisor;
242 WindowManagerService mWindowManager;
243 DisplayManager mDisplayManager;
244 private DisplayManagerInternal mDisplayManagerInternal;
245
246 /** Reference to default display so we can quickly look it up. */
247 private DisplayContent mDefaultDisplay;
248 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
249
250 /** The current user */
251 int mCurrentUser;
252 /** Stack id of the front stack when user switched, indexed by userId. */
253 SparseIntArray mUserStackInFront = new SparseIntArray(2);
254
255 /**
256 * A list of tokens that cause the top activity to be put to sleep.
257 * They are used by components that may hide and block interaction with underlying
258 * activities.
259 */
260 final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
261
Louis Chang149d5c82019-12-30 09:47:39 +0800262 /** Set when a power hint has started, but not ended. */
263 private boolean mPowerHintSent;
264
Louis Chang149d5c82019-12-30 09:47:39 +0800265 // The default minimal size that will be used if the activity doesn't specify its minimal size.
266 // It will be calculated when the default display gets added.
267 int mDefaultMinSizeOfResizeableTaskDp = -1;
268
269 // Whether tasks have moved and we need to rank the tasks before next OOM scoring
270 private boolean mTaskLayersChanged = true;
271 private int mTmpTaskLayerRank;
272
273 private boolean mTmpBoolean;
274 private RemoteException mTmpRemoteException;
275
276 private String mDestroyAllActivitiesReason;
277 private final Runnable mDestroyAllActivitiesRunnable = new Runnable() {
278 @Override
279 public void run() {
280 synchronized (mService.mGlobalLock) {
281 try {
282 mStackSupervisor.beginDeferResume();
283
284 final PooledConsumer c = PooledLambda.obtainConsumer(
285 RootWindowContainer::destroyActivity, RootWindowContainer.this,
286 PooledLambda.__(ActivityRecord.class));
287 forAllActivities(c);
288 c.recycle();
289 } finally {
290 mStackSupervisor.endDeferResume();
291 resumeFocusedStacksTopActivities();
292 }
293 }
294 }
295
296 };
297
298 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
299 static class FindTaskResult implements Function<Task, Boolean> {
300 ActivityRecord mRecord;
301 boolean mIdealMatch;
302
303 private ActivityRecord mTarget;
304 private Intent intent;
305 private ActivityInfo info;
306 private ComponentName cls;
307 private int userId;
308 private boolean isDocument;
309 private Uri documentData;
310
311 /**
312 * Returns the top activity in any existing task matching the given Intent in the input
313 * result. Returns null if no such task is found.
314 */
315 void process(ActivityRecord target, ActivityStack parent) {
316 mTarget = target;
317
318 intent = target.intent;
319 info = target.info;
320 cls = intent.getComponent();
321 if (info.targetActivity != null) {
322 cls = new ComponentName(info.packageName, info.targetActivity);
323 }
324 userId = UserHandle.getUserId(info.applicationInfo.uid);
325 isDocument = intent != null & intent.isDocument();
326 // If documentData is non-null then it must match the existing task data.
327 documentData = isDocument ? intent.getData() : null;
328
329 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
330 parent.forAllTasks(this);
331 }
332
333 void clear() {
334 mRecord = null;
335 mIdealMatch = false;
336 }
337
338 void setTo(FindTaskResult result) {
339 mRecord = result.mRecord;
340 mIdealMatch = result.mIdealMatch;
341 }
342
343 @Override
344 public Boolean apply(Task task) {
345 if (task.voiceSession != null) {
346 // We never match voice sessions; those always run independently.
347 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
348 return false;
349 }
350 if (task.mUserId != userId) {
351 // Looking for a different task.
352 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
353 return false;
354 }
355
356 // Overlays should not be considered as the task's logical top activity.
357 final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
358 if (r == null || r.finishing || r.mUserId != userId
359 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
360 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
361 return false;
362 }
363 if (!r.hasCompatibleActivityType(mTarget)) {
364 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
365 return false;
366 }
367
368 final Intent taskIntent = task.intent;
369 final Intent affinityIntent = task.affinityIntent;
370 final boolean taskIsDocument;
371 final Uri taskDocumentData;
372 if (taskIntent != null && taskIntent.isDocument()) {
373 taskIsDocument = true;
374 taskDocumentData = taskIntent.getData();
375 } else if (affinityIntent != null && affinityIntent.isDocument()) {
376 taskIsDocument = true;
377 taskDocumentData = affinityIntent.getData();
378 } else {
379 taskIsDocument = false;
380 taskDocumentData = null;
381 }
382
383 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
384 + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
385 + "/aff=" + r.getTask().rootAffinity + " to new cls="
386 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
387 // TODO Refactor to remove duplications. Check if logic can be simplified.
388 if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
389 && Objects.equals(documentData, taskDocumentData)) {
390 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
391 //dump();
392 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
393 "For Intent " + intent + " bringing to top: " + r.intent);
394 mRecord = r;
395 mIdealMatch = true;
396 return true;
397 } else if (affinityIntent != null && affinityIntent.getComponent() != null
398 && affinityIntent.getComponent().compareTo(cls) == 0 &&
399 Objects.equals(documentData, taskDocumentData)) {
400 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
401 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
402 "For Intent " + intent + " bringing to top: " + r.intent);
403 mRecord = r;
404 mIdealMatch = true;
405 return true;
406 } else if (!isDocument && !taskIsDocument
407 && mRecord == null && task.rootAffinity != null) {
408 if (task.rootAffinity.equals(mTarget.taskAffinity)) {
409 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
410 // It is possible for multiple tasks to have the same root affinity especially
411 // if they are in separate stacks. We save off this candidate, but keep looking
412 // to see if there is a better candidate.
413 mRecord = r;
414 mIdealMatch = false;
415 }
416 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
417
418 return false;
419 }
420 }
421
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800422 private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
423 if (w.mHasSurface) {
424 try {
425 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason);
426 } catch (RemoteException e) {
427 }
428 }
429 };
430
431 private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700432 final ActivityRecord activity = w.mActivityRecord;
433 if (activity != null) {
434 activity.removeReplacedWindowIfNeeded(w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800435 }
436 };
437
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700438 RootWindowContainer(WindowManagerService service) {
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100439 super(service);
Vishnu Nair33197392019-08-30 10:29:37 -0700440 mDisplayTransaction = service.mTransactionFactory.get();
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200441 mHandler = new MyHandler(service.mH.getLooper());
Louis Chang149d5c82019-12-30 09:47:39 +0800442 mService = service.mAtmService;
443 mStackSupervisor = mService.mStackSupervisor;
444 mStackSupervisor.mRootWindowContainer = this;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700445 }
446
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800447 boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800448 mTopFocusedAppByProcess.clear();
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800449 boolean changed = false;
450 int topFocusedDisplayId = INVALID_DISPLAY;
lumark6f13d20b2018-10-19 14:38:15 +0800451 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700452 final DisplayContent dc = mChildren.get(i);
Louis Changa9350fe2019-04-25 17:14:20 +0800453 changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800454 final WindowState newFocus = dc.mCurrentFocus;
455 if (newFocus != null) {
456 final int pidOfNewFocus = newFocus.mSession.mPid;
457 if (mTopFocusedAppByProcess.get(pidOfNewFocus) == null) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700458 mTopFocusedAppByProcess.put(pidOfNewFocus, newFocus.mActivityRecord);
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800459 }
460 if (topFocusedDisplayId == INVALID_DISPLAY) {
461 topFocusedDisplayId = dc.getDisplayId();
462 }
Louis Changa9350fe2019-04-25 17:14:20 +0800463 } else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) {
464 // The top-most display that has a focused app should still be the top focused
465 // display even when the app window is not ready yet (process not attached or
466 // window not added yet).
467 topFocusedDisplayId = dc.getDisplayId();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700468 }
469 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800470 if (topFocusedDisplayId == INVALID_DISPLAY) {
471 topFocusedDisplayId = DEFAULT_DISPLAY;
472 }
473 if (mTopFocusedDisplayId != topFocusedDisplayId) {
474 mTopFocusedDisplayId = topFocusedDisplayId;
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800475 mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
Tiger Huangdc7356a2018-12-17 16:15:35 +0800476 mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId);
Adrian Roosb125e0b2019-10-02 14:55:14 +0200477 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d",
478 topFocusedDisplayId);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800479 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800480 return changed;
481 }
482
483 DisplayContent getTopFocusedDisplayContent() {
Charles Chen37848f32019-02-27 19:27:45 +0800484 final DisplayContent dc = getDisplayContent(mTopFocusedDisplayId);
485 return dc != null ? dc : getDisplayContent(DEFAULT_DISPLAY);
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800486 }
487
488 @Override
lumarkd0b5c8f2019-09-29 11:30:37 +0800489 boolean isOnTop() {
490 // Considered always on top
491 return true;
492 }
493
494 @Override
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200495 void onChildPositionChanged(WindowContainer child) {
Tiger Huangfc90c132018-12-20 18:53:47 +0800496 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
497 !mWmService.mPerDisplayFocusEnabled /* updateInputWindows */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700498 }
499
Garfield Tanb5910b42019-03-14 14:50:59 -0700500 /**
501 * Called when DisplayWindowSettings values may change.
502 */
503 void onSettingsRetrieved() {
504 final int numDisplays = mChildren.size();
505 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
506 final DisplayContent displayContent = mChildren.get(displayNdx);
507 final boolean changed = mWmService.mDisplayWindowSettings.updateSettingsForDisplay(
508 displayContent);
509 if (!changed) {
510 continue;
511 }
512
Shivam Agrawal6472e0e2019-07-03 16:27:49 -0700513 displayContent.reconfigureDisplayLocked();
Garfield Tanb5910b42019-03-14 14:50:59 -0700514
515 // We need to update global configuration as well if config of default display has
516 // changed. Do it inline because ATMS#retrieveSettings() will soon update the
517 // configuration inline, which will overwrite the new windowing mode.
518 if (displayContent.isDefaultDisplay) {
519 final Configuration newConfig = mWmService.computeNewConfiguration(
520 displayContent.getDisplayId());
521 mWmService.mAtmService.updateConfigurationLocked(newConfig, null /* starting */,
522 false /* initLocale */);
523 }
524 }
525 }
526
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700527 boolean isLayoutNeeded() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700528 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700529 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700530 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700531 if (displayContent.isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700532 return true;
533 }
534 }
535 return false;
536 }
537
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000538 void getWindowsByName(ArrayList<WindowState> output, String name) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700539 int objectId = 0;
540 // See if this is an object ID.
541 try {
542 objectId = Integer.parseInt(name, 16);
543 name = null;
544 } catch (RuntimeException e) {
545 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800546
547 getWindowsByName(output, name, objectId);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700548 }
549
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000550 private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800551 forAllWindows((w) -> {
552 if (name != null) {
553 if (w.mAttrs.getTitle().toString().contains(name)) {
554 output.add(w);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700555 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800556 } else if (System.identityHashCode(w) == objectId) {
557 output.add(w);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700558 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800559 }, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700560 }
561
Wale Ogunwale02319a62016-09-26 15:21:22 -0700562 /**
Charles Chen173ae782019-11-11 20:39:02 +0800563 * Returns {@code true} if the callingUid has any non-toast window currently visible to the
564 * user. Also ignores {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_STARTING},
565 * since those windows don't belong to apps.
566 * @see WindowState#isNonToastOrStarting()
Michal Karpinskia606a292019-01-12 17:29:52 +0000567 */
568 boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
Charles Chen173ae782019-11-11 20:39:02 +0800569 final PooledPredicate p = PooledLambda.obtainPredicate(
570 WindowState::isNonToastWindowVisibleForUid,
571 PooledLambda.__(WindowState.class), callingUid);
572
573 final WindowState w = getWindow(p);
574 p.recycle();
575 return w != null;
Michal Karpinskia606a292019-01-12 17:29:52 +0000576 }
577
578 /**
Wale Ogunwale02319a62016-09-26 15:21:22 -0700579 * Returns the app window token for the input binder if it exist in the system.
580 * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
581 * AppWindowToken represents an activity which can only exist on one display.
582 */
Garfield Tane8d84ab2019-10-11 09:49:40 -0700583 ActivityRecord getActivityRecord(IBinder binder) {
Wale Ogunwale02319a62016-09-26 15:21:22 -0700584 for (int i = mChildren.size() - 1; i >= 0; --i) {
585 final DisplayContent dc = mChildren.get(i);
Garfield Tane8d84ab2019-10-11 09:49:40 -0700586 final ActivityRecord activity = dc.getActivityRecord(binder);
587 if (activity != null) {
588 return activity;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700589 }
590 }
591 return null;
592 }
593
wilsonshihab672942018-08-06 15:42:07 +0800594 /** Returns the window token for the input binder if it exist in the system. */
595 WindowToken getWindowToken(IBinder binder) {
596 for (int i = mChildren.size() - 1; i >= 0; --i) {
597 final DisplayContent dc = mChildren.get(i);
598 final WindowToken wtoken = dc.getWindowToken(binder);
599 if (wtoken != null) {
600 return wtoken;
601 }
602 }
603 return null;
604 }
605
Wale Ogunwale02319a62016-09-26 15:21:22 -0700606 /** Returns the display object the input window token is currently mapped on. */
607 DisplayContent getWindowTokenDisplay(WindowToken token) {
608 if (token == null) {
609 return null;
610 }
611
612 for (int i = mChildren.size() - 1; i >= 0; --i) {
613 final DisplayContent dc = mChildren.get(i);
614 final WindowToken current = dc.getWindowToken(token.token);
615 if (current == token) {
616 return dc;
617 }
618 }
619
620 return null;
621 }
622
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700623 /**
Evan Roskye747c3e2018-10-30 20:06:41 -0700624 * Set new display override config. If called for the default display, global configuration
625 * will also be updated.
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700626 */
Evan Roskye747c3e2018-10-30 20:06:41 -0700627 void setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration,
628 @NonNull DisplayContent displayContent) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700629
Evan Roskydfe3da72018-10-26 17:21:06 -0700630 final Configuration currentConfig = displayContent.getRequestedOverrideConfiguration();
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700631 final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
632 if (!configChanged) {
Evan Roskye747c3e2018-10-30 20:06:41 -0700633 return;
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700634 }
Bryce Leeaea60d22018-01-31 14:42:15 -0800635
Evan Roskydfe3da72018-10-26 17:21:06 -0700636 displayContent.onRequestedOverrideConfigurationChanged(newConfiguration);
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700637
Evan Roskye747c3e2018-10-30 20:06:41 -0700638 if (displayContent.getDisplayId() == DEFAULT_DISPLAY) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700639 // Override configuration of the default display duplicates global config. In this case
640 // we also want to update the global config.
Evan Roskye747c3e2018-10-30 20:06:41 -0700641 setGlobalConfigurationIfNeeded(newConfiguration);
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700642 }
643 }
644
Evan Roskye747c3e2018-10-30 20:06:41 -0700645 private void setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
Andrii Kulian441e4492016-09-29 15:25:00 -0700646 final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
647 if (!configChanged) {
Bryce Leeaea60d22018-01-31 14:42:15 -0800648 return;
Andrii Kulian441e4492016-09-29 15:25:00 -0700649 }
650 onConfigurationChanged(newConfiguration);
Andrii Kulian441e4492016-09-29 15:25:00 -0700651 }
652
653 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -0700654 public void onConfigurationChanged(Configuration newParentConfig) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700655 prepareFreezingTaskBounds();
Andrii Kulian441e4492016-09-29 15:25:00 -0700656 super.onConfigurationChanged(newParentConfig);
Andrii Kulian441e4492016-09-29 15:25:00 -0700657 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700658
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700659 private void prepareFreezingTaskBounds() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700660 for (int i = mChildren.size() - 1; i >= 0; i--) {
661 mChildren.get(i).prepareFreezingTaskBounds();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700662 }
663 }
664
665 void setSecureSurfaceState(int userId, boolean disabled) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800666 forAllWindows((w) -> {
wilsonshihd0fc2ca2020-03-18 22:41:55 +0800667 if (w.mHasSurface && userId == w.mShowUserId) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800668 w.mWinAnimator.setSecureLocked(disabled);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700669 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800670 }, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700671 }
672
Suprabh Shukla69c71422018-04-02 18:39:01 -0700673 void updateHiddenWhileSuspendedState(final ArraySet<String> packages, final boolean suspended) {
674 forAllWindows((w) -> {
675 if (packages.contains(w.getOwningPackage())) {
676 w.setHiddenWhileSuspended(suspended);
677 }
678 }, false);
679 }
680
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700681 void updateAppOpsState() {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800682 forAllWindows((w) -> {
Svet Ganovf7b47252018-02-26 11:11:27 -0800683 w.updateAppOpsState();
Wale Ogunwaled1880962016-11-08 10:31:59 -0800684 }, false /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700685 }
686
687 boolean canShowStrictModeViolation(int pid) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800688 final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
689 return win != null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700690 }
691
692 void closeSystemDialogs(String reason) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800693 mCloseSystemDialogsReason = reason;
694 forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700695 }
696
697 void removeReplacedWindows() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200698 ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION removeReplacedWindows");
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800699 mWmService.openSurfaceTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700700 try {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800701 forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700702 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800703 mWmService.closeSurfaceTransaction("removeReplacedWindows");
Adrian Roosb125e0b2019-10-02 14:55:14 +0200704 ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION removeReplacedWindows");
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700705 }
706 }
707
708 boolean hasPendingLayoutChanges(WindowAnimator animator) {
709 boolean hasChanges = false;
710
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700711 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700712 for (int i = 0; i < count; ++i) {
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800713 final int pendingChanges = mChildren.get(i).pendingLayoutChanges;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700714 if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
715 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
716 }
717 if (pendingChanges != 0) {
718 hasChanges = true;
719 }
720 }
721
722 return hasChanges;
723 }
724
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700725 boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
726 boolean secure) {
727 final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
728 boolean leakedSurface = false;
729 boolean killedApps = false;
Jeff Changd136e772019-11-05 20:33:52 +0800730 EventLogTags.writeWmNoSurfaceMemory(winAnimator.mWin.toString(),
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700731 winAnimator.mSession.mPid, operation);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700732 final long callingIdentity = Binder.clearCallingIdentity();
733 try {
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700734 // There was some problem...first, do a sanity check of the window list to make sure
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700735 // we haven't left any dangling surfaces around.
736
737 Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700738 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700739 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700740 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700741 }
742
743 if (!leakedSurface) {
744 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700745 final SparseIntArray pidCandidates = new SparseIntArray();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700746 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800747 mChildren.get(displayNdx).forAllWindows((w) -> {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800748 if (mWmService.mForceRemoves.contains(w)) {
Wale Ogunwaled1880962016-11-08 10:31:59 -0800749 return;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700750 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800751 final WindowStateAnimator wsa = w.mWinAnimator;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700752 if (wsa.mSurfaceController != null) {
753 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
754 }
Wale Ogunwaled1880962016-11-08 10:31:59 -0800755 }, false /* traverseTopToBottom */);
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700756
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700757 if (pidCandidates.size() > 0) {
758 int[] pids = new int[pidCandidates.size()];
759 for (int i = 0; i < pids.length; i++) {
760 pids[i] = pidCandidates.keyAt(i);
761 }
762 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800763 if (mWmService.mActivityManager.killPids(pids, "Free memory", secure)) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700764 killedApps = true;
765 }
766 } catch (RemoteException e) {
767 }
768 }
769 }
770 }
771
772 if (leakedSurface || killedApps) {
773 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
774 // app to request another one.
775 Slog.w(TAG_WM,
776 "Looks like we have reclaimed some memory, clearing surface for retry.");
777 if (surfaceController != null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200778 ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
779 "SURFACE RECOVER DESTROY: %s", winAnimator.mWin);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700780 winAnimator.destroySurface();
Garfield Tane8d84ab2019-10-11 09:49:40 -0700781 if (winAnimator.mWin.mActivityRecord != null) {
782 winAnimator.mWin.mActivityRecord.removeStartingWindow();
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800783 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700784 }
785
786 try {
787 winAnimator.mWin.mClient.dispatchGetNewSurface();
788 } catch (RemoteException e) {
789 }
790 }
791 } finally {
792 Binder.restoreCallingIdentity(callingIdentity);
793 }
794
795 return leakedSurface || killedApps;
796 }
797
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800798 void performSurfacePlacement() {
Jorim Jaggi4981f152019-03-26 18:58:45 +0100799 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
800 try {
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800801 performSurfacePlacementNoTrace();
Jorim Jaggi4981f152019-03-26 18:58:45 +0100802 } finally {
803 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
804 }
805 }
806
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700807 // "Something has changed! Let's make it correct now."
808 // TODO: Super crazy long method that should be broken down...
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800809 void performSurfacePlacementNoTrace() {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700810 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
811 + Debug.getCallers(3));
812
813 int i;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700814
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800815 if (mWmService.mFocusMayChange) {
816 mWmService.mFocusMayChange = false;
Jorim Jaggi4981f152019-03-26 18:58:45 +0100817 mWmService.updateFocusedWindowLocked(
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700818 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
819 }
820
821 // Initialize state of exiting tokens.
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700822 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700823 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700824 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800825 displayContent.setExitingTokensHasVisible(false);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700826 }
827
828 mHoldScreen = null;
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100829 mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700830 mUserActivityTimeout = -1;
831 mObscureApplicationContentOnSecondaryDisplays = false;
832 mSustainedPerformanceModeCurrent = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800833 mWmService.mTransactionSequence++;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700834
lumark588a3e82018-07-20 18:53:54 +0800835 // TODO(multi-display): recents animation & wallpaper need support multi-display.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800836 final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked();
837 final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700838
839 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
840 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Jorim Jaggi4981f152019-03-26 18:58:45 +0100841 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800842 mWmService.openSurfaceTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700843 try {
Riddle Hsu72d6dc32020-03-25 22:58:00 +0800844 applySurfaceChangesTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700845 } catch (RuntimeException e) {
846 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
847 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800848 mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
Jorim Jaggi4981f152019-03-26 18:58:45 +0100849 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700850 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
851 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
852 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800853 mWmService.mAnimator.executeAfterPrepareSurfacesRunnables();
Chavi Weingarten16d0d072018-02-12 23:50:28 +0000854
lumark588a3e82018-07-20 18:53:54 +0800855 checkAppTransitionReady(surfacePlacer);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700856
Winson Chunge2d72172018-01-25 17:46:20 +0000857 // Defer starting the recents animation until the wallpaper has drawn
858 final RecentsAnimationController recentsAnimationController =
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800859 mWmService.getRecentsAnimationController();
Winson Chunge2d72172018-01-25 17:46:20 +0000860 if (recentsAnimationController != null) {
wilsonshihc32538e2018-11-07 17:27:34 +0800861 recentsAnimationController.checkAnimationReady(defaultDisplay.mWallpaperController);
Winson Chunge2d72172018-01-25 17:46:20 +0000862 }
863
wilsonshihc32538e2018-11-07 17:27:34 +0800864 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
865 final DisplayContent displayContent = mChildren.get(displayNdx);
866 if (displayContent.mWallpaperMayChange) {
867 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
868 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
869 if (DEBUG_LAYOUT_REPEATS) {
870 surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
871 displayContent.pendingLayoutChanges);
872 }
873 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700874 }
875
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800876 if (mWmService.mFocusMayChange) {
877 mWmService.mFocusMayChange = false;
Jorim Jaggi4981f152019-03-26 18:58:45 +0100878 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
879 false /*updateInputWindows*/);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700880 }
881
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700882 if (isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700883 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
884 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
885 defaultDisplay.pendingLayoutChanges);
886 }
887
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800888 handleResizingWindows();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700889
Adrian Roosb125e0b2019-10-02 14:55:14 +0200890 if (mWmService.mDisplayFrozen) {
891 ProtoLog.v(WM_DEBUG_ORIENTATION,
892 "With display frozen, orientationChangeComplete=%b",
893 mOrientationChangeComplete);
894 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700895 if (mOrientationChangeComplete) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800896 if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
897 mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
898 mWmService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
899 mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700900 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800901 mWmService.stopFreezingDisplayLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700902 }
903
904 // Destroy the surface of any windows that are no longer visible.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800905 i = mWmService.mDestroySurface.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700906 if (i > 0) {
907 do {
908 i--;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800909 WindowState win = mWmService.mDestroySurface.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700910 win.mDestroying = false;
lumark90120a82018-08-15 00:33:03 +0800911 final DisplayContent displayContent = win.getDisplayContent();
912 if (displayContent.mInputMethodWindow == win) {
913 displayContent.setInputMethodWindowLocked(null);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700914 }
lumark90120a82018-08-15 00:33:03 +0800915 if (displayContent.mWallpaperController.isWallpaperTarget(win)) {
wilsonshihc32538e2018-11-07 17:27:34 +0800916 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700917 }
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200918 win.destroySurfaceUnchecked();
Robert Carrfa8edf82018-04-19 12:38:47 -0700919 win.mWinAnimator.destroyPreservedSurfaceLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700920 } while (i > 0);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800921 mWmService.mDestroySurface.clear();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700922 }
923
924 // Time to remove any exiting tokens?
925 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700926 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800927 displayContent.removeExistingTokensIfPossible();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700928 }
929
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700930 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700931 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700932 if (displayContent.pendingLayoutChanges != 0) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700933 displayContent.setLayoutNeeded();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700934 }
935 }
936
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800937 mWmService.setHoldScreenLocked(mHoldScreen);
938 if (!mWmService.mDisplayFrozen) {
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100939 final float brightnessOverride = mScreenBrightnessOverride < PowerManager.BRIGHTNESS_MIN
940 || mScreenBrightnessOverride > PowerManager.BRIGHTNESS_MAX
941 ? PowerManager.BRIGHTNESS_INVALID_FLOAT : mScreenBrightnessOverride;
942 int brightnessFloatAsIntBits = Float.floatToIntBits(brightnessOverride);
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200943 // Post these on a handler such that we don't call into power manager service while
944 // holding the window manager lock to avoid lock contention with power manager lock.
Fiona Campbell29dce0f2020-04-03 17:24:45 +0100945 mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightnessFloatAsIntBits,
946 0).sendToTarget();
Jorim Jaggi86c39f92017-05-02 18:02:46 +0200947 mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700948 }
949
950 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
951 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800952 mWmService.mPowerManagerInternal.powerHint(
Ruchi Kandoi0d434042016-10-03 09:12:02 -0700953 PowerHint.SUSTAINED_PERFORMANCE,
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700954 (mSustainedPerformanceModeEnabled ? 1 : 0));
955 }
956
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700957 if (mUpdateRotation) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200958 ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation");
Riddle Hsu654a6f92018-07-13 22:59:36 +0800959 mUpdateRotation = updateRotationUnchecked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700960 }
961
Yunfan Chen87b5a242019-10-01 17:53:59 +0900962 if (!mWmService.mWaitingForDrawnCallbacks.isEmpty()
lumark588a3e82018-07-20 18:53:54 +0800963 || (mOrientationChangeComplete && !isLayoutNeeded()
Jorim Jaggi4981f152019-03-26 18:58:45 +0100964 && !mUpdateRotation)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800965 mWmService.checkDrawnWindowsLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700966 }
967
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800968 final int N = mWmService.mPendingRemove.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700969 if (N > 0) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800970 if (mWmService.mPendingRemoveTmp.length < N) {
971 mWmService.mPendingRemoveTmp = new WindowState[N + 10];
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700972 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800973 mWmService.mPendingRemove.toArray(mWmService.mPendingRemoveTmp);
974 mWmService.mPendingRemove.clear();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700975 ArrayList<DisplayContent> displayList = new ArrayList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700976 for (i = 0; i < N; i++) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800977 final WindowState w = mWmService.mPendingRemoveTmp[i];
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700978 w.removeImmediately();
979 final DisplayContent displayContent = w.getDisplayContent();
980 if (displayContent != null && !displayList.contains(displayContent)) {
981 displayList.add(displayContent);
982 }
983 }
984
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700985 for (int j = displayList.size() - 1; j >= 0; --j) {
986 final DisplayContent dc = displayList.get(j);
987 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700988 }
989 }
990
991 // Remove all deferred displays stacks, tasks, and activities.
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700992 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
993 mChildren.get(displayNdx).checkCompleteDeferredRemoval();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700994 }
995
Jorim Jaggi4981f152019-03-26 18:58:45 +0100996 forAllDisplays(dc -> {
997 dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
998 dc.updateSystemGestureExclusion();
999 dc.updateTouchExcludeRegion();
1000 });
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001001
1002 // Check to see if we are now in a state where the screen should
1003 // be enabled, because the window obscured flags have changed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001004 mWmService.enableScreenIfNeededLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001005
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001006 mWmService.scheduleAnimationLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001007
Evan Rosky0037e5f2019-11-05 10:26:24 -08001008 // Send any pending task-info changes that were queued-up during a layout deferment
1009 mWmService.mAtmService.mTaskOrganizerController.dispatchPendingTaskInfoChanges();
1010
Evan Rosky73a7fe92019-11-18 18:28:01 -08001011 if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit");
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001012 }
1013
lumark588a3e82018-07-20 18:53:54 +08001014 private void checkAppTransitionReady(WindowSurfacePlacer surfacePlacer) {
1015 // Trace all displays app transition by Z-order for pending layout change.
1016 for (int i = mChildren.size() - 1; i >= 0; --i) {
1017 final DisplayContent curDisplay = mChildren.get(i);
1018
1019 // If we are ready to perform an app transition, check through all of the app tokens
1020 // to be shown and see if they are ready to go.
1021 if (curDisplay.mAppTransition.isReady()) {
1022 // handleAppTransitionReady may modify curDisplay.pendingLayoutChanges.
1023 curDisplay.mAppTransitionController.handleAppTransitionReady();
1024 if (DEBUG_LAYOUT_REPEATS) {
1025 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReady",
1026 curDisplay.pendingLayoutChanges);
1027 }
1028 }
1029
lumark9bca6b42019-10-17 18:35:22 +08001030 if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppTransitioning()) {
lumark588a3e82018-07-20 18:53:54 +08001031 // We have finished the animation of an app transition. To do this, we have
1032 // delayed a lot of operations like showing and hiding apps, moving apps in
1033 // Z-order, etc.
1034 // The app token list reflects the correct Z-order, but the window list may now
1035 // be out of sync with it. So here we will just rebuild the entire app window
1036 // list. Fun!
1037 curDisplay.handleAnimatingStoppedAndTransition();
1038 if (DEBUG_LAYOUT_REPEATS) {
1039 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
1040 curDisplay.pendingLayoutChanges);
1041 }
1042 }
1043 }
1044 }
1045
Riddle Hsu72d6dc32020-03-25 22:58:00 +08001046 private void applySurfaceChangesTransaction() {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001047 mHoldScreenWindow = null;
Wale Ogunwaled4a00a02016-10-10 11:29:17 -07001048 mObscuringWindow = null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001049
Andrii Kulian8ee72852017-03-10 10:36:45 -08001050 // TODO(multi-display): Support these features on secondary screens.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001051 final DisplayContent defaultDc = mWmService.getDefaultDisplayContentLocked();
lumark588a3e82018-07-20 18:53:54 +08001052 final DisplayInfo defaultInfo = defaultDc.getDisplayInfo();
1053 final int defaultDw = defaultInfo.logicalWidth;
1054 final int defaultDh = defaultInfo.logicalHeight;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001055 if (mWmService.mWatermark != null) {
chaviw619da692019-06-10 15:39:40 -07001056 mWmService.mWatermark.positionSurface(defaultDw, defaultDh, mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001057 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001058 if (mWmService.mStrictModeFlash != null) {
chaviw619da692019-06-10 15:39:40 -07001059 mWmService.mStrictModeFlash.positionSurface(defaultDw, defaultDh, mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001060 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001061 if (mWmService.mEmulatorDisplayOverlay != null) {
1062 mWmService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
chaviw619da692019-06-10 15:39:40 -07001063 mWmService.getDefaultDisplayRotation(), mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001064 }
1065
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001066 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001067 for (int j = 0; j < count; ++j) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001068 final DisplayContent dc = mChildren.get(j);
Riddle Hsu72d6dc32020-03-25 22:58:00 +08001069 dc.applySurfaceChangesTransaction();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001070 }
1071
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001072 // Give the display manager a chance to adjust properties like display rotation if it needs
1073 // to.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001074 mWmService.mDisplayManagerInternal.performTraversal(mDisplayTransaction);
Robert Carrae606b42018-02-15 15:36:23 -08001075 SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001076 }
1077
1078 /**
David Stevensf833ba92017-03-16 19:00:20 -07001079 * Handles resizing windows during surface placement.
David Stevensf833ba92017-03-16 19:00:20 -07001080 */
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001081 private void handleResizingWindows() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001082 for (int i = mWmService.mResizingWindows.size() - 1; i >= 0; i--) {
1083 WindowState win = mWmService.mResizingWindows.get(i);
Louis Changc3f29da2018-12-10 18:09:06 +08001084 if (win.mAppFreezing || win.getDisplayContent().mWaitingForConfig) {
1085 // Don't remove this window until rotation has completed and is not waiting for the
1086 // complete configuration.
David Stevensf833ba92017-03-16 19:00:20 -07001087 continue;
1088 }
1089 win.reportResized();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001090 mWmService.mResizingWindows.remove(i);
David Stevensf833ba92017-03-16 19:00:20 -07001091 }
David Stevensf833ba92017-03-16 19:00:20 -07001092 }
1093
1094 /**
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001095 * @param w WindowState this method is applied to.
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001096 * @param obscured True if there is a window on top of this obscuring the display.
1097 * @param syswin System window?
1098 * @return True when the display contains content to show the user. When false, the display
1099 * manager may choose to mirror or blank the display.
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001100 */
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001101 boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001102 final WindowManager.LayoutParams attrs = w.mAttrs;
1103 final int attrFlags = attrs.flags;
Aaron Whyte8cbdf042018-01-23 12:06:02 -08001104 final boolean onScreen = w.isOnScreen();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001105 final boolean canBeSeen = w.isDisplayedLw();
1106 final int privateflags = attrs.privateFlags;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001107 boolean displayHasContent = false;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001108
Adrian Roosb125e0b2019-10-02 14:55:14 +02001109 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
1110 "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w"
1111 + ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",
1112 w, w.mHasSurface, onScreen, w.isDisplayedLw(), w.mAttrs.userActivityTimeout);
Aaron Whyte8cbdf042018-01-23 12:06:02 -08001113 if (w.mHasSurface && onScreen) {
1114 if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
1115 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
Adrian Roosb125e0b2019-10-02 14:55:14 +02001116 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "mUserActivityTimeout set to %d",
1117 mUserActivityTimeout);
Aaron Whyte8cbdf042018-01-23 12:06:02 -08001118 }
1119 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001120 if (w.mHasSurface && canBeSeen) {
1121 if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
1122 mHoldScreen = w.mSession;
1123 mHoldScreenWindow = w;
Adrian Roosb125e0b2019-10-02 14:55:14 +02001124 } else if (w == mWmService.mLastWakeLockHoldingWindow) {
1125 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
1126 "handleNotObscuredLocked: %s was holding screen wakelock but no longer "
1127 + "has FLAG_KEEP_SCREEN_ON!!! called by%s",
1128 w, Debug.getCallers(10));
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001129 }
Fiona Campbell29dce0f2020-04-03 17:24:45 +01001130 if (!syswin && w.mAttrs.screenBrightness >= 0
1131 && Float.isNaN(mScreenBrightnessOverride)) {
1132 mScreenBrightnessOverride = w.mAttrs.screenBrightness;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001133 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001134
1135 final int type = attrs.type;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001136 // This function assumes that the contents of the default display are processed first
1137 // before secondary displays.
1138 final DisplayContent displayContent = w.getDisplayContent();
1139 if (displayContent != null && displayContent.isDefaultDisplay) {
1140 // While a dream or keyguard is showing, obscure ordinary application content on
1141 // secondary displays (by forcibly enabling mirroring unless there is other content
1142 // we want to show) but still allow opaque keyguard dialogs to be shown.
Galia Peycheva70b55712020-03-16 18:31:34 +01001143 if (w.isDreamWindow() || mWmService.mPolicy.isKeyguardShowing()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001144 mObscureApplicationContentOnSecondaryDisplays = true;
1145 }
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001146 displayHasContent = true;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001147 } else if (displayContent != null &&
1148 (!mObscureApplicationContentOnSecondaryDisplays
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001149 || (obscured && type == TYPE_KEYGUARD_DIALOG))) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001150 // Allow full screen keyguard presentation dialogs to be seen.
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001151 displayHasContent = true;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001152 }
1153 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1154 mSustainedPerformanceModeCurrent = true;
1155 }
1156 }
Wale Ogunwalef7cab102016-10-25 15:25:14 -07001157
1158 return displayHasContent;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001159 }
1160
Riddle Hsu654a6f92018-07-13 22:59:36 +08001161 boolean updateRotationUnchecked() {
1162 boolean changed = false;
1163 for (int i = mChildren.size() - 1; i >= 0; i--) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001164 if (mChildren.get(i).getDisplayRotation().updateRotationAndSendNewConfigIfChanged()) {
Riddle Hsu654a6f92018-07-13 22:59:36 +08001165 changed = true;
Riddle Hsu654a6f92018-07-13 22:59:36 +08001166 }
1167 }
1168 return changed;
1169 }
1170
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001171 boolean copyAnimToLayoutParams() {
1172 boolean doRequest = false;
1173
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001174 final int bulkUpdateParams = mWmService.mAnimator.mBulkUpdateParams;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001175 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1176 mUpdateRotation = true;
1177 doRequest = true;
1178 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001179 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1180 mOrientationChangeComplete = false;
1181 } else {
1182 mOrientationChangeComplete = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001183 mLastWindowFreezeSource = mWmService.mAnimator.mLastWindowFreezeSource;
1184 if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001185 doRequest = true;
1186 }
1187 }
chaviw042059d2018-01-11 11:24:08 -08001188
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001189 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1190 mWallpaperActionPending = true;
1191 }
1192
1193 return doRequest;
1194 }
1195
Jorim Jaggi86c39f92017-05-02 18:02:46 +02001196 private final class MyHandler extends Handler {
1197
1198 public MyHandler(Looper looper) {
1199 super(looper);
1200 }
1201
1202 @Override
1203 public void handleMessage(Message msg) {
1204 switch (msg.what) {
1205 case SET_SCREEN_BRIGHTNESS_OVERRIDE:
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001206 mWmService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
Fiona Campbell29dce0f2020-04-03 17:24:45 +01001207 Float.intBitsToFloat(msg.arg1));
Jorim Jaggi86c39f92017-05-02 18:02:46 +02001208 break;
1209 case SET_USER_ACTIVITY_TIMEOUT:
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001210 mWmService.mPowerManagerInternal.
1211 setUserActivityTimeoutOverrideFromWindowManager((Long) msg.obj);
Jorim Jaggi86c39f92017-05-02 18:02:46 +02001212 break;
1213 default:
1214 break;
1215 }
1216 }
1217 }
1218
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001219 void dumpDisplayContents(PrintWriter pw) {
1220 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001221 if (mWmService.mDisplayReady) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001222 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001223 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001224 final DisplayContent displayContent = mChildren.get(i);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001225 displayContent.dump(pw, " ", true /* dumpAll */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001226 }
1227 } else {
1228 pw.println(" NO DISPLAY");
1229 }
1230 }
1231
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001232 void dumpTopFocusedDisplayId(PrintWriter pw) {
1233 pw.print(" mTopFocusedDisplayId="); pw.println(mTopFocusedDisplayId);
1234 }
1235
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001236 void dumpLayoutNeededDisplayIds(PrintWriter pw) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001237 if (!isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001238 return;
1239 }
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001240 pw.print(" mLayoutNeeded on displays=");
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001241 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001242 for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001243 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001244 if (displayContent.isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001245 pw.print(displayContent.getDisplayId());
1246 }
1247 }
1248 pw.println();
1249 }
1250
1251 void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
Wale Ogunwaled1880962016-11-08 10:31:59 -08001252 final int[] index = new int[1];
1253 forAllWindows((w) -> {
1254 if (windows == null || windows.contains(w)) {
1255 pw.println(" Window #" + index[0] + " " + w + ":");
1256 w.dump(pw, " ", dumpAll || windows != null);
1257 index[0] = index[0] + 1;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001258 }
Wale Ogunwaled1880962016-11-08 10:31:59 -08001259 }, true /* traverseTopToBottom */);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001260 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001261
Wale Ogunwale02319a62016-09-26 15:21:22 -07001262 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1263 pw.println(" All tokens:");
1264 for (int i = mChildren.size() - 1; i >= 0; --i) {
1265 mChildren.get(i).dumpTokens(pw, dumpAll);
1266 }
1267 }
1268
Wale Ogunwalef342f062020-01-27 07:34:13 -08001269 @Override
1270 public void dumpDebug(ProtoOutputStream proto, long fieldId,
Nataniel Borges023ecb52019-01-16 14:15:43 -08001271 @WindowTraceLogLevel int logLevel) {
1272 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
1273 return;
1274 }
1275
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001276 final long token = proto.start(fieldId);
Jeffrey Huangcb782852019-12-05 11:28:11 -08001277 super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
Wale Ogunwalef342f062020-01-27 07:34:13 -08001278
1279 mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
1280 proto.write(IS_HOME_RECENTS_COMPONENT,
1281 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
1282 mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
1283
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001284 proto.end(token);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001285 }
1286
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001287 @Override
1288 String getName() {
1289 return "ROOT";
1290 }
Robert Carrb1579c82017-09-05 14:54:47 -07001291
1292 @Override
1293 void scheduleAnimation() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001294 mWmService.scheduleAnimationLocked();
Robert Carrb1579c82017-09-05 14:54:47 -07001295 }
Arthur Hung95b38a92018-07-20 18:56:12 +08001296
Charles Chen37848f32019-02-27 19:27:45 +08001297 @Override
1298 protected void removeChild(DisplayContent dc) {
1299 super.removeChild(dc);
1300 if (mTopFocusedDisplayId == dc.getDisplayId()) {
1301 mWmService.updateFocusedWindowLocked(
1302 UPDATE_FOCUS_NORMAL, true /* updateInputWindows */);
1303 }
1304 }
1305
Arthur Hung95b38a92018-07-20 18:56:12 +08001306 /**
1307 * For all display at or below this call the callback.
1308 *
1309 * @param callback Callback to be called for every display.
1310 */
1311 void forAllDisplays(Consumer<DisplayContent> callback) {
1312 for (int i = mChildren.size() - 1; i >= 0; --i) {
1313 callback.accept(mChildren.get(i));
1314 }
1315 }
lumark90120a82018-08-15 00:33:03 +08001316
Tiger Huang7c610aa2018-10-27 00:01:01 +08001317 void forAllDisplayPolicies(Consumer<DisplayPolicy> callback) {
1318 for (int i = mChildren.size() - 1; i >= 0; --i) {
1319 callback.accept(mChildren.get(i).getDisplayPolicy());
1320 }
1321 }
1322
lumark90120a82018-08-15 00:33:03 +08001323 /**
1324 * Get current topmost focused IME window in system.
1325 * Will look on all displays in current Z-order.
1326 */
1327 WindowState getCurrentInputMethodWindow() {
1328 for (int i = mChildren.size() - 1; i >= 0; --i) {
1329 final DisplayContent displayContent = mChildren.get(i);
1330 if (displayContent.mInputMethodWindow != null) {
1331 return displayContent.mInputMethodWindow;
1332 }
1333 }
1334 return null;
1335 }
Charles Chen173ae782019-11-11 20:39:02 +08001336
1337 void getDisplayContextsWithNonToastVisibleWindows(int pid, List<Context> outContexts) {
1338 if (outContexts == null) {
1339 return;
1340 }
1341 for (int i = mChildren.size() - 1; i >= 0; --i) {
1342 DisplayContent dc = mChildren.get(i);
1343 if (dc.isAnyNonToastWindowVisibleForPid(pid)) {
1344 outContexts.add(dc.getDisplayUiContext());
1345 }
1346 }
1347 }
1348
1349 @Nullable Context getDisplayUiContext(int displayId) {
1350 return getDisplayContent(displayId) != null
1351 ? getDisplayContent(displayId).getDisplayUiContext() : null;
1352 }
Louis Chang149d5c82019-12-30 09:47:39 +08001353
1354 void setWindowManager(WindowManagerService wm) {
1355 mWindowManager = wm;
1356 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
1357 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
1358 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
1359
1360 final Display[] displays = mDisplayManager.getDisplays();
1361 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
1362 final Display display = displays[displayNdx];
1363 final DisplayContent displayContent = new DisplayContent(display, this);
Garfield Tanfbd233a2019-12-26 12:39:25 -08001364 addChild(displayContent, POSITION_BOTTOM);
Louis Chang149d5c82019-12-30 09:47:39 +08001365 if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
1366 mDefaultDisplay = displayContent;
1367 }
1368 }
1369 calculateDefaultMinimalSizeOfResizeableTasks();
1370
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001371 final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();
Louis Changdff902b2020-03-31 13:32:47 +08001372 defaultTaskDisplayArea.getOrCreateRootHomeTask();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001373 positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent,
1374 false /* includingParents */);
Louis Chang149d5c82019-12-30 09:47:39 +08001375 }
1376
1377 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
1378 DisplayContent getDefaultDisplay() {
1379 return mDefaultDisplay;
1380 }
1381
1382 /**
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001383 * Get the default display area on the device dedicated to app windows. This one should be used
1384 * only as a fallback location for activity launches when no target display area is specified,
1385 * or for cases when multi-instance is not supported yet (like Split-screen, Freeform, PiP or
1386 * Recents).
1387 */
1388 TaskDisplayArea getDefaultTaskDisplayArea() {
1389 return mDefaultDisplay.getDefaultTaskDisplayArea();
1390 }
1391
1392 /**
Louis Chang149d5c82019-12-30 09:47:39 +08001393 * Get an existing instance of {@link DisplayContent} that has the given uniqueId. Unique ID is
1394 * defined in {@link DisplayInfo#uniqueId}.
1395 *
1396 * @param uniqueId the unique ID of the display
1397 * @return the {@link DisplayContent} or {@code null} if nothing is found.
1398 */
1399 DisplayContent getDisplayContent(String uniqueId) {
1400 for (int i = getChildCount() - 1; i >= 0; --i) {
1401 final DisplayContent display = getChildAt(i);
1402 final boolean isValid = display.mDisplay.isValid();
1403 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
1404 return display;
1405 }
1406 }
1407
1408 return null;
1409 }
1410
1411 // TODO: Look into consolidating with getDisplayContentOrCreate()
1412 DisplayContent getDisplayContent(int displayId) {
1413 for (int i = getChildCount() - 1; i >= 0; --i) {
1414 final DisplayContent displayContent = getChildAt(i);
1415 if (displayContent.mDisplayId == displayId) {
1416 return displayContent;
1417 }
1418 }
1419 return null;
1420 }
1421
1422 /**
1423 * Get an existing instance of {@link DisplayContent} or create new if there is a
1424 * corresponding record in display manager.
1425 */
1426 // TODO: Look into consolidating with getDisplayContent()
1427 @Nullable DisplayContent getDisplayContentOrCreate(int displayId) {
1428 DisplayContent displayContent = getDisplayContent(displayId);
1429 if (displayContent != null) {
1430 return displayContent;
1431 }
1432 if (mDisplayManager == null) {
1433 // The system isn't fully initialized yet.
1434 return null;
1435 }
1436 final Display display = mDisplayManager.getDisplay(displayId);
1437 if (display == null) {
1438 // The display is not registered in DisplayManager.
1439 return null;
1440 }
1441 // The display hasn't been added to ActivityManager yet, create a new record now.
1442 displayContent = new DisplayContent(display, this);
Garfield Tanfbd233a2019-12-26 12:39:25 -08001443 addChild(displayContent, POSITION_BOTTOM);
Louis Chang149d5c82019-12-30 09:47:39 +08001444 return displayContent;
1445 }
1446
Louis Chang149d5c82019-12-30 09:47:39 +08001447 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07001448 return getDefaultTaskDisplayArea().getHomeActivityForUser(userId);
Louis Chang149d5c82019-12-30 09:47:39 +08001449 }
1450
1451 boolean startHomeOnAllDisplays(int userId, String reason) {
1452 boolean homeStarted = false;
1453 for (int i = getChildCount() - 1; i >= 0; i--) {
1454 final int displayId = getChildAt(i).mDisplayId;
1455 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
1456 }
1457 return homeStarted;
1458 }
1459
1460 void startHomeOnEmptyDisplays(String reason) {
1461 for (int i = getChildCount() - 1; i >= 0; i--) {
1462 final DisplayContent display = getChildAt(i);
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001463 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1464 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
1465 if (taskDisplayArea.topRunningActivity() == null) {
1466 startHomeOnTaskDisplayArea(mCurrentUser, reason, taskDisplayArea,
1467 false /* allowInstrumenting */, false /* fromHomeKey */);
1468 }
Louis Chang149d5c82019-12-30 09:47:39 +08001469 }
1470 }
1471 }
1472
1473 boolean startHomeOnDisplay(int userId, String reason, int displayId) {
1474 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
1475 false /* fromHomeKey */);
1476 }
1477
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001478 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
1479 boolean fromHomeKey) {
1480 // Fallback to top focused display or default display if the displayId is invalid.
1481 if (displayId == INVALID_DISPLAY) {
1482 final ActivityStack stack = getTopDisplayFocusedStack();
1483 displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
1484 }
1485
1486 final DisplayContent display = getDisplayContent(displayId);
1487 boolean result = false;
1488 for (int tcNdx = display.getTaskDisplayAreaCount() - 1; tcNdx >= 0; --tcNdx) {
1489 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tcNdx);
1490 result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
1491 allowInstrumenting, fromHomeKey);
1492 }
1493 return result;
1494 }
1495
Louis Chang149d5c82019-12-30 09:47:39 +08001496 /**
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001497 * This starts home activity on display areas that can have system decorations based on
1498 * displayId - default display area always uses primary home component.
1499 * For secondary display areas, the home activity must have category SECONDARY_HOME and then
1500 * resolves according to the priorities listed below.
Louis Chang149d5c82019-12-30 09:47:39 +08001501 * - If default home is not set, always use the secondary home defined in the config.
1502 * - Use currently selected primary home activity.
1503 * - Use the activity in the same package as currently selected primary home activity.
1504 * If there are multiple activities matched, use first one.
1505 * - Use the secondary home defined in the config.
1506 */
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001507 boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
1508 boolean allowInstrumenting, boolean fromHomeKey) {
1509 // Fallback to top focused display area if the provided one is invalid.
1510 if (taskDisplayArea == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08001511 final ActivityStack stack = getTopDisplayFocusedStack();
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001512 taskDisplayArea = stack != null ? stack.getDisplayArea()
1513 : getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08001514 }
1515
1516 Intent homeIntent = null;
1517 ActivityInfo aInfo = null;
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001518 if (taskDisplayArea == getDefaultTaskDisplayArea()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001519 homeIntent = mService.getHomeIntent();
1520 aInfo = resolveHomeActivity(userId, homeIntent);
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001521 } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001522 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
Louis Chang149d5c82019-12-30 09:47:39 +08001523 aInfo = info.first;
1524 homeIntent = info.second;
1525 }
1526 if (aInfo == null || homeIntent == null) {
1527 return false;
1528 }
1529
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001530 if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
Louis Chang149d5c82019-12-30 09:47:39 +08001531 return false;
1532 }
1533
1534 // Updates the home component of the intent.
1535 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
1536 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
1537 // Updates the extra information of the intent.
1538 if (fromHomeKey) {
1539 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
lumark04bceb92020-03-07 00:03:33 +08001540 mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity");
Louis Chang149d5c82019-12-30 09:47:39 +08001541 }
1542 // Update the reason for ANR debugging to verify if the user activity is the one that
1543 // actually launched.
1544 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001545 aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
Louis Chang149d5c82019-12-30 09:47:39 +08001546 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001547 taskDisplayArea);
Louis Chang149d5c82019-12-30 09:47:39 +08001548 return true;
1549 }
1550
1551 /**
1552 * This resolves the home activity info.
1553 * @return the home activity info if any.
1554 */
1555 @VisibleForTesting
1556 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
1557 final int flags = ActivityManagerService.STOCK_PM_FLAGS;
1558 final ComponentName comp = homeIntent.getComponent();
1559 ActivityInfo aInfo = null;
1560 try {
1561 if (comp != null) {
1562 // Factory test.
1563 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
1564 } else {
1565 final String resolvedType =
1566 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
1567 final ResolveInfo info = AppGlobals.getPackageManager()
1568 .resolveIntent(homeIntent, resolvedType, flags, userId);
1569 if (info != null) {
1570 aInfo = info.activityInfo;
1571 }
1572 }
1573 } catch (RemoteException e) {
1574 // ignore
1575 }
1576
1577 if (aInfo == null) {
1578 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
1579 return null;
1580 }
1581
1582 aInfo = new ActivityInfo(aInfo);
1583 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
1584 return aInfo;
1585 }
1586
1587 @VisibleForTesting
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001588 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId,
1589 @NonNull TaskDisplayArea taskDisplayArea) {
1590 if (taskDisplayArea == getDefaultTaskDisplayArea()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001591 throw new IllegalArgumentException(
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001592 "resolveSecondaryHomeActivity: Should not be default task container");
Louis Chang149d5c82019-12-30 09:47:39 +08001593 }
1594 // Resolve activities in the same package as currently selected primary home activity.
1595 Intent homeIntent = mService.getHomeIntent();
1596 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
1597 if (aInfo != null) {
1598 if (ResolverActivity.class.getName().equals(aInfo.name)) {
1599 // Always fallback to secondary home component if default home is not set.
1600 aInfo = null;
1601 } else {
1602 // Look for secondary home activities in the currently selected default home
1603 // package.
1604 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
1605 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
1606 final int size = resolutions.size();
1607 final String targetName = aInfo.name;
1608 aInfo = null;
1609 for (int i = 0; i < size; i++) {
1610 ResolveInfo resolveInfo = resolutions.get(i);
1611 // We need to traverse all resolutions to check if the currently selected
1612 // default home activity is present.
1613 if (resolveInfo.activityInfo.name.equals(targetName)) {
1614 aInfo = resolveInfo.activityInfo;
1615 break;
1616 }
1617 }
1618 if (aInfo == null && size > 0) {
1619 // First one is the best.
1620 aInfo = resolutions.get(0).activityInfo;
1621 }
1622 }
1623 }
1624
1625 if (aInfo != null) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001626 if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, false /* allowInstrumenting */)) {
Louis Chang149d5c82019-12-30 09:47:39 +08001627 aInfo = null;
1628 }
1629 }
1630
1631 // Fallback to secondary home component.
1632 if (aInfo == null) {
1633 homeIntent = mService.getSecondaryHomeIntent(null);
1634 aInfo = resolveHomeActivity(userId, homeIntent);
1635 }
1636 return Pair.create(aInfo, homeIntent);
1637 }
1638
1639 /**
1640 * Retrieve all activities that match the given intent.
1641 * The list should already ordered from best to worst matched.
1642 * {@link android.content.pm.PackageManager#queryIntentActivities}
1643 */
1644 @VisibleForTesting
1645 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
1646 List<ResolveInfo> resolutions;
1647 try {
1648 final String resolvedType =
1649 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
1650 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
1651 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
1652
1653 } catch (RemoteException e) {
1654 resolutions = new ArrayList<>();
1655 }
1656 return resolutions;
1657 }
1658
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001659 boolean resumeHomeActivity(ActivityRecord prev, String reason,
1660 TaskDisplayArea taskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08001661 if (!mService.isBooting() && !mService.isBooted()) {
1662 // Not ready yet!
1663 return false;
1664 }
1665
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001666 if (taskDisplayArea == null) {
1667 taskDisplayArea = getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08001668 }
1669
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001670 final ActivityRecord r = taskDisplayArea.getHomeActivity();
Louis Chang149d5c82019-12-30 09:47:39 +08001671 final String myReason = reason + " resumeHomeActivity";
1672
1673 // Only resume home activity if isn't finishing.
1674 if (r != null && !r.finishing) {
1675 r.moveFocusableActivityToTop(myReason);
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08001676 return resumeFocusedStacksTopActivities(r.getRootTask(), prev, null);
Louis Chang149d5c82019-12-30 09:47:39 +08001677 }
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07001678 return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
1679 false /* allowInstrumenting */, false /* fromHomeKey */);
Louis Chang149d5c82019-12-30 09:47:39 +08001680 }
1681
1682 /**
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001683 * Check if the display area is valid for secondary home activity.
1684 * @param taskDisplayArea The target display area.
Louis Chang149d5c82019-12-30 09:47:39 +08001685 * @return {@code true} if allow to launch, {@code false} otherwise.
1686 */
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001687 boolean shouldPlaceSecondaryHomeOnDisplayArea(TaskDisplayArea taskDisplayArea) {
1688 if (getDefaultTaskDisplayArea() == taskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08001689 throw new IllegalArgumentException(
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001690 "shouldPlaceSecondaryHomeOnDisplay: Should not be on default task container");
1691 } else if (taskDisplayArea == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08001692 return false;
1693 }
1694
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001695 if (taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) {
Louis Chang149d5c82019-12-30 09:47:39 +08001696 // Can't launch home on secondary display if device does not support multi-display.
1697 return false;
1698 }
1699
1700 final boolean deviceProvisioned = Settings.Global.getInt(
1701 mService.mContext.getContentResolver(),
1702 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1703 if (!deviceProvisioned) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001704 // Can't launch home on secondary display areas before device is provisioned.
Louis Chang149d5c82019-12-30 09:47:39 +08001705 return false;
1706 }
1707
1708 if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001709 // Can't launch home on secondary display areas if device is still locked.
Louis Chang149d5c82019-12-30 09:47:39 +08001710 return false;
1711 }
1712
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001713 final DisplayContent display = taskDisplayArea.getDisplayContent();
Louis Chang149d5c82019-12-30 09:47:39 +08001714 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
1715 // Can't launch home on display that doesn't support system decorations.
1716 return false;
1717 }
1718
1719 return true;
1720 }
1721
1722 /**
1723 * Check if home activity start should be allowed on a display.
1724 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001725 * @param taskDisplayArea The target display area.
Louis Chang149d5c82019-12-30 09:47:39 +08001726 * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
1727 * @return {@code true} if allow to launch, {@code false} otherwise.
1728 */
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001729 boolean canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea,
Louis Chang149d5c82019-12-30 09:47:39 +08001730 boolean allowInstrumenting) {
1731 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
1732 && mService.mTopAction == null) {
1733 // We are running in factory test mode, but unable to find the factory test app, so
1734 // just sit around displaying the error message and don't try to start anything.
1735 return false;
1736 }
1737
1738 final WindowProcessController app =
1739 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
1740 if (!allowInstrumenting && app != null && app.isInstrumenting()) {
1741 // Don't do this if the home app is currently being instrumented.
1742 return false;
1743 }
1744
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001745 final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId()
1746 : INVALID_DISPLAY;
Louis Chang149d5c82019-12-30 09:47:39 +08001747 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
1748 && displayId == mService.mVr2dDisplayId)) {
1749 // No restrictions to default display or vr 2d display.
1750 return true;
1751 }
1752
Andrii Kulian1cfcae82020-04-10 12:44:38 -07001753 if (!shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Louis Chang149d5c82019-12-30 09:47:39 +08001754 return false;
1755 }
1756
1757 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
1758 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
1759 if (!supportMultipleInstance) {
1760 // Can't launch home on secondary displays if it requested to be single instance.
1761 return false;
1762 }
1763
1764 return true;
1765 }
1766
1767 /**
1768 * Ensure all activities visibility, update orientation and configuration.
1769 *
1770 * @param starting The currently starting activity or {@code null} if there is none.
1771 * @param displayId The id of the display where operation is executed.
1772 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
1773 * {@code true} if config changed.
1774 * @param deferResume Whether to defer resume while updating config.
1775 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
1776 * because of configuration update.
1777 */
1778 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
1779 boolean markFrozenIfConfigChanged, boolean deferResume) {
1780 // First ensure visibility without updating the config just yet. We need this to know what
1781 // activities are affecting configuration now.
1782 // Passing null here for 'starting' param value, so that visibility of actual starting
1783 // activity will be properly updated.
1784 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
1785 false /* preserveWindows */, false /* notifyClients */);
1786
1787 if (displayId == INVALID_DISPLAY) {
1788 // The caller didn't provide a valid display id, skip updating config.
1789 return true;
1790 }
1791
1792 // Force-update the orientation from the WindowManager, since we need the true configuration
1793 // to send to the client now.
1794 final DisplayContent displayContent = getDisplayContent(displayId);
1795 Configuration config = null;
1796 if (displayContent != null) {
1797 config = displayContent.updateOrientation(
1798 getDisplayOverrideConfiguration(displayId),
1799 starting != null && starting.mayFreezeScreenLocked()
1800 ? starting.appToken : null,
1801 true /* forceUpdate */);
1802 }
1803 // Visibilities may change so let the starting activity have a chance to report. Can't do it
1804 // when visibility is changed in each AppWindowToken because it may trigger wrong
1805 // configuration push because the visibility of some activities may not be updated yet.
1806 if (starting != null) {
1807 starting.reportDescendantOrientationChangeIfNeeded();
1808 }
1809 if (starting != null && markFrozenIfConfigChanged && config != null) {
1810 starting.frozenBeforeDestroy = true;
1811 }
1812
1813 if (displayContent != null) {
1814 // Update the configuration of the activities on the display.
1815 return displayContent.updateDisplayOverrideConfigurationLocked(config, starting,
1816 deferResume, null /* result */);
1817 } else {
1818 return true;
1819 }
1820 }
1821
1822 /**
1823 * @return a list of activities which are the top ones in each visible stack. The first
1824 * entry will be the focused activity.
1825 */
1826 List<IBinder> getTopVisibleActivities() {
1827 final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
1828 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
1829 // Traverse all displays.
Andrii Kulianf9df4a82020-03-31 12:09:27 -07001830 for (int dNdx = getChildCount() - 1; dNdx >= 0; dNdx--) {
1831 final DisplayContent display = getChildAt(dNdx);
1832 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1833 final TaskDisplayArea taskDisplayArea =
1834 display.getTaskDisplayAreaAt(tdaNdx);
1835 // Traverse all stacks on a display area.
1836 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
1837 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
1838 // Get top activity from a visible stack and add it to the list.
1839 if (stack.shouldBeVisible(null /* starting */)) {
1840 final ActivityRecord top = stack.getTopNonFinishingActivity();
1841 if (top != null) {
1842 if (stack == topFocusedStack) {
1843 topActivityTokens.add(0, top.appToken);
1844 } else {
1845 topActivityTokens.add(top.appToken);
1846 }
Louis Chang149d5c82019-12-30 09:47:39 +08001847 }
1848 }
1849 }
1850 }
1851 }
1852 return topActivityTokens;
1853 }
1854
1855 ActivityStack getTopDisplayFocusedStack() {
1856 for (int i = getChildCount() - 1; i >= 0; --i) {
1857 final ActivityStack focusedStack = getChildAt(i).getFocusedStack();
1858 if (focusedStack != null) {
1859 return focusedStack;
1860 }
1861 }
1862 return null;
1863 }
1864
1865 ActivityRecord getTopResumedActivity() {
1866 final ActivityStack focusedStack = getTopDisplayFocusedStack();
1867 if (focusedStack == null) {
1868 return null;
1869 }
1870 final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
1871 if (resumedActivity != null && resumedActivity.app != null) {
1872 return resumedActivity;
1873 }
1874 // The top focused stack might not have a resumed activity yet - look on all displays in
1875 // focus order.
1876 for (int i = getChildCount() - 1; i >= 0; --i) {
1877 final DisplayContent display = getChildAt(i);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07001878 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1879 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
1880 final ActivityRecord resumedActivityOnTaskContainer = taskDisplayArea
1881 .getFocusedActivity();
1882 if (resumedActivityOnTaskContainer != null) {
1883 return resumedActivityOnTaskContainer;
1884 }
Louis Chang149d5c82019-12-30 09:47:39 +08001885 }
1886 }
1887 return null;
1888 }
1889
Louis Chang149d5c82019-12-30 09:47:39 +08001890 boolean isTopDisplayFocusedStack(ActivityStack stack) {
1891 return stack != null && stack == getTopDisplayFocusedStack();
1892 }
1893
1894 void updatePreviousProcess(ActivityRecord r) {
1895 // Now that this process has stopped, we may want to consider it to be the previous app to
1896 // try to keep around in case the user wants to return to it.
1897
1898 // First, found out what is currently the foreground app, so that we don't blow away the
1899 // previous app if this activity is being hosted by the process that is actually still the
1900 // foreground.
1901 WindowProcessController fgApp = null;
1902 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
1903 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07001904 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
1905 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
1906 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
1907 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
1908 if (isTopDisplayFocusedStack(stack)) {
1909 final ActivityRecord resumedActivity = stack.getResumedActivity();
1910 if (resumedActivity != null) {
1911 fgApp = resumedActivity.app;
1912 } else if (stack.mPausingActivity != null) {
1913 fgApp = stack.mPausingActivity.app;
1914 }
1915 break;
Louis Chang149d5c82019-12-30 09:47:39 +08001916 }
Louis Chang149d5c82019-12-30 09:47:39 +08001917 }
1918 }
1919 }
1920
1921 // Now set this one as the previous process, only if that really makes sense to.
1922 if (r.hasProcess() && fgApp != null && r.app != fgApp
1923 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
1924 && r.app != mService.mHomeProcess) {
1925 mService.mPreviousProcess = r.app;
1926 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1927 }
1928 }
1929
1930 boolean attachApplication(WindowProcessController app) throws RemoteException {
1931 final String processName = app.mName;
1932 boolean didSomething = false;
1933 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
1934 final DisplayContent display = getChildAt(displayNdx);
1935 final ActivityStack stack = display.getFocusedStack();
1936 if (stack == null) {
1937 continue;
1938 }
1939
1940 mTmpRemoteException = null;
1941 mTmpBoolean = false; // Set to true if an activity was started.
1942 final PooledFunction c = PooledLambda.obtainFunction(
1943 RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
1944 PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
1945 stack.forAllActivities(c);
1946 c.recycle();
1947 if (mTmpRemoteException != null) {
1948 throw mTmpRemoteException;
1949 }
1950 didSomething |= mTmpBoolean;
1951 }
1952 if (!didSomething) {
1953 ensureActivitiesVisible(null, 0, false /* preserve_windows */);
1954 }
1955 return didSomething;
1956 }
1957
1958 private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
1959 WindowProcessController app, ActivityRecord top) {
1960 if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
1961 || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
1962 return false;
1963 }
1964
1965 try {
1966 if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
1967 true /*checkConfig*/)) {
1968 mTmpBoolean = true;
1969 }
1970 } catch (RemoteException e) {
1971 Slog.w(TAG, "Exception in new application when starting activity "
1972 + top.intent.getComponent().flattenToShortString(), e);
1973 mTmpRemoteException = e;
1974 return true;
1975 }
1976 return false;
1977 }
1978
1979 /**
1980 * Make sure that all activities that need to be visible in the system actually are and update
1981 * their configuration.
1982 */
1983 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
1984 boolean preserveWindows) {
1985 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
1986 }
1987
1988 /**
1989 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
1990 */
1991 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
1992 boolean preserveWindows, boolean notifyClients) {
Riddle Hsuf2ff25f2020-04-29 19:15:33 +08001993 if (mStackSupervisor.inActivityVisibilityUpdate()) {
Louis Chang149d5c82019-12-30 09:47:39 +08001994 // Don't do recursive work.
1995 return;
1996 }
Louis Chang149d5c82019-12-30 09:47:39 +08001997
1998 try {
Riddle Hsuf2ff25f2020-04-29 19:15:33 +08001999 mStackSupervisor.beginActivityVisibilityUpdate();
Louis Chang149d5c82019-12-30 09:47:39 +08002000 // First the front stacks. In case any are not fullscreen and are in front of home.
2001 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2002 final DisplayContent display = getChildAt(displayNdx);
2003 display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
2004 notifyClients);
2005 }
2006 } finally {
Riddle Hsuf2ff25f2020-04-29 19:15:33 +08002007 mStackSupervisor.endActivityVisibilityUpdate();
Louis Chang149d5c82019-12-30 09:47:39 +08002008 }
2009 }
2010
2011 boolean switchUser(int userId, UserState uss) {
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08002012 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
2013 final int focusStackId = topFocusedStack != null
2014 ? topFocusedStack.getRootTaskId() : INVALID_TASK_ID;
Louis Chang149d5c82019-12-30 09:47:39 +08002015 // We dismiss the docked stack whenever we switch users.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002016 if (getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
2017 getDefaultTaskDisplayArea().onSplitScreenModeDismissed();
Louis Chang149d5c82019-12-30 09:47:39 +08002018 }
2019 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
2020 // also cause all tasks to be moved to the fullscreen stack at a position that is
2021 // appropriate.
2022 removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2023
2024 mUserStackInFront.put(mCurrentUser, focusStackId);
Louis Chang149d5c82019-12-30 09:47:39 +08002025 mCurrentUser = userId;
2026
2027 mStackSupervisor.mStartingUsers.add(uss);
2028 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2029 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002030 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2031 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2032 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2033 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2034 stack.switchUser(userId);
2035 }
Louis Chang149d5c82019-12-30 09:47:39 +08002036 }
2037 }
2038
Darryl L Johnson3388bd22019-12-19 17:38:41 -08002039 final int restoreStackId = mUserStackInFront.get(userId);
Louis Chang149d5c82019-12-30 09:47:39 +08002040 ActivityStack stack = getStack(restoreStackId);
2041 if (stack == null) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002042 stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
Louis Chang149d5c82019-12-30 09:47:39 +08002043 }
2044 final boolean homeInFront = stack.isActivityTypeHome();
2045 if (stack.isOnHomeDisplay()) {
2046 stack.moveToFront("switchUserOnHomeDisplay");
2047 } else {
2048 // Stack was moved to another display while user was swapped out.
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002049 resumeHomeActivity(null, "switchUserOnOtherDisplay", getDefaultTaskDisplayArea());
Louis Chang149d5c82019-12-30 09:47:39 +08002050 }
2051 return homeInFront;
2052 }
2053
2054 void removeUser(int userId) {
2055 mUserStackInFront.delete(userId);
2056 }
2057
2058 /**
2059 * Update the last used stack id for non-current user (current user's last
2060 * used stack is the focused stack)
2061 */
2062 void updateUserStack(int userId, ActivityStack stack) {
2063 if (userId != mCurrentUser) {
Darryl L Johnson3388bd22019-12-19 17:38:41 -08002064 if (stack == null) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002065 stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
Darryl L Johnson3388bd22019-12-19 17:38:41 -08002066 }
2067
2068 mUserStackInFront.put(userId, stack.getRootTaskId());
Louis Chang149d5c82019-12-30 09:47:39 +08002069 }
2070 }
2071
2072 /**
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002073 * Move stack with all its existing content to specified task display area.
2074 * @param stackId Id of stack to move.
2075 * @param taskDisplayArea The task display area to move stack to.
2076 * @param onTop Indicates whether container should be place on top or on bottom.
2077 */
2078 void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) {
2079 final ActivityStack stack = getStack(stackId);
2080 if (stack == null) {
2081 throw new IllegalArgumentException("moveStackToTaskDisplayArea: Unknown stackId="
2082 + stackId);
2083 }
2084
2085 final TaskDisplayArea currentTaskDisplayArea = stack.getDisplayArea();
2086 if (currentTaskDisplayArea == null) {
2087 throw new IllegalStateException("moveStackToTaskDisplayArea: stack=" + stack
2088 + " is not attached to any task display area.");
2089 }
2090
2091 if (taskDisplayArea == null) {
2092 throw new IllegalArgumentException(
2093 "moveStackToTaskDisplayArea: Unknown taskDisplayArea=" + taskDisplayArea);
2094 }
2095
2096 if (currentTaskDisplayArea == taskDisplayArea) {
2097 throw new IllegalArgumentException("Trying to move stack=" + stack
2098 + " to its current taskDisplayArea=" + taskDisplayArea);
2099 }
2100 stack.reparent(taskDisplayArea, onTop);
2101 // TODO(multi-display): resize stacks properly if moved from split-screen.
2102 }
2103
2104 /**
Louis Chang149d5c82019-12-30 09:47:39 +08002105 * Move stack with all its existing content to specified display.
2106 * @param stackId Id of stack to move.
2107 * @param displayId Id of display to move stack to.
2108 * @param onTop Indicates whether container should be place on top or on bottom.
2109 */
2110 void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
2111 final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
2112 if (displayContent == null) {
2113 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
2114 + displayId);
2115 }
Louis Chang149d5c82019-12-30 09:47:39 +08002116
2117 if (displayContent.isSingleTaskInstance() && displayContent.getStackCount() > 0) {
2118 // We don't allow moving stacks to single instance display that already has a child.
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002119 Slog.e(TAG, "Can not move stackId=" + stackId
Louis Chang149d5c82019-12-30 09:47:39 +08002120 + " to single task instance display=" + displayContent);
2121 return;
2122 }
2123
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002124 moveStackToTaskDisplayArea(stackId, displayContent.getDefaultTaskDisplayArea(), onTop);
Louis Chang149d5c82019-12-30 09:47:39 +08002125 }
2126
2127 boolean moveTopStackActivityToPinnedStack(int stackId) {
2128 final ActivityStack stack = getStack(stackId);
2129 if (stack == null) {
2130 throw new IllegalArgumentException(
2131 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
2132 }
2133
2134 final ActivityRecord r = stack.topRunningActivity();
2135 if (r == null) {
2136 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
2137 + " in stack=" + stack);
2138 return false;
2139 }
2140
2141 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
2142 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
2143 + " r=" + r);
2144 return false;
2145 }
2146
Hongwei Wange8e32862020-04-08 13:23:45 -07002147 moveActivityToPinnedStack(r, "moveTopActivityToPinnedStack");
Louis Chang149d5c82019-12-30 09:47:39 +08002148 return true;
2149 }
2150
Hongwei Wange8e32862020-04-08 13:23:45 -07002151 void moveActivityToPinnedStack(ActivityRecord r, String reason) {
Louis Chang149d5c82019-12-30 09:47:39 +08002152 mService.deferWindowLayout();
2153
Andrii Kulian86d676c2020-03-27 19:34:54 -07002154 final TaskDisplayArea taskDisplayArea = r.getDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08002155
2156 try {
2157 final Task task = r.getTask();
Andrii Kulian86d676c2020-03-27 19:34:54 -07002158 final ActivityStack pinnedStack = taskDisplayArea.getRootPinnedTask();
Winson Chung8b5d23a2020-04-06 19:23:23 -07002159
Louis Chang149d5c82019-12-30 09:47:39 +08002160 // This will change the pinned stack's windowing mode to its original mode, ensuring
2161 // we only have one stack that is in pinned mode.
2162 if (pinnedStack != null) {
2163 pinnedStack.dismissPip();
2164 }
2165
Winson Chung8b5d23a2020-04-06 19:23:23 -07002166 // Set a transition to ensure that we don't immediately try and update the visibility
2167 // of the activity entering PIP
2168 r.getDisplayContent().prepareAppTransition(TRANSIT_NONE, false);
Louis Chang149d5c82019-12-30 09:47:39 +08002169
Winson Chung8b5d23a2020-04-06 19:23:23 -07002170 final boolean singleActivity = task.getChildCount() == 1;
Louis Chang149d5c82019-12-30 09:47:39 +08002171 final ActivityStack stack;
2172 if (singleActivity) {
Evan Rosky2af969c2020-05-08 16:26:31 +00002173 stack = (ActivityStack) task;
Louis Chang149d5c82019-12-30 09:47:39 +08002174 } else {
Louis Changa009c762020-02-26 11:21:31 +08002175 // In the case of multiple activities, we will create a new task for it and then
2176 // move the PIP activity into the task.
Hongwei Wange8e32862020-04-08 13:23:45 -07002177 stack = taskDisplayArea.createStack(WINDOWING_MODE_UNDEFINED, r.getActivityType(),
Andrii Kulian86d676c2020-03-27 19:34:54 -07002178 ON_TOP, r.info, r.intent, false /* createdByOrganizer */);
Louis Changa009c762020-02-26 11:21:31 +08002179
Louis Chang149d5c82019-12-30 09:47:39 +08002180 // There are multiple activities in the task and moving the top activity should
2181 // reveal/leave the other activities in their original task.
Hongwei Wange8e32862020-04-08 13:23:45 -07002182 // On the other hand, ActivityRecord#onParentChanged takes care of setting the
2183 // up-to-dated pinned stack information on this newly created stack.
2184 r.reparent(stack, MAX_VALUE, reason);
Louis Chang149d5c82019-12-30 09:47:39 +08002185 }
Evan Rosky2af969c2020-05-08 16:26:31 +00002186 if (stack.getParent() != taskDisplayArea) {
2187 // stack is nested, but pinned tasks need to be direct children of their
2188 // display area, so reparent.
2189 stack.reparent(taskDisplayArea, true /* onTop */);
2190 }
Winson Chungc4d4ee82020-05-05 12:51:06 -07002191 // Defer the windowing mode change until after the transition to prevent the activity
2192 // from doing work and changing the activity visuals while animating
2193 // TODO(task-org): Figure-out more structured way to do this long term.
2194 r.setWindowingMode(stack.getWindowingMode());
Hongwei Wange8e32862020-04-08 13:23:45 -07002195 stack.setWindowingMode(WINDOWING_MODE_PINNED);
Louis Chang149d5c82019-12-30 09:47:39 +08002196
Louis Chang149d5c82019-12-30 09:47:39 +08002197 // Reset the state that indicates it can enter PiP while pausing after we've moved it
2198 // to the pinned stack
2199 r.supportsEnterPipOnTaskSwitch = false;
2200 } finally {
2201 mService.continueWindowLayout();
2202 }
2203
Louis Chang149d5c82019-12-30 09:47:39 +08002204 ensureActivitiesVisible(null, 0, false /* preserveWindows */);
2205 resumeFocusedStacksTopActivities();
2206
2207 mService.getTaskChangeNotificationController().notifyActivityPinned(r);
2208 }
2209
2210 void executeAppTransitionForAllDisplay() {
2211 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2212 final DisplayContent display = getChildAt(displayNdx);
2213 display.mDisplayContent.executeAppTransition();
2214 }
2215 }
2216
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002217 ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08002218 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
2219 mTmpFindTaskResult.clear();
2220
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002221 // Looking up task on preferred display area first
2222 if (preferredTaskDisplayArea != null) {
2223 preferredTaskDisplayArea.findTaskLocked(r, true /* isPreferredDisplay */,
2224 mTmpFindTaskResult);
Louis Chang149d5c82019-12-30 09:47:39 +08002225 if (mTmpFindTaskResult.mIdealMatch) {
2226 return mTmpFindTaskResult.mRecord;
2227 }
2228 }
2229
2230 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2231 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002232 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2233 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2234 if (taskDisplayArea == preferredTaskDisplayArea) {
2235 continue;
2236 }
Louis Chang149d5c82019-12-30 09:47:39 +08002237
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002238 taskDisplayArea.findTaskLocked(r, false /* isPreferredDisplay */,
2239 mTmpFindTaskResult);
2240 if (mTmpFindTaskResult.mIdealMatch) {
2241 return mTmpFindTaskResult.mRecord;
2242 }
Louis Chang149d5c82019-12-30 09:47:39 +08002243 }
2244 }
2245
2246 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
2247 return mTmpFindTaskResult.mRecord;
2248 }
2249
2250 /**
2251 * Finish the topmost activities in all stacks that belong to the crashed app.
2252 * @param app The app that crashed.
2253 * @param reason Reason to perform this action.
2254 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
2255 */
2256 int finishTopCrashedActivities(WindowProcessController app, String reason) {
2257 Task finishedTask = null;
2258 ActivityStack focusedStack = getTopDisplayFocusedStack();
2259 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2260 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002261 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2262 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2263 // It is possible that request to finish activity might also remove its task and
2264 // stack, so we need to be careful with indexes in the loop and check child count
2265 // every time.
Andrii Kulian5bb053b2020-04-08 17:04:33 -07002266 for (int stackNdx = 0; stackNdx < taskDisplayArea.getStackCount(); ++stackNdx) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002267 final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx);
2268 final Task t = stack.finishTopCrashedActivityLocked(app, reason);
2269 if (stack == focusedStack || finishedTask == null) {
2270 finishedTask = t;
2271 }
Louis Chang149d5c82019-12-30 09:47:39 +08002272 }
2273 }
2274 }
2275 return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
2276 }
2277
2278 boolean resumeFocusedStacksTopActivities() {
2279 return resumeFocusedStacksTopActivities(null, null, null);
2280 }
2281
2282 boolean resumeFocusedStacksTopActivities(
2283 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
2284
2285 if (!mStackSupervisor.readyToResume()) {
2286 return false;
2287 }
2288
2289 boolean result = false;
Andrii Kulian86d676c2020-03-27 19:34:54 -07002290 if (targetStack != null && (targetStack.isTopStackInDisplayArea()
Louis Chang149d5c82019-12-30 09:47:39 +08002291 || getTopDisplayFocusedStack() == targetStack)) {
2292 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
2293 }
2294
2295 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2296 boolean resumedOnDisplay = false;
2297 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002298 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2299 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2300 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2301 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2302 final ActivityRecord topRunningActivity = stack.topRunningActivity();
2303 if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
2304 continue;
2305 }
2306 if (stack == targetStack) {
2307 // Simply update the result for targetStack because the targetStack had
2308 // already resumed in above. We don't want to resume it again, especially in
2309 // some cases, it would cause a second launch failure if app process was
2310 // dead.
2311 resumedOnDisplay |= result;
2312 continue;
2313 }
2314 if (taskDisplayArea.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
2315 // Kick off any lingering app transitions form the MoveTaskToFront
2316 // operation, but only consider the top task and stack on that display.
2317 stack.executeAppTransition(targetOptions);
2318 } else {
2319 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
2320 }
Louis Chang149d5c82019-12-30 09:47:39 +08002321 }
2322 }
2323 if (!resumedOnDisplay) {
2324 // In cases when there are no valid activities (e.g. device just booted or launcher
2325 // crashed) it's possible that nothing was resumed on a display. Requesting resume
2326 // of top activity in focused stack explicitly will make sure that at least home
2327 // activity is started and resumed, and no recursion occurs.
2328 final ActivityStack focusedStack = display.getFocusedStack();
2329 if (focusedStack != null) {
2330 result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Riddle Hsu7baffbb2020-03-05 22:48:24 +08002331 } else if (targetStack == null) {
2332 result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
Andrii Kulian1cb59dd2020-04-10 12:17:17 -07002333 display.getDefaultTaskDisplayArea());
Louis Chang149d5c82019-12-30 09:47:39 +08002334 }
2335 }
2336 }
2337
2338 return result;
2339 }
2340
2341 void applySleepTokens(boolean applyToStacks) {
2342 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2343 // Set the sleeping state of the display.
2344 final DisplayContent display = getChildAt(displayNdx);
2345 final boolean displayShouldSleep = display.shouldSleep();
2346 if (displayShouldSleep == display.isSleeping()) {
2347 continue;
2348 }
2349 display.setIsSleeping(displayShouldSleep);
2350
2351 if (!applyToStacks) {
2352 continue;
2353 }
2354
2355 // Set the sleeping state of the stacks on the display.
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002356 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2357 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2358 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2359 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2360 if (displayShouldSleep) {
2361 stack.goToSleepIfPossible(false /* shuttingDown */);
2362 } else {
2363 // When the display which can only contain one task turns on, start a
2364 // special transition.
2365 // {@link AppTransitionController#handleAppTransitionReady} later picks up
2366 // the transition, and schedules
2367 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
2368 // triggered after contents are drawn on the display.
2369 if (display.isSingleTaskInstance()) {
2370 display.mDisplayContent.prepareAppTransition(
2371 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
2372 }
2373 stack.awakeFromSleepingLocked();
2374 if (display.isSingleTaskInstance()) {
2375 display.executeAppTransition();
2376 }
2377 if (stack.isFocusedStackOnDisplay()
2378 && !mStackSupervisor.getKeyguardController()
2379 .isKeyguardOrAodShowing(display.mDisplayId)) {
2380 // If the keyguard is unlocked - resume immediately.
2381 // It is possible that the display will not be awake at the time we
2382 // process the keyguard going away, which can happen before the sleep
2383 // token is released. As a result, it is important we resume the
2384 // activity here.
2385 resumeFocusedStacksTopActivities();
2386 }
Louis Chang149d5c82019-12-30 09:47:39 +08002387 }
2388 }
2389 }
Louis Chang149d5c82019-12-30 09:47:39 +08002390 }
2391 }
2392
2393 protected ActivityStack getStack(int stackId) {
2394 for (int i = getChildCount() - 1; i >= 0; --i) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002395 final ActivityStack stack = getChildAt(i).getStack(stackId);
Louis Chang149d5c82019-12-30 09:47:39 +08002396 if (stack != null) {
2397 return stack;
2398 }
2399 }
2400 return null;
2401 }
2402
2403 /** @see DisplayContent#getStack(int, int) */
2404 ActivityStack getStack(int windowingMode, int activityType) {
2405 for (int i = getChildCount() - 1; i >= 0; --i) {
2406 final ActivityStack stack = getChildAt(i).getStack(windowingMode, activityType);
2407 if (stack != null) {
2408 return stack;
2409 }
2410 }
2411 return null;
2412 }
2413
2414 private ActivityStack getStack(int windowingMode, int activityType,
2415 int displayId) {
2416 DisplayContent display = getDisplayContent(displayId);
2417 if (display == null) {
2418 return null;
2419 }
2420 return display.getStack(windowingMode, activityType);
2421 }
2422
2423 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002424 final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08002425 ActivityManager.StackInfo info = new ActivityManager.StackInfo();
2426 stack.getBounds(info.bounds);
Andrii Kulian86d676c2020-03-27 19:34:54 -07002427 info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY;
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002428 info.stackId = stack.mTaskId;
Wale Ogunwaleadf116e2020-03-27 16:36:01 -07002429 info.stackToken = stack.mRemoteToken.toWindowContainerToken();
Louis Chang149d5c82019-12-30 09:47:39 +08002430 info.userId = stack.mCurrentUser;
2431 info.visible = stack.shouldBeVisible(null);
2432 // A stack might be not attached to a display.
Wale Ogunwale0db64ac2020-04-11 10:00:42 -07002433 // TODO: Can be removed since no one is using it.
Andrii Kulian86d676c2020-03-27 19:34:54 -07002434 info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(stack) : 0;
Louis Chang149d5c82019-12-30 09:47:39 +08002435 info.configuration.setTo(stack.getConfiguration());
2436
Wale Ogunwale8f93b642019-12-26 12:10:52 -08002437 final int numTasks = stack.getDescendantTaskCount();
Louis Chang149d5c82019-12-30 09:47:39 +08002438 info.taskIds = new int[numTasks];
2439 info.taskNames = new String[numTasks];
2440 info.taskBounds = new Rect[numTasks];
2441 info.taskUserIds = new int[numTasks];
Wale Ogunwale8f93b642019-12-26 12:10:52 -08002442 final int[] currentIndex = {0};
Louis Chang149d5c82019-12-30 09:47:39 +08002443
2444 final PooledConsumer c = PooledLambda.obtainConsumer(
2445 RootWindowContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
Wale Ogunwale8f93b642019-12-26 12:10:52 -08002446 currentIndex);
Wale Ogunwale0d465192020-01-23 19:14:44 -08002447 stack.forAllLeafTasks(c, false /* traverseTopToBottom */);
Louis Chang149d5c82019-12-30 09:47:39 +08002448 c.recycle();
2449
2450 final ActivityRecord top = stack.topRunningActivity();
2451 info.topActivity = top != null ? top.intent.getComponent() : null;
2452 return info;
2453 }
2454
2455 private static void processTaskForStackInfo(
2456 Task task, ActivityManager.StackInfo info, int[] currentIndex) {
2457 int i = currentIndex[0];
2458 info.taskIds[i] = task.mTaskId;
2459 info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2460 : task.realActivity != null ? task.realActivity.flattenToString()
2461 : task.getTopNonFinishingActivity() != null
2462 ? task.getTopNonFinishingActivity().packageName : "unknown";
2463 info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
2464 info.taskUserIds[i] = task.mUserId;
2465 currentIndex[0] = ++i;
2466 }
2467
2468 ActivityManager.StackInfo getStackInfo(int stackId) {
2469 ActivityStack stack = getStack(stackId);
2470 if (stack != null) {
2471 return getStackInfo(stack);
2472 }
2473 return null;
2474 }
2475
2476 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
2477 final ActivityStack stack = getStack(windowingMode, activityType);
2478 return (stack != null) ? getStackInfo(stack) : null;
2479 }
2480
2481 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) {
2482 final ActivityStack stack = getStack(windowingMode, activityType, displayId);
2483 return (stack != null) ? getStackInfo(stack) : null;
2484 }
2485
2486 /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */
2487 ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) {
2488 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
2489 if (displayId == INVALID_DISPLAY) {
2490 for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
2491 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002492 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2493 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2494 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2495 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2496 list.add(getStackInfo(stack));
2497 }
Louis Chang149d5c82019-12-30 09:47:39 +08002498 }
2499 }
2500 return list;
2501 }
2502 final DisplayContent display = getDisplayContent(displayId);
2503 if (display == null) {
2504 return list;
2505 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002506 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2507 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2508 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2509 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2510 list.add(getStackInfo(stack));
2511 }
Louis Chang149d5c82019-12-30 09:47:39 +08002512 }
2513 return list;
2514 }
2515
Louis Chang149d5c82019-12-30 09:47:39 +08002516 @Override
2517 public void onDisplayAdded(int displayId) {
2518 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
2519 synchronized (mService.mGlobalLock) {
2520 final DisplayContent display = getDisplayContentOrCreate(displayId);
2521 if (display == null) {
2522 return;
2523 }
2524 // Do not start home before booting, or it may accidentally finish booting before it
2525 // starts. Instead, we expect home activities to be launched when the system is ready
2526 // (ActivityManagerService#systemReady).
2527 if (mService.isBooted() || mService.isBooting()) {
2528 startSystemDecorations(display.mDisplayContent);
2529 }
2530 }
2531 }
2532
2533 private void startSystemDecorations(final DisplayContent displayContent) {
2534 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
2535 displayContent.getDisplayPolicy().notifyDisplayReady();
2536 }
2537
2538 @Override
2539 public void onDisplayRemoved(int displayId) {
2540 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
2541 if (displayId == DEFAULT_DISPLAY) {
2542 throw new IllegalArgumentException("Can't remove the primary display.");
2543 }
2544
2545 synchronized (mService.mGlobalLock) {
2546 final DisplayContent displayContent = getDisplayContent(displayId);
2547 if (displayContent == null) {
2548 return;
2549 }
2550
2551 displayContent.remove();
2552 }
2553 }
2554
2555 @Override
2556 public void onDisplayChanged(int displayId) {
2557 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
2558 synchronized (mService.mGlobalLock) {
2559 final DisplayContent displayContent = getDisplayContent(displayId);
2560 if (displayContent != null) {
2561 displayContent.onDisplayChanged();
2562 }
2563 }
2564 }
2565
2566 /** Update lists of UIDs that are present on displays and have access to them. */
2567 void updateUIDsPresentOnDisplay() {
2568 mDisplayAccessUIDs.clear();
2569 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2570 final DisplayContent displayContent = getChildAt(displayNdx);
2571 // Only bother calculating the whitelist for private displays
2572 if (displayContent.isPrivate()) {
2573 mDisplayAccessUIDs.append(
2574 displayContent.mDisplayId, displayContent.getPresentUIDs());
2575 }
2576 }
2577 // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
2578 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
2579 }
2580
2581 ActivityStack findStackBehind(ActivityStack stack) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002582 final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
2583 if (taskDisplayArea != null) {
2584 for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; i--) {
2585 if (taskDisplayArea.getStackAt(i) == stack && i > 0) {
2586 return taskDisplayArea.getStackAt(i - 1);
Louis Chang149d5c82019-12-30 09:47:39 +08002587 }
2588 }
2589 }
2590 throw new IllegalStateException("Failed to find a stack behind stack=" + stack
Andrii Kulian86d676c2020-03-27 19:34:54 -07002591 + " in=" + taskDisplayArea);
Louis Chang149d5c82019-12-30 09:47:39 +08002592 }
2593
2594 @Override
2595 void positionChildAt(int position, DisplayContent child, boolean includingParents) {
2596 super.positionChildAt(position, child, includingParents);
2597 mStackSupervisor.updateTopResumedActivityIfNeeded();
2598 }
2599
2600 Configuration getDisplayOverrideConfiguration(int displayId) {
2601 final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
2602 if (displayContent == null) {
2603 throw new IllegalArgumentException("No display found with id: " + displayId);
2604 }
2605
2606 return displayContent.getRequestedOverrideConfiguration();
2607 }
2608
2609 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, 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 displayContent.onRequestedOverrideConfigurationChanged(overrideConfiguration);
2616 }
2617
2618 void prepareForShutdown() {
2619 for (int i = 0; i < getChildCount(); i++) {
2620 createSleepToken("shutdown", getChildAt(i).mDisplayId);
2621 }
2622 }
2623
2624 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
2625 final DisplayContent display = getDisplayContent(displayId);
2626 if (display == null) {
2627 throw new IllegalArgumentException("Invalid display: " + displayId);
2628 }
2629
2630 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
2631 mSleepTokens.add(token);
2632 display.mAllSleepTokens.add(token);
2633 return token;
2634 }
2635
2636 private void removeSleepToken(SleepTokenImpl token) {
2637 mSleepTokens.remove(token);
2638
2639 final DisplayContent display = getDisplayContent(token.mDisplayId);
2640 if (display != null) {
2641 display.mAllSleepTokens.remove(token);
2642 if (display.mAllSleepTokens.isEmpty()) {
2643 mService.updateSleepIfNeededLocked();
2644 }
2645 }
2646 }
2647
2648 void addStartingWindowsForVisibleActivities() {
2649 forAllActivities((r) -> {
2650 if (r.mVisibleRequested) {
2651 r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/);
2652 }
2653 });
2654 }
2655
2656 void invalidateTaskLayers() {
2657 mTaskLayersChanged = true;
2658 }
2659
2660 void rankTaskLayersIfNeeded() {
2661 if (!mTaskLayersChanged) {
2662 return;
2663 }
2664 mTaskLayersChanged = false;
2665 mTmpTaskLayerRank = 0;
2666 final PooledConsumer c = PooledLambda.obtainConsumer(
2667 RootWindowContainer::rankTaskLayerForActivity, this,
2668 PooledLambda.__(ActivityRecord.class));
2669 forAllActivities(c);
2670 c.recycle();
2671 }
2672
2673 private void rankTaskLayerForActivity(ActivityRecord r) {
2674 if (r.canBeTopRunning() && r.mVisibleRequested) {
2675 r.getTask().mLayerRank = ++mTmpTaskLayerRank;
2676 } else {
2677 r.getTask().mLayerRank = -1;
2678 }
2679 }
2680
2681 void clearOtherAppTimeTrackers(AppTimeTracker except) {
2682 final PooledConsumer c = PooledLambda.obtainConsumer(
2683 RootWindowContainer::clearOtherAppTimeTrackers,
2684 PooledLambda.__(ActivityRecord.class), except);
2685 forAllActivities(c);
2686 c.recycle();
2687 }
2688
2689 private static void clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except) {
2690 if (r.appTimeTracker != except) {
2691 r.appTimeTracker = null;
2692 }
2693 }
2694
2695 void scheduleDestroyAllActivities(String reason) {
2696 mDestroyAllActivitiesReason = reason;
2697 mService.mH.post(mDestroyAllActivitiesRunnable);
2698 }
2699
2700 private void destroyActivity(ActivityRecord r) {
2701 if (r.finishing || !r.isDestroyable()) return;
2702
2703 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState()
2704 + " resumed=" + r.getStack().mResumedActivity + " pausing="
2705 + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason);
2706
2707 r.destroyImmediately(true /* removeFromTask */, mDestroyAllActivitiesReason);
2708 }
2709
2710 // Tries to put all activity stacks to sleep. Returns true if all stacks were
2711 // successfully put to sleep.
2712 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
2713 boolean allSleep = true;
2714 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2715 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002716 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2717 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
2718 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
2719 // Stacks and activities could be removed while putting activities to sleep if
2720 // the app process was gone. This prevents us getting exception by accessing an
2721 // invalid stack index.
2722 if (sNdx >= taskDisplayArea.getStackCount()) {
2723 continue;
2724 }
2725 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
2726 if (allowDelay) {
2727 allSleep &= stack.goToSleepIfPossible(shuttingDown);
2728 } else {
2729 stack.goToSleep();
2730 }
Louis Chang149d5c82019-12-30 09:47:39 +08002731 }
2732 }
2733 }
2734 return allSleep;
2735 }
2736
2737 void handleAppCrash(WindowProcessController app) {
2738 final PooledConsumer c = PooledLambda.obtainConsumer(
2739 RootWindowContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app);
2740 forAllActivities(c);
2741 c.recycle();
2742 }
2743
2744 private static void handleAppCrash(ActivityRecord r, WindowProcessController app) {
2745 if (r.app != app) return;
2746 Slog.w(TAG, " Force finishing activity "
2747 + r.intent.getComponent().flattenToShortString());
2748 r.app = null;
2749 r.getDisplay().mDisplayContent.prepareAppTransition(
2750 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
2751 r.destroyIfPossible("handleAppCrashed");
2752 }
2753
2754 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
2755 ComponentName cls = intent.getComponent();
2756 if (info.targetActivity != null) {
2757 cls = new ComponentName(info.packageName, info.targetActivity);
2758 }
2759 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
2760
2761 final PooledPredicate p = PooledLambda.obtainPredicate(
2762 RootWindowContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
2763 userId, compareIntentFilters, intent, cls);
2764 final ActivityRecord r = getActivity(p);
2765 p.recycle();
2766 return r;
2767 }
2768
2769 private static boolean matchesActivity(ActivityRecord r, int userId,
2770 boolean compareIntentFilters, Intent intent, ComponentName cls) {
2771 if (!r.canBeTopRunning() || r.mUserId != userId) return false;
2772
2773 if (compareIntentFilters) {
2774 if (r.intent.filterEquals(intent)) {
2775 return true;
2776 }
2777 } else {
Riddle Hsu8be3b9f2020-03-13 18:47:17 +08002778 // Compare the target component instead of intent component so we don't miss if the
2779 // activity uses alias.
2780 if (r.mActivityComponent.equals(cls)) {
Louis Chang149d5c82019-12-30 09:47:39 +08002781 return true;
2782 }
2783 }
2784 return false;
2785 }
2786
2787 boolean hasAwakeDisplay() {
2788 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
2789 final DisplayContent display = getChildAt(displayNdx);
2790 if (!display.shouldSleep()) {
2791 return true;
2792 }
2793 }
2794 return false;
2795 }
2796
2797 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
2798 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
2799 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
2800 -1 /* no realCallingPid */, -1 /* no realCallingUid */);
2801 }
2802
2803 /**
2804 * Returns the right stack to use for launching factoring in all the input parameters.
2805 *
2806 * @param r The activity we are trying to launch. Can be null.
2807 * @param options The activity options used to the launch. Can be null.
2808 * @param candidateTask The possible task the activity might be launched in. Can be null.
2809 * @param launchParams The resolved launch params to use.
2810 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
2811 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
2812 *
2813 * @return The stack to use for the launch or INVALID_STACK_ID.
2814 */
2815 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
2816 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
2817 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
2818 int realCallingUid) {
2819 int taskId = INVALID_TASK_ID;
2820 int displayId = INVALID_DISPLAY;
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002821 TaskDisplayArea taskDisplayArea = null;
Louis Chang149d5c82019-12-30 09:47:39 +08002822
2823 // We give preference to the launch preference in activity options.
2824 if (options != null) {
2825 taskId = options.getLaunchTaskId();
2826 displayId = options.getLaunchDisplayId();
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002827 final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
2828 taskDisplayArea = daToken != null
2829 ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;
Louis Chang149d5c82019-12-30 09:47:39 +08002830 }
2831
2832 // First preference for stack goes to the task Id set in the activity options. Use the stack
2833 // associated with that if possible.
2834 if (taskId != INVALID_TASK_ID) {
2835 // Temporarily set the task id to invalid in case in re-entry.
2836 options.setLaunchTaskId(INVALID_TASK_ID);
2837 final Task task = anyTaskForId(taskId,
2838 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
2839 options.setLaunchTaskId(taskId);
2840 if (task != null) {
2841 return task.getStack();
2842 }
2843 }
2844
2845 final int activityType = resolveActivityType(r, options, candidateTask);
Louis Chang38430df2020-01-02 17:14:59 +08002846 ActivityStack stack = null;
Louis Chang149d5c82019-12-30 09:47:39 +08002847
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002848 // Next preference for stack goes to the taskDisplayArea candidate.
2849 if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
2850 taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
Louis Chang149d5c82019-12-30 09:47:39 +08002851 }
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002852
2853 if (taskDisplayArea == null && displayId != INVALID_DISPLAY) {
2854 final DisplayContent displayContent = getDisplayContent(displayId);
2855 if (displayContent != null) {
2856 taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08002857 }
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002858 }
2859
2860 if (taskDisplayArea != null) {
2861 final int tdaDisplayId = taskDisplayArea.getDisplayId();
2862 final boolean canLaunchOnDisplayFromStartRequest =
2863 realCallingPid != 0 && realCallingUid > 0 && r != null
2864 && mStackSupervisor.canPlaceEntityOnDisplay(tdaDisplayId,
2865 realCallingPid, realCallingUid, r.info);
2866 if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) {
2867 if (r != null) {
2868 final ActivityStack result = getValidLaunchStackInTaskDisplayArea(
2869 taskDisplayArea, r, candidateTask, options, launchParams);
2870 if (result != null) {
2871 return result;
2872 }
2873 }
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002874 // Falling back to default task container
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002875 taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002876 stack = taskDisplayArea.getOrCreateStack(r, options, candidateTask, activityType,
2877 onTop);
Louis Chang149d5c82019-12-30 09:47:39 +08002878 if (stack != null) {
2879 return stack;
2880 }
2881 }
2882 }
2883
2884 // Give preference to the stack and display of the input task and activity if they match the
2885 // mode we want to launch into.
Andrii Kulian86d676c2020-03-27 19:34:54 -07002886 TaskDisplayArea container = null;
Louis Chang149d5c82019-12-30 09:47:39 +08002887 if (candidateTask != null) {
2888 stack = candidateTask.getStack();
2889 }
2890 if (stack == null && r != null) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002891 stack = r.getRootTask();
Louis Chang149d5c82019-12-30 09:47:39 +08002892 }
Louis Changa009c762020-02-26 11:21:31 +08002893 int windowingMode = launchParams != null ? launchParams.mWindowingMode
2894 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Louis Chang149d5c82019-12-30 09:47:39 +08002895 if (stack != null) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002896 container = stack.getDisplayArea();
2897 if (container != null && canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
Louis Chang149d5c82019-12-30 09:47:39 +08002898 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002899 windowingMode = container.resolveWindowingMode(r, options, candidateTask,
2900 activityType);
Louis Chang149d5c82019-12-30 09:47:39 +08002901 }
Louis Changa009c762020-02-26 11:21:31 +08002902 // Always allow organized tasks that created by organizer since the activity type
2903 // of an organized task is decided by the activity type of its top child, which
2904 // could be incompatible with the given windowing mode and activity type.
2905 if (stack.isCompatible(windowingMode, activityType) || stack.mCreatedByOrganizer) {
Louis Chang149d5c82019-12-30 09:47:39 +08002906 return stack;
2907 }
2908 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
Andrii Kulian86d676c2020-03-27 19:34:54 -07002909 && container.getRootSplitScreenPrimaryTask() == stack
Louis Chang149d5c82019-12-30 09:47:39 +08002910 && candidateTask == stack.getTopMostTask()) {
2911 // This is a special case when we try to launch an activity that is currently on
2912 // top of split-screen primary stack, but is targeting split-screen secondary.
2913 // In this case we don't want to move it to another stack.
2914 // TODO(b/78788972): Remove after differentiating between preferred and required
2915 // launch options.
2916 return stack;
2917 }
2918 }
2919 }
2920
Andrii Kulian86d676c2020-03-27 19:34:54 -07002921 if (container == null
2922 || !canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002923 container = getDefaultTaskDisplayArea();
Louis Changa009c762020-02-26 11:21:31 +08002924 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
Andrii Kulian86d676c2020-03-27 19:34:54 -07002925 windowingMode = container.resolveWindowingMode(r, options, candidateTask,
2926 activityType);
Louis Changa009c762020-02-26 11:21:31 +08002927 }
Louis Chang149d5c82019-12-30 09:47:39 +08002928 }
2929
Andrii Kulian86d676c2020-03-27 19:34:54 -07002930 return container.getOrCreateStack(r, options, candidateTask, activityType, onTop);
Louis Chang149d5c82019-12-30 09:47:39 +08002931 }
2932
2933 /** @return true if activity record is null or can be launched on provided display. */
2934 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
2935 if (r == null) {
2936 return true;
2937 }
2938 return r.canBeLaunchedOnDisplay(displayId);
2939 }
2940
2941 /**
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002942 * Get a topmost stack on the display area, that is a valid launch stack for specified activity.
Louis Chang149d5c82019-12-30 09:47:39 +08002943 * If there is no such stack, new dynamic stack can be created.
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002944 * @param taskDisplayArea Target display area.
Louis Chang149d5c82019-12-30 09:47:39 +08002945 * @param r Activity that should be launched there.
2946 * @param candidateTask The possible task the activity might be put in.
2947 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
2948 */
Louis Changdd63da52020-03-24 14:49:49 +08002949 @VisibleForTesting
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002950 ActivityStack getValidLaunchStackInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea,
2951 @NonNull ActivityRecord r, @Nullable Task candidateTask,
2952 @Nullable ActivityOptions options,
Louis Chang149d5c82019-12-30 09:47:39 +08002953 @Nullable LaunchParamsController.LaunchParams launchParams) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002954 if (!r.canBeLaunchedOnDisplay(taskDisplayArea.getDisplayId())) {
Louis Chang149d5c82019-12-30 09:47:39 +08002955 return null;
2956 }
2957
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002958 // If {@code r} is already in target display area and its task is the same as the candidate
2959 // task, the intention should be getting a launch stack for the reusable activity, so we can
2960 // use the existing stack.
Louis Chang149d5c82019-12-30 09:47:39 +08002961 if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002962 // TODO(b/153920825): Fix incorrect evaluation of attached state
2963 final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null
2964 ? r.getTask().getDisplayArea() : r.getDisplayArea();
2965 if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) {
Louis Chang149d5c82019-12-30 09:47:39 +08002966 return candidateTask.getStack();
2967 }
Louis Changdd63da52020-03-24 14:49:49 +08002968 // Or the candidate task is already a root task that can be reused by reparenting
2969 // it to the target display.
2970 if (candidateTask.isRootTask()) {
2971 final ActivityStack stack = candidateTask.getStack();
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002972 stack.reparent(taskDisplayArea, true /* onTop */);
Louis Changdd63da52020-03-24 14:49:49 +08002973 return stack;
2974 }
Louis Chang149d5c82019-12-30 09:47:39 +08002975 }
2976
2977 int windowingMode;
2978 if (launchParams != null) {
2979 // When launch params is not null, we always defer to its windowing mode. Sometimes
2980 // it could be unspecified, which indicates it should inherit windowing mode from
2981 // display.
2982 windowingMode = launchParams.mWindowingMode;
2983 } else {
2984 windowingMode = options != null ? options.getLaunchWindowingMode()
2985 : r.getWindowingMode();
2986 }
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002987 windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask,
2988 r.getActivityType());
Louis Chang149d5c82019-12-30 09:47:39 +08002989
2990 // Return the topmost valid stack on the display.
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002991 for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; --i) {
2992 final ActivityStack stack = taskDisplayArea.getStackAt(i);
2993 if (isValidLaunchStack(stack, r, windowingMode)) {
2994 return stack;
Louis Chang149d5c82019-12-30 09:47:39 +08002995 }
2996 }
2997
Andrii Kulian1cfcae82020-04-10 12:44:38 -07002998 // If there is no valid stack on the secondary display area - check if new dynamic stack
2999 // will do.
3000 if (taskDisplayArea != getDisplayContent(taskDisplayArea.getDisplayId())
3001 .getDefaultTaskDisplayArea()) {
Louis Chang149d5c82019-12-30 09:47:39 +08003002 final int activityType =
3003 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
3004 ? options.getLaunchActivityType() : r.getActivityType();
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07003005 return taskDisplayArea.createStack(windowingMode, activityType, true /*onTop*/);
Louis Chang149d5c82019-12-30 09:47:39 +08003006 }
3007
3008 return null;
3009 }
3010
Louis Chang149d5c82019-12-30 09:47:39 +08003011 // TODO: Can probably be consolidated into getLaunchStack()...
3012 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
3013 switch (stack.getActivityType()) {
3014 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
3015 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
3016 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
Galia Peycheva45f48d32020-02-20 15:39:10 +01003017 case ACTIVITY_TYPE_DREAM: return r.isActivityTypeDream();
Louis Chang149d5c82019-12-30 09:47:39 +08003018 }
Louis Changa009c762020-02-26 11:21:31 +08003019 if (stack.mCreatedByOrganizer) {
3020 // Don't launch directly into task created by organizer...but why can't we?
Evan Rosky0037e5f2019-11-05 10:26:24 -08003021 return false;
3022 }
Louis Chang149d5c82019-12-30 09:47:39 +08003023 // There is a 1-to-1 relationship between stack and task when not in
3024 // primary split-windowing mode.
3025 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
3026 && r.supportsSplitScreenWindowingMode()
3027 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
3028 || windowingMode == WINDOWING_MODE_UNDEFINED)) {
3029 return true;
3030 }
3031 return false;
3032 }
3033
3034 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
3035 @Nullable Task task) {
3036 // Preference is given to the activity type for the activity then the task since the type
3037 // once set shouldn't change.
3038 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
3039 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
3040 activityType = task.getActivityType();
3041 }
3042 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
3043 return activityType;
3044 }
3045 if (options != null) {
3046 activityType = options.getLaunchActivityType();
3047 }
3048 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
3049 }
3050
3051 /**
3052 * Get next focusable stack in the system. This will search through the stack on the same
3053 * display as the current focused stack, looking for a focusable and visible stack, different
3054 * from the target stack. If no valid candidates will be found, it will then go through all
3055 * displays and stacks in last-focused order.
3056 *
3057 * @param currentFocus The stack that previously had focus.
3058 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
3059 * candidate.
3060 * @return Next focusable {@link ActivityStack}, {@code null} if not found.
3061 */
3062 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
3063 boolean ignoreCurrent) {
3064 // First look for next focusable stack on the same display
Andrii Kulian86d676c2020-03-27 19:34:54 -07003065 TaskDisplayArea preferredDisplayArea = currentFocus.getDisplayArea();
3066 if (preferredDisplayArea == null) {
Louis Chang149d5c82019-12-30 09:47:39 +08003067 // Stack is currently detached because it is being removed. Use the previous display it
3068 // was on.
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07003069 preferredDisplayArea = getDisplayContent(currentFocus.mPrevDisplayId)
3070 .getDefaultTaskDisplayArea();
Louis Chang149d5c82019-12-30 09:47:39 +08003071 }
Andrii Kulian86d676c2020-03-27 19:34:54 -07003072 final ActivityStack preferredFocusableStack = preferredDisplayArea.getNextFocusableStack(
3073 currentFocus, ignoreCurrent);
Louis Chang149d5c82019-12-30 09:47:39 +08003074 if (preferredFocusableStack != null) {
3075 return preferredFocusableStack;
3076 }
Andrii Kulian86d676c2020-03-27 19:34:54 -07003077 if (preferredDisplayArea.mDisplayContent.supportsSystemDecorations()) {
Louis Chang149d5c82019-12-30 09:47:39 +08003078 // Stop looking for focusable stack on other displays because the preferred display
3079 // supports system decorations. Home activity would be launched on the same display if
3080 // no focusable stack found.
3081 return null;
3082 }
3083
3084 // Now look through all displays
3085 for (int i = getChildCount() - 1; i >= 0; --i) {
3086 final DisplayContent display = getChildAt(i);
Andrii Kulian86d676c2020-03-27 19:34:54 -07003087 if (display == preferredDisplayArea.mDisplayContent) {
Louis Chang149d5c82019-12-30 09:47:39 +08003088 // We've already checked this one
3089 continue;
3090 }
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07003091 final ActivityStack nextFocusableStack = display.getDefaultTaskDisplayArea()
Andrii Kulian9ea12da2020-03-27 17:16:38 -07003092 .getNextFocusableStack(currentFocus, ignoreCurrent);
Louis Chang149d5c82019-12-30 09:47:39 +08003093 if (nextFocusableStack != null) {
3094 return nextFocusableStack;
3095 }
3096 }
3097
3098 return null;
3099 }
3100
Louis Chang149d5c82019-12-30 09:47:39 +08003101 boolean handleAppDied(WindowProcessController app) {
3102 boolean hasVisibleActivities = false;
3103 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3104 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003105 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3106 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3107 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3108 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3109 hasVisibleActivities |= stack.handleAppDied(app);
3110 }
Louis Chang149d5c82019-12-30 09:47:39 +08003111 }
3112 }
3113 return hasVisibleActivities;
3114 }
3115
3116 void closeSystemDialogs() {
3117 forAllActivities((r) -> {
3118 if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3119 r.finishIfPossible("close-sys", true /* oomAdj */);
3120 }
3121 });
3122 }
3123
3124 FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
3125 new FinishDisabledPackageActivitiesHelper();
3126 class FinishDisabledPackageActivitiesHelper {
3127 private boolean mDidSomething;
3128 private String mPackageName;
3129 private Set<String> mFilterByClasses;
3130 private boolean mDoit;
3131 private boolean mEvenPersistent;
3132 private int mUserId;
3133 private Task mLastTask;
3134 private ComponentName mHomeActivity;
3135
3136 private void reset(String packageName, Set<String> filterByClasses,
3137 boolean doit, boolean evenPersistent, int userId) {
3138 mDidSomething = false;
3139 mPackageName = packageName;
3140 mFilterByClasses = filterByClasses;
3141 mDoit = doit;
3142 mEvenPersistent = evenPersistent;
3143 mUserId = userId;
3144 mLastTask = null;
3145 mHomeActivity = null;
3146 }
3147
3148 boolean process(String packageName, Set<String> filterByClasses,
3149 boolean doit, boolean evenPersistent, int userId) {
3150 reset(packageName, filterByClasses, doit, evenPersistent, userId);
3151
3152 final PooledFunction f = PooledLambda.obtainFunction(
3153 FinishDisabledPackageActivitiesHelper::processActivity, this,
3154 PooledLambda.__(ActivityRecord.class));
3155 forAllActivities(f);
3156 f.recycle();
3157 return mDidSomething;
3158 }
3159
3160 private boolean processActivity(ActivityRecord r) {
3161 final boolean sameComponent =
3162 (r.packageName.equals(mPackageName) && (mFilterByClasses == null
3163 || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
3164 || (mPackageName == null && r.mUserId == mUserId);
3165 if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
3166 && (sameComponent || r.getTask() == mLastTask)
3167 && (r.app == null || mEvenPersistent || !r.app.isPersistent())) {
3168 if (!mDoit) {
3169 if (r.finishing) {
3170 // If this activity is just finishing, then it is not
3171 // interesting as far as something to stop.
3172 return false;
3173 }
3174 return true;
3175 }
3176 if (r.isActivityTypeHome()) {
3177 if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) {
3178 Slog.i(TAG, "Skip force-stop again " + r);
3179 return false;
3180 } else {
3181 mHomeActivity = r.mActivityComponent;
3182 }
3183 }
3184 mDidSomething = true;
3185 Slog.i(TAG, " Force finishing activity " + r);
3186 mLastTask = r.getTask();
3187 r.finishIfPossible("force-stop", true);
3188 }
3189
3190 return false;
3191 }
3192 }
3193
3194 /** @return true if some activity was finished (or would have finished if doit were true). */
3195 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
3196 boolean doit, boolean evenPersistent, int userId) {
3197 return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
3198 evenPersistent, userId);
3199 }
3200
3201 void updateActivityApplicationInfo(ApplicationInfo aInfo) {
3202 final String packageName = aInfo.packageName;
3203 final int userId = UserHandle.getUserId(aInfo.uid);
3204 final PooledConsumer c = PooledLambda.obtainConsumer(
3205 RootWindowContainer::updateActivityApplicationInfo,
3206 PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName);
3207 forAllActivities(c);
3208 c.recycle();
3209 }
3210
3211 private static void updateActivityApplicationInfo(
3212 ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName) {
3213 if (r.mUserId == userId && packageName.equals(r.packageName)) {
3214 r.updateApplicationInfo(aInfo);
3215 }
3216 }
3217
3218 void finishVoiceTask(IVoiceInteractionSession session) {
3219 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3220 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003221 int numTaskContainers = display.getTaskDisplayAreaCount();
3222 for (int tdaNdx = 0; tdaNdx < numTaskContainers; tdaNdx++) {
3223 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3224 final int numStacks = display.getStackCount();
3225 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
3226 final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx);
3227 stack.finishVoiceTask(session);
3228 }
Louis Chang149d5c82019-12-30 09:47:39 +08003229 }
3230 }
3231 }
3232
3233 /**
3234 * Removes stacks in the input windowing modes from the system if they are of activity type
3235 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
3236 */
3237 void removeStacksInWindowingModes(int... windowingModes) {
3238 for (int i = getChildCount() - 1; i >= 0; --i) {
3239 getChildAt(i).removeStacksInWindowingModes(windowingModes);
3240 }
3241 }
3242
3243 void removeStacksWithActivityTypes(int... activityTypes) {
3244 for (int i = getChildCount() - 1; i >= 0; --i) {
3245 getChildAt(i).removeStacksWithActivityTypes(activityTypes);
3246 }
3247 }
3248
3249 ActivityRecord topRunningActivity() {
3250 for (int i = getChildCount() - 1; i >= 0; --i) {
3251 final ActivityRecord topActivity = getChildAt(i).topRunningActivity();
3252 if (topActivity != null) {
3253 return topActivity;
3254 }
3255 }
3256 return null;
3257 }
3258
3259 boolean allResumedActivitiesIdle() {
3260 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3261 // TODO(b/117135575): Check resumed activities on all visible stacks.
3262 final DisplayContent display = getChildAt(displayNdx);
3263 if (display.isSleeping()) {
3264 // No resumed activities while display is sleeping.
3265 continue;
3266 }
3267
3268 // If the focused stack is not null or not empty, there should have some activities
3269 // resuming or resumed. Make sure these activities are idle.
3270 final ActivityStack stack = display.getFocusedStack();
3271 if (stack == null || !stack.hasActivity()) {
3272 continue;
3273 }
3274 final ActivityRecord resumedActivity = stack.getResumedActivity();
3275 if (resumedActivity == null || !resumedActivity.idle) {
3276 if (DEBUG_STATES) {
3277 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08003278 + stack.getRootTaskId() + " " + resumedActivity + " not idle");
Louis Chang149d5c82019-12-30 09:47:39 +08003279 }
3280 return false;
3281 }
3282 }
3283 // Send launch end powerhint when idle
3284 sendPowerHintForLaunchEndIfNeeded();
3285 return true;
3286 }
3287
3288 boolean allResumedActivitiesVisible() {
3289 boolean foundResumed = false;
3290 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3291 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003292 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3293 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3294 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3295 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3296 final ActivityRecord r = stack.getResumedActivity();
3297 if (r != null) {
3298 if (!r.nowVisible) {
3299 return false;
3300 }
3301 foundResumed = true;
Louis Chang149d5c82019-12-30 09:47:39 +08003302 }
Louis Chang149d5c82019-12-30 09:47:39 +08003303 }
3304 }
3305 }
3306 return foundResumed;
3307 }
3308
3309 boolean allPausedActivitiesComplete() {
3310 boolean pausing = true;
3311 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3312 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003313 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3314 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3315 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3316 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3317 final ActivityRecord r = stack.mPausingActivity;
Chris Li74f622a2020-04-19 18:57:35 -07003318 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003319 if (DEBUG_STATES) {
3320 Slog.d(TAG_STATES, "allPausedActivitiesComplete: r=" + r
3321 + " state=" + r.getState());
3322 pausing = false;
3323 } else {
3324 return false;
3325 }
Louis Chang149d5c82019-12-30 09:47:39 +08003326 }
3327 }
3328 }
3329 }
3330 return pausing;
3331 }
3332
3333 /**
3334 * Find all visible task stacks containing {@param userId} and intercept them with an activity
3335 * to block out the contents and possibly start a credential-confirming intent.
3336 *
3337 * @param userId user handle for the locked managed profile.
3338 */
3339 void lockAllProfileTasks(@UserIdInt int userId) {
3340 mService.deferWindowLayout();
3341 try {
3342 final PooledConsumer c = PooledLambda.obtainConsumer(
3343 RootWindowContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class),
3344 userId);
Wale Ogunwale0d465192020-01-23 19:14:44 -08003345 forAllLeafTasks(c, true /* traverseTopToBottom */);
Louis Chang149d5c82019-12-30 09:47:39 +08003346 c.recycle();
3347 } finally {
3348 mService.continueWindowLayout();
3349 }
3350 }
3351
3352 /**
3353 * Detects whether we should show a lock screen in front of this task for a locked user.
3354 * <p>
3355 * We'll do this if either of the following holds:
3356 * <ul>
3357 * <li>The top activity explicitly belongs to {@param userId}.</li>
3358 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
3359 * </ul>
3360 *
3361 * @return {@code true} if the top activity looks like it belongs to {@param userId}.
3362 */
3363 private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
3364 // To handle the case that work app is in the task but just is not the top one.
3365 final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
3366 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
3367
3368 // Check the task for a top activity belonging to userId, or returning a
3369 // result to an activity belonging to userId. Example case: a document
3370 // picker for personal files, opened by a work app, should still get locked.
3371 if ((activityRecord != null && activityRecord.mUserId == userId)
3372 || (resultTo != null && resultTo.mUserId == userId)) {
3373 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
3374 task.mTaskId, userId);
3375 }
3376 }
3377
3378 void cancelInitializingActivities() {
3379 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3380 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003381 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3382 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3383 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3384 taskDisplayArea.getStackAt(sNdx).cancelInitializingActivities();
3385 }
Louis Chang149d5c82019-12-30 09:47:39 +08003386 }
3387 }
3388 }
3389
3390 Task anyTaskForId(int id) {
3391 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
3392 }
3393
3394 Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode) {
3395 return anyTaskForId(id, matchMode, null, !ON_TOP);
3396 }
3397
3398 /**
3399 * Returns a {@link Task} for the input id if available. {@code null} otherwise.
3400 * @param id Id of the task we would like returned.
3401 * @param matchMode The mode to match the given task id in.
3402 * @param aOptions The activity options to use for restoration. Can be null.
3403 * @param onTop If the stack for the task should be the topmost on the display.
3404 */
3405 Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode,
3406 @Nullable ActivityOptions aOptions, boolean onTop) {
3407 // If options are set, ensure that we are attempting to actually restore a task
3408 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
3409 throw new IllegalArgumentException("Should not specify activity options for non-restore"
3410 + " lookup");
3411 }
3412
3413 final PooledPredicate p = PooledLambda.obtainPredicate(
3414 Task::isTaskId, PooledLambda.__(Task.class), id);
3415 Task task = getTask(p);
3416 p.recycle();
3417
3418 if (task != null) {
3419 if (aOptions != null) {
3420 // Resolve the stack the task should be placed in now based on options
3421 // and reparent if needed.
3422 final ActivityStack launchStack =
3423 getLaunchStack(null, aOptions, task, onTop);
3424 if (launchStack != null && task.getStack() != launchStack) {
3425 final int reparentMode = onTop
3426 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
3427 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
3428 "anyTaskForId");
3429 }
3430 }
3431 return task;
3432 }
3433
3434 // If we are matching stack tasks only, return now
3435 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
3436 return null;
3437 }
3438
3439 // Otherwise, check the recent tasks and return if we find it there and we are not restoring
3440 // the task from recents
3441 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
3442 task = mStackSupervisor.mRecentTasks.getTask(id);
3443
3444 if (task == null) {
3445 if (DEBUG_RECENTS) {
3446 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
3447 }
3448
3449 return null;
3450 }
3451
3452 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
3453 return task;
3454 }
3455
3456 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
3457 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
3458 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
3459 "Couldn't restore task id=" + id + " found in recents");
3460 return null;
3461 }
3462 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
3463 return task;
3464 }
3465
3466 ActivityRecord isInAnyStack(IBinder token) {
Wale Ogunwale0d465192020-01-23 19:14:44 -08003467 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3468 return (r != null && r.isDescendantOf(this)) ? r : null;
Louis Chang149d5c82019-12-30 09:47:39 +08003469 }
3470
3471 @VisibleForTesting
3472 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
Winson Chunge5ab0172020-03-21 23:00:24 -07003473 boolean filterOnlyVisibleRecents, int callingUid, boolean allowed, boolean crossUser,
3474 ArraySet<Integer> profileIds) {
3475 mStackSupervisor.getRunningTasks().getTasks(maxNum, list, filterOnlyVisibleRecents, this,
3476 callingUid, allowed, crossUser, profileIds);
Louis Chang149d5c82019-12-30 09:47:39 +08003477 }
3478
3479 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
3480 boolean sendHint = forceSend;
3481
3482 if (!sendHint) {
3483 // Send power hint if we don't know what we're launching yet
3484 sendHint = targetActivity == null || targetActivity.app == null;
3485 }
3486
3487 if (!sendHint) { // targetActivity != null
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003488 // Send power hint when the activity's process is different than the current top resumed
3489 // activity on all display areas, or if there are no resumed activities in the system.
Louis Chang149d5c82019-12-30 09:47:39 +08003490 boolean noResumedActivities = true;
3491 boolean allFocusedProcessesDiffer = true;
3492 for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003493 final DisplayContent dc = getChildAt(displayNdx);
3494 for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3495 final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx);
3496 final ActivityRecord resumedActivity = taskDisplayArea.getFocusedActivity();
3497 final WindowProcessController resumedActivityProcess =
3498 resumedActivity == null ? null : resumedActivity.app;
Louis Chang149d5c82019-12-30 09:47:39 +08003499
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003500 noResumedActivities &= resumedActivityProcess == null;
3501 if (resumedActivityProcess != null) {
3502 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(
3503 targetActivity.app);
3504 }
Louis Chang149d5c82019-12-30 09:47:39 +08003505 }
3506 }
3507 sendHint = noResumedActivities || allFocusedProcessesDiffer;
3508 }
3509
3510 if (sendHint && mService.mPowerManagerInternal != null) {
3511 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
3512 mPowerHintSent = true;
3513 }
3514 }
3515
3516 void sendPowerHintForLaunchEndIfNeeded() {
3517 // Trigger launch power hint if activity is launched
3518 if (mPowerHintSent && mService.mPowerManagerInternal != null) {
3519 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
3520 mPowerHintSent = false;
3521 }
3522 }
3523
3524 private void calculateDefaultMinimalSizeOfResizeableTasks() {
3525 final Resources res = mService.mContext.getResources();
3526 final float minimalSize = res.getDimension(
3527 com.android.internal.R.dimen.default_minimal_size_resizable_task);
3528 final DisplayMetrics dm = res.getDisplayMetrics();
3529
3530 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
3531 }
3532
3533 /**
3534 * Dumps the activities matching the given {@param name} in the either the focused stack
3535 * or all visible stacks if {@param dumpVisibleStacks} is true.
3536 */
3537 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
3538 boolean dumpFocusedStackOnly) {
3539 if (dumpFocusedStackOnly) {
Darryl L Johnson1e3885c2020-02-27 17:38:13 -08003540 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
3541 if (topFocusedStack != null) {
3542 return topFocusedStack.getDumpActivitiesLocked(name);
3543 } else {
3544 return new ArrayList<>();
3545 }
Louis Chang149d5c82019-12-30 09:47:39 +08003546 } else {
3547 ArrayList<ActivityRecord> activities = new ArrayList<>();
3548 int numDisplays = getChildCount();
3549 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
3550 final DisplayContent display = getChildAt(displayNdx);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003551 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3552 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
3553 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3554 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
3555 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
3556 activities.addAll(stack.getDumpActivitiesLocked(name));
3557 }
Louis Chang149d5c82019-12-30 09:47:39 +08003558 }
3559 }
3560 }
3561 return activities;
3562 }
3563 }
3564
3565 public void dump(PrintWriter pw, String prefix) {
3566 pw.print(prefix);
3567 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
3568 for (int i = getChildCount() - 1; i >= 0; --i) {
3569 final DisplayContent display = getChildAt(i);
3570 display.dump(pw, prefix, true /* dumpAll */);
3571 }
Winson Chung268eccb2020-03-26 13:43:44 -07003572 pw.println();
Louis Chang149d5c82019-12-30 09:47:39 +08003573 }
3574
3575 /**
3576 * Dump all connected displays' configurations.
3577 * @param prefix Prefix to apply to each line of the dump.
3578 */
3579 void dumpDisplayConfigs(PrintWriter pw, String prefix) {
3580 pw.print(prefix); pw.println("Display override configurations:");
3581 final int displayCount = getChildCount();
3582 for (int i = 0; i < displayCount; i++) {
3583 final DisplayContent displayContent = getChildAt(i);
3584 pw.print(prefix); pw.print(" "); pw.print(displayContent.mDisplayId); pw.print(": ");
3585 pw.println(displayContent.getRequestedOverrideConfiguration());
3586 }
3587 }
3588
Louis Chang149d5c82019-12-30 09:47:39 +08003589 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
3590 String dumpPackage) {
3591 boolean printed = false;
3592 boolean needSep = false;
3593 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
3594 DisplayContent displayContent = getChildAt(displayNdx);
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003595 if (printed) {
3596 pw.println();
3597 }
Louis Chang149d5c82019-12-30 09:47:39 +08003598 pw.print("Display #"); pw.print(displayContent.mDisplayId);
3599 pw.println(" (activities from top to bottom):");
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003600 for (int tdaNdx = displayContent.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3601 final TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(tdaNdx);
3602 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
3603 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003604 if (needSep) {
3605 pw.println();
3606 }
3607 needSep = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, false);
3608 printed |= needSep;
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003609 }
Louis Chang149d5c82019-12-30 09:47:39 +08003610 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003611 for (int tdaNdx = displayContent.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
3612 final TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(tdaNdx);
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003613 printed |= printThisActivity(pw, taskDisplayArea.getFocusedActivity(),
3614 dumpPackage, needSep, " Resumed: ", () -> {
3615 pw.println(" Resumed activities in task display areas"
3616 + " (from top to bottom):");
3617 });
Andrii Kulianf9df4a82020-03-31 12:09:27 -07003618 }
Louis Chang149d5c82019-12-30 09:47:39 +08003619 }
3620
3621 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ",
3622 "Fin", false, !dumpAll,
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003623 false, dumpPackage, true,
3624 () -> { pw.println(" Activities waiting to finish:"); }, null);
Louis Chang149d5c82019-12-30 09:47:39 +08003625 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
3626 "Stop", false, !dumpAll,
Dianne Hackborn9106f2a2020-04-30 16:23:20 -07003627 false, dumpPackage, true,
3628 () -> { pw.println(" Activities waiting to stop:"); }, null);
Louis Chang149d5c82019-12-30 09:47:39 +08003629
3630 return printed;
3631 }
3632
Louis Chang149d5c82019-12-30 09:47:39 +08003633 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
3634 private final String mTag;
3635 private final long mAcquireTime;
3636 private final int mDisplayId;
3637
3638 public SleepTokenImpl(String tag, int displayId) {
3639 mTag = tag;
3640 mDisplayId = displayId;
3641 mAcquireTime = SystemClock.uptimeMillis();
3642 }
3643
3644 @Override
3645 public void release() {
3646 synchronized (mService.mGlobalLock) {
3647 removeSleepToken(this);
3648 }
3649 }
3650
3651 @Override
3652 public String toString() {
3653 return "{\"" + mTag + "\", display " + mDisplayId
3654 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
3655 }
3656 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07003657}