blob: 704a4b7e65ea67e19af0f3fa682a7d6c335184cd [file] [log] [blame]
Wale Ogunwaled32da472018-11-16 07:19:28 -08001/*
2 * Copyright (C) 2018 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
19import static android.app.ActivityTaskManager.INVALID_STACK_ID;
20import static android.app.ActivityTaskManager.INVALID_TASK_ID;
21import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
22import 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;
26import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
27import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
28import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
29import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwaled32da472018-11-16 07:19:28 -080030import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwaled32da472018-11-16 07:19:28 -080031import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
32import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
33import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Wale Ogunwaled32da472018-11-16 07:19:28 -080034import static android.view.Display.DEFAULT_DISPLAY;
35import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwalea38654f2019-11-17 20:37:15 -080036import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
Issei Suzukicac2a502019-04-16 16:52:50 +020037import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
Wale Ogunwaled32da472018-11-16 07:19:28 -080038
39import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
40import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
41import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
42import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
43import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
44import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
45import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
46import 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;
Wale Ogunwaled32da472018-11-16 07:19:28 -080052import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
53import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
54import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
Wale Ogunwaled32da472018-11-16 07:19:28 -080055import 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_TASKS;
58import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
59import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
60import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
61import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
62import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
63import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
64import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Louis Changcdec0802019-11-11 11:45:07 +080065import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
66import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
Wale Ogunwaled32da472018-11-16 07:19:28 -080067
68import static java.lang.Integer.MAX_VALUE;
69
70import android.annotation.IntDef;
71import android.annotation.NonNull;
72import android.annotation.Nullable;
73import android.annotation.UserIdInt;
74import android.app.ActivityManager;
75import android.app.ActivityOptions;
76import android.app.AppGlobals;
77import android.app.WindowConfiguration;
78import android.content.ComponentName;
79import android.content.Intent;
80import android.content.pm.ActivityInfo;
81import android.content.pm.ApplicationInfo;
82import android.content.pm.ResolveInfo;
83import android.content.res.Configuration;
84import android.content.res.Resources;
85import android.graphics.Rect;
86import android.hardware.display.DisplayManager;
87import android.hardware.display.DisplayManagerInternal;
88import android.hardware.power.V1_0.PowerHint;
Wale Ogunwalea38654f2019-11-17 20:37:15 -080089import android.net.Uri;
Wale Ogunwaled32da472018-11-16 07:19:28 -080090import android.os.FactoryTest;
91import android.os.IBinder;
92import android.os.RemoteException;
93import android.os.SystemClock;
Wale Ogunwaled32da472018-11-16 07:19:28 -080094import android.os.UserHandle;
Chilun85ebc0d2019-04-15 16:00:53 +080095import android.os.storage.StorageManager;
Chilun2ef71f72018-11-16 17:57:15 +080096import android.provider.Settings;
Wale Ogunwaled32da472018-11-16 07:19:28 -080097import android.service.voice.IVoiceInteractionSession;
98import android.util.ArraySet;
99import android.util.DisplayMetrics;
100import android.util.IntArray;
Chilun2ef71f72018-11-16 17:57:15 +0800101import android.util.Pair;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800102import android.util.Slog;
103import android.util.SparseArray;
104import android.util.SparseIntArray;
105import android.util.TimeUtils;
106import android.util.proto.ProtoOutputStream;
107import android.view.Display;
108import android.view.DisplayInfo;
109
110import com.android.internal.annotations.VisibleForTesting;
Chilun2ef71f72018-11-16 17:57:15 +0800111import com.android.internal.app.ResolverActivity;
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800112import com.android.internal.util.ToBooleanFunction;
113import com.android.internal.util.function.pooled.PooledConsumer;
114import com.android.internal.util.function.pooled.PooledFunction;
115import com.android.internal.util.function.pooled.PooledLambda;
116import com.android.internal.util.function.pooled.PooledPredicate;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800117import com.android.server.LocalServices;
118import com.android.server.am.ActivityManagerService;
119import com.android.server.am.AppTimeTracker;
120import com.android.server.am.UserState;
Chilun8b1f1be2019-03-13 17:14:36 +0800121import com.android.server.policy.WindowManagerPolicy;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800122
123import java.io.FileDescriptor;
124import java.io.PrintWriter;
125import java.lang.annotation.Retention;
126import java.lang.annotation.RetentionPolicy;
127import java.util.ArrayList;
128import java.util.Iterator;
129import java.util.List;
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800130import java.util.Objects;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800131import java.util.Set;
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900132import java.util.function.Function;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800133
134/**
135 * Root node for activity containers.
136 * TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
137 * intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
138 */
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800139class RootActivityContainer extends ConfigurationContainer
140 implements DisplayManager.DisplayListener {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800141
142 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootActivityContainer" : TAG_ATM;
143 static final String TAG_TASKS = TAG + POSTFIX_TASKS;
144 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
145 static final String TAG_STATES = TAG + POSTFIX_STATES;
146 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
147
148 /**
149 * The modes which affect which tasks are returned when calling
150 * {@link RootActivityContainer#anyTaskForId(int)}.
151 */
152 @Retention(RetentionPolicy.SOURCE)
153 @IntDef({
154 MATCH_TASK_IN_STACKS_ONLY,
155 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
156 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
157 })
158 public @interface AnyTaskForIdMatchTaskMode {}
159 // Match only tasks in the current stacks
160 static final int MATCH_TASK_IN_STACKS_ONLY = 0;
161 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
162 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
163 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
164 // provided stack id
165 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
166
167 ActivityTaskManagerService mService;
168 ActivityStackSupervisor mStackSupervisor;
169 WindowManagerService mWindowManager;
170 DisplayManager mDisplayManager;
171 private DisplayManagerInternal mDisplayManagerInternal;
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900172 // TODO(root-unify): Remove after object merge with RootWindowContainer.
173 RootWindowContainer mRootWindowContainer;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800174
175 /**
176 * List of displays which contain activities, sorted by z-order.
177 * The last entry in the list is the topmost.
178 */
179 private final ArrayList<ActivityDisplay> mActivityDisplays = new ArrayList<>();
180
181 /** Reference to default display so we can quickly look it up. */
182 private ActivityDisplay mDefaultDisplay;
183 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
184
185 /** The current user */
186 int mCurrentUser;
187 /** Stack id of the front stack when user switched, indexed by userId. */
188 SparseIntArray mUserStackInFront = new SparseIntArray(2);
189
190 /**
191 * A list of tokens that cause the top activity to be put to sleep.
192 * They are used by components that may hide and block interaction with underlying
193 * activities.
194 */
195 final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
196
197 /** Is dock currently minimized. */
198 boolean mIsDockMinimized;
199
200 /** Set when a power hint has started, but not ended. */
201 private boolean mPowerHintSent;
202
Louis Changa5d070e2019-09-04 13:20:01 +0800203 /** Used to keep ensureActivitiesVisible() from being entered recursively. */
204 private boolean mInEnsureActivitiesVisible = false;
205
Wale Ogunwaled32da472018-11-16 07:19:28 -0800206 // The default minimal size that will be used if the activity doesn't specify its minimal size.
207 // It will be calculated when the default display gets added.
208 int mDefaultMinSizeOfResizeableTaskDp = -1;
209
210 // Whether tasks have moved and we need to rank the tasks before next OOM scoring
211 private boolean mTaskLayersChanged = true;
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800212 private int mTmpTaskLayerRank;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800213
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800214 private boolean mTmpBoolean;
215 private RemoteException mTmpRemoteException;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800216
217 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900218 static class FindTaskResult implements Function<Task, Boolean> {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800219 ActivityRecord mRecord;
220 boolean mIdealMatch;
221
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800222 private ActivityRecord mTarget;
223 private Intent intent;
224 private ActivityInfo info;
225 private ComponentName cls;
226 private int userId;
227 private boolean isDocument;
228 private Uri documentData;
229
230 /**
231 * Returns the top activity in any existing task matching the given Intent in the input
232 * result. Returns null if no such task is found.
233 */
234 void process(ActivityRecord target, ActivityStack parent) {
235 mTarget = target;
236
237 intent = target.intent;
238 info = target.info;
239 cls = intent.getComponent();
240 if (info.targetActivity != null) {
241 cls = new ComponentName(info.packageName, info.targetActivity);
242 }
243 userId = UserHandle.getUserId(info.applicationInfo.uid);
244 isDocument = intent != null & intent.isDocument();
245 // If documentData is non-null then it must match the existing task data.
246 documentData = isDocument ? intent.getData() : null;
247
248 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
249 parent.forAllTasks(this);
250 }
251
Wale Ogunwaled32da472018-11-16 07:19:28 -0800252 void clear() {
253 mRecord = null;
254 mIdealMatch = false;
255 }
256
257 void setTo(FindTaskResult result) {
258 mRecord = result.mRecord;
259 mIdealMatch = result.mIdealMatch;
260 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800261
262 @Override
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900263 public Boolean apply(Task task) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800264 if (task.voiceSession != null) {
265 // We never match voice sessions; those always run independently.
266 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
267 return false;
268 }
269 if (task.mUserId != userId) {
270 // Looking for a different task.
271 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
272 return false;
273 }
274
275 // Overlays should not be considered as the task's logical top activity.
276 final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
277 if (r == null || r.finishing || r.mUserId != userId ||
278 r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
279 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
280 return false;
281 }
282 if (!r.hasCompatibleActivityType(mTarget)) {
283 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
284 return false;
285 }
286
287 final Intent taskIntent = task.intent;
288 final Intent affinityIntent = task.affinityIntent;
289 final boolean taskIsDocument;
290 final Uri taskDocumentData;
291 if (taskIntent != null && taskIntent.isDocument()) {
292 taskIsDocument = true;
293 taskDocumentData = taskIntent.getData();
294 } else if (affinityIntent != null && affinityIntent.isDocument()) {
295 taskIsDocument = true;
296 taskDocumentData = affinityIntent.getData();
297 } else {
298 taskIsDocument = false;
299 taskDocumentData = null;
300 }
301
302 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
303 + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
304 + "/aff=" + r.getTask().rootAffinity + " to new cls="
305 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
306 // TODO Refactor to remove duplications. Check if logic can be simplified.
307 if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
308 && Objects.equals(documentData, taskDocumentData)) {
309 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
310 //dump();
311 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
312 "For Intent " + intent + " bringing to top: " + r.intent);
313 mRecord = r;
314 mIdealMatch = true;
315 return true;
316 } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
317 affinityIntent.getComponent().compareTo(cls) == 0 &&
318 Objects.equals(documentData, taskDocumentData)) {
319 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
320 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
321 "For Intent " + intent + " bringing to top: " + r.intent);
322 mRecord = r;
323 mIdealMatch = true;
324 return true;
325 } else if (!isDocument && !taskIsDocument
326 && mRecord == null && task.rootAffinity != null) {
327 if (task.rootAffinity.equals(mTarget.taskAffinity)) {
328 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
329 // It is possible for multiple tasks to have the same root affinity especially
330 // if they are in separate stacks. We save off this candidate, but keep looking
331 // to see if there is a better candidate.
332 mRecord = r;
333 mIdealMatch = false;
334 }
335 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
336
337 return false;
338 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800339 }
340
341 RootActivityContainer(ActivityTaskManagerService service) {
342 mService = service;
343 mStackSupervisor = service.mStackSupervisor;
344 mStackSupervisor.mRootActivityContainer = this;
345 }
346
Wale Ogunwaled32da472018-11-16 07:19:28 -0800347 void setWindowManager(WindowManagerService wm) {
348 mWindowManager = wm;
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700349 mRootWindowContainer = mWindowManager.mRoot;
350 mRootWindowContainer.setRootActivityContainer(this);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800351 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
Charles Chen699e3602019-01-10 15:00:25 +0800352 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800353 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
354
355 final Display[] displays = mDisplayManager.getDisplays();
356 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
357 final Display display = displays[displayNdx];
358 final ActivityDisplay activityDisplay = new ActivityDisplay(this, display);
359 if (activityDisplay.mDisplayId == DEFAULT_DISPLAY) {
360 mDefaultDisplay = activityDisplay;
361 }
362 addChild(activityDisplay, ActivityDisplay.POSITION_TOP);
363 }
364 calculateDefaultMinimalSizeOfResizeableTasks();
365
366 final ActivityDisplay defaultDisplay = getDefaultDisplay();
367
368 defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
369 positionChildAt(defaultDisplay, ActivityDisplay.POSITION_TOP);
370 }
371
372 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
373 ActivityDisplay getDefaultDisplay() {
374 return mDefaultDisplay;
375 }
376
377 /**
378 * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is
379 * defined in {@link DisplayInfo#uniqueId}.
380 *
381 * @param uniqueId the unique ID of the display
382 * @return the {@link ActivityDisplay} or {@code null} if nothing is found.
383 */
384 ActivityDisplay getActivityDisplay(String uniqueId) {
385 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
386 final ActivityDisplay display = mActivityDisplays.get(i);
387 final boolean isValid = display.mDisplay.isValid();
388 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
389 return display;
390 }
391 }
392
393 return null;
394 }
395
396 // TODO: Look into consolidating with getActivityDisplayOrCreate()
397 ActivityDisplay getActivityDisplay(int displayId) {
398 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
399 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
400 if (activityDisplay.mDisplayId == displayId) {
401 return activityDisplay;
402 }
403 }
404 return null;
405 }
406
407 /**
408 * Get an existing instance of {@link ActivityDisplay} or create new if there is a
409 * corresponding record in display manager.
410 */
411 // TODO: Look into consolidating with getActivityDisplay()
Charles Chenb409e6c2019-02-12 12:30:17 +0800412 @Nullable ActivityDisplay getActivityDisplayOrCreate(int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800413 ActivityDisplay activityDisplay = getActivityDisplay(displayId);
414 if (activityDisplay != null) {
415 return activityDisplay;
416 }
417 if (mDisplayManager == null) {
418 // The system isn't fully initialized yet.
419 return null;
420 }
421 final Display display = mDisplayManager.getDisplay(displayId);
422 if (display == null) {
423 // The display is not registered in DisplayManager.
424 return null;
425 }
426 // The display hasn't been added to ActivityManager yet, create a new record now.
427 activityDisplay = new ActivityDisplay(this, display);
428 addChild(activityDisplay, ActivityDisplay.POSITION_BOTTOM);
429 return activityDisplay;
430 }
431
Wale Ogunwaled32da472018-11-16 07:19:28 -0800432 ActivityRecord getDefaultDisplayHomeActivity() {
433 return getDefaultDisplayHomeActivityForUser(mCurrentUser);
434 }
435
436 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
437 return getActivityDisplay(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
438 }
439
440 boolean startHomeOnAllDisplays(int userId, String reason) {
441 boolean homeStarted = false;
442 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
443 final int displayId = mActivityDisplays.get(i).mDisplayId;
444 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
445 }
446 return homeStarted;
447 }
448
Louis Changdcdde952018-12-04 15:38:44 +0800449 void startHomeOnEmptyDisplays(String reason) {
450 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
451 final ActivityDisplay display = mActivityDisplays.get(i);
452 if (display.topRunningActivity() == null) {
453 startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
454 }
455 }
456 }
457
Chilun8b1f1be2019-03-13 17:14:36 +0800458 boolean startHomeOnDisplay(int userId, String reason, int displayId) {
Chilun39232092019-03-22 14:41:30 +0800459 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
460 false /* fromHomeKey */);
Chilun8b1f1be2019-03-13 17:14:36 +0800461 }
462
Wale Ogunwaled32da472018-11-16 07:19:28 -0800463 /**
Chilun2ef71f72018-11-16 17:57:15 +0800464 * This starts home activity on displays that can have system decorations based on displayId -
465 * Default display always use primary home component.
466 * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
467 * according to the priorities listed below.
468 * - If default home is not set, always use the secondary home defined in the config.
469 * - Use currently selected primary home activity.
470 * - Use the activity in the same package as currently selected primary home activity.
471 * If there are multiple activities matched, use first one.
472 * - Use the secondary home defined in the config.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800473 */
Chilun39232092019-03-22 14:41:30 +0800474 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
475 boolean fromHomeKey) {
Chilun8b1f1be2019-03-13 17:14:36 +0800476 // Fallback to top focused display if the displayId is invalid.
477 if (displayId == INVALID_DISPLAY) {
Wale Ogunwalefef90a02019-11-06 17:56:33 -0800478 final ActivityStack stack = getTopDisplayFocusedStack();
479 displayId = stack != null ? stack.mDisplayId : DEFAULT_DISPLAY;
Chilun8b1f1be2019-03-13 17:14:36 +0800480 }
481
Chilun85ebc0d2019-04-15 16:00:53 +0800482 Intent homeIntent = null;
483 ActivityInfo aInfo = null;
Chilun2ef71f72018-11-16 17:57:15 +0800484 if (displayId == DEFAULT_DISPLAY) {
485 homeIntent = mService.getHomeIntent();
486 aInfo = resolveHomeActivity(userId, homeIntent);
Chilun85ebc0d2019-04-15 16:00:53 +0800487 } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Chilun2ef71f72018-11-16 17:57:15 +0800488 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
489 aInfo = info.first;
490 homeIntent = info.second;
491 }
Chilun85ebc0d2019-04-15 16:00:53 +0800492 if (aInfo == null || homeIntent == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800493 return false;
494 }
495
Chilun39232092019-03-22 14:41:30 +0800496 if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800497 return false;
498 }
499
Chilun2ef71f72018-11-16 17:57:15 +0800500 // Updates the home component of the intent.
501 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
502 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
Chilun8b1f1be2019-03-13 17:14:36 +0800503 // Updates the extra information of the intent.
504 if (fromHomeKey) {
505 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
506 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800507 // Update the reason for ANR debugging to verify if the user activity is the one that
508 // actually launched.
509 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
Chilun2ef71f72018-11-16 17:57:15 +0800510 aInfo.applicationInfo.uid) + ":" + displayId;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800511 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
512 displayId);
513 return true;
514 }
515
516 /**
Chilun2ef71f72018-11-16 17:57:15 +0800517 * This resolves the home activity info.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800518 * @return the home activity info if any.
519 */
Chilun2ef71f72018-11-16 17:57:15 +0800520 @VisibleForTesting
521 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800522 final int flags = ActivityManagerService.STOCK_PM_FLAGS;
523 final ComponentName comp = homeIntent.getComponent();
524 ActivityInfo aInfo = null;
525 try {
526 if (comp != null) {
527 // Factory test.
528 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
529 } else {
530 final String resolvedType =
531 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
532 final ResolveInfo info = AppGlobals.getPackageManager()
533 .resolveIntent(homeIntent, resolvedType, flags, userId);
534 if (info != null) {
535 aInfo = info.activityInfo;
536 }
537 }
538 } catch (RemoteException e) {
539 // ignore
540 }
541
542 if (aInfo == null) {
543 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
544 return null;
545 }
546
Wale Ogunwaled32da472018-11-16 07:19:28 -0800547 aInfo = new ActivityInfo(aInfo);
548 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800549 return aInfo;
550 }
551
Chilun2ef71f72018-11-16 17:57:15 +0800552 @VisibleForTesting
553 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) {
554 if (displayId == DEFAULT_DISPLAY) {
555 throw new IllegalArgumentException(
556 "resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY");
557 }
558 // Resolve activities in the same package as currently selected primary home activity.
559 Intent homeIntent = mService.getHomeIntent();
560 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
561 if (aInfo != null) {
562 if (ResolverActivity.class.getName().equals(aInfo.name)) {
563 // Always fallback to secondary home component if default home is not set.
564 aInfo = null;
565 } else {
566 // Look for secondary home activities in the currently selected default home
567 // package.
568 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
569 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
570 final int size = resolutions.size();
571 final String targetName = aInfo.name;
572 aInfo = null;
573 for (int i = 0; i < size; i++) {
574 ResolveInfo resolveInfo = resolutions.get(i);
575 // We need to traverse all resolutions to check if the currently selected
576 // default home activity is present.
577 if (resolveInfo.activityInfo.name.equals(targetName)) {
578 aInfo = resolveInfo.activityInfo;
579 break;
580 }
581 }
582 if (aInfo == null && size > 0) {
583 // First one is the best.
584 aInfo = resolutions.get(0).activityInfo;
585 }
586 }
587 }
588
589 if (aInfo != null) {
590 if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
591 aInfo = null;
592 }
593 }
594
595 // Fallback to secondary home component.
596 if (aInfo == null) {
597 homeIntent = mService.getSecondaryHomeIntent(null);
598 aInfo = resolveHomeActivity(userId, homeIntent);
599 }
600 return Pair.create(aInfo, homeIntent);
601 }
602
603 /**
604 * Retrieve all activities that match the given intent.
605 * The list should already ordered from best to worst matched.
606 * {@link android.content.pm.PackageManager#queryIntentActivities}
607 */
608 @VisibleForTesting
609 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
610 List<ResolveInfo> resolutions;
611 try {
612 final String resolvedType =
613 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
614 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
615 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
616
617 } catch (RemoteException e) {
618 resolutions = new ArrayList<>();
619 }
620 return resolutions;
621 }
622
Wale Ogunwaled32da472018-11-16 07:19:28 -0800623 boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
624 if (!mService.isBooting() && !mService.isBooted()) {
625 // Not ready yet!
626 return false;
627 }
628
629 if (displayId == INVALID_DISPLAY) {
630 displayId = DEFAULT_DISPLAY;
631 }
632
633 final ActivityRecord r = getActivityDisplay(displayId).getHomeActivity();
634 final String myReason = reason + " resumeHomeActivity";
635
636 // Only resume home activity if isn't finishing.
637 if (r != null && !r.finishing) {
638 r.moveFocusableActivityToTop(myReason);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800639 return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800640 }
641 return startHomeOnDisplay(mCurrentUser, myReason, displayId);
642 }
643
644 /**
Chilun85ebc0d2019-04-15 16:00:53 +0800645 * Check if the display is valid for secondary home activity.
646 * @param displayId The id of the target display.
647 * @return {@code true} if allow to launch, {@code false} otherwise.
648 */
649 boolean shouldPlaceSecondaryHomeOnDisplay(int displayId) {
650 if (displayId == DEFAULT_DISPLAY) {
651 throw new IllegalArgumentException(
652 "shouldPlaceSecondaryHomeOnDisplay: Should not be DEFAULT_DISPLAY");
653 } else if (displayId == INVALID_DISPLAY) {
654 return false;
655 }
656
657 if (!mService.mSupportsMultiDisplay) {
658 // Can't launch home on secondary display if device does not support multi-display.
659 return false;
660 }
661
662 final boolean deviceProvisioned = Settings.Global.getInt(
663 mService.mContext.getContentResolver(),
664 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
665 if (!deviceProvisioned) {
666 // Can't launch home on secondary display before device is provisioned.
667 return false;
668 }
669
670 if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
671 // Can't launch home on secondary displays if device is still locked.
672 return false;
673 }
674
675 final ActivityDisplay display = getActivityDisplay(displayId);
676 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
677 // Can't launch home on display that doesn't support system decorations.
678 return false;
679 }
680
681 return true;
682 }
683
684 /**
Wale Ogunwaled32da472018-11-16 07:19:28 -0800685 * Check if home activity start should be allowed on a display.
686 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
687 * @param displayId The id of the target display.
688 * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
689 * @return {@code true} if allow to launch, {@code false} otherwise.
690 */
691 boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId,
692 boolean allowInstrumenting) {
693 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
694 && mService.mTopAction == null) {
695 // We are running in factory test mode, but unable to find the factory test app, so
696 // just sit around displaying the error message and don't try to start anything.
697 return false;
698 }
699
700 final WindowProcessController app =
701 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
702 if (!allowInstrumenting && app != null && app.isInstrumenting()) {
703 // Don't do this if the home app is currently being instrumented.
704 return false;
705 }
706
707 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
708 && displayId == mService.mVr2dDisplayId)) {
709 // No restrictions to default display or vr 2d display.
710 return true;
711 }
712
Chilun85ebc0d2019-04-15 16:00:53 +0800713 if (!shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800714 return false;
715 }
716
717 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
Chilun2ef71f72018-11-16 17:57:15 +0800718 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800719 if (!supportMultipleInstance) {
Chilun2ef71f72018-11-16 17:57:15 +0800720 // Can't launch home on secondary displays if it requested to be single instance.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800721 return false;
722 }
723
724 return true;
725 }
726
727 /**
728 * Ensure all activities visibility, update orientation and configuration.
729 *
730 * @param starting The currently starting activity or {@code null} if there is none.
731 * @param displayId The id of the display where operation is executed.
732 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
733 * {@code true} if config changed.
734 * @param deferResume Whether to defer resume while updating config.
735 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
736 * because of configuration update.
737 */
738 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
739 boolean markFrozenIfConfigChanged, boolean deferResume) {
740 // First ensure visibility without updating the config just yet. We need this to know what
741 // activities are affecting configuration now.
742 // Passing null here for 'starting' param value, so that visibility of actual starting
743 // activity will be properly updated.
744 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
745 false /* preserveWindows */, false /* notifyClients */);
746
747 if (displayId == INVALID_DISPLAY) {
748 // The caller didn't provide a valid display id, skip updating config.
749 return true;
750 }
751
752 // Force-update the orientation from the WindowManager, since we need the true configuration
753 // to send to the client now.
Garfield Tan90b04282018-12-11 14:04:42 -0800754 final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId);
755 Configuration config = null;
756 if (displayContent != null) {
Riddle Hsuccf09402019-08-13 00:33:06 +0800757 config = displayContent.updateOrientation(
Garfield Tan90b04282018-12-11 14:04:42 -0800758 getDisplayOverrideConfiguration(displayId),
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800759 starting != null && starting.mayFreezeScreenLocked()
Garfield Tan90b04282018-12-11 14:04:42 -0800760 ? starting.appToken : null,
761 true /* forceUpdate */);
762 }
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800763 // Visibilities may change so let the starting activity have a chance to report. Can't do it
764 // when visibility is changed in each AppWindowToken because it may trigger wrong
765 // configuration push because the visibility of some activities may not be updated yet.
766 if (starting != null) {
767 starting.reportDescendantOrientationChangeIfNeeded();
768 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800769 if (starting != null && markFrozenIfConfigChanged && config != null) {
770 starting.frozenBeforeDestroy = true;
771 }
772
Louis Chang2453d062019-11-19 22:30:48 +0800773 if (displayContent != null) {
Shivam Agrawal1d3db652019-07-01 15:26:11 -0700774 // Update the configuration of the activities on the display.
Louis Chang2453d062019-11-19 22:30:48 +0800775 // TODO(display-merge): Remove cast
776 return ((ActivityDisplay) displayContent)
777 .updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
778 null /* result */);
Shivam Agrawal1d3db652019-07-01 15:26:11 -0700779 } else {
780 return true;
781 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800782 }
783
784 /**
785 * @return a list of activities which are the top ones in each visible stack. The first
786 * entry will be the focused activity.
787 */
788 List<IBinder> getTopVisibleActivities() {
789 final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
790 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
791 // Traverse all displays.
792 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
793 final ActivityDisplay display = mActivityDisplays.get(i);
794 // Traverse all stacks on a display.
Louis Chang2453d062019-11-19 22:30:48 +0800795 for (int j = display.getStackCount() - 1; j >= 0; --j) {
796 final ActivityStack stack = display.getStackAt(j);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800797 // Get top activity from a visible stack and add it to the list.
798 if (stack.shouldBeVisible(null /* starting */)) {
Wale Ogunwale21e06482019-11-18 05:14:15 -0800799 final ActivityRecord top = stack.getTopNonFinishingActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800800 if (top != null) {
801 if (stack == topFocusedStack) {
802 topActivityTokens.add(0, top.appToken);
803 } else {
804 topActivityTokens.add(top.appToken);
805 }
806 }
807 }
808 }
809 }
810 return topActivityTokens;
811 }
812
813 ActivityStack getTopDisplayFocusedStack() {
814 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
815 final ActivityStack focusedStack = mActivityDisplays.get(i).getFocusedStack();
816 if (focusedStack != null) {
817 return focusedStack;
818 }
819 }
820 return null;
821 }
822
823 ActivityRecord getTopResumedActivity() {
824 final ActivityStack focusedStack = getTopDisplayFocusedStack();
825 if (focusedStack == null) {
826 return null;
827 }
828 final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
829 if (resumedActivity != null && resumedActivity.app != null) {
830 return resumedActivity;
831 }
832 // The top focused stack might not have a resumed activity yet - look on all displays in
833 // focus order.
834 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
835 final ActivityDisplay display = mActivityDisplays.get(i);
836 final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity();
837 if (resumedActivityOnDisplay != null) {
838 return resumedActivityOnDisplay;
839 }
840 }
841 return null;
842 }
843
844 boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
845 if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) {
846 return false;
847 }
848
849 return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
850 }
851
852 boolean isTopDisplayFocusedStack(ActivityStack stack) {
853 return stack != null && stack == getTopDisplayFocusedStack();
854 }
855
856 void updatePreviousProcess(ActivityRecord r) {
857 // Now that this process has stopped, we may want to consider it to be the previous app to
858 // try to keep around in case the user wants to return to it.
859
860 // First, found out what is currently the foreground app, so that we don't blow away the
861 // previous app if this activity is being hosted by the process that is actually still the
862 // foreground.
863 WindowProcessController fgApp = null;
864 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
865 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +0800866 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
867 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800868 if (isTopDisplayFocusedStack(stack)) {
869 final ActivityRecord resumedActivity = stack.getResumedActivity();
870 if (resumedActivity != null) {
871 fgApp = resumedActivity.app;
872 } else if (stack.mPausingActivity != null) {
873 fgApp = stack.mPausingActivity.app;
874 }
875 break;
876 }
877 }
878 }
879
880 // Now set this one as the previous process, only if that really makes sense to.
881 if (r.hasProcess() && fgApp != null && r.app != fgApp
882 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
883 && r.app != mService.mHomeProcess) {
884 mService.mPreviousProcess = r.app;
885 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
886 }
887 }
888
889 boolean attachApplication(WindowProcessController app) throws RemoteException {
890 final String processName = app.mName;
891 boolean didSomething = false;
892 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
893 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
894 final ActivityStack stack = display.getFocusedStack();
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800895 if (stack == null) {
896 continue;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800897 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800898
899 mTmpRemoteException = null;
900 mTmpBoolean = false; // Set to true if an activity was started.
901 final PooledFunction c = PooledLambda.obtainFunction(
902 RootActivityContainer::startActivityForAttachedApplicationIfNeeded, this,
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900903 PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800904 stack.forAllActivities(c);
905 c.recycle();
906 if (mTmpRemoteException != null) {
907 throw mTmpRemoteException;
908 }
909 didSomething |= mTmpBoolean;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800910 }
911 if (!didSomething) {
912 ensureActivitiesVisible(null, 0, false /* preserve_windows */);
913 }
914 return didSomething;
915 }
916
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800917 private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
918 WindowProcessController app, ActivityRecord top) {
919 if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
920 || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
921 return false;
922 }
923
924 try {
925 if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
926 true /*checkConfig*/)) {
927 mTmpBoolean = true;
928 }
929 } catch (RemoteException e) {
930 Slog.w(TAG, "Exception in new application when starting activity "
931 + top.intent.getComponent().flattenToShortString(), e);
932 mTmpRemoteException = e;
933 return true;
934 }
935 return false;
936 }
937
Wale Ogunwaled32da472018-11-16 07:19:28 -0800938 /**
939 * Make sure that all activities that need to be visible in the system actually are and update
940 * their configuration.
941 */
942 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
943 boolean preserveWindows) {
944 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
945 }
946
947 /**
948 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
949 */
950 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
951 boolean preserveWindows, boolean notifyClients) {
Louis Changa5d070e2019-09-04 13:20:01 +0800952 if (mInEnsureActivitiesVisible) {
953 // Don't do recursive work.
954 return;
955 }
956 mInEnsureActivitiesVisible = true;
957
Wale Ogunwaled32da472018-11-16 07:19:28 -0800958 try {
Louis Changa5d070e2019-09-04 13:20:01 +0800959 mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800960 // First the front stacks. In case any are not fullscreen and are in front of home.
961 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
962 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang77ce34d2019-01-03 15:45:12 +0800963 display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
964 notifyClients);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800965 }
966 } finally {
967 mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
Louis Changa5d070e2019-09-04 13:20:01 +0800968 mInEnsureActivitiesVisible = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800969 }
970 }
971
972 boolean switchUser(int userId, UserState uss) {
973 final int focusStackId = getTopDisplayFocusedStack().getStackId();
974 // We dismiss the docked stack whenever we switch users.
975 final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
976 if (dockedStack != null) {
977 mStackSupervisor.moveTasksToFullscreenStackLocked(
978 dockedStack, dockedStack.isFocusedStackOnDisplay());
979 }
980 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
981 // also cause all tasks to be moved to the fullscreen stack at a position that is
982 // appropriate.
983 removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
984
985 mUserStackInFront.put(mCurrentUser, focusStackId);
986 final int restoreStackId =
987 mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId);
988 mCurrentUser = userId;
989
990 mStackSupervisor.mStartingUsers.add(uss);
991 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
992 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +0800993 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
994 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700995 stack.switchUser(userId);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900996 Task task = stack.getTopMostTask();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800997 if (task != null) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700998 stack.positionChildAtTop(task);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800999 }
1000 }
1001 }
1002
1003 ActivityStack stack = getStack(restoreStackId);
1004 if (stack == null) {
1005 stack = getDefaultDisplay().getHomeStack();
1006 }
1007 final boolean homeInFront = stack.isActivityTypeHome();
1008 if (stack.isOnHomeDisplay()) {
1009 stack.moveToFront("switchUserOnHomeDisplay");
1010 } else {
1011 // Stack was moved to another display while user was swapped out.
1012 resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
1013 }
1014 return homeInFront;
1015 }
1016
1017 void removeUser(int userId) {
1018 mUserStackInFront.delete(userId);
1019 }
1020
1021 /**
1022 * Update the last used stack id for non-current user (current user's last
1023 * used stack is the focused stack)
1024 */
1025 void updateUserStack(int userId, ActivityStack stack) {
1026 if (userId != mCurrentUser) {
1027 mUserStackInFront.put(userId, stack != null ? stack.getStackId()
1028 : getDefaultDisplay().getHomeStack().mStackId);
1029 }
1030 }
1031
Wale Ogunwaled32da472018-11-16 07:19:28 -08001032 /**
1033 * Move stack with all its existing content to specified display.
1034 * @param stackId Id of stack to move.
1035 * @param displayId Id of display to move stack to.
1036 * @param onTop Indicates whether container should be place on top or on bottom.
1037 */
1038 void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
1039 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1040 if (activityDisplay == null) {
1041 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
1042 + displayId);
1043 }
1044 final ActivityStack stack = getStack(stackId);
1045 if (stack == null) {
1046 throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId="
1047 + stackId);
1048 }
1049
1050 final ActivityDisplay currentDisplay = stack.getDisplay();
1051 if (currentDisplay == null) {
1052 throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack
1053 + " is not attached to any display.");
1054 }
1055
1056 if (currentDisplay.mDisplayId == displayId) {
1057 throw new IllegalArgumentException("Trying to move stack=" + stack
1058 + " to its current displayId=" + displayId);
1059 }
1060
Louis Chang2453d062019-11-19 22:30:48 +08001061 if (activityDisplay.isSingleTaskInstance() && activityDisplay.getStackCount() > 0) {
Wale Ogunwale9e737db2018-12-17 15:42:37 -08001062 // We don't allow moving stacks to single instance display that already has a child.
1063 Slog.e(TAG, "Can not move stack=" + stack
1064 + " to single task instance display=" + activityDisplay);
1065 return;
1066 }
1067
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001068 stack.reparent(activityDisplay.mDisplayContent, onTop);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001069 // TODO(multi-display): resize stacks properly if moved from split-screen.
1070 }
1071
1072 boolean moveTopStackActivityToPinnedStack(int stackId) {
1073 final ActivityStack stack = getStack(stackId);
1074 if (stack == null) {
1075 throw new IllegalArgumentException(
1076 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
1077 }
1078
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001079 final ActivityRecord r = stack.topRunningActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001080 if (r == null) {
1081 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
1082 + " in stack=" + stack);
1083 return false;
1084 }
1085
1086 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
1087 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
1088 + " r=" + r);
1089 return false;
1090 }
1091
1092 moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */,
1093 "moveTopActivityToPinnedStack");
1094 return true;
1095 }
1096
1097 void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
1098 String reason) {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001099 mService.deferWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001100
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001101 final ActivityDisplay display = r.getActivityStack().getDisplay();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001102
Wale Ogunwaled32da472018-11-16 07:19:28 -08001103 try {
Louis Changcdec0802019-11-11 11:45:07 +08001104 final Task task = r.getTask();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001105
Ben Lin6db8fb22019-10-18 16:03:44 -07001106 final ActivityStack pinnedStack = display.getPinnedStack();
1107 // This will change the pinned stack's windowing mode to its original mode, ensuring
1108 // we only have one stack that is in pinned mode.
1109 if (pinnedStack != null) {
1110 pinnedStack.dismissPip();
1111 }
1112
1113 final boolean singleActivity = task.getChildCount() == 1;
1114
1115 final ActivityStack stack;
1116 if (singleActivity) {
1117 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001118 } else {
Ben Lin6db8fb22019-10-18 16:03:44 -07001119 // In the case of multiple activities, we will create a new stack for it and then
1120 // move the PIP activity into the stack.
1121 // We will then perform a windowing mode change for both scenarios.
1122 stack = display.createStack(
1123 r.getActivityStack().getRequestedOverrideWindowingMode(),
1124 r.getActivityType(), ON_TOP);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001125 // There are multiple activities in the task and moving the top activity should
1126 // reveal/leave the other activities in their original task.
1127
1128 // Currently, we don't support reparenting activities across tasks in two different
1129 // stacks, so instead, just create a new task in the same stack, reparent the
1130 // activity into that task, and then reparent the whole task to the new stack. This
1131 // ensures that all the necessary work to migrate states in the old and new stacks
1132 // is also done.
Louis Changcdec0802019-11-11 11:45:07 +08001133 final Task newTask = task.getStack().createTask(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001134 mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001135 r.intent, null, null, true);
1136 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
1137
1138 // Defer resume until below, and do not schedule PiP changes until we animate below
1139 newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
1140 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
1141 }
1142
Ben Lin6db8fb22019-10-18 16:03:44 -07001143 stack.setWindowingMode(WINDOWING_MODE_PINNED);
1144
Wale Ogunwaled32da472018-11-16 07:19:28 -08001145 // Reset the state that indicates it can enter PiP while pausing after we've moved it
1146 // to the pinned stack
1147 r.supportsEnterPipOnTaskSwitch = false;
1148 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001149 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001150 }
1151
Hongwei Wang43a752b2019-09-17 20:20:30 +00001152 // Notify the pinned stack controller to prepare the PiP animation, expect callback
1153 // delivered from SystemUI to WM to start the animation.
1154 final PinnedStackController pinnedStackController =
1155 display.mDisplayContent.getPinnedStackController();
1156 pinnedStackController.prepareAnimation(sourceHintBounds, aspectRatio,
1157 null /* stackBounds */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001158
Hongwei Wang43a752b2019-09-17 20:20:30 +00001159 // TODO: revisit the following statement after the animation is moved from WM to SysUI.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001160 // Update the visibility of all activities after the they have been reparented to the new
1161 // stack. This MUST run after the animation above is scheduled to ensure that the windows
1162 // drawn signal is scheduled after the bounds animation start call on the bounds animator
1163 // thread.
1164 ensureActivitiesVisible(null, 0, false /* preserveWindows */);
1165 resumeFocusedStacksTopActivities();
1166
1167 mService.getTaskChangeNotificationController().notifyActivityPinned(r);
1168 }
1169
1170 void executeAppTransitionForAllDisplay() {
1171 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1172 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001173 display.mDisplayContent.executeAppTransition();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001174 }
1175 }
1176
1177 void setDockedStackMinimized(boolean minimized) {
1178 // Get currently focused stack before setting mIsDockMinimized. We do this because if
1179 // split-screen is active, primary stack will not be focusable (see #isFocusable) while
1180 // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
1181 final ActivityStack current = getTopDisplayFocusedStack();
1182 mIsDockMinimized = minimized;
1183 if (mIsDockMinimized) {
1184 if (current.inSplitScreenPrimaryWindowingMode()) {
1185 // The primary split-screen stack can't be focused while it is minimize, so move
1186 // focus to something else.
1187 current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
1188 }
1189 }
1190 }
1191
1192 ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
1193 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
1194 mTmpFindTaskResult.clear();
1195
1196 // Looking up task on preferred display first
1197 final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId);
1198 if (preferredDisplay != null) {
1199 preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult);
1200 if (mTmpFindTaskResult.mIdealMatch) {
1201 return mTmpFindTaskResult.mRecord;
1202 }
1203 }
1204
1205 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1206 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1207 if (display.mDisplayId == preferredDisplayId) {
1208 continue;
1209 }
1210
1211 display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult);
1212 if (mTmpFindTaskResult.mIdealMatch) {
1213 return mTmpFindTaskResult.mRecord;
1214 }
1215 }
1216
1217 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
1218 return mTmpFindTaskResult.mRecord;
1219 }
1220
1221 /**
1222 * Finish the topmost activities in all stacks that belong to the crashed app.
1223 * @param app The app that crashed.
1224 * @param reason Reason to perform this action.
1225 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
1226 */
1227 int finishTopCrashedActivities(WindowProcessController app, String reason) {
Louis Changcdec0802019-11-11 11:45:07 +08001228 Task finishedTask = null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001229 ActivityStack focusedStack = getTopDisplayFocusedStack();
1230 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1231 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1232 // It is possible that request to finish activity might also remove its task and stack,
1233 // so we need to be careful with indexes in the loop and check child count every time.
Louis Chang2453d062019-11-19 22:30:48 +08001234 for (int stackNdx = 0; stackNdx < display.getStackCount(); ++stackNdx) {
1235 final ActivityStack stack = display.getStackAt(stackNdx);
Louis Changcdec0802019-11-11 11:45:07 +08001236 final Task t = stack.finishTopCrashedActivityLocked(app, reason);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001237 if (stack == focusedStack || finishedTask == null) {
1238 finishedTask = t;
1239 }
1240 }
1241 }
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001242 return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001243 }
1244
1245 boolean resumeFocusedStacksTopActivities() {
1246 return resumeFocusedStacksTopActivities(null, null, null);
1247 }
1248
1249 boolean resumeFocusedStacksTopActivities(
1250 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1251
1252 if (!mStackSupervisor.readyToResume()) {
1253 return false;
1254 }
1255
Andrii Kulian6b321512019-01-23 06:37:00 +00001256 boolean result = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001257 if (targetStack != null && (targetStack.isTopStackOnDisplay()
1258 || getTopDisplayFocusedStack() == targetStack)) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001259 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001260 }
1261
Wale Ogunwaled32da472018-11-16 07:19:28 -08001262 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001263 boolean resumedOnDisplay = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001264 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001265 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1266 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001267 final ActivityRecord topRunningActivity = stack.topRunningActivity();
Andrii Kulian6b321512019-01-23 06:37:00 +00001268 if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
1269 continue;
1270 }
Louis Changc50a9362019-02-12 12:35:24 +08001271 if (stack == targetStack) {
1272 // Simply update the result for targetStack because the targetStack had
1273 // already resumed in above. We don't want to resume it again, especially in
1274 // some cases, it would cause a second launch failure if app process was dead.
1275 resumedOnDisplay |= result;
1276 continue;
1277 }
Jorim Jaggia5cf6802019-04-26 19:43:11 +02001278 if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
1279 // Kick off any lingering app transitions form the MoveTaskToFront operation,
1280 // but only consider the top task and stack on that display.
Andrii Kulian6b321512019-01-23 06:37:00 +00001281 stack.executeAppTransition(targetOptions);
1282 } else {
1283 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
1284 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001285 }
Andrii Kulian6b321512019-01-23 06:37:00 +00001286 if (!resumedOnDisplay) {
1287 // In cases when there are no valid activities (e.g. device just booted or launcher
1288 // crashed) it's possible that nothing was resumed on a display. Requesting resume
1289 // of top activity in focused stack explicitly will make sure that at least home
1290 // activity is started and resumed, and no recursion occurs.
1291 final ActivityStack focusedStack = display.getFocusedStack();
1292 if (focusedStack != null) {
wilsonshih4c9824a2019-10-25 18:47:50 +08001293 result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Riddle Hsua0175ab2019-11-12 23:52:32 +08001294 } else if (targetStack == null && !display.hasChild()) {
1295 result |= resumeHomeActivity(null /* prev */, "empty-display",
1296 display.mDisplayId);
Andrii Kulian6b321512019-01-23 06:37:00 +00001297 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001298 }
1299 }
1300
Andrii Kulian6b321512019-01-23 06:37:00 +00001301 return result;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001302 }
1303
1304 void applySleepTokens(boolean applyToStacks) {
1305 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1306 // Set the sleeping state of the display.
1307 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1308 final boolean displayShouldSleep = display.shouldSleep();
1309 if (displayShouldSleep == display.isSleeping()) {
1310 continue;
1311 }
1312 display.setIsSleeping(displayShouldSleep);
1313
1314 if (!applyToStacks) {
1315 continue;
1316 }
1317
1318 // Set the sleeping state of the stacks on the display.
Louis Chang2453d062019-11-19 22:30:48 +08001319 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1320 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001321 if (displayShouldSleep) {
1322 stack.goToSleepIfPossible(false /* shuttingDown */);
1323 } else {
Issei Suzukicac2a502019-04-16 16:52:50 +02001324 // When the display which can only contain one task turns on, start a special
1325 // transition. {@link AppTransitionController#handleAppTransitionReady} later
1326 // picks up the transition, and schedules
1327 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
1328 // triggered after contents are drawn on the display.
1329 if (display.isSingleTaskInstance()) {
1330 display.mDisplayContent.prepareAppTransition(
1331 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
1332 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001333 stack.awakeFromSleepingLocked();
1334 if (stack.isFocusedStackOnDisplay()
1335 && !mStackSupervisor.getKeyguardController()
1336 .isKeyguardOrAodShowing(display.mDisplayId)) {
1337 // If the keyguard is unlocked - resume immediately.
1338 // It is possible that the display will not be awake at the time we
1339 // process the keyguard going away, which can happen before the sleep token
1340 // is released. As a result, it is important we resume the activity here.
1341 resumeFocusedStacksTopActivities();
1342 }
1343 }
1344 }
1345
1346 if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) {
1347 continue;
1348 }
1349 // The display is awake now, so clean up the going to sleep list.
1350 for (Iterator<ActivityRecord> it =
1351 mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) {
1352 final ActivityRecord r = it.next();
1353 if (r.getDisplayId() == display.mDisplayId) {
1354 it.remove();
1355 }
1356 }
1357 }
1358 }
1359
Louis Chang2453d062019-11-19 22:30:48 +08001360 protected ActivityStack getStack(int stackId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001361 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
Louis Chang2453d062019-11-19 22:30:48 +08001362 final ActivityStack stack = mActivityDisplays.get(i).getStack(stackId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001363 if (stack != null) {
1364 return stack;
1365 }
1366 }
1367 return null;
1368 }
1369
1370 /** @see ActivityDisplay#getStack(int, int) */
Louis Chang2453d062019-11-19 22:30:48 +08001371 ActivityStack getStack(int windowingMode, int activityType) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001372 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
Louis Chang2453d062019-11-19 22:30:48 +08001373 final ActivityStack stack =
1374 mActivityDisplays.get(i).getStack(windowingMode, activityType);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001375 if (stack != null) {
1376 return stack;
1377 }
1378 }
1379 return null;
1380 }
1381
Louis Chang2453d062019-11-19 22:30:48 +08001382 private ActivityStack getStack(int windowingMode, int activityType,
Evan Roskyfd439692019-11-06 16:12:59 -08001383 int displayId) {
1384 ActivityDisplay display = getActivityDisplay(displayId);
1385 if (display == null) {
1386 return null;
1387 }
1388 return display.getStack(windowingMode, activityType);
1389 }
1390
Wale Ogunwaled32da472018-11-16 07:19:28 -08001391 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
1392 final int displayId = stack.mDisplayId;
1393 final ActivityDisplay display = getActivityDisplay(displayId);
1394 ActivityManager.StackInfo info = new ActivityManager.StackInfo();
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001395 stack.getBounds(info.bounds);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001396 info.displayId = displayId;
1397 info.stackId = stack.mStackId;
Evan Rosky282ee672019-11-13 15:50:46 -08001398 info.stackToken = stack.mRemoteToken;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001399 info.userId = stack.mCurrentUser;
1400 info.visible = stack.shouldBeVisible(null);
1401 // A stack might be not attached to a display.
1402 info.position = display != null ? display.getIndexOf(stack) : 0;
1403 info.configuration.setTo(stack.getConfiguration());
1404
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001405 final int numTasks = stack.getChildCount();
1406 info.taskIds = new int[numTasks];
1407 info.taskNames = new String[numTasks];
1408 info.taskBounds = new Rect[numTasks];
1409 info.taskUserIds = new int[numTasks];
1410 final int[] currenIndex = {0};
Wale Ogunwaled32da472018-11-16 07:19:28 -08001411
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001412 final PooledConsumer c = PooledLambda.obtainConsumer(
1413 RootActivityContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
1414 currenIndex);
1415 stack.forAllTasks(c, false);
1416 c.recycle();
1417
1418 final ActivityRecord top = stack.topRunningActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001419 info.topActivity = top != null ? top.intent.getComponent() : null;
1420 return info;
1421 }
1422
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001423 private static void processTaskForStackInfo(
1424 Task task, ActivityManager.StackInfo info, int[] currentIndex) {
1425 int i = currentIndex[0];
1426 info.taskIds[i] = task.mTaskId;
1427 info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
1428 : task.realActivity != null ? task.realActivity.flattenToString()
1429 : task.getTopNonFinishingActivity() != null
1430 ? task.getTopNonFinishingActivity().packageName : "unknown";
1431 info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
1432 info.taskUserIds[i] = task.mUserId;
1433 currentIndex[0] = ++i;
1434 }
1435
Wale Ogunwaled32da472018-11-16 07:19:28 -08001436 ActivityManager.StackInfo getStackInfo(int stackId) {
1437 ActivityStack stack = getStack(stackId);
1438 if (stack != null) {
1439 return getStackInfo(stack);
1440 }
1441 return null;
1442 }
1443
1444 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
1445 final ActivityStack stack = getStack(windowingMode, activityType);
1446 return (stack != null) ? getStackInfo(stack) : null;
1447 }
1448
Evan Roskyfd439692019-11-06 16:12:59 -08001449 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) {
1450 final ActivityStack stack = getStack(windowingMode, activityType, displayId);
1451 return (stack != null) ? getStackInfo(stack) : null;
1452 }
1453
1454 /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */
1455 ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001456 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
Evan Roskyfd439692019-11-06 16:12:59 -08001457 if (displayId == INVALID_DISPLAY) {
1458 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
1459 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001460 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1461 final ActivityStack stack = display.getStackAt(stackNdx);
Evan Roskyfd439692019-11-06 16:12:59 -08001462 list.add(getStackInfo(stack));
1463 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001464 }
Evan Roskyfd439692019-11-06 16:12:59 -08001465 return list;
1466 }
1467 final ActivityDisplay display = getActivityDisplay(displayId);
1468 if (display == null) {
1469 return list;
1470 }
Louis Chang2453d062019-11-19 22:30:48 +08001471 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1472 final ActivityStack stack = display.getStackAt(stackNdx);
Evan Roskyfd439692019-11-06 16:12:59 -08001473 list.add(getStackInfo(stack));
Wale Ogunwaled32da472018-11-16 07:19:28 -08001474 }
1475 return list;
1476 }
1477
1478 void deferUpdateBounds(int activityType) {
1479 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1480 if (stack != null) {
1481 stack.deferUpdateBounds();
1482 }
1483 }
1484
1485 void continueUpdateBounds(int activityType) {
1486 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1487 if (stack != null) {
1488 stack.continueUpdateBounds();
1489 }
1490 }
1491
1492 @Override
1493 public void onDisplayAdded(int displayId) {
1494 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
1495 synchronized (mService.mGlobalLock) {
Charles Chen3dedec32019-01-24 22:19:37 +08001496 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
Charles Chenb409e6c2019-02-12 12:30:17 +08001497 if (display == null) {
1498 return;
1499 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001500 // Do not start home before booting, or it may accidentally finish booting before it
1501 // starts. Instead, we expect home activities to be launched when the system is ready
1502 // (ActivityManagerService#systemReady).
1503 if (mService.isBooted() || mService.isBooting()) {
Charles Chen3dedec32019-01-24 22:19:37 +08001504 startSystemDecorations(display.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001505 }
1506 }
1507 }
1508
Charles Chen3dedec32019-01-24 22:19:37 +08001509 private void startSystemDecorations(final DisplayContent displayContent) {
1510 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
1511 displayContent.getDisplayPolicy().notifyDisplayReady();
1512 }
1513
Wale Ogunwaled32da472018-11-16 07:19:28 -08001514 @Override
1515 public void onDisplayRemoved(int displayId) {
1516 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
1517 if (displayId == DEFAULT_DISPLAY) {
1518 throw new IllegalArgumentException("Can't remove the primary display.");
1519 }
1520
1521 synchronized (mService.mGlobalLock) {
1522 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1523 if (activityDisplay == null) {
1524 return;
1525 }
1526
1527 activityDisplay.remove();
1528 }
1529 }
1530
1531 @Override
1532 public void onDisplayChanged(int displayId) {
1533 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
1534 synchronized (mService.mGlobalLock) {
1535 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1536 if (activityDisplay != null) {
1537 activityDisplay.onDisplayChanged();
1538 }
1539 }
1540 }
1541
1542 /** Update lists of UIDs that are present on displays and have access to them. */
1543 void updateUIDsPresentOnDisplay() {
1544 mDisplayAccessUIDs.clear();
1545 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1546 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
1547 // Only bother calculating the whitelist for private displays
1548 if (activityDisplay.isPrivate()) {
1549 mDisplayAccessUIDs.append(
1550 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs());
1551 }
1552 }
1553 // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
1554 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
1555 }
1556
1557 ActivityStack findStackBehind(ActivityStack stack) {
1558 final ActivityDisplay display = getActivityDisplay(stack.mDisplayId);
1559 if (display != null) {
Louis Chang2453d062019-11-19 22:30:48 +08001560 for (int i = display.getStackCount() - 1; i >= 0; i--) {
1561 if (display.getStackAt(i) == stack && i > 0) {
1562 return display.getStackAt(i - 1);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001563 }
1564 }
1565 }
1566 throw new IllegalStateException("Failed to find a stack behind stack=" + stack
1567 + " in=" + display);
1568 }
1569
1570 @Override
1571 protected int getChildCount() {
1572 return mActivityDisplays.size();
1573 }
1574
1575 @Override
1576 protected ActivityDisplay getChildAt(int index) {
1577 return mActivityDisplays.get(index);
1578 }
1579
1580 @Override
1581 protected ConfigurationContainer getParent() {
1582 return null;
1583 }
1584
Wale Ogunwale31acb3f2018-11-20 15:23:55 -08001585 // TODO: remove after object merge with RootWindowContainer
Louis Chang2453d062019-11-19 22:30:48 +08001586 void onChildPositionChanged(DisplayContent display, int position) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001587 // Assume AM lock is held from positionChildAt of controller in each hierarchy.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001588 if (display != null) {
1589 positionChildAt(display, position);
1590 }
1591 }
1592
1593 /** Change the z-order of the given display. */
Louis Chang2453d062019-11-19 22:30:48 +08001594 private void positionChildAt(DisplayContent display, int position) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001595 if (position >= mActivityDisplays.size()) {
1596 position = mActivityDisplays.size() - 1;
1597 } else if (position < 0) {
1598 position = 0;
1599 }
1600
Louis Chang2453d062019-11-19 22:30:48 +08001601 // TODO(display-merge): Remove cast
1602 final ActivityDisplay activityDisplay = (ActivityDisplay) display;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001603 if (mActivityDisplays.isEmpty()) {
Louis Chang2453d062019-11-19 22:30:48 +08001604 mActivityDisplays.add(activityDisplay);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001605 } else if (mActivityDisplays.get(position) != display) {
1606 mActivityDisplays.remove(display);
Louis Chang2453d062019-11-19 22:30:48 +08001607 mActivityDisplays.add(position, activityDisplay);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001608 }
Andrii Kulian86e70fc2019-02-12 11:04:10 +00001609 mStackSupervisor.updateTopResumedActivityIfNeeded();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001610 }
1611
1612 @VisibleForTesting
1613 void addChild(ActivityDisplay activityDisplay, int position) {
1614 positionChildAt(activityDisplay, position);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001615 mRootWindowContainer.positionChildAt(position, activityDisplay.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001616 }
1617
1618 void removeChild(ActivityDisplay activityDisplay) {
1619 // The caller must tell the controller of {@link ActivityDisplay} to release its container
1620 // {@link DisplayContent}. That is done in {@link ActivityDisplay#releaseSelfIfNeeded}).
1621 mActivityDisplays.remove(activityDisplay);
1622 }
1623
1624 Configuration getDisplayOverrideConfiguration(int displayId) {
1625 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1626 if (activityDisplay == null) {
1627 throw new IllegalArgumentException("No display found with id: " + displayId);
1628 }
1629
Evan Roskydfe3da72018-10-26 17:21:06 -07001630 return activityDisplay.getRequestedOverrideConfiguration();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001631 }
1632
1633 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
1634 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1635 if (activityDisplay == null) {
1636 throw new IllegalArgumentException("No display found with id: " + displayId);
1637 }
1638
Evan Roskydfe3da72018-10-26 17:21:06 -07001639 activityDisplay.onRequestedOverrideConfigurationChanged(overrideConfiguration);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001640 }
1641
1642 void prepareForShutdown() {
1643 for (int i = 0; i < mActivityDisplays.size(); i++) {
1644 createSleepToken("shutdown", mActivityDisplays.get(i).mDisplayId);
1645 }
1646 }
1647
1648 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
1649 final ActivityDisplay display = getActivityDisplay(displayId);
1650 if (display == null) {
1651 throw new IllegalArgumentException("Invalid display: " + displayId);
1652 }
1653
1654 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
1655 mSleepTokens.add(token);
1656 display.mAllSleepTokens.add(token);
1657 return token;
1658 }
1659
1660 private void removeSleepToken(SleepTokenImpl token) {
1661 mSleepTokens.remove(token);
1662
1663 final ActivityDisplay display = getActivityDisplay(token.mDisplayId);
1664 if (display != null) {
1665 display.mAllSleepTokens.remove(token);
1666 if (display.mAllSleepTokens.isEmpty()) {
1667 mService.updateSleepIfNeededLocked();
1668 }
1669 }
1670 }
1671
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001672 void addStartingWindowsForVisibleActivities() {
1673 mRootWindowContainer.forAllActivities((r) -> {
1674 if (r.mVisibleRequested) {
1675 r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001676 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001677 });
Wale Ogunwaled32da472018-11-16 07:19:28 -08001678 }
1679
1680 void invalidateTaskLayers() {
1681 mTaskLayersChanged = true;
1682 }
1683
1684 void rankTaskLayersIfNeeded() {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001685 if (!mTaskLayersChanged || mRootWindowContainer == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001686 return;
1687 }
1688 mTaskLayersChanged = false;
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001689 mTmpTaskLayerRank = 0;
1690 final PooledConsumer c = PooledLambda.obtainConsumer(
1691 RootActivityContainer::rankTaskLayerForActivity, this,
1692 PooledLambda.__(ActivityRecord.class));
1693 mRootWindowContainer.forAllActivities(c);
1694 c.recycle();
1695 }
1696
1697 private void rankTaskLayerForActivity(ActivityRecord r) {
1698 if (r.canBeTopRunning() && r.mVisibleRequested) {
1699 r.getTask().mLayerRank = ++mTmpTaskLayerRank;
1700 } else {
1701 r.getTask().mLayerRank = -1;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001702 }
1703 }
1704
1705 void clearOtherAppTimeTrackers(AppTimeTracker except) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001706 final PooledConsumer c = PooledLambda.obtainConsumer(
1707 RootActivityContainer::clearOtherAppTimeTrackers,
1708 PooledLambda.__(ActivityRecord.class), except);
1709 mRootWindowContainer.forAllActivities(c);
1710 c.recycle();
1711 }
1712
1713 private static void clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except) {
1714 if ( r.appTimeTracker != except) {
1715 r.appTimeTracker = null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001716 }
1717 }
1718
1719 void scheduleDestroyAllActivities(WindowProcessController app, String reason) {
1720 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1721 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001722 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1723 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001724 stack.scheduleDestroyActivities(app, reason);
1725 }
1726 }
1727 }
1728
Wale Ogunwaled32da472018-11-16 07:19:28 -08001729 // Tries to put all activity stacks to sleep. Returns true if all stacks were
1730 // successfully put to sleep.
1731 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
1732 boolean allSleep = true;
1733 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1734 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001735 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
Louis Changc219bc32018-12-06 15:38:41 +08001736 // Stacks and activities could be removed while putting activities to sleep if
1737 // the app process was gone. This prevents us getting exception by accessing an
1738 // invalid stack index.
Louis Chang2453d062019-11-19 22:30:48 +08001739 if (stackNdx >= display.getStackCount()) {
Louis Changc219bc32018-12-06 15:38:41 +08001740 continue;
1741 }
1742
Louis Chang2453d062019-11-19 22:30:48 +08001743 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001744 if (allowDelay) {
1745 allSleep &= stack.goToSleepIfPossible(shuttingDown);
1746 } else {
1747 stack.goToSleep();
1748 }
1749 }
1750 }
1751 return allSleep;
1752 }
1753
1754 void handleAppCrash(WindowProcessController app) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001755 final PooledConsumer c = PooledLambda.obtainConsumer(
1756 RootActivityContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app);
1757 mRootWindowContainer.forAllActivities(c);
1758 c.recycle();
1759 }
1760
1761 private static void handleAppCrash(ActivityRecord r, WindowProcessController app) {
1762 if (r.app != app) return;
1763 Slog.w(TAG, " Force finishing activity "
1764 + r.intent.getComponent().flattenToShortString());
1765 // Force the destroy to skip right to removal.
1766 r.app = null;
1767 r.getDisplay().mDisplayContent.prepareAppTransition(
1768 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
1769 r.destroyIfPossible("handleAppCrashed");
Wale Ogunwaled32da472018-11-16 07:19:28 -08001770 }
1771
1772 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001773 ComponentName cls = intent.getComponent();
1774 if (info.targetActivity != null) {
1775 cls = new ComponentName(info.packageName, info.targetActivity);
1776 }
1777 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
1778
1779 final PooledPredicate p = PooledLambda.obtainPredicate(
1780 RootActivityContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
1781 userId, compareIntentFilters, intent, cls);
1782 final ActivityRecord r = mRootWindowContainer.getActivity(p);
1783 p.recycle();
1784 return r;
1785 }
1786
1787 private static boolean matchesActivity(ActivityRecord r, int userId,
1788 boolean compareIntentFilters, Intent intent, ComponentName cls) {
1789 if (!r.canBeTopRunning() || r.mUserId != userId) return false;
1790
1791 if (compareIntentFilters) {
1792 if (r.intent.filterEquals(intent)) {
1793 return true;
1794 }
1795 } else {
1796 if (r.intent.getComponent().equals(cls)) {
1797 return true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001798 }
1799 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001800 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001801 }
1802
1803 boolean hasAwakeDisplay() {
1804 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1805 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1806 if (!display.shouldSleep()) {
1807 return true;
1808 }
1809 }
1810 return false;
1811 }
1812
Wale Ogunwale8577a052019-10-26 23:22:34 -07001813 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001814 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
lumarkf65e02d2019-09-14 19:25:21 +08001815 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
1816 -1 /* no realCallingPid */, -1 /* no realCallingUid */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001817 }
1818
1819 /**
1820 * Returns the right stack to use for launching factoring in all the input parameters.
1821 *
1822 * @param r The activity we are trying to launch. Can be null.
1823 * @param options The activity options used to the launch. Can be null.
1824 * @param candidateTask The possible task the activity might be launched in. Can be null.
lumarkf65e02d2019-09-14 19:25:21 +08001825 * @param launchParams The resolved launch params to use.
1826 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
1827 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
Wale Ogunwaled32da472018-11-16 07:19:28 -08001828 *
1829 * @return The stack to use for the launch or INVALID_STACK_ID.
1830 */
Wale Ogunwale8577a052019-10-26 23:22:34 -07001831 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001832 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
lumarkf65e02d2019-09-14 19:25:21 +08001833 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
1834 int realCallingUid) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001835 int taskId = INVALID_TASK_ID;
1836 int displayId = INVALID_DISPLAY;
1837 //Rect bounds = null;
1838
1839 // We give preference to the launch preference in activity options.
1840 if (options != null) {
1841 taskId = options.getLaunchTaskId();
1842 displayId = options.getLaunchDisplayId();
1843 }
1844
1845 // First preference for stack goes to the task Id set in the activity options. Use the stack
1846 // associated with that if possible.
1847 if (taskId != INVALID_TASK_ID) {
1848 // Temporarily set the task id to invalid in case in re-entry.
1849 options.setLaunchTaskId(INVALID_TASK_ID);
Louis Changcdec0802019-11-11 11:45:07 +08001850 final Task task = anyTaskForId(taskId,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001851 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
1852 options.setLaunchTaskId(taskId);
1853 if (task != null) {
1854 return task.getStack();
1855 }
1856 }
1857
1858 final int activityType = resolveActivityType(r, options, candidateTask);
Wale Ogunwale8577a052019-10-26 23:22:34 -07001859 ActivityStack stack;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001860
1861 // Next preference for stack goes to the display Id set the candidate display.
1862 if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
1863 displayId = launchParams.mPreferredDisplayId;
1864 }
lumarkf65e02d2019-09-14 19:25:21 +08001865 final boolean canLaunchOnDisplayFromStartRequest =
1866 realCallingPid != 0 && realCallingUid > 0 && r != null
1867 && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid,
1868 realCallingUid, r.info);
1869 // Checking if the activity's launch caller, or the realCallerId of the activity from
1870 // start request (i.e. entity that invokes PendingIntent) is allowed to launch on the
1871 // display.
1872 if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
1873 || canLaunchOnDisplayFromStartRequest)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001874 if (r != null) {
Wale Ogunwale8577a052019-10-26 23:22:34 -07001875 stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001876 launchParams);
1877 if (stack != null) {
1878 return stack;
1879 }
1880 }
1881 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
1882 if (display != null) {
1883 stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1884 if (stack != null) {
1885 return stack;
1886 }
1887 }
1888 }
1889
1890 // Give preference to the stack and display of the input task and activity if they match the
1891 // mode we want to launch into.
1892 stack = null;
1893 ActivityDisplay display = null;
1894 if (candidateTask != null) {
1895 stack = candidateTask.getStack();
1896 }
1897 if (stack == null && r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001898 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001899 }
1900 if (stack != null) {
1901 display = stack.getDisplay();
1902 if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) {
1903 int windowingMode = launchParams != null ? launchParams.mWindowingMode
1904 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
1905 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
1906 windowingMode = display.resolveWindowingMode(r, options, candidateTask,
1907 activityType);
1908 }
1909 if (stack.isCompatible(windowingMode, activityType)) {
1910 return stack;
1911 }
1912 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
1913 && display.getSplitScreenPrimaryStack() == stack
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09001914 && candidateTask == stack.getTopMostTask()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001915 // This is a special case when we try to launch an activity that is currently on
1916 // top of split-screen primary stack, but is targeting split-screen secondary.
1917 // In this case we don't want to move it to another stack.
1918 // TODO(b/78788972): Remove after differentiating between preferred and required
1919 // launch options.
1920 return stack;
1921 }
1922 }
1923 }
1924
1925 if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) {
1926 display = getDefaultDisplay();
1927 }
1928
1929 return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1930 }
1931
1932 /** @return true if activity record is null or can be launched on provided display. */
1933 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
1934 if (r == null) {
1935 return true;
1936 }
1937 return r.canBeLaunchedOnDisplay(displayId);
1938 }
1939
1940 /**
1941 * Get a topmost stack on the display, that is a valid launch stack for specified activity.
1942 * If there is no such stack, new dynamic stack can be created.
1943 * @param displayId Target display.
1944 * @param r Activity that should be launched there.
1945 * @param candidateTask The possible task the activity might be put in.
1946 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
1947 */
1948 private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001949 @Nullable Task candidateTask, @Nullable ActivityOptions options,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001950 @Nullable LaunchParamsController.LaunchParams launchParams) {
1951 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1952 if (activityDisplay == null) {
1953 throw new IllegalArgumentException(
1954 "Display with displayId=" + displayId + " not found.");
1955 }
1956
1957 if (!r.canBeLaunchedOnDisplay(displayId)) {
1958 return null;
1959 }
1960
1961 // If {@code r} is already in target display and its task is the same as the candidate task,
1962 // the intention should be getting a launch stack for the reusable activity, so we can use
1963 // the existing stack.
Louis Changcdec0802019-11-11 11:45:07 +08001964 if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
Louis Changf3070c52019-10-09 15:57:30 +08001965 final int attachedDisplayId = r.getDisplayId();
1966 if (attachedDisplayId == INVALID_DISPLAY || attachedDisplayId == displayId) {
1967 return candidateTask.getStack();
1968 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001969 }
1970
Louis Chang6fb1e842018-12-03 16:07:50 +08001971 int windowingMode;
1972 if (launchParams != null) {
1973 // When launch params is not null, we always defer to its windowing mode. Sometimes
1974 // it could be unspecified, which indicates it should inherit windowing mode from
1975 // display.
1976 windowingMode = launchParams.mWindowingMode;
1977 } else {
1978 windowingMode = options != null ? options.getLaunchWindowingMode()
1979 : r.getWindowingMode();
1980 }
1981 windowingMode = activityDisplay.validateWindowingMode(windowingMode, r, candidateTask,
1982 r.getActivityType());
1983
Wale Ogunwaled32da472018-11-16 07:19:28 -08001984 // Return the topmost valid stack on the display.
Louis Chang2453d062019-11-19 22:30:48 +08001985 for (int i = activityDisplay.getStackCount() - 1; i >= 0; --i) {
1986 final ActivityStack stack = activityDisplay.getStackAt(i);
Louis Chang6fb1e842018-12-03 16:07:50 +08001987 if (isValidLaunchStack(stack, r, windowingMode)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001988 return stack;
1989 }
1990 }
1991
1992 // If there is no valid stack on the external display - check if new dynamic stack will do.
1993 if (displayId != DEFAULT_DISPLAY) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001994 final int activityType =
1995 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
1996 ? options.getLaunchActivityType() : r.getActivityType();
1997 return activityDisplay.createStack(windowingMode, activityType, true /*onTop*/);
1998 }
1999
Wale Ogunwaled32da472018-11-16 07:19:28 -08002000 return null;
2001 }
2002
2003 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
2004 @Nullable ActivityOptions options,
2005 @Nullable LaunchParamsController.LaunchParams launchParams) {
2006 return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options,
2007 launchParams);
2008 }
2009
2010 // TODO: Can probably be consolidated into getLaunchStack()...
Louis Chang6fb1e842018-12-03 16:07:50 +08002011 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002012 switch (stack.getActivityType()) {
2013 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
2014 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
2015 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
2016 }
2017 // There is a 1-to-1 relationship between stack and task when not in
2018 // primary split-windowing mode.
Louis Chang6fb1e842018-12-03 16:07:50 +08002019 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
2020 && r.supportsSplitScreenWindowingMode()
2021 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
2022 || windowingMode == WINDOWING_MODE_UNDEFINED)) {
2023 return true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002024 }
Louis Chang6fb1e842018-12-03 16:07:50 +08002025 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002026 }
2027
2028 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
Louis Changcdec0802019-11-11 11:45:07 +08002029 @Nullable Task task) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002030 // Preference is given to the activity type for the activity then the task since the type
2031 // once set shouldn't change.
2032 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
2033 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
2034 activityType = task.getActivityType();
2035 }
2036 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
2037 return activityType;
2038 }
2039 if (options != null) {
2040 activityType = options.getLaunchActivityType();
2041 }
2042 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
2043 }
2044
2045 /**
2046 * Get next focusable stack in the system. This will search through the stack on the same
2047 * display as the current focused stack, looking for a focusable and visible stack, different
2048 * from the target stack. If no valid candidates will be found, it will then go through all
2049 * displays and stacks in last-focused order.
2050 *
2051 * @param currentFocus The stack that previously had focus.
2052 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
2053 * candidate.
2054 * @return Next focusable {@link ActivityStack}, {@code null} if not found.
2055 */
2056 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
2057 boolean ignoreCurrent) {
2058 // First look for next focusable stack on the same display
Wale Ogunwale2322bed2019-10-10 17:24:19 +02002059 ActivityDisplay preferredDisplay = currentFocus.getDisplay();
2060 if (preferredDisplay == null) {
2061 // Stack is currently detached because it is being removed. Use the previous display it
2062 // was on.
2063 preferredDisplay = getActivityDisplay(currentFocus.mPrevDisplayId);
2064 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08002065 final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
2066 currentFocus, ignoreCurrent);
2067 if (preferredFocusableStack != null) {
2068 return preferredFocusableStack;
2069 }
2070 if (preferredDisplay.supportsSystemDecorations()) {
2071 // Stop looking for focusable stack on other displays because the preferred display
2072 // supports system decorations. Home activity would be launched on the same display if
2073 // no focusable stack found.
2074 return null;
2075 }
2076
2077 // Now look through all displays
2078 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2079 final ActivityDisplay display = mActivityDisplays.get(i);
2080 if (display == preferredDisplay) {
2081 // We've already checked this one
2082 continue;
2083 }
2084 final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
2085 ignoreCurrent);
2086 if (nextFocusableStack != null) {
2087 return nextFocusableStack;
2088 }
2089 }
2090
2091 return null;
2092 }
2093
2094 /**
2095 * Get next valid stack for launching provided activity in the system. This will search across
2096 * displays and stacks in last-focused order for a focusable and visible stack, except those
2097 * that are on a currently focused display.
2098 *
2099 * @param r The activity that is being launched.
2100 * @param currentFocus The display that previously had focus and thus needs to be ignored when
2101 * searching for the next candidate.
2102 * @return Next valid {@link ActivityStack}, null if not found.
2103 */
2104 ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) {
2105 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2106 final ActivityDisplay display = mActivityDisplays.get(i);
2107 if (display.mDisplayId == currentFocus) {
2108 continue;
2109 }
2110 final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r,
2111 null /* options */, null /* launchParams */);
2112 if (stack != null) {
2113 return stack;
2114 }
2115 }
2116 return null;
2117 }
2118
2119 boolean handleAppDied(WindowProcessController app) {
2120 boolean hasVisibleActivities = false;
2121 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2122 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002123 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2124 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002125 hasVisibleActivities |= stack.handleAppDiedLocked(app);
2126 }
2127 }
2128 return hasVisibleActivities;
2129 }
2130
2131 void closeSystemDialogs() {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002132 mRootWindowContainer.forAllActivities((r) -> {
2133 if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
2134 r.finishIfPossible("close-sys", true /* oomAdj */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002135 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002136 });
2137 }
2138
2139 FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
2140 new FinishDisabledPackageActivitiesHelper();
2141 class FinishDisabledPackageActivitiesHelper {
2142 private boolean mDidSomething;
2143 private String mPackageName;
2144 private Set<String> mFilterByClasses;
2145 private boolean mDoit;
2146 private boolean mEvenPersistent;
2147 private int mUserId;
2148 private Task mLastTask;
2149 private ComponentName mHomeActivity;
2150
2151 private void reset(String packageName, Set<String> filterByClasses,
2152 boolean doit, boolean evenPersistent, int userId) {
2153 mDidSomething = false;
2154 mPackageName = packageName;
2155 mFilterByClasses = filterByClasses;
2156 mDoit = doit;
2157 mEvenPersistent = evenPersistent;
2158 mUserId = userId;
2159 mLastTask = null;
2160 mHomeActivity = null;
2161 }
2162
2163 boolean process(String packageName, Set<String> filterByClasses,
2164 boolean doit, boolean evenPersistent, int userId) {
2165 reset(packageName, filterByClasses, doit, evenPersistent, userId);
2166
2167 final PooledFunction f = PooledLambda.obtainFunction(
2168 FinishDisabledPackageActivitiesHelper::processActivity, this,
2169 PooledLambda.__(ActivityRecord.class));
2170 mRootWindowContainer.forAllActivities(f);
2171 f.recycle();
2172 return mDidSomething;
2173 }
2174
2175 private boolean processActivity(ActivityRecord r) {
2176 final boolean sameComponent =
2177 (r.packageName.equals(mPackageName) && (mFilterByClasses == null
2178 || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
2179 || (mPackageName == null && r.mUserId == mUserId);
2180 if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
2181 && (sameComponent || r.getTask() == mLastTask)
2182 && (r.app == null || mEvenPersistent || !r.app.isPersistent())) {
2183 if (!mDoit) {
2184 if (r.finishing) {
2185 // If this activity is just finishing, then it is not
2186 // interesting as far as something to stop.
2187 return false;
2188 }
2189 return true;
2190 }
2191 if (r.isActivityTypeHome()) {
2192 if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) {
2193 Slog.i(TAG, "Skip force-stop again " + r);
2194 return false;
2195 } else {
2196 mHomeActivity = r.mActivityComponent;
2197 }
2198 }
2199 mDidSomething = true;
2200 Slog.i(TAG, " Force finishing activity " + r);
2201 mLastTask = r.getTask();
2202 r.finishIfPossible("force-stop", true);
2203 }
2204
2205 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002206 }
2207 }
2208
2209 /** @return true if some activity was finished (or would have finished if doit were true). */
2210 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
2211 boolean doit, boolean evenPersistent, int userId) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002212 return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
2213 evenPersistent, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002214 }
2215
2216 void updateActivityApplicationInfo(ApplicationInfo aInfo) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002217 final String packageName = aInfo.packageName;
2218 final int userId = UserHandle.getUserId(aInfo.uid);
2219 final PooledConsumer c = PooledLambda.obtainConsumer(
2220 RootActivityContainer::updateActivityApplicationInfo,
2221 PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName);
2222 mRootWindowContainer.forAllActivities(c);
2223 c.recycle();
2224 }
2225
2226 private static void updateActivityApplicationInfo(
2227 ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName) {
2228 if (r.mUserId == userId && packageName.equals(r.packageName)) {
2229 r.updateApplicationInfo(aInfo);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002230 }
2231 }
2232
2233 void finishVoiceTask(IVoiceInteractionSession session) {
2234 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2235 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002236 final int numStacks = display.getStackCount();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002237 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Louis Chang2453d062019-11-19 22:30:48 +08002238 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002239 stack.finishVoiceTask(session);
2240 }
2241 }
2242 }
2243
2244 /**
2245 * Removes stacks in the input windowing modes from the system if they are of activity type
2246 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2247 */
2248 void removeStacksInWindowingModes(int... windowingModes) {
2249 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2250 mActivityDisplays.get(i).removeStacksInWindowingModes(windowingModes);
2251 }
2252 }
2253
2254 void removeStacksWithActivityTypes(int... activityTypes) {
2255 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2256 mActivityDisplays.get(i).removeStacksWithActivityTypes(activityTypes);
2257 }
2258 }
2259
2260 ActivityRecord topRunningActivity() {
2261 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2262 final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
2263 if (topActivity != null) {
2264 return topActivity;
2265 }
2266 }
2267 return null;
2268 }
2269
2270 boolean allResumedActivitiesIdle() {
2271 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2272 // TODO(b/117135575): Check resumed activities on all visible stacks.
2273 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2274 if (display.isSleeping()) {
2275 // No resumed activities while display is sleeping.
2276 continue;
2277 }
2278
2279 // If the focused stack is not null or not empty, there should have some activities
2280 // resuming or resumed. Make sure these activities are idle.
2281 final ActivityStack stack = display.getFocusedStack();
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002282 if (stack == null || !stack.hasActivity()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002283 continue;
2284 }
2285 final ActivityRecord resumedActivity = stack.getResumedActivity();
2286 if (resumedActivity == null || !resumedActivity.idle) {
2287 if (DEBUG_STATES) {
2288 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
2289 + stack.mStackId + " " + resumedActivity + " not idle");
2290 }
2291 return false;
2292 }
2293 }
2294 // Send launch end powerhint when idle
2295 sendPowerHintForLaunchEndIfNeeded();
2296 return true;
2297 }
2298
2299 boolean allResumedActivitiesVisible() {
2300 boolean foundResumed = false;
2301 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2302 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002303 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2304 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002305 final ActivityRecord r = stack.getResumedActivity();
2306 if (r != null) {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002307 if (!r.nowVisible) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002308 return false;
2309 }
2310 foundResumed = true;
2311 }
2312 }
2313 }
2314 return foundResumed;
2315 }
2316
2317 boolean allPausedActivitiesComplete() {
2318 boolean pausing = true;
2319 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2320 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002321 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2322 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002323 final ActivityRecord r = stack.mPausingActivity;
2324 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
2325 if (DEBUG_STATES) {
2326 Slog.d(TAG_STATES,
2327 "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
2328 pausing = false;
2329 } else {
2330 return false;
2331 }
2332 }
2333 }
2334 }
2335 return pausing;
2336 }
2337
2338 /**
2339 * Find all visible task stacks containing {@param userId} and intercept them with an activity
2340 * to block out the contents and possibly start a credential-confirming intent.
2341 *
2342 * @param userId user handle for the locked managed profile.
2343 */
2344 void lockAllProfileTasks(@UserIdInt int userId) {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002345 mService.deferWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002346 try {
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002347 final PooledConsumer c = PooledLambda.obtainConsumer(
2348 RootActivityContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class),
2349 userId);
2350 mRootWindowContainer.forAllTasks(c);
2351 c.recycle();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002352 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002353 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002354 }
2355 }
2356
2357 /**
2358 * Detects whether we should show a lock screen in front of this task for a locked user.
2359 * <p>
2360 * We'll do this if either of the following holds:
2361 * <ul>
2362 * <li>The top activity explicitly belongs to {@param userId}.</li>
2363 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
2364 * </ul>
2365 *
2366 * @return {@code true} if the top activity looks like it belongs to {@param userId}.
2367 */
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002368 private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002369 // To handle the case that work app is in the task but just is not the top one.
Wale Ogunwale21e06482019-11-18 05:14:15 -08002370 final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002371 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
2372
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002373 // Check the task for a top activity belonging to userId, or returning a
2374 // result to an activity belonging to userId. Example case: a document
2375 // picker for personal files, opened by a work app, should still get locked.
2376 if ((activityRecord != null && activityRecord.mUserId == userId)
2377 || (resultTo != null && resultTo.mUserId == userId)) {
2378 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
2379 task.mTaskId, userId);
2380 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08002381 }
2382
2383 void cancelInitializingActivities() {
2384 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2385 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002386 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2387 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002388 stack.cancelInitializingActivities();
2389 }
2390 }
2391 }
2392
Louis Changcdec0802019-11-11 11:45:07 +08002393 Task anyTaskForId(int id) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002394 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
2395 }
2396
Louis Changcdec0802019-11-11 11:45:07 +08002397 Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002398 return anyTaskForId(id, matchMode, null, !ON_TOP);
2399 }
2400
2401 /**
Louis Changcdec0802019-11-11 11:45:07 +08002402 * Returns a {@link Task} for the input id if available. {@code null} otherwise.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002403 * @param id Id of the task we would like returned.
2404 * @param matchMode The mode to match the given task id in.
2405 * @param aOptions The activity options to use for restoration. Can be null.
2406 * @param onTop If the stack for the task should be the topmost on the display.
2407 */
Louis Changcdec0802019-11-11 11:45:07 +08002408 Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode,
Wale Ogunwaled32da472018-11-16 07:19:28 -08002409 @Nullable ActivityOptions aOptions, boolean onTop) {
2410 // If options are set, ensure that we are attempting to actually restore a task
2411 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
2412 throw new IllegalArgumentException("Should not specify activity options for non-restore"
2413 + " lookup");
2414 }
2415
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002416 final PooledPredicate p = PooledLambda.obtainPredicate(
2417 Task::isTaskId, PooledLambda.__(Task.class), id);
2418 Task task = mRootWindowContainer.getTask(p);
2419 p.recycle();
2420
2421 if (task != null) {
2422 if (aOptions != null) {
2423 // Resolve the stack the task should be placed in now based on options
2424 // and reparent if needed.
2425 final ActivityStack launchStack =
2426 getLaunchStack(null, aOptions, task, onTop);
2427 if (launchStack != null && task.getStack() != launchStack) {
2428 final int reparentMode = onTop
2429 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
2430 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
2431 "anyTaskForId");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002432 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08002433 }
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002434 return task;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002435 }
2436
2437 // If we are matching stack tasks only, return now
2438 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
2439 return null;
2440 }
2441
2442 // Otherwise, check the recent tasks and return if we find it there and we are not restoring
2443 // the task from recents
2444 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002445 task = mStackSupervisor.mRecentTasks.getTask(id);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002446
2447 if (task == null) {
2448 if (DEBUG_RECENTS) {
2449 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
2450 }
2451
2452 return null;
2453 }
2454
2455 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
2456 return task;
2457 }
2458
2459 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
2460 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
2461 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
2462 "Couldn't restore task id=" + id + " found in recents");
2463 return null;
2464 }
2465 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
2466 return task;
2467 }
2468
2469 ActivityRecord isInAnyStack(IBinder token) {
2470 int numDisplays = mActivityDisplays.size();
2471 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2472 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002473 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2474 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002475 final ActivityRecord r = stack.isInStackLocked(token);
2476 if (r != null) {
2477 return r;
2478 }
2479 }
2480 }
2481 return null;
2482 }
2483
2484 @VisibleForTesting
2485 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
2486 @WindowConfiguration.ActivityType int ignoreActivityType,
2487 @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -07002488 boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -07002489 mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002490 ignoreWindowingMode, this, callingUid, allowed, crossUser, profileIds);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002491 }
2492
2493 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
2494 boolean sendHint = forceSend;
2495
2496 if (!sendHint) {
2497 // Send power hint if we don't know what we're launching yet
2498 sendHint = targetActivity == null || targetActivity.app == null;
2499 }
2500
2501 if (!sendHint) { // targetActivity != null
2502 // Send power hint when the activity's process is different than the current resumed
2503 // activity on all displays, or if there are no resumed activities in the system.
2504 boolean noResumedActivities = true;
2505 boolean allFocusedProcessesDiffer = true;
2506 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2507 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2508 final ActivityRecord resumedActivity = activityDisplay.getResumedActivity();
2509 final WindowProcessController resumedActivityProcess =
2510 resumedActivity == null ? null : resumedActivity.app;
2511
2512 noResumedActivities &= resumedActivityProcess == null;
2513 if (resumedActivityProcess != null) {
2514 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
2515 }
2516 }
2517 sendHint = noResumedActivities || allFocusedProcessesDiffer;
2518 }
2519
2520 if (sendHint && mService.mPowerManagerInternal != null) {
2521 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
2522 mPowerHintSent = true;
2523 }
2524 }
2525
2526 void sendPowerHintForLaunchEndIfNeeded() {
2527 // Trigger launch power hint if activity is launched
2528 if (mPowerHintSent && mService.mPowerManagerInternal != null) {
2529 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
2530 mPowerHintSent = false;
2531 }
2532 }
2533
2534 private void calculateDefaultMinimalSizeOfResizeableTasks() {
2535 final Resources res = mService.mContext.getResources();
2536 final float minimalSize = res.getDimension(
2537 com.android.internal.R.dimen.default_minimal_size_resizable_task);
2538 final DisplayMetrics dm = res.getDisplayMetrics();
2539
2540 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
2541 }
2542
2543 /**
2544 * Dumps the activities matching the given {@param name} in the either the focused stack
2545 * or all visible stacks if {@param dumpVisibleStacks} is true.
2546 */
2547 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
2548 boolean dumpFocusedStackOnly) {
2549 if (dumpFocusedStackOnly) {
2550 return getTopDisplayFocusedStack().getDumpActivitiesLocked(name);
2551 } else {
2552 ArrayList<ActivityRecord> activities = new ArrayList<>();
2553 int numDisplays = mActivityDisplays.size();
2554 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2555 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002556 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2557 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002558 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
2559 activities.addAll(stack.getDumpActivitiesLocked(name));
2560 }
2561 }
2562 }
2563 return activities;
2564 }
2565 }
2566
2567 public void dump(PrintWriter pw, String prefix) {
2568 pw.print(prefix);
2569 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
2570 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2571 final ActivityDisplay display = mActivityDisplays.get(i);
2572 display.dump(pw, prefix);
2573 }
2574 }
2575
2576 /**
2577 * Dump all connected displays' configurations.
2578 * @param prefix Prefix to apply to each line of the dump.
2579 */
2580 void dumpDisplayConfigs(PrintWriter pw, String prefix) {
2581 pw.print(prefix); pw.println("Display override configurations:");
2582 final int displayCount = mActivityDisplays.size();
2583 for (int i = 0; i < displayCount; i++) {
2584 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
2585 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": ");
Evan Roskydfe3da72018-10-26 17:21:06 -07002586 pw.println(activityDisplay.getRequestedOverrideConfiguration());
Wale Ogunwaled32da472018-11-16 07:19:28 -08002587 }
2588 }
2589
2590 public void dumpDisplays(PrintWriter pw) {
2591 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2592 final ActivityDisplay display = mActivityDisplays.get(i);
2593 pw.print("[id:" + display.mDisplayId + " stacks:");
2594 display.dumpStacks(pw);
2595 pw.print("]");
2596 }
2597 }
2598
2599 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
2600 String dumpPackage) {
2601 boolean printed = false;
2602 boolean needSep = false;
2603 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2604 ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2605 pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
2606 pw.println(" (activities from top to bottom):");
2607 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002608 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2609 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002610 pw.println();
Garfield Tan347bd602018-12-21 15:11:12 -08002611 printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002612 needSep = printed;
2613 }
2614 printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep,
2615 " ResumedActivity:");
2616 }
2617
2618 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ",
2619 "Fin", false, !dumpAll,
2620 false, dumpPackage, true, " Activities waiting to finish:", null);
2621 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
2622 "Stop", false, !dumpAll,
2623 false, dumpPackage, true, " Activities waiting to stop:", null);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002624 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
2625 " ", "Sleep", false, !dumpAll,
2626 false, dumpPackage, true, " Activities waiting to sleep:", null);
2627
2628 return printed;
2629 }
2630
Jeffrey Huangcb782852019-12-05 11:28:11 -08002631 protected void dumpDebug(ProtoOutputStream proto, long fieldId,
Nataniel Borges023ecb52019-01-16 14:15:43 -08002632 @WindowTraceLogLevel int logLevel) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002633 final long token = proto.start(fieldId);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002634 super.dumpDebug(proto, CONFIGURATION_CONTAINER, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002635 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2636 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002637 activityDisplay.dumpDebug(proto, DISPLAYS, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002638 }
Jeffrey Huangcb782852019-12-05 11:28:11 -08002639 mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002640 // TODO(b/111541062): Update tests to look for resumed activities on all displays
2641 final ActivityStack focusedStack = getTopDisplayFocusedStack();
2642 if (focusedStack != null) {
2643 proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
2644 final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
2645 if (focusedActivity != null) {
2646 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
2647 }
2648 } else {
2649 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
2650 }
2651 proto.write(IS_HOME_RECENTS_COMPONENT,
2652 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
Jeffrey Huangcb782852019-12-05 11:28:11 -08002653 mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002654 proto.end(token);
2655 }
2656
2657 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
2658 private final String mTag;
2659 private final long mAcquireTime;
2660 private final int mDisplayId;
2661
2662 public SleepTokenImpl(String tag, int displayId) {
2663 mTag = tag;
2664 mDisplayId = displayId;
2665 mAcquireTime = SystemClock.uptimeMillis();
2666 }
2667
2668 @Override
2669 public void release() {
2670 synchronized (mService.mGlobalLock) {
2671 removeSleepToken(this);
2672 }
2673 }
2674
2675 @Override
2676 public String toString() {
2677 return "{\"" + mTag + "\", display " + mDisplayId
2678 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
2679 }
2680 }
2681}