blob: 5653ec07a3400bd99c3a3ef8c40f9f24ce357daa [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;
132
133/**
134 * Root node for activity containers.
135 * TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
136 * intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
137 */
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800138class RootActivityContainer extends ConfigurationContainer
139 implements DisplayManager.DisplayListener {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800140
141 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootActivityContainer" : TAG_ATM;
142 static final String TAG_TASKS = TAG + POSTFIX_TASKS;
143 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
144 static final String TAG_STATES = TAG + POSTFIX_STATES;
145 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
146
147 /**
148 * The modes which affect which tasks are returned when calling
149 * {@link RootActivityContainer#anyTaskForId(int)}.
150 */
151 @Retention(RetentionPolicy.SOURCE)
152 @IntDef({
153 MATCH_TASK_IN_STACKS_ONLY,
154 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
155 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
156 })
157 public @interface AnyTaskForIdMatchTaskMode {}
158 // Match only tasks in the current stacks
159 static final int MATCH_TASK_IN_STACKS_ONLY = 0;
160 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
161 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
162 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
163 // provided stack id
164 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
165
166 ActivityTaskManagerService mService;
167 ActivityStackSupervisor mStackSupervisor;
168 WindowManagerService mWindowManager;
169 DisplayManager mDisplayManager;
170 private DisplayManagerInternal mDisplayManagerInternal;
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800171 // TODO: Remove after object merge with RootWindowContainer.
172 private RootWindowContainer mRootWindowContainer;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800173
174 /**
175 * List of displays which contain activities, sorted by z-order.
176 * The last entry in the list is the topmost.
177 */
178 private final ArrayList<ActivityDisplay> mActivityDisplays = new ArrayList<>();
179
180 /** Reference to default display so we can quickly look it up. */
181 private ActivityDisplay mDefaultDisplay;
182 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
183
184 /** The current user */
185 int mCurrentUser;
186 /** Stack id of the front stack when user switched, indexed by userId. */
187 SparseIntArray mUserStackInFront = new SparseIntArray(2);
188
189 /**
190 * A list of tokens that cause the top activity to be put to sleep.
191 * They are used by components that may hide and block interaction with underlying
192 * activities.
193 */
194 final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
195
196 /** Is dock currently minimized. */
197 boolean mIsDockMinimized;
198
199 /** Set when a power hint has started, but not ended. */
200 private boolean mPowerHintSent;
201
Louis Changa5d070e2019-09-04 13:20:01 +0800202 /** Used to keep ensureActivitiesVisible() from being entered recursively. */
203 private boolean mInEnsureActivitiesVisible = false;
204
Wale Ogunwaled32da472018-11-16 07:19:28 -0800205 // The default minimal size that will be used if the activity doesn't specify its minimal size.
206 // It will be calculated when the default display gets added.
207 int mDefaultMinSizeOfResizeableTaskDp = -1;
208
209 // Whether tasks have moved and we need to rank the tasks before next OOM scoring
210 private boolean mTaskLayersChanged = true;
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800211 private int mTmpTaskLayerRank;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800212
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800213 private boolean mTmpBoolean;
214 private RemoteException mTmpRemoteException;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800215
216 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800217 static class FindTaskResult implements ToBooleanFunction<Task> {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800218 ActivityRecord mRecord;
219 boolean mIdealMatch;
220
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800221 private ActivityRecord mTarget;
222 private Intent intent;
223 private ActivityInfo info;
224 private ComponentName cls;
225 private int userId;
226 private boolean isDocument;
227 private Uri documentData;
228
229 /**
230 * Returns the top activity in any existing task matching the given Intent in the input
231 * result. Returns null if no such task is found.
232 */
233 void process(ActivityRecord target, ActivityStack parent) {
234 mTarget = target;
235
236 intent = target.intent;
237 info = target.info;
238 cls = intent.getComponent();
239 if (info.targetActivity != null) {
240 cls = new ComponentName(info.packageName, info.targetActivity);
241 }
242 userId = UserHandle.getUserId(info.applicationInfo.uid);
243 isDocument = intent != null & intent.isDocument();
244 // If documentData is non-null then it must match the existing task data.
245 documentData = isDocument ? intent.getData() : null;
246
247 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
248 parent.forAllTasks(this);
249 }
250
Wale Ogunwaled32da472018-11-16 07:19:28 -0800251 void clear() {
252 mRecord = null;
253 mIdealMatch = false;
254 }
255
256 void setTo(FindTaskResult result) {
257 mRecord = result.mRecord;
258 mIdealMatch = result.mIdealMatch;
259 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800260
261 @Override
262 public boolean apply(Task task) {
263 if (task.voiceSession != null) {
264 // We never match voice sessions; those always run independently.
265 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
266 return false;
267 }
268 if (task.mUserId != userId) {
269 // Looking for a different task.
270 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
271 return false;
272 }
273
274 // Overlays should not be considered as the task's logical top activity.
275 final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
276 if (r == null || r.finishing || r.mUserId != userId ||
277 r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
278 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
279 return false;
280 }
281 if (!r.hasCompatibleActivityType(mTarget)) {
282 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
283 return false;
284 }
285
286 final Intent taskIntent = task.intent;
287 final Intent affinityIntent = task.affinityIntent;
288 final boolean taskIsDocument;
289 final Uri taskDocumentData;
290 if (taskIntent != null && taskIntent.isDocument()) {
291 taskIsDocument = true;
292 taskDocumentData = taskIntent.getData();
293 } else if (affinityIntent != null && affinityIntent.isDocument()) {
294 taskIsDocument = true;
295 taskDocumentData = affinityIntent.getData();
296 } else {
297 taskIsDocument = false;
298 taskDocumentData = null;
299 }
300
301 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
302 + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
303 + "/aff=" + r.getTask().rootAffinity + " to new cls="
304 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
305 // TODO Refactor to remove duplications. Check if logic can be simplified.
306 if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
307 && Objects.equals(documentData, taskDocumentData)) {
308 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
309 //dump();
310 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
311 "For Intent " + intent + " bringing to top: " + r.intent);
312 mRecord = r;
313 mIdealMatch = true;
314 return true;
315 } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
316 affinityIntent.getComponent().compareTo(cls) == 0 &&
317 Objects.equals(documentData, taskDocumentData)) {
318 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
319 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
320 "For Intent " + intent + " bringing to top: " + r.intent);
321 mRecord = r;
322 mIdealMatch = true;
323 return true;
324 } else if (!isDocument && !taskIsDocument
325 && mRecord == null && task.rootAffinity != null) {
326 if (task.rootAffinity.equals(mTarget.taskAffinity)) {
327 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
328 // It is possible for multiple tasks to have the same root affinity especially
329 // if they are in separate stacks. We save off this candidate, but keep looking
330 // to see if there is a better candidate.
331 mRecord = r;
332 mIdealMatch = false;
333 }
334 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
335
336 return false;
337 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800338 }
339
340 RootActivityContainer(ActivityTaskManagerService service) {
341 mService = service;
342 mStackSupervisor = service.mStackSupervisor;
343 mStackSupervisor.mRootActivityContainer = this;
344 }
345
Wale Ogunwaled32da472018-11-16 07:19:28 -0800346 void setWindowManager(WindowManagerService wm) {
347 mWindowManager = wm;
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700348 mRootWindowContainer = mWindowManager.mRoot;
349 mRootWindowContainer.setRootActivityContainer(this);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800350 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
Charles Chen699e3602019-01-10 15:00:25 +0800351 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800352 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
353
354 final Display[] displays = mDisplayManager.getDisplays();
355 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
356 final Display display = displays[displayNdx];
357 final ActivityDisplay activityDisplay = new ActivityDisplay(this, display);
358 if (activityDisplay.mDisplayId == DEFAULT_DISPLAY) {
359 mDefaultDisplay = activityDisplay;
360 }
361 addChild(activityDisplay, ActivityDisplay.POSITION_TOP);
362 }
363 calculateDefaultMinimalSizeOfResizeableTasks();
364
365 final ActivityDisplay defaultDisplay = getDefaultDisplay();
366
367 defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
368 positionChildAt(defaultDisplay, ActivityDisplay.POSITION_TOP);
369 }
370
371 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
372 ActivityDisplay getDefaultDisplay() {
373 return mDefaultDisplay;
374 }
375
376 /**
377 * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is
378 * defined in {@link DisplayInfo#uniqueId}.
379 *
380 * @param uniqueId the unique ID of the display
381 * @return the {@link ActivityDisplay} or {@code null} if nothing is found.
382 */
383 ActivityDisplay getActivityDisplay(String uniqueId) {
384 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
385 final ActivityDisplay display = mActivityDisplays.get(i);
386 final boolean isValid = display.mDisplay.isValid();
387 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
388 return display;
389 }
390 }
391
392 return null;
393 }
394
395 // TODO: Look into consolidating with getActivityDisplayOrCreate()
396 ActivityDisplay getActivityDisplay(int displayId) {
397 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
398 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
399 if (activityDisplay.mDisplayId == displayId) {
400 return activityDisplay;
401 }
402 }
403 return null;
404 }
405
406 /**
407 * Get an existing instance of {@link ActivityDisplay} or create new if there is a
408 * corresponding record in display manager.
409 */
410 // TODO: Look into consolidating with getActivityDisplay()
Charles Chenb409e6c2019-02-12 12:30:17 +0800411 @Nullable ActivityDisplay getActivityDisplayOrCreate(int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800412 ActivityDisplay activityDisplay = getActivityDisplay(displayId);
413 if (activityDisplay != null) {
414 return activityDisplay;
415 }
416 if (mDisplayManager == null) {
417 // The system isn't fully initialized yet.
418 return null;
419 }
420 final Display display = mDisplayManager.getDisplay(displayId);
421 if (display == null) {
422 // The display is not registered in DisplayManager.
423 return null;
424 }
425 // The display hasn't been added to ActivityManager yet, create a new record now.
426 activityDisplay = new ActivityDisplay(this, display);
427 addChild(activityDisplay, ActivityDisplay.POSITION_BOTTOM);
428 return activityDisplay;
429 }
430
Wale Ogunwaled32da472018-11-16 07:19:28 -0800431 ActivityRecord getDefaultDisplayHomeActivity() {
432 return getDefaultDisplayHomeActivityForUser(mCurrentUser);
433 }
434
435 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
436 return getActivityDisplay(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
437 }
438
439 boolean startHomeOnAllDisplays(int userId, String reason) {
440 boolean homeStarted = false;
441 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
442 final int displayId = mActivityDisplays.get(i).mDisplayId;
443 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
444 }
445 return homeStarted;
446 }
447
Louis Changdcdde952018-12-04 15:38:44 +0800448 void startHomeOnEmptyDisplays(String reason) {
449 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
450 final ActivityDisplay display = mActivityDisplays.get(i);
451 if (display.topRunningActivity() == null) {
452 startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
453 }
454 }
455 }
456
Chilun8b1f1be2019-03-13 17:14:36 +0800457 boolean startHomeOnDisplay(int userId, String reason, int displayId) {
Chilun39232092019-03-22 14:41:30 +0800458 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
459 false /* fromHomeKey */);
Chilun8b1f1be2019-03-13 17:14:36 +0800460 }
461
Wale Ogunwaled32da472018-11-16 07:19:28 -0800462 /**
Chilun2ef71f72018-11-16 17:57:15 +0800463 * This starts home activity on displays that can have system decorations based on displayId -
464 * Default display always use primary home component.
465 * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
466 * according to the priorities listed below.
467 * - If default home is not set, always use the secondary home defined in the config.
468 * - Use currently selected primary home activity.
469 * - Use the activity in the same package as currently selected primary home activity.
470 * If there are multiple activities matched, use first one.
471 * - Use the secondary home defined in the config.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800472 */
Chilun39232092019-03-22 14:41:30 +0800473 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
474 boolean fromHomeKey) {
Chilun8b1f1be2019-03-13 17:14:36 +0800475 // Fallback to top focused display if the displayId is invalid.
476 if (displayId == INVALID_DISPLAY) {
Wale Ogunwalefef90a02019-11-06 17:56:33 -0800477 final ActivityStack stack = getTopDisplayFocusedStack();
478 displayId = stack != null ? stack.mDisplayId : DEFAULT_DISPLAY;
Chilun8b1f1be2019-03-13 17:14:36 +0800479 }
480
Chilun85ebc0d2019-04-15 16:00:53 +0800481 Intent homeIntent = null;
482 ActivityInfo aInfo = null;
Chilun2ef71f72018-11-16 17:57:15 +0800483 if (displayId == DEFAULT_DISPLAY) {
484 homeIntent = mService.getHomeIntent();
485 aInfo = resolveHomeActivity(userId, homeIntent);
Chilun85ebc0d2019-04-15 16:00:53 +0800486 } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Chilun2ef71f72018-11-16 17:57:15 +0800487 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
488 aInfo = info.first;
489 homeIntent = info.second;
490 }
Chilun85ebc0d2019-04-15 16:00:53 +0800491 if (aInfo == null || homeIntent == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800492 return false;
493 }
494
Chilun39232092019-03-22 14:41:30 +0800495 if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800496 return false;
497 }
498
Chilun2ef71f72018-11-16 17:57:15 +0800499 // Updates the home component of the intent.
500 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
501 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
Chilun8b1f1be2019-03-13 17:14:36 +0800502 // Updates the extra information of the intent.
503 if (fromHomeKey) {
504 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
505 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800506 // Update the reason for ANR debugging to verify if the user activity is the one that
507 // actually launched.
508 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
Chilun2ef71f72018-11-16 17:57:15 +0800509 aInfo.applicationInfo.uid) + ":" + displayId;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800510 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
511 displayId);
512 return true;
513 }
514
515 /**
Chilun2ef71f72018-11-16 17:57:15 +0800516 * This resolves the home activity info.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800517 * @return the home activity info if any.
518 */
Chilun2ef71f72018-11-16 17:57:15 +0800519 @VisibleForTesting
520 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800521 final int flags = ActivityManagerService.STOCK_PM_FLAGS;
522 final ComponentName comp = homeIntent.getComponent();
523 ActivityInfo aInfo = null;
524 try {
525 if (comp != null) {
526 // Factory test.
527 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
528 } else {
529 final String resolvedType =
530 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
531 final ResolveInfo info = AppGlobals.getPackageManager()
532 .resolveIntent(homeIntent, resolvedType, flags, userId);
533 if (info != null) {
534 aInfo = info.activityInfo;
535 }
536 }
537 } catch (RemoteException e) {
538 // ignore
539 }
540
541 if (aInfo == null) {
542 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
543 return null;
544 }
545
Wale Ogunwaled32da472018-11-16 07:19:28 -0800546 aInfo = new ActivityInfo(aInfo);
547 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800548 return aInfo;
549 }
550
Chilun2ef71f72018-11-16 17:57:15 +0800551 @VisibleForTesting
552 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) {
553 if (displayId == DEFAULT_DISPLAY) {
554 throw new IllegalArgumentException(
555 "resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY");
556 }
557 // Resolve activities in the same package as currently selected primary home activity.
558 Intent homeIntent = mService.getHomeIntent();
559 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
560 if (aInfo != null) {
561 if (ResolverActivity.class.getName().equals(aInfo.name)) {
562 // Always fallback to secondary home component if default home is not set.
563 aInfo = null;
564 } else {
565 // Look for secondary home activities in the currently selected default home
566 // package.
567 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
568 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
569 final int size = resolutions.size();
570 final String targetName = aInfo.name;
571 aInfo = null;
572 for (int i = 0; i < size; i++) {
573 ResolveInfo resolveInfo = resolutions.get(i);
574 // We need to traverse all resolutions to check if the currently selected
575 // default home activity is present.
576 if (resolveInfo.activityInfo.name.equals(targetName)) {
577 aInfo = resolveInfo.activityInfo;
578 break;
579 }
580 }
581 if (aInfo == null && size > 0) {
582 // First one is the best.
583 aInfo = resolutions.get(0).activityInfo;
584 }
585 }
586 }
587
588 if (aInfo != null) {
589 if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
590 aInfo = null;
591 }
592 }
593
594 // Fallback to secondary home component.
595 if (aInfo == null) {
596 homeIntent = mService.getSecondaryHomeIntent(null);
597 aInfo = resolveHomeActivity(userId, homeIntent);
598 }
599 return Pair.create(aInfo, homeIntent);
600 }
601
602 /**
603 * Retrieve all activities that match the given intent.
604 * The list should already ordered from best to worst matched.
605 * {@link android.content.pm.PackageManager#queryIntentActivities}
606 */
607 @VisibleForTesting
608 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
609 List<ResolveInfo> resolutions;
610 try {
611 final String resolvedType =
612 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
613 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
614 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
615
616 } catch (RemoteException e) {
617 resolutions = new ArrayList<>();
618 }
619 return resolutions;
620 }
621
Wale Ogunwaled32da472018-11-16 07:19:28 -0800622 boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
623 if (!mService.isBooting() && !mService.isBooted()) {
624 // Not ready yet!
625 return false;
626 }
627
628 if (displayId == INVALID_DISPLAY) {
629 displayId = DEFAULT_DISPLAY;
630 }
631
632 final ActivityRecord r = getActivityDisplay(displayId).getHomeActivity();
633 final String myReason = reason + " resumeHomeActivity";
634
635 // Only resume home activity if isn't finishing.
636 if (r != null && !r.finishing) {
637 r.moveFocusableActivityToTop(myReason);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800638 return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800639 }
640 return startHomeOnDisplay(mCurrentUser, myReason, displayId);
641 }
642
643 /**
Chilun85ebc0d2019-04-15 16:00:53 +0800644 * Check if the display is valid for secondary home activity.
645 * @param displayId The id of the target display.
646 * @return {@code true} if allow to launch, {@code false} otherwise.
647 */
648 boolean shouldPlaceSecondaryHomeOnDisplay(int displayId) {
649 if (displayId == DEFAULT_DISPLAY) {
650 throw new IllegalArgumentException(
651 "shouldPlaceSecondaryHomeOnDisplay: Should not be DEFAULT_DISPLAY");
652 } else if (displayId == INVALID_DISPLAY) {
653 return false;
654 }
655
656 if (!mService.mSupportsMultiDisplay) {
657 // Can't launch home on secondary display if device does not support multi-display.
658 return false;
659 }
660
661 final boolean deviceProvisioned = Settings.Global.getInt(
662 mService.mContext.getContentResolver(),
663 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
664 if (!deviceProvisioned) {
665 // Can't launch home on secondary display before device is provisioned.
666 return false;
667 }
668
669 if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
670 // Can't launch home on secondary displays if device is still locked.
671 return false;
672 }
673
674 final ActivityDisplay display = getActivityDisplay(displayId);
675 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
676 // Can't launch home on display that doesn't support system decorations.
677 return false;
678 }
679
680 return true;
681 }
682
683 /**
Wale Ogunwaled32da472018-11-16 07:19:28 -0800684 * Check if home activity start should be allowed on a display.
685 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
686 * @param displayId The id of the target display.
687 * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
688 * @return {@code true} if allow to launch, {@code false} otherwise.
689 */
690 boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId,
691 boolean allowInstrumenting) {
692 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
693 && mService.mTopAction == null) {
694 // We are running in factory test mode, but unable to find the factory test app, so
695 // just sit around displaying the error message and don't try to start anything.
696 return false;
697 }
698
699 final WindowProcessController app =
700 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
701 if (!allowInstrumenting && app != null && app.isInstrumenting()) {
702 // Don't do this if the home app is currently being instrumented.
703 return false;
704 }
705
706 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
707 && displayId == mService.mVr2dDisplayId)) {
708 // No restrictions to default display or vr 2d display.
709 return true;
710 }
711
Chilun85ebc0d2019-04-15 16:00:53 +0800712 if (!shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800713 return false;
714 }
715
716 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
Chilun2ef71f72018-11-16 17:57:15 +0800717 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800718 if (!supportMultipleInstance) {
Chilun2ef71f72018-11-16 17:57:15 +0800719 // Can't launch home on secondary displays if it requested to be single instance.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800720 return false;
721 }
722
723 return true;
724 }
725
726 /**
727 * Ensure all activities visibility, update orientation and configuration.
728 *
729 * @param starting The currently starting activity or {@code null} if there is none.
730 * @param displayId The id of the display where operation is executed.
731 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
732 * {@code true} if config changed.
733 * @param deferResume Whether to defer resume while updating config.
734 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
735 * because of configuration update.
736 */
737 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
738 boolean markFrozenIfConfigChanged, boolean deferResume) {
739 // First ensure visibility without updating the config just yet. We need this to know what
740 // activities are affecting configuration now.
741 // Passing null here for 'starting' param value, so that visibility of actual starting
742 // activity will be properly updated.
743 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
744 false /* preserveWindows */, false /* notifyClients */);
745
746 if (displayId == INVALID_DISPLAY) {
747 // The caller didn't provide a valid display id, skip updating config.
748 return true;
749 }
750
751 // Force-update the orientation from the WindowManager, since we need the true configuration
752 // to send to the client now.
Garfield Tan90b04282018-12-11 14:04:42 -0800753 final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId);
754 Configuration config = null;
755 if (displayContent != null) {
Riddle Hsuccf09402019-08-13 00:33:06 +0800756 config = displayContent.updateOrientation(
Garfield Tan90b04282018-12-11 14:04:42 -0800757 getDisplayOverrideConfiguration(displayId),
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800758 starting != null && starting.mayFreezeScreenLocked()
Garfield Tan90b04282018-12-11 14:04:42 -0800759 ? starting.appToken : null,
760 true /* forceUpdate */);
761 }
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800762 // Visibilities may change so let the starting activity have a chance to report. Can't do it
763 // when visibility is changed in each AppWindowToken because it may trigger wrong
764 // configuration push because the visibility of some activities may not be updated yet.
765 if (starting != null) {
766 starting.reportDescendantOrientationChangeIfNeeded();
767 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800768 if (starting != null && markFrozenIfConfigChanged && config != null) {
769 starting.frozenBeforeDestroy = true;
770 }
771
Louis Chang2453d062019-11-19 22:30:48 +0800772 if (displayContent != null) {
Shivam Agrawal1d3db652019-07-01 15:26:11 -0700773 // Update the configuration of the activities on the display.
Louis Chang2453d062019-11-19 22:30:48 +0800774 // TODO(display-merge): Remove cast
775 return ((ActivityDisplay) displayContent)
776 .updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
777 null /* result */);
Shivam Agrawal1d3db652019-07-01 15:26:11 -0700778 } else {
779 return true;
780 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800781 }
782
783 /**
784 * @return a list of activities which are the top ones in each visible stack. The first
785 * entry will be the focused activity.
786 */
787 List<IBinder> getTopVisibleActivities() {
788 final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
789 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
790 // Traverse all displays.
791 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
792 final ActivityDisplay display = mActivityDisplays.get(i);
793 // Traverse all stacks on a display.
Louis Chang2453d062019-11-19 22:30:48 +0800794 for (int j = display.getStackCount() - 1; j >= 0; --j) {
795 final ActivityStack stack = display.getStackAt(j);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800796 // Get top activity from a visible stack and add it to the list.
797 if (stack.shouldBeVisible(null /* starting */)) {
Wale Ogunwale21e06482019-11-18 05:14:15 -0800798 final ActivityRecord top = stack.getTopNonFinishingActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800799 if (top != null) {
800 if (stack == topFocusedStack) {
801 topActivityTokens.add(0, top.appToken);
802 } else {
803 topActivityTokens.add(top.appToken);
804 }
805 }
806 }
807 }
808 }
809 return topActivityTokens;
810 }
811
812 ActivityStack getTopDisplayFocusedStack() {
813 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
814 final ActivityStack focusedStack = mActivityDisplays.get(i).getFocusedStack();
815 if (focusedStack != null) {
816 return focusedStack;
817 }
818 }
819 return null;
820 }
821
822 ActivityRecord getTopResumedActivity() {
823 final ActivityStack focusedStack = getTopDisplayFocusedStack();
824 if (focusedStack == null) {
825 return null;
826 }
827 final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
828 if (resumedActivity != null && resumedActivity.app != null) {
829 return resumedActivity;
830 }
831 // The top focused stack might not have a resumed activity yet - look on all displays in
832 // focus order.
833 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
834 final ActivityDisplay display = mActivityDisplays.get(i);
835 final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity();
836 if (resumedActivityOnDisplay != null) {
837 return resumedActivityOnDisplay;
838 }
839 }
840 return null;
841 }
842
843 boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
844 if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) {
845 return false;
846 }
847
848 return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
849 }
850
851 boolean isTopDisplayFocusedStack(ActivityStack stack) {
852 return stack != null && stack == getTopDisplayFocusedStack();
853 }
854
855 void updatePreviousProcess(ActivityRecord r) {
856 // Now that this process has stopped, we may want to consider it to be the previous app to
857 // try to keep around in case the user wants to return to it.
858
859 // First, found out what is currently the foreground app, so that we don't blow away the
860 // previous app if this activity is being hosted by the process that is actually still the
861 // foreground.
862 WindowProcessController fgApp = null;
863 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
864 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +0800865 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
866 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800867 if (isTopDisplayFocusedStack(stack)) {
868 final ActivityRecord resumedActivity = stack.getResumedActivity();
869 if (resumedActivity != null) {
870 fgApp = resumedActivity.app;
871 } else if (stack.mPausingActivity != null) {
872 fgApp = stack.mPausingActivity.app;
873 }
874 break;
875 }
876 }
877 }
878
879 // Now set this one as the previous process, only if that really makes sense to.
880 if (r.hasProcess() && fgApp != null && r.app != fgApp
881 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
882 && r.app != mService.mHomeProcess) {
883 mService.mPreviousProcess = r.app;
884 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
885 }
886 }
887
888 boolean attachApplication(WindowProcessController app) throws RemoteException {
889 final String processName = app.mName;
890 boolean didSomething = false;
891 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
892 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
893 final ActivityStack stack = display.getFocusedStack();
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800894 if (stack == null) {
895 continue;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800896 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800897
898 mTmpRemoteException = null;
899 mTmpBoolean = false; // Set to true if an activity was started.
900 final PooledFunction c = PooledLambda.obtainFunction(
901 RootActivityContainer::startActivityForAttachedApplicationIfNeeded, this,
902 PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivityLocked());
903 stack.forAllActivities(c);
904 c.recycle();
905 if (mTmpRemoteException != null) {
906 throw mTmpRemoteException;
907 }
908 didSomething |= mTmpBoolean;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800909 }
910 if (!didSomething) {
911 ensureActivitiesVisible(null, 0, false /* preserve_windows */);
912 }
913 return didSomething;
914 }
915
Wale Ogunwalea38654f2019-11-17 20:37:15 -0800916 private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
917 WindowProcessController app, ActivityRecord top) {
918 if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
919 || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
920 return false;
921 }
922
923 try {
924 if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
925 true /*checkConfig*/)) {
926 mTmpBoolean = true;
927 }
928 } catch (RemoteException e) {
929 Slog.w(TAG, "Exception in new application when starting activity "
930 + top.intent.getComponent().flattenToShortString(), e);
931 mTmpRemoteException = e;
932 return true;
933 }
934 return false;
935 }
936
Wale Ogunwaled32da472018-11-16 07:19:28 -0800937 /**
938 * Make sure that all activities that need to be visible in the system actually are and update
939 * their configuration.
940 */
941 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
942 boolean preserveWindows) {
943 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
944 }
945
946 /**
947 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
948 */
949 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
950 boolean preserveWindows, boolean notifyClients) {
Louis Changa5d070e2019-09-04 13:20:01 +0800951 if (mInEnsureActivitiesVisible) {
952 // Don't do recursive work.
953 return;
954 }
955 mInEnsureActivitiesVisible = true;
956
Wale Ogunwaled32da472018-11-16 07:19:28 -0800957 try {
Louis Changa5d070e2019-09-04 13:20:01 +0800958 mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800959 // First the front stacks. In case any are not fullscreen and are in front of home.
960 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
961 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang77ce34d2019-01-03 15:45:12 +0800962 display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
963 notifyClients);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800964 }
965 } finally {
966 mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
Louis Changa5d070e2019-09-04 13:20:01 +0800967 mInEnsureActivitiesVisible = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800968 }
969 }
970
971 boolean switchUser(int userId, UserState uss) {
972 final int focusStackId = getTopDisplayFocusedStack().getStackId();
973 // We dismiss the docked stack whenever we switch users.
974 final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
975 if (dockedStack != null) {
976 mStackSupervisor.moveTasksToFullscreenStackLocked(
977 dockedStack, dockedStack.isFocusedStackOnDisplay());
978 }
979 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
980 // also cause all tasks to be moved to the fullscreen stack at a position that is
981 // appropriate.
982 removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
983
984 mUserStackInFront.put(mCurrentUser, focusStackId);
985 final int restoreStackId =
986 mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId);
987 mCurrentUser = userId;
988
989 mStackSupervisor.mStartingUsers.add(uss);
990 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
991 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +0800992 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
993 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700994 stack.switchUser(userId);
Louis Changcdec0802019-11-11 11:45:07 +0800995 Task task = stack.topTask();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800996 if (task != null) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700997 stack.positionChildAtTop(task);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800998 }
999 }
1000 }
1001
1002 ActivityStack stack = getStack(restoreStackId);
1003 if (stack == null) {
1004 stack = getDefaultDisplay().getHomeStack();
1005 }
1006 final boolean homeInFront = stack.isActivityTypeHome();
1007 if (stack.isOnHomeDisplay()) {
1008 stack.moveToFront("switchUserOnHomeDisplay");
1009 } else {
1010 // Stack was moved to another display while user was swapped out.
1011 resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
1012 }
1013 return homeInFront;
1014 }
1015
1016 void removeUser(int userId) {
1017 mUserStackInFront.delete(userId);
1018 }
1019
1020 /**
1021 * Update the last used stack id for non-current user (current user's last
1022 * used stack is the focused stack)
1023 */
1024 void updateUserStack(int userId, ActivityStack stack) {
1025 if (userId != mCurrentUser) {
1026 mUserStackInFront.put(userId, stack != null ? stack.getStackId()
1027 : getDefaultDisplay().getHomeStack().mStackId);
1028 }
1029 }
1030
Wale Ogunwaled32da472018-11-16 07:19:28 -08001031 /**
1032 * Move stack with all its existing content to specified display.
1033 * @param stackId Id of stack to move.
1034 * @param displayId Id of display to move stack to.
1035 * @param onTop Indicates whether container should be place on top or on bottom.
1036 */
1037 void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
1038 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1039 if (activityDisplay == null) {
1040 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
1041 + displayId);
1042 }
1043 final ActivityStack stack = getStack(stackId);
1044 if (stack == null) {
1045 throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId="
1046 + stackId);
1047 }
1048
1049 final ActivityDisplay currentDisplay = stack.getDisplay();
1050 if (currentDisplay == null) {
1051 throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack
1052 + " is not attached to any display.");
1053 }
1054
1055 if (currentDisplay.mDisplayId == displayId) {
1056 throw new IllegalArgumentException("Trying to move stack=" + stack
1057 + " to its current displayId=" + displayId);
1058 }
1059
Louis Chang2453d062019-11-19 22:30:48 +08001060 if (activityDisplay.isSingleTaskInstance() && activityDisplay.getStackCount() > 0) {
Wale Ogunwale9e737db2018-12-17 15:42:37 -08001061 // We don't allow moving stacks to single instance display that already has a child.
1062 Slog.e(TAG, "Can not move stack=" + stack
1063 + " to single task instance display=" + activityDisplay);
1064 return;
1065 }
1066
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001067 stack.reparent(activityDisplay.mDisplayContent, onTop);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001068 // TODO(multi-display): resize stacks properly if moved from split-screen.
1069 }
1070
1071 boolean moveTopStackActivityToPinnedStack(int stackId) {
1072 final ActivityStack stack = getStack(stackId);
1073 if (stack == null) {
1074 throw new IllegalArgumentException(
1075 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
1076 }
1077
1078 final ActivityRecord r = stack.topRunningActivityLocked();
1079 if (r == null) {
1080 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
1081 + " in stack=" + stack);
1082 return false;
1083 }
1084
1085 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
1086 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
1087 + " r=" + r);
1088 return false;
1089 }
1090
1091 moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */,
1092 "moveTopActivityToPinnedStack");
1093 return true;
1094 }
1095
1096 void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
1097 String reason) {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001098 mService.deferWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001099
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001100 final ActivityDisplay display = r.getActivityStack().getDisplay();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001101
Wale Ogunwaled32da472018-11-16 07:19:28 -08001102 try {
Louis Changcdec0802019-11-11 11:45:07 +08001103 final Task task = r.getTask();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001104
Ben Lin6db8fb22019-10-18 16:03:44 -07001105 final ActivityStack pinnedStack = display.getPinnedStack();
1106 // This will change the pinned stack's windowing mode to its original mode, ensuring
1107 // we only have one stack that is in pinned mode.
1108 if (pinnedStack != null) {
1109 pinnedStack.dismissPip();
1110 }
1111
1112 final boolean singleActivity = task.getChildCount() == 1;
1113
1114 final ActivityStack stack;
1115 if (singleActivity) {
1116 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001117 } else {
Ben Lin6db8fb22019-10-18 16:03:44 -07001118 // In the case of multiple activities, we will create a new stack for it and then
1119 // move the PIP activity into the stack.
1120 // We will then perform a windowing mode change for both scenarios.
1121 stack = display.createStack(
1122 r.getActivityStack().getRequestedOverrideWindowingMode(),
1123 r.getActivityType(), ON_TOP);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001124 // There are multiple activities in the task and moving the top activity should
1125 // reveal/leave the other activities in their original task.
1126
1127 // Currently, we don't support reparenting activities across tasks in two different
1128 // stacks, so instead, just create a new task in the same stack, reparent the
1129 // activity into that task, and then reparent the whole task to the new stack. This
1130 // ensures that all the necessary work to migrate states in the old and new stacks
1131 // is also done.
Louis Changcdec0802019-11-11 11:45:07 +08001132 final Task newTask = task.getStack().createTask(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001133 mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001134 r.intent, null, null, true);
1135 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
1136
1137 // Defer resume until below, and do not schedule PiP changes until we animate below
1138 newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
1139 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
1140 }
1141
Ben Lin6db8fb22019-10-18 16:03:44 -07001142 stack.setWindowingMode(WINDOWING_MODE_PINNED);
1143
Wale Ogunwaled32da472018-11-16 07:19:28 -08001144 // Reset the state that indicates it can enter PiP while pausing after we've moved it
1145 // to the pinned stack
1146 r.supportsEnterPipOnTaskSwitch = false;
1147 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001148 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001149 }
1150
Hongwei Wang43a752b2019-09-17 20:20:30 +00001151 // Notify the pinned stack controller to prepare the PiP animation, expect callback
1152 // delivered from SystemUI to WM to start the animation.
1153 final PinnedStackController pinnedStackController =
1154 display.mDisplayContent.getPinnedStackController();
1155 pinnedStackController.prepareAnimation(sourceHintBounds, aspectRatio,
1156 null /* stackBounds */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001157
Hongwei Wang43a752b2019-09-17 20:20:30 +00001158 // TODO: revisit the following statement after the animation is moved from WM to SysUI.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001159 // Update the visibility of all activities after the they have been reparented to the new
1160 // stack. This MUST run after the animation above is scheduled to ensure that the windows
1161 // drawn signal is scheduled after the bounds animation start call on the bounds animator
1162 // thread.
1163 ensureActivitiesVisible(null, 0, false /* preserveWindows */);
1164 resumeFocusedStacksTopActivities();
1165
1166 mService.getTaskChangeNotificationController().notifyActivityPinned(r);
1167 }
1168
1169 void executeAppTransitionForAllDisplay() {
1170 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1171 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001172 display.mDisplayContent.executeAppTransition();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001173 }
1174 }
1175
1176 void setDockedStackMinimized(boolean minimized) {
1177 // Get currently focused stack before setting mIsDockMinimized. We do this because if
1178 // split-screen is active, primary stack will not be focusable (see #isFocusable) while
1179 // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
1180 final ActivityStack current = getTopDisplayFocusedStack();
1181 mIsDockMinimized = minimized;
1182 if (mIsDockMinimized) {
1183 if (current.inSplitScreenPrimaryWindowingMode()) {
1184 // The primary split-screen stack can't be focused while it is minimize, so move
1185 // focus to something else.
1186 current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
1187 }
1188 }
1189 }
1190
1191 ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
1192 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
1193 mTmpFindTaskResult.clear();
1194
1195 // Looking up task on preferred display first
1196 final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId);
1197 if (preferredDisplay != null) {
1198 preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult);
1199 if (mTmpFindTaskResult.mIdealMatch) {
1200 return mTmpFindTaskResult.mRecord;
1201 }
1202 }
1203
1204 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1205 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1206 if (display.mDisplayId == preferredDisplayId) {
1207 continue;
1208 }
1209
1210 display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult);
1211 if (mTmpFindTaskResult.mIdealMatch) {
1212 return mTmpFindTaskResult.mRecord;
1213 }
1214 }
1215
1216 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
1217 return mTmpFindTaskResult.mRecord;
1218 }
1219
1220 /**
1221 * Finish the topmost activities in all stacks that belong to the crashed app.
1222 * @param app The app that crashed.
1223 * @param reason Reason to perform this action.
1224 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
1225 */
1226 int finishTopCrashedActivities(WindowProcessController app, String reason) {
Louis Changcdec0802019-11-11 11:45:07 +08001227 Task finishedTask = null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001228 ActivityStack focusedStack = getTopDisplayFocusedStack();
1229 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1230 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1231 // It is possible that request to finish activity might also remove its task and stack,
1232 // so we need to be careful with indexes in the loop and check child count every time.
Louis Chang2453d062019-11-19 22:30:48 +08001233 for (int stackNdx = 0; stackNdx < display.getStackCount(); ++stackNdx) {
1234 final ActivityStack stack = display.getStackAt(stackNdx);
Louis Changcdec0802019-11-11 11:45:07 +08001235 final Task t = stack.finishTopCrashedActivityLocked(app, reason);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001236 if (stack == focusedStack || finishedTask == null) {
1237 finishedTask = t;
1238 }
1239 }
1240 }
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001241 return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001242 }
1243
1244 boolean resumeFocusedStacksTopActivities() {
1245 return resumeFocusedStacksTopActivities(null, null, null);
1246 }
1247
1248 boolean resumeFocusedStacksTopActivities(
1249 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1250
1251 if (!mStackSupervisor.readyToResume()) {
1252 return false;
1253 }
1254
Andrii Kulian6b321512019-01-23 06:37:00 +00001255 boolean result = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001256 if (targetStack != null && (targetStack.isTopStackOnDisplay()
1257 || getTopDisplayFocusedStack() == targetStack)) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001258 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001259 }
1260
Wale Ogunwaled32da472018-11-16 07:19:28 -08001261 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001262 boolean resumedOnDisplay = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001263 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001264 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1265 final ActivityStack stack = display.getStackAt(stackNdx);
Andrii Kulian6b321512019-01-23 06:37:00 +00001266 final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
1267 if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
1268 continue;
1269 }
Louis Changc50a9362019-02-12 12:35:24 +08001270 if (stack == targetStack) {
1271 // Simply update the result for targetStack because the targetStack had
1272 // already resumed in above. We don't want to resume it again, especially in
1273 // some cases, it would cause a second launch failure if app process was dead.
1274 resumedOnDisplay |= result;
1275 continue;
1276 }
Jorim Jaggia5cf6802019-04-26 19:43:11 +02001277 if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
1278 // Kick off any lingering app transitions form the MoveTaskToFront operation,
1279 // but only consider the top task and stack on that display.
Andrii Kulian6b321512019-01-23 06:37:00 +00001280 stack.executeAppTransition(targetOptions);
1281 } else {
1282 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
1283 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001284 }
Andrii Kulian6b321512019-01-23 06:37:00 +00001285 if (!resumedOnDisplay) {
1286 // In cases when there are no valid activities (e.g. device just booted or launcher
1287 // crashed) it's possible that nothing was resumed on a display. Requesting resume
1288 // of top activity in focused stack explicitly will make sure that at least home
1289 // activity is started and resumed, and no recursion occurs.
1290 final ActivityStack focusedStack = display.getFocusedStack();
1291 if (focusedStack != null) {
wilsonshih4c9824a2019-10-25 18:47:50 +08001292 result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Riddle Hsua0175ab2019-11-12 23:52:32 +08001293 } else if (targetStack == null && !display.hasChild()) {
1294 result |= resumeHomeActivity(null /* prev */, "empty-display",
1295 display.mDisplayId);
Andrii Kulian6b321512019-01-23 06:37:00 +00001296 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001297 }
1298 }
1299
Andrii Kulian6b321512019-01-23 06:37:00 +00001300 return result;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001301 }
1302
1303 void applySleepTokens(boolean applyToStacks) {
1304 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1305 // Set the sleeping state of the display.
1306 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1307 final boolean displayShouldSleep = display.shouldSleep();
1308 if (displayShouldSleep == display.isSleeping()) {
1309 continue;
1310 }
1311 display.setIsSleeping(displayShouldSleep);
1312
1313 if (!applyToStacks) {
1314 continue;
1315 }
1316
1317 // Set the sleeping state of the stacks on the display.
Louis Chang2453d062019-11-19 22:30:48 +08001318 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1319 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001320 if (displayShouldSleep) {
1321 stack.goToSleepIfPossible(false /* shuttingDown */);
1322 } else {
Issei Suzukicac2a502019-04-16 16:52:50 +02001323 // When the display which can only contain one task turns on, start a special
1324 // transition. {@link AppTransitionController#handleAppTransitionReady} later
1325 // picks up the transition, and schedules
1326 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
1327 // triggered after contents are drawn on the display.
1328 if (display.isSingleTaskInstance()) {
1329 display.mDisplayContent.prepareAppTransition(
1330 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
1331 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001332 stack.awakeFromSleepingLocked();
1333 if (stack.isFocusedStackOnDisplay()
1334 && !mStackSupervisor.getKeyguardController()
1335 .isKeyguardOrAodShowing(display.mDisplayId)) {
1336 // If the keyguard is unlocked - resume immediately.
1337 // It is possible that the display will not be awake at the time we
1338 // process the keyguard going away, which can happen before the sleep token
1339 // is released. As a result, it is important we resume the activity here.
1340 resumeFocusedStacksTopActivities();
1341 }
1342 }
1343 }
1344
1345 if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) {
1346 continue;
1347 }
1348 // The display is awake now, so clean up the going to sleep list.
1349 for (Iterator<ActivityRecord> it =
1350 mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) {
1351 final ActivityRecord r = it.next();
1352 if (r.getDisplayId() == display.mDisplayId) {
1353 it.remove();
1354 }
1355 }
1356 }
1357 }
1358
Louis Chang2453d062019-11-19 22:30:48 +08001359 protected ActivityStack getStack(int stackId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001360 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
Louis Chang2453d062019-11-19 22:30:48 +08001361 final ActivityStack stack = mActivityDisplays.get(i).getStack(stackId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001362 if (stack != null) {
1363 return stack;
1364 }
1365 }
1366 return null;
1367 }
1368
1369 /** @see ActivityDisplay#getStack(int, int) */
Louis Chang2453d062019-11-19 22:30:48 +08001370 ActivityStack getStack(int windowingMode, int activityType) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001371 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
Louis Chang2453d062019-11-19 22:30:48 +08001372 final ActivityStack stack =
1373 mActivityDisplays.get(i).getStack(windowingMode, activityType);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001374 if (stack != null) {
1375 return stack;
1376 }
1377 }
1378 return null;
1379 }
1380
Louis Chang2453d062019-11-19 22:30:48 +08001381 private ActivityStack getStack(int windowingMode, int activityType,
Evan Roskyfd439692019-11-06 16:12:59 -08001382 int displayId) {
1383 ActivityDisplay display = getActivityDisplay(displayId);
1384 if (display == null) {
1385 return null;
1386 }
1387 return display.getStack(windowingMode, activityType);
1388 }
1389
Wale Ogunwaled32da472018-11-16 07:19:28 -08001390 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
1391 final int displayId = stack.mDisplayId;
1392 final ActivityDisplay display = getActivityDisplay(displayId);
1393 ActivityManager.StackInfo info = new ActivityManager.StackInfo();
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001394 stack.getBounds(info.bounds);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001395 info.displayId = displayId;
1396 info.stackId = stack.mStackId;
Evan Rosky282ee672019-11-13 15:50:46 -08001397 info.stackToken = stack.mRemoteToken;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001398 info.userId = stack.mCurrentUser;
1399 info.visible = stack.shouldBeVisible(null);
1400 // A stack might be not attached to a display.
1401 info.position = display != null ? display.getIndexOf(stack) : 0;
1402 info.configuration.setTo(stack.getConfiguration());
1403
Louis Changcdec0802019-11-11 11:45:07 +08001404 ArrayList<Task> tasks = stack.getAllTasks();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001405 final int numTasks = tasks.size();
1406 int[] taskIds = new int[numTasks];
1407 String[] taskNames = new String[numTasks];
1408 Rect[] taskBounds = new Rect[numTasks];
1409 int[] taskUserIds = new int[numTasks];
1410 for (int i = 0; i < numTasks; ++i) {
Louis Changcdec0802019-11-11 11:45:07 +08001411 final Task task = tasks.get(i);
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001412 taskIds[i] = task.mTaskId;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001413 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
1414 : task.realActivity != null ? task.realActivity.flattenToString()
Wale Ogunwale21e06482019-11-18 05:14:15 -08001415 : task.getTopNonFinishingActivity() != null
1416 ? task.getTopNonFinishingActivity().packageName : "unknown";
Wale Ogunwale2322bed2019-10-10 17:24:19 +02001417 taskBounds[i] = mService.getTaskBounds(task.mTaskId);
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001418 taskUserIds[i] = task.mUserId;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001419 }
1420 info.taskIds = taskIds;
1421 info.taskNames = taskNames;
1422 info.taskBounds = taskBounds;
1423 info.taskUserIds = taskUserIds;
1424
1425 final ActivityRecord top = stack.topRunningActivityLocked();
1426 info.topActivity = top != null ? top.intent.getComponent() : null;
1427 return info;
1428 }
1429
1430 ActivityManager.StackInfo getStackInfo(int stackId) {
1431 ActivityStack stack = getStack(stackId);
1432 if (stack != null) {
1433 return getStackInfo(stack);
1434 }
1435 return null;
1436 }
1437
1438 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
1439 final ActivityStack stack = getStack(windowingMode, activityType);
1440 return (stack != null) ? getStackInfo(stack) : null;
1441 }
1442
Evan Roskyfd439692019-11-06 16:12:59 -08001443 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) {
1444 final ActivityStack stack = getStack(windowingMode, activityType, displayId);
1445 return (stack != null) ? getStackInfo(stack) : null;
1446 }
1447
1448 /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */
1449 ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001450 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
Evan Roskyfd439692019-11-06 16:12:59 -08001451 if (displayId == INVALID_DISPLAY) {
1452 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
1453 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001454 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1455 final ActivityStack stack = display.getStackAt(stackNdx);
Evan Roskyfd439692019-11-06 16:12:59 -08001456 list.add(getStackInfo(stack));
1457 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001458 }
Evan Roskyfd439692019-11-06 16:12:59 -08001459 return list;
1460 }
1461 final ActivityDisplay display = getActivityDisplay(displayId);
1462 if (display == null) {
1463 return list;
1464 }
Louis Chang2453d062019-11-19 22:30:48 +08001465 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1466 final ActivityStack stack = display.getStackAt(stackNdx);
Evan Roskyfd439692019-11-06 16:12:59 -08001467 list.add(getStackInfo(stack));
Wale Ogunwaled32da472018-11-16 07:19:28 -08001468 }
1469 return list;
1470 }
1471
1472 void deferUpdateBounds(int activityType) {
1473 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1474 if (stack != null) {
1475 stack.deferUpdateBounds();
1476 }
1477 }
1478
1479 void continueUpdateBounds(int activityType) {
1480 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1481 if (stack != null) {
1482 stack.continueUpdateBounds();
1483 }
1484 }
1485
1486 @Override
1487 public void onDisplayAdded(int displayId) {
1488 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
1489 synchronized (mService.mGlobalLock) {
Charles Chen3dedec32019-01-24 22:19:37 +08001490 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
Charles Chenb409e6c2019-02-12 12:30:17 +08001491 if (display == null) {
1492 return;
1493 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001494 // Do not start home before booting, or it may accidentally finish booting before it
1495 // starts. Instead, we expect home activities to be launched when the system is ready
1496 // (ActivityManagerService#systemReady).
1497 if (mService.isBooted() || mService.isBooting()) {
Charles Chen3dedec32019-01-24 22:19:37 +08001498 startSystemDecorations(display.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001499 }
1500 }
1501 }
1502
Charles Chen3dedec32019-01-24 22:19:37 +08001503 private void startSystemDecorations(final DisplayContent displayContent) {
1504 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
1505 displayContent.getDisplayPolicy().notifyDisplayReady();
1506 }
1507
Wale Ogunwaled32da472018-11-16 07:19:28 -08001508 @Override
1509 public void onDisplayRemoved(int displayId) {
1510 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
1511 if (displayId == DEFAULT_DISPLAY) {
1512 throw new IllegalArgumentException("Can't remove the primary display.");
1513 }
1514
1515 synchronized (mService.mGlobalLock) {
1516 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1517 if (activityDisplay == null) {
1518 return;
1519 }
1520
1521 activityDisplay.remove();
1522 }
1523 }
1524
1525 @Override
1526 public void onDisplayChanged(int displayId) {
1527 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
1528 synchronized (mService.mGlobalLock) {
1529 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1530 if (activityDisplay != null) {
1531 activityDisplay.onDisplayChanged();
1532 }
1533 }
1534 }
1535
1536 /** Update lists of UIDs that are present on displays and have access to them. */
1537 void updateUIDsPresentOnDisplay() {
1538 mDisplayAccessUIDs.clear();
1539 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1540 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
1541 // Only bother calculating the whitelist for private displays
1542 if (activityDisplay.isPrivate()) {
1543 mDisplayAccessUIDs.append(
1544 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs());
1545 }
1546 }
1547 // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
1548 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
1549 }
1550
1551 ActivityStack findStackBehind(ActivityStack stack) {
1552 final ActivityDisplay display = getActivityDisplay(stack.mDisplayId);
1553 if (display != null) {
Louis Chang2453d062019-11-19 22:30:48 +08001554 for (int i = display.getStackCount() - 1; i >= 0; i--) {
1555 if (display.getStackAt(i) == stack && i > 0) {
1556 return display.getStackAt(i - 1);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001557 }
1558 }
1559 }
1560 throw new IllegalStateException("Failed to find a stack behind stack=" + stack
1561 + " in=" + display);
1562 }
1563
1564 @Override
1565 protected int getChildCount() {
1566 return mActivityDisplays.size();
1567 }
1568
1569 @Override
1570 protected ActivityDisplay getChildAt(int index) {
1571 return mActivityDisplays.get(index);
1572 }
1573
1574 @Override
1575 protected ConfigurationContainer getParent() {
1576 return null;
1577 }
1578
Wale Ogunwale31acb3f2018-11-20 15:23:55 -08001579 // TODO: remove after object merge with RootWindowContainer
Louis Chang2453d062019-11-19 22:30:48 +08001580 void onChildPositionChanged(DisplayContent display, int position) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001581 // Assume AM lock is held from positionChildAt of controller in each hierarchy.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001582 if (display != null) {
1583 positionChildAt(display, position);
1584 }
1585 }
1586
1587 /** Change the z-order of the given display. */
Louis Chang2453d062019-11-19 22:30:48 +08001588 private void positionChildAt(DisplayContent display, int position) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001589 if (position >= mActivityDisplays.size()) {
1590 position = mActivityDisplays.size() - 1;
1591 } else if (position < 0) {
1592 position = 0;
1593 }
1594
Louis Chang2453d062019-11-19 22:30:48 +08001595 // TODO(display-merge): Remove cast
1596 final ActivityDisplay activityDisplay = (ActivityDisplay) display;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001597 if (mActivityDisplays.isEmpty()) {
Louis Chang2453d062019-11-19 22:30:48 +08001598 mActivityDisplays.add(activityDisplay);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001599 } else if (mActivityDisplays.get(position) != display) {
1600 mActivityDisplays.remove(display);
Louis Chang2453d062019-11-19 22:30:48 +08001601 mActivityDisplays.add(position, activityDisplay);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001602 }
Andrii Kulian86e70fc2019-02-12 11:04:10 +00001603 mStackSupervisor.updateTopResumedActivityIfNeeded();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001604 }
1605
1606 @VisibleForTesting
1607 void addChild(ActivityDisplay activityDisplay, int position) {
1608 positionChildAt(activityDisplay, position);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001609 mRootWindowContainer.positionChildAt(position, activityDisplay.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001610 }
1611
1612 void removeChild(ActivityDisplay activityDisplay) {
1613 // The caller must tell the controller of {@link ActivityDisplay} to release its container
1614 // {@link DisplayContent}. That is done in {@link ActivityDisplay#releaseSelfIfNeeded}).
1615 mActivityDisplays.remove(activityDisplay);
1616 }
1617
1618 Configuration getDisplayOverrideConfiguration(int displayId) {
1619 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1620 if (activityDisplay == null) {
1621 throw new IllegalArgumentException("No display found with id: " + displayId);
1622 }
1623
Evan Roskydfe3da72018-10-26 17:21:06 -07001624 return activityDisplay.getRequestedOverrideConfiguration();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001625 }
1626
1627 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
1628 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1629 if (activityDisplay == null) {
1630 throw new IllegalArgumentException("No display found with id: " + displayId);
1631 }
1632
Evan Roskydfe3da72018-10-26 17:21:06 -07001633 activityDisplay.onRequestedOverrideConfigurationChanged(overrideConfiguration);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001634 }
1635
1636 void prepareForShutdown() {
1637 for (int i = 0; i < mActivityDisplays.size(); i++) {
1638 createSleepToken("shutdown", mActivityDisplays.get(i).mDisplayId);
1639 }
1640 }
1641
1642 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
1643 final ActivityDisplay display = getActivityDisplay(displayId);
1644 if (display == null) {
1645 throw new IllegalArgumentException("Invalid display: " + displayId);
1646 }
1647
1648 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
1649 mSleepTokens.add(token);
1650 display.mAllSleepTokens.add(token);
1651 return token;
1652 }
1653
1654 private void removeSleepToken(SleepTokenImpl token) {
1655 mSleepTokens.remove(token);
1656
1657 final ActivityDisplay display = getActivityDisplay(token.mDisplayId);
1658 if (display != null) {
1659 display.mAllSleepTokens.remove(token);
1660 if (display.mAllSleepTokens.isEmpty()) {
1661 mService.updateSleepIfNeededLocked();
1662 }
1663 }
1664 }
1665
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001666 void addStartingWindowsForVisibleActivities() {
1667 mRootWindowContainer.forAllActivities((r) -> {
1668 if (r.mVisibleRequested) {
1669 r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001670 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001671 });
Wale Ogunwaled32da472018-11-16 07:19:28 -08001672 }
1673
1674 void invalidateTaskLayers() {
1675 mTaskLayersChanged = true;
1676 }
1677
1678 void rankTaskLayersIfNeeded() {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001679 if (!mTaskLayersChanged || mRootWindowContainer == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001680 return;
1681 }
1682 mTaskLayersChanged = false;
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001683 mTmpTaskLayerRank = 0;
1684 final PooledConsumer c = PooledLambda.obtainConsumer(
1685 RootActivityContainer::rankTaskLayerForActivity, this,
1686 PooledLambda.__(ActivityRecord.class));
1687 mRootWindowContainer.forAllActivities(c);
1688 c.recycle();
1689 }
1690
1691 private void rankTaskLayerForActivity(ActivityRecord r) {
1692 if (r.canBeTopRunning() && r.mVisibleRequested) {
1693 r.getTask().mLayerRank = ++mTmpTaskLayerRank;
1694 } else {
1695 r.getTask().mLayerRank = -1;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001696 }
1697 }
1698
1699 void clearOtherAppTimeTrackers(AppTimeTracker except) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001700 final PooledConsumer c = PooledLambda.obtainConsumer(
1701 RootActivityContainer::clearOtherAppTimeTrackers,
1702 PooledLambda.__(ActivityRecord.class), except);
1703 mRootWindowContainer.forAllActivities(c);
1704 c.recycle();
1705 }
1706
1707 private static void clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except) {
1708 if ( r.appTimeTracker != except) {
1709 r.appTimeTracker = null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001710 }
1711 }
1712
1713 void scheduleDestroyAllActivities(WindowProcessController app, String reason) {
1714 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1715 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001716 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
1717 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001718 stack.scheduleDestroyActivities(app, reason);
1719 }
1720 }
1721 }
1722
Wale Ogunwaled32da472018-11-16 07:19:28 -08001723 // Tries to put all activity stacks to sleep. Returns true if all stacks were
1724 // successfully put to sleep.
1725 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
1726 boolean allSleep = true;
1727 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1728 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08001729 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
Louis Changc219bc32018-12-06 15:38:41 +08001730 // Stacks and activities could be removed while putting activities to sleep if
1731 // the app process was gone. This prevents us getting exception by accessing an
1732 // invalid stack index.
Louis Chang2453d062019-11-19 22:30:48 +08001733 if (stackNdx >= display.getStackCount()) {
Louis Changc219bc32018-12-06 15:38:41 +08001734 continue;
1735 }
1736
Louis Chang2453d062019-11-19 22:30:48 +08001737 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001738 if (allowDelay) {
1739 allSleep &= stack.goToSleepIfPossible(shuttingDown);
1740 } else {
1741 stack.goToSleep();
1742 }
1743 }
1744 }
1745 return allSleep;
1746 }
1747
1748 void handleAppCrash(WindowProcessController app) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001749 final PooledConsumer c = PooledLambda.obtainConsumer(
1750 RootActivityContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app);
1751 mRootWindowContainer.forAllActivities(c);
1752 c.recycle();
1753 }
1754
1755 private static void handleAppCrash(ActivityRecord r, WindowProcessController app) {
1756 if (r.app != app) return;
1757 Slog.w(TAG, " Force finishing activity "
1758 + r.intent.getComponent().flattenToShortString());
1759 // Force the destroy to skip right to removal.
1760 r.app = null;
1761 r.getDisplay().mDisplayContent.prepareAppTransition(
1762 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
1763 r.destroyIfPossible("handleAppCrashed");
Wale Ogunwaled32da472018-11-16 07:19:28 -08001764 }
1765
1766 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001767 ComponentName cls = intent.getComponent();
1768 if (info.targetActivity != null) {
1769 cls = new ComponentName(info.packageName, info.targetActivity);
1770 }
1771 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
1772
1773 final PooledPredicate p = PooledLambda.obtainPredicate(
1774 RootActivityContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
1775 userId, compareIntentFilters, intent, cls);
1776 final ActivityRecord r = mRootWindowContainer.getActivity(p);
1777 p.recycle();
1778 return r;
1779 }
1780
1781 private static boolean matchesActivity(ActivityRecord r, int userId,
1782 boolean compareIntentFilters, Intent intent, ComponentName cls) {
1783 if (!r.canBeTopRunning() || r.mUserId != userId) return false;
1784
1785 if (compareIntentFilters) {
1786 if (r.intent.filterEquals(intent)) {
1787 return true;
1788 }
1789 } else {
1790 if (r.intent.getComponent().equals(cls)) {
1791 return true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001792 }
1793 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -08001794 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001795 }
1796
1797 boolean hasAwakeDisplay() {
1798 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1799 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1800 if (!display.shouldSleep()) {
1801 return true;
1802 }
1803 }
1804 return false;
1805 }
1806
Wale Ogunwale8577a052019-10-26 23:22:34 -07001807 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001808 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
lumarkf65e02d2019-09-14 19:25:21 +08001809 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
1810 -1 /* no realCallingPid */, -1 /* no realCallingUid */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001811 }
1812
1813 /**
1814 * Returns the right stack to use for launching factoring in all the input parameters.
1815 *
1816 * @param r The activity we are trying to launch. Can be null.
1817 * @param options The activity options used to the launch. Can be null.
1818 * @param candidateTask The possible task the activity might be launched in. Can be null.
lumarkf65e02d2019-09-14 19:25:21 +08001819 * @param launchParams The resolved launch params to use.
1820 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
1821 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
Wale Ogunwaled32da472018-11-16 07:19:28 -08001822 *
1823 * @return The stack to use for the launch or INVALID_STACK_ID.
1824 */
Wale Ogunwale8577a052019-10-26 23:22:34 -07001825 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001826 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
lumarkf65e02d2019-09-14 19:25:21 +08001827 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
1828 int realCallingUid) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001829 int taskId = INVALID_TASK_ID;
1830 int displayId = INVALID_DISPLAY;
1831 //Rect bounds = null;
1832
1833 // We give preference to the launch preference in activity options.
1834 if (options != null) {
1835 taskId = options.getLaunchTaskId();
1836 displayId = options.getLaunchDisplayId();
1837 }
1838
1839 // First preference for stack goes to the task Id set in the activity options. Use the stack
1840 // associated with that if possible.
1841 if (taskId != INVALID_TASK_ID) {
1842 // Temporarily set the task id to invalid in case in re-entry.
1843 options.setLaunchTaskId(INVALID_TASK_ID);
Louis Changcdec0802019-11-11 11:45:07 +08001844 final Task task = anyTaskForId(taskId,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001845 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
1846 options.setLaunchTaskId(taskId);
1847 if (task != null) {
1848 return task.getStack();
1849 }
1850 }
1851
1852 final int activityType = resolveActivityType(r, options, candidateTask);
Wale Ogunwale8577a052019-10-26 23:22:34 -07001853 ActivityStack stack;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001854
1855 // Next preference for stack goes to the display Id set the candidate display.
1856 if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
1857 displayId = launchParams.mPreferredDisplayId;
1858 }
lumarkf65e02d2019-09-14 19:25:21 +08001859 final boolean canLaunchOnDisplayFromStartRequest =
1860 realCallingPid != 0 && realCallingUid > 0 && r != null
1861 && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid,
1862 realCallingUid, r.info);
1863 // Checking if the activity's launch caller, or the realCallerId of the activity from
1864 // start request (i.e. entity that invokes PendingIntent) is allowed to launch on the
1865 // display.
1866 if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
1867 || canLaunchOnDisplayFromStartRequest)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001868 if (r != null) {
Wale Ogunwale8577a052019-10-26 23:22:34 -07001869 stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001870 launchParams);
1871 if (stack != null) {
1872 return stack;
1873 }
1874 }
1875 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
1876 if (display != null) {
1877 stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1878 if (stack != null) {
1879 return stack;
1880 }
1881 }
1882 }
1883
1884 // Give preference to the stack and display of the input task and activity if they match the
1885 // mode we want to launch into.
1886 stack = null;
1887 ActivityDisplay display = null;
1888 if (candidateTask != null) {
1889 stack = candidateTask.getStack();
1890 }
1891 if (stack == null && r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001892 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001893 }
1894 if (stack != null) {
1895 display = stack.getDisplay();
1896 if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) {
1897 int windowingMode = launchParams != null ? launchParams.mWindowingMode
1898 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
1899 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
1900 windowingMode = display.resolveWindowingMode(r, options, candidateTask,
1901 activityType);
1902 }
1903 if (stack.isCompatible(windowingMode, activityType)) {
1904 return stack;
1905 }
1906 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
1907 && display.getSplitScreenPrimaryStack() == stack
1908 && candidateTask == stack.topTask()) {
1909 // This is a special case when we try to launch an activity that is currently on
1910 // top of split-screen primary stack, but is targeting split-screen secondary.
1911 // In this case we don't want to move it to another stack.
1912 // TODO(b/78788972): Remove after differentiating between preferred and required
1913 // launch options.
1914 return stack;
1915 }
1916 }
1917 }
1918
1919 if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) {
1920 display = getDefaultDisplay();
1921 }
1922
1923 return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1924 }
1925
1926 /** @return true if activity record is null or can be launched on provided display. */
1927 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
1928 if (r == null) {
1929 return true;
1930 }
1931 return r.canBeLaunchedOnDisplay(displayId);
1932 }
1933
1934 /**
1935 * Get a topmost stack on the display, that is a valid launch stack for specified activity.
1936 * If there is no such stack, new dynamic stack can be created.
1937 * @param displayId Target display.
1938 * @param r Activity that should be launched there.
1939 * @param candidateTask The possible task the activity might be put in.
1940 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
1941 */
1942 private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001943 @Nullable Task candidateTask, @Nullable ActivityOptions options,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001944 @Nullable LaunchParamsController.LaunchParams launchParams) {
1945 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1946 if (activityDisplay == null) {
1947 throw new IllegalArgumentException(
1948 "Display with displayId=" + displayId + " not found.");
1949 }
1950
1951 if (!r.canBeLaunchedOnDisplay(displayId)) {
1952 return null;
1953 }
1954
1955 // If {@code r} is already in target display and its task is the same as the candidate task,
1956 // the intention should be getting a launch stack for the reusable activity, so we can use
1957 // the existing stack.
Louis Changcdec0802019-11-11 11:45:07 +08001958 if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
Louis Changf3070c52019-10-09 15:57:30 +08001959 final int attachedDisplayId = r.getDisplayId();
1960 if (attachedDisplayId == INVALID_DISPLAY || attachedDisplayId == displayId) {
1961 return candidateTask.getStack();
1962 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001963 }
1964
Louis Chang6fb1e842018-12-03 16:07:50 +08001965 int windowingMode;
1966 if (launchParams != null) {
1967 // When launch params is not null, we always defer to its windowing mode. Sometimes
1968 // it could be unspecified, which indicates it should inherit windowing mode from
1969 // display.
1970 windowingMode = launchParams.mWindowingMode;
1971 } else {
1972 windowingMode = options != null ? options.getLaunchWindowingMode()
1973 : r.getWindowingMode();
1974 }
1975 windowingMode = activityDisplay.validateWindowingMode(windowingMode, r, candidateTask,
1976 r.getActivityType());
1977
Wale Ogunwaled32da472018-11-16 07:19:28 -08001978 // Return the topmost valid stack on the display.
Louis Chang2453d062019-11-19 22:30:48 +08001979 for (int i = activityDisplay.getStackCount() - 1; i >= 0; --i) {
1980 final ActivityStack stack = activityDisplay.getStackAt(i);
Louis Chang6fb1e842018-12-03 16:07:50 +08001981 if (isValidLaunchStack(stack, r, windowingMode)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001982 return stack;
1983 }
1984 }
1985
1986 // If there is no valid stack on the external display - check if new dynamic stack will do.
1987 if (displayId != DEFAULT_DISPLAY) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001988 final int activityType =
1989 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
1990 ? options.getLaunchActivityType() : r.getActivityType();
1991 return activityDisplay.createStack(windowingMode, activityType, true /*onTop*/);
1992 }
1993
Wale Ogunwaled32da472018-11-16 07:19:28 -08001994 return null;
1995 }
1996
1997 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
1998 @Nullable ActivityOptions options,
1999 @Nullable LaunchParamsController.LaunchParams launchParams) {
2000 return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options,
2001 launchParams);
2002 }
2003
2004 // TODO: Can probably be consolidated into getLaunchStack()...
Louis Chang6fb1e842018-12-03 16:07:50 +08002005 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002006 switch (stack.getActivityType()) {
2007 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
2008 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
2009 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
2010 }
2011 // There is a 1-to-1 relationship between stack and task when not in
2012 // primary split-windowing mode.
Louis Chang6fb1e842018-12-03 16:07:50 +08002013 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
2014 && r.supportsSplitScreenWindowingMode()
2015 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
2016 || windowingMode == WINDOWING_MODE_UNDEFINED)) {
2017 return true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002018 }
Louis Chang6fb1e842018-12-03 16:07:50 +08002019 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002020 }
2021
2022 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
Louis Changcdec0802019-11-11 11:45:07 +08002023 @Nullable Task task) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002024 // Preference is given to the activity type for the activity then the task since the type
2025 // once set shouldn't change.
2026 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
2027 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
2028 activityType = task.getActivityType();
2029 }
2030 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
2031 return activityType;
2032 }
2033 if (options != null) {
2034 activityType = options.getLaunchActivityType();
2035 }
2036 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
2037 }
2038
2039 /**
2040 * Get next focusable stack in the system. This will search through the stack on the same
2041 * display as the current focused stack, looking for a focusable and visible stack, different
2042 * from the target stack. If no valid candidates will be found, it will then go through all
2043 * displays and stacks in last-focused order.
2044 *
2045 * @param currentFocus The stack that previously had focus.
2046 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
2047 * candidate.
2048 * @return Next focusable {@link ActivityStack}, {@code null} if not found.
2049 */
2050 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
2051 boolean ignoreCurrent) {
2052 // First look for next focusable stack on the same display
Wale Ogunwale2322bed2019-10-10 17:24:19 +02002053 ActivityDisplay preferredDisplay = currentFocus.getDisplay();
2054 if (preferredDisplay == null) {
2055 // Stack is currently detached because it is being removed. Use the previous display it
2056 // was on.
2057 preferredDisplay = getActivityDisplay(currentFocus.mPrevDisplayId);
2058 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08002059 final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
2060 currentFocus, ignoreCurrent);
2061 if (preferredFocusableStack != null) {
2062 return preferredFocusableStack;
2063 }
2064 if (preferredDisplay.supportsSystemDecorations()) {
2065 // Stop looking for focusable stack on other displays because the preferred display
2066 // supports system decorations. Home activity would be launched on the same display if
2067 // no focusable stack found.
2068 return null;
2069 }
2070
2071 // Now look through all displays
2072 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2073 final ActivityDisplay display = mActivityDisplays.get(i);
2074 if (display == preferredDisplay) {
2075 // We've already checked this one
2076 continue;
2077 }
2078 final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
2079 ignoreCurrent);
2080 if (nextFocusableStack != null) {
2081 return nextFocusableStack;
2082 }
2083 }
2084
2085 return null;
2086 }
2087
2088 /**
2089 * Get next valid stack for launching provided activity in the system. This will search across
2090 * displays and stacks in last-focused order for a focusable and visible stack, except those
2091 * that are on a currently focused display.
2092 *
2093 * @param r The activity that is being launched.
2094 * @param currentFocus The display that previously had focus and thus needs to be ignored when
2095 * searching for the next candidate.
2096 * @return Next valid {@link ActivityStack}, null if not found.
2097 */
2098 ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) {
2099 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2100 final ActivityDisplay display = mActivityDisplays.get(i);
2101 if (display.mDisplayId == currentFocus) {
2102 continue;
2103 }
2104 final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r,
2105 null /* options */, null /* launchParams */);
2106 if (stack != null) {
2107 return stack;
2108 }
2109 }
2110 return null;
2111 }
2112
2113 boolean handleAppDied(WindowProcessController app) {
2114 boolean hasVisibleActivities = false;
2115 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2116 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002117 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2118 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002119 hasVisibleActivities |= stack.handleAppDiedLocked(app);
2120 }
2121 }
2122 return hasVisibleActivities;
2123 }
2124
2125 void closeSystemDialogs() {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002126 mRootWindowContainer.forAllActivities((r) -> {
2127 if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
2128 r.finishIfPossible("close-sys", true /* oomAdj */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002129 }
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002130 });
2131 }
2132
2133 FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
2134 new FinishDisabledPackageActivitiesHelper();
2135 class FinishDisabledPackageActivitiesHelper {
2136 private boolean mDidSomething;
2137 private String mPackageName;
2138 private Set<String> mFilterByClasses;
2139 private boolean mDoit;
2140 private boolean mEvenPersistent;
2141 private int mUserId;
2142 private Task mLastTask;
2143 private ComponentName mHomeActivity;
2144
2145 private void reset(String packageName, Set<String> filterByClasses,
2146 boolean doit, boolean evenPersistent, int userId) {
2147 mDidSomething = false;
2148 mPackageName = packageName;
2149 mFilterByClasses = filterByClasses;
2150 mDoit = doit;
2151 mEvenPersistent = evenPersistent;
2152 mUserId = userId;
2153 mLastTask = null;
2154 mHomeActivity = null;
2155 }
2156
2157 boolean process(String packageName, Set<String> filterByClasses,
2158 boolean doit, boolean evenPersistent, int userId) {
2159 reset(packageName, filterByClasses, doit, evenPersistent, userId);
2160
2161 final PooledFunction f = PooledLambda.obtainFunction(
2162 FinishDisabledPackageActivitiesHelper::processActivity, this,
2163 PooledLambda.__(ActivityRecord.class));
2164 mRootWindowContainer.forAllActivities(f);
2165 f.recycle();
2166 return mDidSomething;
2167 }
2168
2169 private boolean processActivity(ActivityRecord r) {
2170 final boolean sameComponent =
2171 (r.packageName.equals(mPackageName) && (mFilterByClasses == null
2172 || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
2173 || (mPackageName == null && r.mUserId == mUserId);
2174 if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
2175 && (sameComponent || r.getTask() == mLastTask)
2176 && (r.app == null || mEvenPersistent || !r.app.isPersistent())) {
2177 if (!mDoit) {
2178 if (r.finishing) {
2179 // If this activity is just finishing, then it is not
2180 // interesting as far as something to stop.
2181 return false;
2182 }
2183 return true;
2184 }
2185 if (r.isActivityTypeHome()) {
2186 if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) {
2187 Slog.i(TAG, "Skip force-stop again " + r);
2188 return false;
2189 } else {
2190 mHomeActivity = r.mActivityComponent;
2191 }
2192 }
2193 mDidSomething = true;
2194 Slog.i(TAG, " Force finishing activity " + r);
2195 mLastTask = r.getTask();
2196 r.finishIfPossible("force-stop", true);
2197 }
2198
2199 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002200 }
2201 }
2202
2203 /** @return true if some activity was finished (or would have finished if doit were true). */
2204 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
2205 boolean doit, boolean evenPersistent, int userId) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002206 return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
2207 evenPersistent, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002208 }
2209
2210 void updateActivityApplicationInfo(ApplicationInfo aInfo) {
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002211 final String packageName = aInfo.packageName;
2212 final int userId = UserHandle.getUserId(aInfo.uid);
2213 final PooledConsumer c = PooledLambda.obtainConsumer(
2214 RootActivityContainer::updateActivityApplicationInfo,
2215 PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName);
2216 mRootWindowContainer.forAllActivities(c);
2217 c.recycle();
2218 }
2219
2220 private static void updateActivityApplicationInfo(
2221 ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName) {
2222 if (r.mUserId == userId && packageName.equals(r.packageName)) {
2223 r.updateApplicationInfo(aInfo);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002224 }
2225 }
2226
2227 void finishVoiceTask(IVoiceInteractionSession session) {
2228 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2229 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002230 final int numStacks = display.getStackCount();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002231 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Louis Chang2453d062019-11-19 22:30:48 +08002232 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002233 stack.finishVoiceTask(session);
2234 }
2235 }
2236 }
2237
2238 /**
2239 * Removes stacks in the input windowing modes from the system if they are of activity type
2240 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2241 */
2242 void removeStacksInWindowingModes(int... windowingModes) {
2243 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2244 mActivityDisplays.get(i).removeStacksInWindowingModes(windowingModes);
2245 }
2246 }
2247
2248 void removeStacksWithActivityTypes(int... activityTypes) {
2249 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2250 mActivityDisplays.get(i).removeStacksWithActivityTypes(activityTypes);
2251 }
2252 }
2253
2254 ActivityRecord topRunningActivity() {
2255 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2256 final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
2257 if (topActivity != null) {
2258 return topActivity;
2259 }
2260 }
2261 return null;
2262 }
2263
2264 boolean allResumedActivitiesIdle() {
2265 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2266 // TODO(b/117135575): Check resumed activities on all visible stacks.
2267 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2268 if (display.isSleeping()) {
2269 // No resumed activities while display is sleeping.
2270 continue;
2271 }
2272
2273 // If the focused stack is not null or not empty, there should have some activities
2274 // resuming or resumed. Make sure these activities are idle.
2275 final ActivityStack stack = display.getFocusedStack();
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002276 if (stack == null || !stack.hasActivity()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002277 continue;
2278 }
2279 final ActivityRecord resumedActivity = stack.getResumedActivity();
2280 if (resumedActivity == null || !resumedActivity.idle) {
2281 if (DEBUG_STATES) {
2282 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
2283 + stack.mStackId + " " + resumedActivity + " not idle");
2284 }
2285 return false;
2286 }
2287 }
2288 // Send launch end powerhint when idle
2289 sendPowerHintForLaunchEndIfNeeded();
2290 return true;
2291 }
2292
2293 boolean allResumedActivitiesVisible() {
2294 boolean foundResumed = false;
2295 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2296 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002297 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2298 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002299 final ActivityRecord r = stack.getResumedActivity();
2300 if (r != null) {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002301 if (!r.nowVisible) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002302 return false;
2303 }
2304 foundResumed = true;
2305 }
2306 }
2307 }
2308 return foundResumed;
2309 }
2310
2311 boolean allPausedActivitiesComplete() {
2312 boolean pausing = true;
2313 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2314 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002315 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2316 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002317 final ActivityRecord r = stack.mPausingActivity;
2318 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
2319 if (DEBUG_STATES) {
2320 Slog.d(TAG_STATES,
2321 "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
2322 pausing = false;
2323 } else {
2324 return false;
2325 }
2326 }
2327 }
2328 }
2329 return pausing;
2330 }
2331
2332 /**
2333 * Find all visible task stacks containing {@param userId} and intercept them with an activity
2334 * to block out the contents and possibly start a credential-confirming intent.
2335 *
2336 * @param userId user handle for the locked managed profile.
2337 */
2338 void lockAllProfileTasks(@UserIdInt int userId) {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002339 mService.deferWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002340 try {
2341 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2342 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002343 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2344 final ActivityStack stack = display.getStackAt(stackNdx);
Louis Changcdec0802019-11-11 11:45:07 +08002345 final List<Task> tasks = stack.getAllTasks();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002346 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
Louis Changcdec0802019-11-11 11:45:07 +08002347 final Task task = tasks.get(taskNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002348
2349 // Check the task for a top activity belonging to userId, or returning a
2350 // result to an activity belonging to userId. Example case: a document
2351 // picker for personal files, opened by a work app, should still get locked.
2352 if (taskTopActivityIsUser(task, userId)) {
2353 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07002354 task.mTaskId, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002355 }
2356 }
2357 }
2358 }
2359 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002360 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002361 }
2362 }
2363
2364 /**
2365 * Detects whether we should show a lock screen in front of this task for a locked user.
2366 * <p>
2367 * We'll do this if either of the following holds:
2368 * <ul>
2369 * <li>The top activity explicitly belongs to {@param userId}.</li>
2370 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
2371 * </ul>
2372 *
2373 * @return {@code true} if the top activity looks like it belongs to {@param userId}.
2374 */
Louis Changcdec0802019-11-11 11:45:07 +08002375 private boolean taskTopActivityIsUser(Task task, @UserIdInt int userId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002376 // 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 -08002377 final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002378 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
2379
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002380 return (activityRecord != null && activityRecord.mUserId == userId)
2381 || (resultTo != null && resultTo.mUserId == userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002382 }
2383
2384 void cancelInitializingActivities() {
2385 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2386 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002387 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2388 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002389 stack.cancelInitializingActivities();
2390 }
2391 }
2392 }
2393
Louis Changcdec0802019-11-11 11:45:07 +08002394 Task anyTaskForId(int id) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002395 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
2396 }
2397
Louis Changcdec0802019-11-11 11:45:07 +08002398 Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002399 return anyTaskForId(id, matchMode, null, !ON_TOP);
2400 }
2401
2402 /**
Louis Changcdec0802019-11-11 11:45:07 +08002403 * Returns a {@link Task} for the input id if available. {@code null} otherwise.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002404 * @param id Id of the task we would like returned.
2405 * @param matchMode The mode to match the given task id in.
2406 * @param aOptions The activity options to use for restoration. Can be null.
2407 * @param onTop If the stack for the task should be the topmost on the display.
2408 */
Louis Changcdec0802019-11-11 11:45:07 +08002409 Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode,
Wale Ogunwaled32da472018-11-16 07:19:28 -08002410 @Nullable ActivityOptions aOptions, boolean onTop) {
2411 // If options are set, ensure that we are attempting to actually restore a task
2412 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
2413 throw new IllegalArgumentException("Should not specify activity options for non-restore"
2414 + " lookup");
2415 }
2416
2417 int numDisplays = mActivityDisplays.size();
2418 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2419 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002420 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2421 final ActivityStack stack = display.getStackAt(stackNdx);
Louis Changcdec0802019-11-11 11:45:07 +08002422 final Task task = stack.taskForIdLocked(id);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002423 if (task == null) {
2424 continue;
2425 }
2426 if (aOptions != null) {
2427 // Resolve the stack the task should be placed in now based on options
2428 // and reparent if needed.
2429 final ActivityStack launchStack =
2430 getLaunchStack(null, aOptions, task, onTop);
2431 if (launchStack != null && stack != launchStack) {
2432 final int reparentMode = onTop
2433 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
2434 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
2435 "anyTaskForId");
2436 }
2437 }
2438 return task;
2439 }
2440 }
2441
2442 // If we are matching stack tasks only, return now
2443 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
2444 return null;
2445 }
2446
2447 // Otherwise, check the recent tasks and return if we find it there and we are not restoring
2448 // the task from recents
2449 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
Louis Changcdec0802019-11-11 11:45:07 +08002450 final Task task = mStackSupervisor.mRecentTasks.getTask(id);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002451
2452 if (task == null) {
2453 if (DEBUG_RECENTS) {
2454 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
2455 }
2456
2457 return null;
2458 }
2459
2460 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
2461 return task;
2462 }
2463
2464 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
2465 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
2466 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
2467 "Couldn't restore task id=" + id + " found in recents");
2468 return null;
2469 }
2470 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
2471 return task;
2472 }
2473
2474 ActivityRecord isInAnyStack(IBinder token) {
2475 int numDisplays = mActivityDisplays.size();
2476 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2477 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002478 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2479 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002480 final ActivityRecord r = stack.isInStackLocked(token);
2481 if (r != null) {
2482 return r;
2483 }
2484 }
2485 }
2486 return null;
2487 }
2488
2489 @VisibleForTesting
2490 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
2491 @WindowConfiguration.ActivityType int ignoreActivityType,
2492 @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -07002493 boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -07002494 mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -07002495 ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser, profileIds);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002496 }
2497
2498 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
2499 boolean sendHint = forceSend;
2500
2501 if (!sendHint) {
2502 // Send power hint if we don't know what we're launching yet
2503 sendHint = targetActivity == null || targetActivity.app == null;
2504 }
2505
2506 if (!sendHint) { // targetActivity != null
2507 // Send power hint when the activity's process is different than the current resumed
2508 // activity on all displays, or if there are no resumed activities in the system.
2509 boolean noResumedActivities = true;
2510 boolean allFocusedProcessesDiffer = true;
2511 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2512 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2513 final ActivityRecord resumedActivity = activityDisplay.getResumedActivity();
2514 final WindowProcessController resumedActivityProcess =
2515 resumedActivity == null ? null : resumedActivity.app;
2516
2517 noResumedActivities &= resumedActivityProcess == null;
2518 if (resumedActivityProcess != null) {
2519 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
2520 }
2521 }
2522 sendHint = noResumedActivities || allFocusedProcessesDiffer;
2523 }
2524
2525 if (sendHint && mService.mPowerManagerInternal != null) {
2526 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
2527 mPowerHintSent = true;
2528 }
2529 }
2530
2531 void sendPowerHintForLaunchEndIfNeeded() {
2532 // Trigger launch power hint if activity is launched
2533 if (mPowerHintSent && mService.mPowerManagerInternal != null) {
2534 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
2535 mPowerHintSent = false;
2536 }
2537 }
2538
2539 private void calculateDefaultMinimalSizeOfResizeableTasks() {
2540 final Resources res = mService.mContext.getResources();
2541 final float minimalSize = res.getDimension(
2542 com.android.internal.R.dimen.default_minimal_size_resizable_task);
2543 final DisplayMetrics dm = res.getDisplayMetrics();
2544
2545 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
2546 }
2547
2548 /**
2549 * Dumps the activities matching the given {@param name} in the either the focused stack
2550 * or all visible stacks if {@param dumpVisibleStacks} is true.
2551 */
2552 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
2553 boolean dumpFocusedStackOnly) {
2554 if (dumpFocusedStackOnly) {
2555 return getTopDisplayFocusedStack().getDumpActivitiesLocked(name);
2556 } else {
2557 ArrayList<ActivityRecord> activities = new ArrayList<>();
2558 int numDisplays = mActivityDisplays.size();
2559 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2560 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002561 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2562 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002563 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
2564 activities.addAll(stack.getDumpActivitiesLocked(name));
2565 }
2566 }
2567 }
2568 return activities;
2569 }
2570 }
2571
2572 public void dump(PrintWriter pw, String prefix) {
2573 pw.print(prefix);
2574 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
2575 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2576 final ActivityDisplay display = mActivityDisplays.get(i);
2577 display.dump(pw, prefix);
2578 }
2579 }
2580
2581 /**
2582 * Dump all connected displays' configurations.
2583 * @param prefix Prefix to apply to each line of the dump.
2584 */
2585 void dumpDisplayConfigs(PrintWriter pw, String prefix) {
2586 pw.print(prefix); pw.println("Display override configurations:");
2587 final int displayCount = mActivityDisplays.size();
2588 for (int i = 0; i < displayCount; i++) {
2589 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
2590 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": ");
Evan Roskydfe3da72018-10-26 17:21:06 -07002591 pw.println(activityDisplay.getRequestedOverrideConfiguration());
Wale Ogunwaled32da472018-11-16 07:19:28 -08002592 }
2593 }
2594
2595 public void dumpDisplays(PrintWriter pw) {
2596 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2597 final ActivityDisplay display = mActivityDisplays.get(i);
2598 pw.print("[id:" + display.mDisplayId + " stacks:");
2599 display.dumpStacks(pw);
2600 pw.print("]");
2601 }
2602 }
2603
2604 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
2605 String dumpPackage) {
2606 boolean printed = false;
2607 boolean needSep = false;
2608 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2609 ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2610 pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
2611 pw.println(" (activities from top to bottom):");
2612 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang2453d062019-11-19 22:30:48 +08002613 for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2614 final ActivityStack stack = display.getStackAt(stackNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002615 pw.println();
Garfield Tan347bd602018-12-21 15:11:12 -08002616 printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002617 needSep = printed;
2618 }
2619 printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep,
2620 " ResumedActivity:");
2621 }
2622
2623 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ",
2624 "Fin", false, !dumpAll,
2625 false, dumpPackage, true, " Activities waiting to finish:", null);
2626 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
2627 "Stop", false, !dumpAll,
2628 false, dumpPackage, true, " Activities waiting to stop:", null);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002629 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
2630 " ", "Sleep", false, !dumpAll,
2631 false, dumpPackage, true, " Activities waiting to sleep:", null);
2632
2633 return printed;
2634 }
2635
Jeffrey Huangcb782852019-12-05 11:28:11 -08002636 protected void dumpDebug(ProtoOutputStream proto, long fieldId,
Nataniel Borges023ecb52019-01-16 14:15:43 -08002637 @WindowTraceLogLevel int logLevel) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002638 final long token = proto.start(fieldId);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002639 super.dumpDebug(proto, CONFIGURATION_CONTAINER, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002640 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2641 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002642 activityDisplay.dumpDebug(proto, DISPLAYS, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002643 }
Jeffrey Huangcb782852019-12-05 11:28:11 -08002644 mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002645 // TODO(b/111541062): Update tests to look for resumed activities on all displays
2646 final ActivityStack focusedStack = getTopDisplayFocusedStack();
2647 if (focusedStack != null) {
2648 proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
2649 final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
2650 if (focusedActivity != null) {
2651 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
2652 }
2653 } else {
2654 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
2655 }
2656 proto.write(IS_HOME_RECENTS_COMPONENT,
2657 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
Jeffrey Huangcb782852019-12-05 11:28:11 -08002658 mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002659 proto.end(token);
2660 }
2661
2662 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
2663 private final String mTag;
2664 private final long mAcquireTime;
2665 private final int mDisplayId;
2666
2667 public SleepTokenImpl(String tag, int displayId) {
2668 mTag = tag;
2669 mDisplayId = displayId;
2670 mAcquireTime = SystemClock.uptimeMillis();
2671 }
2672
2673 @Override
2674 public void release() {
2675 synchronized (mService.mGlobalLock) {
2676 removeSleepToken(this);
2677 }
2678 }
2679
2680 @Override
2681 public String toString() {
2682 return "{\"" + mTag + "\", display " + mDisplayId
2683 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
2684 }
2685 }
2686}