blob: 698835772df50fbd5197b9002d877da7b571f0d5 [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;
30import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
31import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwaled32da472018-11-16 07:19:28 -080032import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
33import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
34import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
35import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
36import static android.view.Display.DEFAULT_DISPLAY;
37import static android.view.Display.INVALID_DISPLAY;
38
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;
52import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
53import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
54import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
55import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
56import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
57import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
58import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
59import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
60import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
61import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
62import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
63import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
64import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
65import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
66import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
67import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
68import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
69
70import static java.lang.Integer.MAX_VALUE;
71
72import android.annotation.IntDef;
73import android.annotation.NonNull;
74import android.annotation.Nullable;
75import android.annotation.UserIdInt;
76import android.app.ActivityManager;
77import android.app.ActivityOptions;
78import android.app.AppGlobals;
79import android.app.WindowConfiguration;
80import android.content.ComponentName;
81import android.content.Intent;
82import android.content.pm.ActivityInfo;
83import android.content.pm.ApplicationInfo;
84import android.content.pm.ResolveInfo;
85import android.content.res.Configuration;
86import android.content.res.Resources;
87import android.graphics.Rect;
88import android.hardware.display.DisplayManager;
89import android.hardware.display.DisplayManagerInternal;
90import android.hardware.power.V1_0.PowerHint;
Wale Ogunwaled32da472018-11-16 07:19:28 -080091import android.os.FactoryTest;
92import android.os.IBinder;
93import android.os.RemoteException;
94import android.os.SystemClock;
95import android.os.Trace;
96import android.os.UserHandle;
Chilun2ef71f72018-11-16 17:57:15 +080097import android.provider.Settings;
Wale Ogunwaled32da472018-11-16 07:19:28 -080098import android.service.voice.IVoiceInteractionSession;
99import android.util.ArraySet;
100import android.util.DisplayMetrics;
101import android.util.IntArray;
Chilun2ef71f72018-11-16 17:57:15 +0800102import android.util.Pair;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800103import android.util.Slog;
104import android.util.SparseArray;
105import android.util.SparseIntArray;
106import android.util.TimeUtils;
107import android.util.proto.ProtoOutputStream;
108import android.view.Display;
109import android.view.DisplayInfo;
110
111import com.android.internal.annotations.VisibleForTesting;
Chilun2ef71f72018-11-16 17:57:15 +0800112import com.android.internal.app.ResolverActivity;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800113import com.android.server.LocalServices;
114import com.android.server.am.ActivityManagerService;
115import com.android.server.am.AppTimeTracker;
116import com.android.server.am.UserState;
117
118import java.io.FileDescriptor;
119import java.io.PrintWriter;
120import java.lang.annotation.Retention;
121import java.lang.annotation.RetentionPolicy;
122import java.util.ArrayList;
123import java.util.Iterator;
124import java.util.List;
125import java.util.Set;
126
127/**
128 * Root node for activity containers.
129 * TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
130 * intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
131 */
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800132class RootActivityContainer extends ConfigurationContainer
133 implements DisplayManager.DisplayListener {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800134
135 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootActivityContainer" : TAG_ATM;
136 static final String TAG_TASKS = TAG + POSTFIX_TASKS;
137 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
138 static final String TAG_STATES = TAG + POSTFIX_STATES;
139 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
140
141 /**
142 * The modes which affect which tasks are returned when calling
143 * {@link RootActivityContainer#anyTaskForId(int)}.
144 */
145 @Retention(RetentionPolicy.SOURCE)
146 @IntDef({
147 MATCH_TASK_IN_STACKS_ONLY,
148 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
149 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
150 })
151 public @interface AnyTaskForIdMatchTaskMode {}
152 // Match only tasks in the current stacks
153 static final int MATCH_TASK_IN_STACKS_ONLY = 0;
154 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
155 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
156 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
157 // provided stack id
158 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
159
160 ActivityTaskManagerService mService;
161 ActivityStackSupervisor mStackSupervisor;
162 WindowManagerService mWindowManager;
163 DisplayManager mDisplayManager;
164 private DisplayManagerInternal mDisplayManagerInternal;
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800165 // TODO: Remove after object merge with RootWindowContainer.
166 private RootWindowContainer mRootWindowContainer;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800167
168 /**
169 * List of displays which contain activities, sorted by z-order.
170 * The last entry in the list is the topmost.
171 */
172 private final ArrayList<ActivityDisplay> mActivityDisplays = new ArrayList<>();
173
174 /** Reference to default display so we can quickly look it up. */
175 private ActivityDisplay mDefaultDisplay;
176 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
177
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800178 /**
179 * Cached value of the topmost resumed activity in the system. Updated when new activity is
180 * resumed.
181 */
182 private ActivityRecord mTopResumedActivity;
183
Wale Ogunwaled32da472018-11-16 07:19:28 -0800184 /** 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
202 // The default minimal size that will be used if the activity doesn't specify its minimal size.
203 // It will be calculated when the default display gets added.
204 int mDefaultMinSizeOfResizeableTaskDp = -1;
205
206 // Whether tasks have moved and we need to rank the tasks before next OOM scoring
207 private boolean mTaskLayersChanged = true;
208
209 private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
210
211 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
212 static class FindTaskResult {
213 ActivityRecord mRecord;
214 boolean mIdealMatch;
215
216 void clear() {
217 mRecord = null;
218 mIdealMatch = false;
219 }
220
221 void setTo(FindTaskResult result) {
222 mRecord = result.mRecord;
223 mIdealMatch = result.mIdealMatch;
224 }
225 }
226
227 RootActivityContainer(ActivityTaskManagerService service) {
228 mService = service;
229 mStackSupervisor = service.mStackSupervisor;
230 mStackSupervisor.mRootActivityContainer = this;
231 }
232
233 @VisibleForTesting
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800234 void setWindowContainer(RootWindowContainer container) {
235 mRootWindowContainer = container;
236 mRootWindowContainer.setRootActivityContainer(this);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800237 }
238
239 void setWindowManager(WindowManagerService wm) {
240 mWindowManager = wm;
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800241 setWindowContainer(mWindowManager.mRoot);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800242 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
Charles Chen699e3602019-01-10 15:00:25 +0800243 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800244 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
245
246 final Display[] displays = mDisplayManager.getDisplays();
247 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
248 final Display display = displays[displayNdx];
249 final ActivityDisplay activityDisplay = new ActivityDisplay(this, display);
250 if (activityDisplay.mDisplayId == DEFAULT_DISPLAY) {
251 mDefaultDisplay = activityDisplay;
252 }
253 addChild(activityDisplay, ActivityDisplay.POSITION_TOP);
254 }
255 calculateDefaultMinimalSizeOfResizeableTasks();
256
257 final ActivityDisplay defaultDisplay = getDefaultDisplay();
258
259 defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
260 positionChildAt(defaultDisplay, ActivityDisplay.POSITION_TOP);
261 }
262
263 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
264 ActivityDisplay getDefaultDisplay() {
265 return mDefaultDisplay;
266 }
267
268 /**
269 * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is
270 * defined in {@link DisplayInfo#uniqueId}.
271 *
272 * @param uniqueId the unique ID of the display
273 * @return the {@link ActivityDisplay} or {@code null} if nothing is found.
274 */
275 ActivityDisplay getActivityDisplay(String uniqueId) {
276 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
277 final ActivityDisplay display = mActivityDisplays.get(i);
278 final boolean isValid = display.mDisplay.isValid();
279 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
280 return display;
281 }
282 }
283
284 return null;
285 }
286
287 // TODO: Look into consolidating with getActivityDisplayOrCreate()
288 ActivityDisplay getActivityDisplay(int displayId) {
289 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
290 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
291 if (activityDisplay.mDisplayId == displayId) {
292 return activityDisplay;
293 }
294 }
295 return null;
296 }
297
298 /**
299 * Get an existing instance of {@link ActivityDisplay} or create new if there is a
300 * corresponding record in display manager.
301 */
302 // TODO: Look into consolidating with getActivityDisplay()
Charles Chenb409e6c2019-02-12 12:30:17 +0800303 @Nullable ActivityDisplay getActivityDisplayOrCreate(int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800304 ActivityDisplay activityDisplay = getActivityDisplay(displayId);
305 if (activityDisplay != null) {
306 return activityDisplay;
307 }
308 if (mDisplayManager == null) {
309 // The system isn't fully initialized yet.
310 return null;
311 }
312 final Display display = mDisplayManager.getDisplay(displayId);
313 if (display == null) {
314 // The display is not registered in DisplayManager.
315 return null;
316 }
317 // The display hasn't been added to ActivityManager yet, create a new record now.
318 activityDisplay = new ActivityDisplay(this, display);
319 addChild(activityDisplay, ActivityDisplay.POSITION_BOTTOM);
320 return activityDisplay;
321 }
322
323 /** Check if display with specified id is added to the list. */
324 boolean isDisplayAdded(int displayId) {
325 return getActivityDisplayOrCreate(displayId) != null;
326 }
327
328 ActivityRecord getDefaultDisplayHomeActivity() {
329 return getDefaultDisplayHomeActivityForUser(mCurrentUser);
330 }
331
332 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
333 return getActivityDisplay(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
334 }
335
336 boolean startHomeOnAllDisplays(int userId, String reason) {
337 boolean homeStarted = false;
338 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
339 final int displayId = mActivityDisplays.get(i).mDisplayId;
340 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
341 }
342 return homeStarted;
343 }
344
Louis Changdcdde952018-12-04 15:38:44 +0800345 void startHomeOnEmptyDisplays(String reason) {
346 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
347 final ActivityDisplay display = mActivityDisplays.get(i);
348 if (display.topRunningActivity() == null) {
349 startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
350 }
351 }
352 }
353
Wale Ogunwaled32da472018-11-16 07:19:28 -0800354 /**
Chilun2ef71f72018-11-16 17:57:15 +0800355 * This starts home activity on displays that can have system decorations based on displayId -
356 * Default display always use primary home component.
357 * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
358 * according to the priorities listed below.
359 * - If default home is not set, always use the secondary home defined in the config.
360 * - Use currently selected primary home activity.
361 * - Use the activity in the same package as currently selected primary home activity.
362 * If there are multiple activities matched, use first one.
363 * - Use the secondary home defined in the config.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800364 */
365 boolean startHomeOnDisplay(int userId, String reason, int displayId) {
Chilun2ef71f72018-11-16 17:57:15 +0800366 Intent homeIntent;
367 ActivityInfo aInfo;
368 if (displayId == DEFAULT_DISPLAY) {
369 homeIntent = mService.getHomeIntent();
370 aInfo = resolveHomeActivity(userId, homeIntent);
371 } else {
372 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
373 aInfo = info.first;
374 homeIntent = info.second;
375 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800376 if (aInfo == null) {
377 return false;
378 }
379
Chilun2ef71f72018-11-16 17:57:15 +0800380 if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800381 return false;
382 }
383
Chilun2ef71f72018-11-16 17:57:15 +0800384 // Updates the home component of the intent.
385 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
386 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800387 // Update the reason for ANR debugging to verify if the user activity is the one that
388 // actually launched.
389 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
Chilun2ef71f72018-11-16 17:57:15 +0800390 aInfo.applicationInfo.uid) + ":" + displayId;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800391 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
392 displayId);
393 return true;
394 }
395
396 /**
Chilun2ef71f72018-11-16 17:57:15 +0800397 * This resolves the home activity info.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800398 * @return the home activity info if any.
399 */
Chilun2ef71f72018-11-16 17:57:15 +0800400 @VisibleForTesting
401 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800402 final int flags = ActivityManagerService.STOCK_PM_FLAGS;
403 final ComponentName comp = homeIntent.getComponent();
404 ActivityInfo aInfo = null;
405 try {
406 if (comp != null) {
407 // Factory test.
408 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
409 } else {
410 final String resolvedType =
411 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
412 final ResolveInfo info = AppGlobals.getPackageManager()
413 .resolveIntent(homeIntent, resolvedType, flags, userId);
414 if (info != null) {
415 aInfo = info.activityInfo;
416 }
417 }
418 } catch (RemoteException e) {
419 // ignore
420 }
421
422 if (aInfo == null) {
423 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
424 return null;
425 }
426
Wale Ogunwaled32da472018-11-16 07:19:28 -0800427 aInfo = new ActivityInfo(aInfo);
428 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800429 return aInfo;
430 }
431
Chilun2ef71f72018-11-16 17:57:15 +0800432 @VisibleForTesting
433 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) {
434 if (displayId == DEFAULT_DISPLAY) {
435 throw new IllegalArgumentException(
436 "resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY");
437 }
438 // Resolve activities in the same package as currently selected primary home activity.
439 Intent homeIntent = mService.getHomeIntent();
440 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
441 if (aInfo != null) {
442 if (ResolverActivity.class.getName().equals(aInfo.name)) {
443 // Always fallback to secondary home component if default home is not set.
444 aInfo = null;
445 } else {
446 // Look for secondary home activities in the currently selected default home
447 // package.
448 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
449 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
450 final int size = resolutions.size();
451 final String targetName = aInfo.name;
452 aInfo = null;
453 for (int i = 0; i < size; i++) {
454 ResolveInfo resolveInfo = resolutions.get(i);
455 // We need to traverse all resolutions to check if the currently selected
456 // default home activity is present.
457 if (resolveInfo.activityInfo.name.equals(targetName)) {
458 aInfo = resolveInfo.activityInfo;
459 break;
460 }
461 }
462 if (aInfo == null && size > 0) {
463 // First one is the best.
464 aInfo = resolutions.get(0).activityInfo;
465 }
466 }
467 }
468
469 if (aInfo != null) {
470 if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
471 aInfo = null;
472 }
473 }
474
475 // Fallback to secondary home component.
476 if (aInfo == null) {
477 homeIntent = mService.getSecondaryHomeIntent(null);
478 aInfo = resolveHomeActivity(userId, homeIntent);
479 }
480 return Pair.create(aInfo, homeIntent);
481 }
482
483 /**
484 * Retrieve all activities that match the given intent.
485 * The list should already ordered from best to worst matched.
486 * {@link android.content.pm.PackageManager#queryIntentActivities}
487 */
488 @VisibleForTesting
489 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
490 List<ResolveInfo> resolutions;
491 try {
492 final String resolvedType =
493 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
494 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
495 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
496
497 } catch (RemoteException e) {
498 resolutions = new ArrayList<>();
499 }
500 return resolutions;
501 }
502
Wale Ogunwaled32da472018-11-16 07:19:28 -0800503 boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
504 if (!mService.isBooting() && !mService.isBooted()) {
505 // Not ready yet!
506 return false;
507 }
508
509 if (displayId == INVALID_DISPLAY) {
510 displayId = DEFAULT_DISPLAY;
511 }
512
513 final ActivityRecord r = getActivityDisplay(displayId).getHomeActivity();
514 final String myReason = reason + " resumeHomeActivity";
515
516 // Only resume home activity if isn't finishing.
517 if (r != null && !r.finishing) {
518 r.moveFocusableActivityToTop(myReason);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800519 return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800520 }
521 return startHomeOnDisplay(mCurrentUser, myReason, displayId);
522 }
523
524 /**
525 * Check if home activity start should be allowed on a display.
526 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
527 * @param displayId The id of the target display.
528 * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
529 * @return {@code true} if allow to launch, {@code false} otherwise.
530 */
531 boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId,
532 boolean allowInstrumenting) {
533 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
534 && mService.mTopAction == null) {
535 // We are running in factory test mode, but unable to find the factory test app, so
536 // just sit around displaying the error message and don't try to start anything.
537 return false;
538 }
539
540 final WindowProcessController app =
541 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
542 if (!allowInstrumenting && app != null && app.isInstrumenting()) {
543 // Don't do this if the home app is currently being instrumented.
544 return false;
545 }
546
547 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
548 && displayId == mService.mVr2dDisplayId)) {
549 // No restrictions to default display or vr 2d display.
550 return true;
551 }
552
Chilun2ef71f72018-11-16 17:57:15 +0800553 final boolean deviceProvisioned = Settings.Global.getInt(
554 mService.mContext.getContentResolver(),
555 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
556 if (displayId != DEFAULT_DISPLAY && displayId != INVALID_DISPLAY && !deviceProvisioned) {
557 // Can't launch home on secondary display before device is provisioned.
558 return false;
559 }
560
Wale Ogunwaled32da472018-11-16 07:19:28 -0800561 final ActivityDisplay display = getActivityDisplay(displayId);
562 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
563 // Can't launch home on display that doesn't support system decorations.
564 return false;
565 }
566
567 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
Chilun2ef71f72018-11-16 17:57:15 +0800568 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800569 if (!supportMultipleInstance) {
Chilun2ef71f72018-11-16 17:57:15 +0800570 // Can't launch home on secondary displays if it requested to be single instance.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800571 return false;
572 }
573
574 return true;
575 }
576
577 /**
578 * Ensure all activities visibility, update orientation and configuration.
579 *
580 * @param starting The currently starting activity or {@code null} if there is none.
581 * @param displayId The id of the display where operation is executed.
582 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
583 * {@code true} if config changed.
584 * @param deferResume Whether to defer resume while updating config.
585 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
586 * because of configuration update.
587 */
588 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
589 boolean markFrozenIfConfigChanged, boolean deferResume) {
590 // First ensure visibility without updating the config just yet. We need this to know what
591 // activities are affecting configuration now.
592 // Passing null here for 'starting' param value, so that visibility of actual starting
593 // activity will be properly updated.
594 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
595 false /* preserveWindows */, false /* notifyClients */);
596
597 if (displayId == INVALID_DISPLAY) {
598 // The caller didn't provide a valid display id, skip updating config.
599 return true;
600 }
601
602 // Force-update the orientation from the WindowManager, since we need the true configuration
603 // to send to the client now.
Garfield Tan90b04282018-12-11 14:04:42 -0800604 final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId);
605 Configuration config = null;
606 if (displayContent != null) {
607 config = displayContent.updateOrientationFromAppTokens(
608 getDisplayOverrideConfiguration(displayId),
609 starting != null && starting.mayFreezeScreenLocked(starting.app)
610 ? starting.appToken : null,
611 true /* forceUpdate */);
612 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800613 if (starting != null && markFrozenIfConfigChanged && config != null) {
614 starting.frozenBeforeDestroy = true;
615 }
616
617 // Update the configuration of the activities on the display.
618 return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
619 displayId);
620 }
621
622 /**
623 * @return a list of activities which are the top ones in each visible stack. The first
624 * entry will be the focused activity.
625 */
626 List<IBinder> getTopVisibleActivities() {
627 final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
628 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
629 // Traverse all displays.
630 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
631 final ActivityDisplay display = mActivityDisplays.get(i);
632 // Traverse all stacks on a display.
633 for (int j = display.getChildCount() - 1; j >= 0; --j) {
634 final ActivityStack stack = display.getChildAt(j);
635 // Get top activity from a visible stack and add it to the list.
636 if (stack.shouldBeVisible(null /* starting */)) {
637 final ActivityRecord top = stack.getTopActivity();
638 if (top != null) {
639 if (stack == topFocusedStack) {
640 topActivityTokens.add(0, top.appToken);
641 } else {
642 topActivityTokens.add(top.appToken);
643 }
644 }
645 }
646 }
647 }
648 return topActivityTokens;
649 }
650
651 ActivityStack getTopDisplayFocusedStack() {
652 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
653 final ActivityStack focusedStack = mActivityDisplays.get(i).getFocusedStack();
654 if (focusedStack != null) {
655 return focusedStack;
656 }
657 }
658 return null;
659 }
660
661 ActivityRecord getTopResumedActivity() {
662 final ActivityStack focusedStack = getTopDisplayFocusedStack();
663 if (focusedStack == null) {
664 return null;
665 }
666 final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
667 if (resumedActivity != null && resumedActivity.app != null) {
668 return resumedActivity;
669 }
670 // The top focused stack might not have a resumed activity yet - look on all displays in
671 // focus order.
672 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
673 final ActivityDisplay display = mActivityDisplays.get(i);
674 final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity();
675 if (resumedActivityOnDisplay != null) {
676 return resumedActivityOnDisplay;
677 }
678 }
679 return null;
680 }
681
682 boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
683 if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) {
684 return false;
685 }
686
687 return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
688 }
689
690 boolean isTopDisplayFocusedStack(ActivityStack stack) {
691 return stack != null && stack == getTopDisplayFocusedStack();
692 }
693
694 void updatePreviousProcess(ActivityRecord r) {
695 // Now that this process has stopped, we may want to consider it to be the previous app to
696 // try to keep around in case the user wants to return to it.
697
698 // First, found out what is currently the foreground app, so that we don't blow away the
699 // previous app if this activity is being hosted by the process that is actually still the
700 // foreground.
701 WindowProcessController fgApp = null;
702 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
703 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
704 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
705 final ActivityStack stack = display.getChildAt(stackNdx);
706 if (isTopDisplayFocusedStack(stack)) {
707 final ActivityRecord resumedActivity = stack.getResumedActivity();
708 if (resumedActivity != null) {
709 fgApp = resumedActivity.app;
710 } else if (stack.mPausingActivity != null) {
711 fgApp = stack.mPausingActivity.app;
712 }
713 break;
714 }
715 }
716 }
717
718 // Now set this one as the previous process, only if that really makes sense to.
719 if (r.hasProcess() && fgApp != null && r.app != fgApp
720 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
721 && r.app != mService.mHomeProcess) {
722 mService.mPreviousProcess = r.app;
723 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
724 }
725 }
726
727 boolean attachApplication(WindowProcessController app) throws RemoteException {
728 final String processName = app.mName;
729 boolean didSomething = false;
730 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
731 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
732 final ActivityStack stack = display.getFocusedStack();
733 if (stack != null) {
734 stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
735 final ActivityRecord top = stack.topRunningActivityLocked();
736 final int size = mTmpActivityList.size();
737 for (int i = 0; i < size; i++) {
738 final ActivityRecord activity = mTmpActivityList.get(i);
739 if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
740 && processName.equals(activity.processName)) {
741 try {
742 if (mStackSupervisor.realStartActivityLocked(activity, app,
743 top == activity /* andResume */, true /* checkConfig */)) {
744 didSomething = true;
745 }
746 } catch (RemoteException e) {
747 Slog.w(TAG, "Exception in new application when starting activity "
748 + top.intent.getComponent().flattenToShortString(), e);
749 throw e;
750 }
751 }
752 }
753 }
754 }
755 if (!didSomething) {
756 ensureActivitiesVisible(null, 0, false /* preserve_windows */);
757 }
758 return didSomething;
759 }
760
761 /**
762 * Make sure that all activities that need to be visible in the system actually are and update
763 * their configuration.
764 */
765 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
766 boolean preserveWindows) {
767 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
768 }
769
770 /**
771 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
772 */
773 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
774 boolean preserveWindows, boolean notifyClients) {
775 mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
776 try {
777 // First the front stacks. In case any are not fullscreen and are in front of home.
778 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
779 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang77ce34d2019-01-03 15:45:12 +0800780 display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
781 notifyClients);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800782 }
783 } finally {
784 mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
785 }
786 }
787
788 boolean switchUser(int userId, UserState uss) {
789 final int focusStackId = getTopDisplayFocusedStack().getStackId();
790 // We dismiss the docked stack whenever we switch users.
791 final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
792 if (dockedStack != null) {
793 mStackSupervisor.moveTasksToFullscreenStackLocked(
794 dockedStack, dockedStack.isFocusedStackOnDisplay());
795 }
796 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
797 // also cause all tasks to be moved to the fullscreen stack at a position that is
798 // appropriate.
799 removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
800
801 mUserStackInFront.put(mCurrentUser, focusStackId);
802 final int restoreStackId =
803 mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId);
804 mCurrentUser = userId;
805
806 mStackSupervisor.mStartingUsers.add(uss);
807 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
808 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
809 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
810 final ActivityStack stack = display.getChildAt(stackNdx);
811 stack.switchUserLocked(userId);
812 TaskRecord task = stack.topTask();
813 if (task != null) {
814 stack.positionChildWindowContainerAtTop(task);
815 }
816 }
817 }
818
819 ActivityStack stack = getStack(restoreStackId);
820 if (stack == null) {
821 stack = getDefaultDisplay().getHomeStack();
822 }
823 final boolean homeInFront = stack.isActivityTypeHome();
824 if (stack.isOnHomeDisplay()) {
825 stack.moveToFront("switchUserOnHomeDisplay");
826 } else {
827 // Stack was moved to another display while user was swapped out.
828 resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
829 }
830 return homeInFront;
831 }
832
833 void removeUser(int userId) {
834 mUserStackInFront.delete(userId);
835 }
836
837 /**
838 * Update the last used stack id for non-current user (current user's last
839 * used stack is the focused stack)
840 */
841 void updateUserStack(int userId, ActivityStack stack) {
842 if (userId != mCurrentUser) {
843 mUserStackInFront.put(userId, stack != null ? stack.getStackId()
844 : getDefaultDisplay().getHomeStack().mStackId);
845 }
846 }
847
848 void resizeStack(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
849 Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode,
850 boolean deferResume) {
851
852 if (stack.inSplitScreenPrimaryWindowingMode()) {
853 mStackSupervisor.resizeDockedStackLocked(bounds, tempTaskBounds,
854 tempTaskInsetBounds, null, null, preserveWindows, deferResume);
855 return;
856 }
857
858 final boolean splitScreenActive = getDefaultDisplay().hasSplitScreenPrimaryStack();
859 if (!allowResizeInDockedMode
860 && !stack.getWindowConfiguration().tasksAreFloating() && splitScreenActive) {
861 // If the docked stack exists, don't resize non-floating stacks independently of the
862 // size computed from the docked stack size (otherwise they will be out of sync)
863 return;
864 }
865
866 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stack.mStackId);
867 mWindowManager.deferSurfaceLayout();
868 try {
869 if (stack.affectedBySplitScreenResize()) {
870 if (bounds == null && stack.inSplitScreenWindowingMode()) {
871 // null bounds = fullscreen windowing mode...at least for now.
872 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
873 } else if (splitScreenActive) {
874 // If we are in split-screen mode and this stack support split-screen, then
875 // it should be split-screen secondary mode. i.e. adjacent to the docked stack.
876 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
877 }
878 }
879 stack.resize(bounds, tempTaskBounds, tempTaskInsetBounds);
880 if (!deferResume) {
881 stack.ensureVisibleActivitiesConfigurationLocked(
882 stack.topRunningActivityLocked(), preserveWindows);
883 }
884 } finally {
885 mWindowManager.continueSurfaceLayout();
886 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
887 }
888 }
889
890 /**
891 * Move stack with all its existing content to specified display.
892 * @param stackId Id of stack to move.
893 * @param displayId Id of display to move stack to.
894 * @param onTop Indicates whether container should be place on top or on bottom.
895 */
896 void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
897 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
898 if (activityDisplay == null) {
899 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
900 + displayId);
901 }
902 final ActivityStack stack = getStack(stackId);
903 if (stack == null) {
904 throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId="
905 + stackId);
906 }
907
908 final ActivityDisplay currentDisplay = stack.getDisplay();
909 if (currentDisplay == null) {
910 throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack
911 + " is not attached to any display.");
912 }
913
914 if (currentDisplay.mDisplayId == displayId) {
915 throw new IllegalArgumentException("Trying to move stack=" + stack
916 + " to its current displayId=" + displayId);
917 }
918
Wale Ogunwale9e737db2018-12-17 15:42:37 -0800919 if (activityDisplay.isSingleTaskInstance() && activityDisplay.getChildCount() > 0) {
920 // We don't allow moving stacks to single instance display that already has a child.
921 Slog.e(TAG, "Can not move stack=" + stack
922 + " to single task instance display=" + activityDisplay);
923 return;
924 }
925
Wale Ogunwaled32da472018-11-16 07:19:28 -0800926 stack.reparent(activityDisplay, onTop, false /* displayRemoved */);
927 // TODO(multi-display): resize stacks properly if moved from split-screen.
928 }
929
930 boolean moveTopStackActivityToPinnedStack(int stackId) {
931 final ActivityStack stack = getStack(stackId);
932 if (stack == null) {
933 throw new IllegalArgumentException(
934 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
935 }
936
937 final ActivityRecord r = stack.topRunningActivityLocked();
938 if (r == null) {
939 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
940 + " in stack=" + stack);
941 return false;
942 }
943
944 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
945 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
946 + " r=" + r);
947 return false;
948 }
949
950 moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */,
951 "moveTopActivityToPinnedStack");
952 return true;
953 }
954
955 void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
956 String reason) {
957
958 mWindowManager.deferSurfaceLayout();
959
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800960 final ActivityDisplay display = r.getActivityStack().getDisplay();
Yunfan Chen279f5582018-12-12 15:24:50 -0800961 ActivityStack stack = display.getPinnedStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800962
963 // This will clear the pinned stack by moving an existing task to the full screen stack,
964 // ensuring only one task is present.
965 if (stack != null) {
966 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, !ON_TOP);
967 }
968
969 // Need to make sure the pinned stack exist so we can resize it below...
970 stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP);
971
972 // Calculate the target bounds here before the task is reparented back into pinned windowing
973 // mode (which will reset the saved bounds)
974 final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio);
975
976 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800977 final TaskRecord task = r.getTaskRecord();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800978 // Resize the pinned stack to match the current size of the task the activity we are
979 // going to be moving is currently contained in. We do this to have the right starting
980 // animation bounds for the pinned stack to the desired bounds the caller wants.
Evan Roskydfe3da72018-10-26 17:21:06 -0700981 resizeStack(stack, task.getRequestedOverrideBounds(), null /* tempTaskBounds */,
Wale Ogunwaled32da472018-11-16 07:19:28 -0800982 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
983 true /* allowResizeInDockedMode */, !DEFER_RESUME);
984
985 if (task.mActivities.size() == 1) {
986 // Defer resume until below, and do not schedule PiP changes until we animate below
987 task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME,
988 false /* schedulePictureInPictureModeChange */, reason);
989 } else {
990 // There are multiple activities in the task and moving the top activity should
991 // reveal/leave the other activities in their original task.
992
993 // Currently, we don't support reparenting activities across tasks in two different
994 // stacks, so instead, just create a new task in the same stack, reparent the
995 // activity into that task, and then reparent the whole task to the new stack. This
996 // ensures that all the necessary work to migrate states in the old and new stacks
997 // is also done.
998 final TaskRecord newTask = task.getStack().createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800999 mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001000 r.intent, null, null, true);
1001 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
1002
1003 // Defer resume until below, and do not schedule PiP changes until we animate below
1004 newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
1005 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
1006 }
1007
1008 // Reset the state that indicates it can enter PiP while pausing after we've moved it
1009 // to the pinned stack
1010 r.supportsEnterPipOnTaskSwitch = false;
1011 } finally {
1012 mWindowManager.continueSurfaceLayout();
1013 }
1014
1015 stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
1016 true /* fromFullscreen */);
1017
1018 // Update the visibility of all activities after the they have been reparented to the new
1019 // stack. This MUST run after the animation above is scheduled to ensure that the windows
1020 // drawn signal is scheduled after the bounds animation start call on the bounds animator
1021 // thread.
1022 ensureActivitiesVisible(null, 0, false /* preserveWindows */);
1023 resumeFocusedStacksTopActivities();
1024
1025 mService.getTaskChangeNotificationController().notifyActivityPinned(r);
1026 }
1027
1028 void executeAppTransitionForAllDisplay() {
1029 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1030 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001031 display.mDisplayContent.executeAppTransition();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001032 }
1033 }
1034
1035 void setDockedStackMinimized(boolean minimized) {
1036 // Get currently focused stack before setting mIsDockMinimized. We do this because if
1037 // split-screen is active, primary stack will not be focusable (see #isFocusable) while
1038 // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
1039 final ActivityStack current = getTopDisplayFocusedStack();
1040 mIsDockMinimized = minimized;
1041 if (mIsDockMinimized) {
1042 if (current.inSplitScreenPrimaryWindowingMode()) {
1043 // The primary split-screen stack can't be focused while it is minimize, so move
1044 // focus to something else.
1045 current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
1046 }
1047 }
1048 }
1049
1050 ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
1051 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
1052 mTmpFindTaskResult.clear();
1053
1054 // Looking up task on preferred display first
1055 final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId);
1056 if (preferredDisplay != null) {
1057 preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult);
1058 if (mTmpFindTaskResult.mIdealMatch) {
1059 return mTmpFindTaskResult.mRecord;
1060 }
1061 }
1062
1063 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1064 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1065 if (display.mDisplayId == preferredDisplayId) {
1066 continue;
1067 }
1068
1069 display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult);
1070 if (mTmpFindTaskResult.mIdealMatch) {
1071 return mTmpFindTaskResult.mRecord;
1072 }
1073 }
1074
1075 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
1076 return mTmpFindTaskResult.mRecord;
1077 }
1078
1079 /**
1080 * Finish the topmost activities in all stacks that belong to the crashed app.
1081 * @param app The app that crashed.
1082 * @param reason Reason to perform this action.
1083 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
1084 */
1085 int finishTopCrashedActivities(WindowProcessController app, String reason) {
1086 TaskRecord finishedTask = null;
1087 ActivityStack focusedStack = getTopDisplayFocusedStack();
1088 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1089 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1090 // It is possible that request to finish activity might also remove its task and stack,
1091 // so we need to be careful with indexes in the loop and check child count every time.
1092 for (int stackNdx = 0; stackNdx < display.getChildCount(); ++stackNdx) {
1093 final ActivityStack stack = display.getChildAt(stackNdx);
1094 final TaskRecord t = stack.finishTopCrashedActivityLocked(app, reason);
1095 if (stack == focusedStack || finishedTask == null) {
1096 finishedTask = t;
1097 }
1098 }
1099 }
1100 return finishedTask != null ? finishedTask.taskId : INVALID_TASK_ID;
1101 }
1102
1103 boolean resumeFocusedStacksTopActivities() {
1104 return resumeFocusedStacksTopActivities(null, null, null);
1105 }
1106
1107 boolean resumeFocusedStacksTopActivities(
1108 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1109
1110 if (!mStackSupervisor.readyToResume()) {
1111 return false;
1112 }
1113
Andrii Kulian6b321512019-01-23 06:37:00 +00001114 boolean result = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001115 if (targetStack != null && (targetStack.isTopStackOnDisplay()
1116 || getTopDisplayFocusedStack() == targetStack)) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001117 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001118 }
1119
Wale Ogunwaled32da472018-11-16 07:19:28 -08001120 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001121 boolean resumedOnDisplay = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001122 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Andrii Kulian6b321512019-01-23 06:37:00 +00001123 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1124 final ActivityStack stack = display.getChildAt(stackNdx);
1125 final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
1126 if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
1127 continue;
1128 }
Louis Changc50a9362019-02-12 12:35:24 +08001129 if (stack == targetStack) {
1130 // Simply update the result for targetStack because the targetStack had
1131 // already resumed in above. We don't want to resume it again, especially in
1132 // some cases, it would cause a second launch failure if app process was dead.
1133 resumedOnDisplay |= result;
1134 continue;
1135 }
Andrii Kulian6b321512019-01-23 06:37:00 +00001136 if (topRunningActivity.isState(RESUMED)) {
1137 // Kick off any lingering app transitions form the MoveTaskToFront operation.
1138 stack.executeAppTransition(targetOptions);
1139 } else {
1140 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
1141 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001142 }
Andrii Kulian6b321512019-01-23 06:37:00 +00001143 if (!resumedOnDisplay) {
1144 // In cases when there are no valid activities (e.g. device just booted or launcher
1145 // crashed) it's possible that nothing was resumed on a display. Requesting resume
1146 // of top activity in focused stack explicitly will make sure that at least home
1147 // activity is started and resumed, and no recursion occurs.
1148 final ActivityStack focusedStack = display.getFocusedStack();
1149 if (focusedStack != null) {
1150 focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1151 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001152 }
1153 }
1154
Andrii Kulian6b321512019-01-23 06:37:00 +00001155 return result;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001156 }
1157
Andrii Kuliand70cdb92019-01-08 15:03:50 -08001158 void updateTopResumedActivityIfNeeded() {
1159 final ActivityRecord prevTopActivity = mTopResumedActivity;
1160 final ActivityStack topStack = getTopDisplayFocusedStack();
1161 if (topStack == null || topStack.mResumedActivity == prevTopActivity) {
1162 return;
1163 }
1164 // Clear previous top state
1165 if (prevTopActivity != null) {
1166 prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */);
1167 }
1168 // Update the current top activity
1169 mTopResumedActivity = topStack.mResumedActivity;
1170 if (mTopResumedActivity != null) {
1171 mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */);
1172 }
1173 }
1174
Wale Ogunwaled32da472018-11-16 07:19:28 -08001175 void applySleepTokens(boolean applyToStacks) {
1176 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1177 // Set the sleeping state of the display.
1178 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1179 final boolean displayShouldSleep = display.shouldSleep();
1180 if (displayShouldSleep == display.isSleeping()) {
1181 continue;
1182 }
1183 display.setIsSleeping(displayShouldSleep);
1184
1185 if (!applyToStacks) {
1186 continue;
1187 }
1188
1189 // Set the sleeping state of the stacks on the display.
1190 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1191 final ActivityStack stack = display.getChildAt(stackNdx);
1192 if (displayShouldSleep) {
1193 stack.goToSleepIfPossible(false /* shuttingDown */);
1194 } else {
1195 stack.awakeFromSleepingLocked();
1196 if (stack.isFocusedStackOnDisplay()
1197 && !mStackSupervisor.getKeyguardController()
1198 .isKeyguardOrAodShowing(display.mDisplayId)) {
1199 // If the keyguard is unlocked - resume immediately.
1200 // It is possible that the display will not be awake at the time we
1201 // process the keyguard going away, which can happen before the sleep token
1202 // is released. As a result, it is important we resume the activity here.
1203 resumeFocusedStacksTopActivities();
1204 }
1205 }
1206 }
1207
1208 if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) {
1209 continue;
1210 }
1211 // The display is awake now, so clean up the going to sleep list.
1212 for (Iterator<ActivityRecord> it =
1213 mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) {
1214 final ActivityRecord r = it.next();
1215 if (r.getDisplayId() == display.mDisplayId) {
1216 it.remove();
1217 }
1218 }
1219 }
1220 }
1221
1222 protected <T extends ActivityStack> T getStack(int stackId) {
1223 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1224 final T stack = mActivityDisplays.get(i).getStack(stackId);
1225 if (stack != null) {
1226 return stack;
1227 }
1228 }
1229 return null;
1230 }
1231
1232 /** @see ActivityDisplay#getStack(int, int) */
1233 private <T extends ActivityStack> T getStack(int windowingMode, int activityType) {
1234 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1235 final T stack = mActivityDisplays.get(i).getStack(windowingMode, activityType);
1236 if (stack != null) {
1237 return stack;
1238 }
1239 }
1240 return null;
1241 }
1242
1243 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
1244 final int displayId = stack.mDisplayId;
1245 final ActivityDisplay display = getActivityDisplay(displayId);
1246 ActivityManager.StackInfo info = new ActivityManager.StackInfo();
1247 stack.getWindowContainerBounds(info.bounds);
1248 info.displayId = displayId;
1249 info.stackId = stack.mStackId;
1250 info.userId = stack.mCurrentUser;
1251 info.visible = stack.shouldBeVisible(null);
1252 // A stack might be not attached to a display.
1253 info.position = display != null ? display.getIndexOf(stack) : 0;
1254 info.configuration.setTo(stack.getConfiguration());
1255
1256 ArrayList<TaskRecord> tasks = stack.getAllTasks();
1257 final int numTasks = tasks.size();
1258 int[] taskIds = new int[numTasks];
1259 String[] taskNames = new String[numTasks];
1260 Rect[] taskBounds = new Rect[numTasks];
1261 int[] taskUserIds = new int[numTasks];
1262 for (int i = 0; i < numTasks; ++i) {
1263 final TaskRecord task = tasks.get(i);
1264 taskIds[i] = task.taskId;
1265 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
1266 : task.realActivity != null ? task.realActivity.flattenToString()
1267 : task.getTopActivity() != null ? task.getTopActivity().packageName
1268 : "unknown";
1269 taskBounds[i] = new Rect();
1270 task.getWindowContainerBounds(taskBounds[i]);
1271 taskUserIds[i] = task.userId;
1272 }
1273 info.taskIds = taskIds;
1274 info.taskNames = taskNames;
1275 info.taskBounds = taskBounds;
1276 info.taskUserIds = taskUserIds;
1277
1278 final ActivityRecord top = stack.topRunningActivityLocked();
1279 info.topActivity = top != null ? top.intent.getComponent() : null;
1280 return info;
1281 }
1282
1283 ActivityManager.StackInfo getStackInfo(int stackId) {
1284 ActivityStack stack = getStack(stackId);
1285 if (stack != null) {
1286 return getStackInfo(stack);
1287 }
1288 return null;
1289 }
1290
1291 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
1292 final ActivityStack stack = getStack(windowingMode, activityType);
1293 return (stack != null) ? getStackInfo(stack) : null;
1294 }
1295
1296 ArrayList<ActivityManager.StackInfo> getAllStackInfos() {
1297 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
1298 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
1299 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1300 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1301 final ActivityStack stack = display.getChildAt(stackNdx);
1302 list.add(getStackInfo(stack));
1303 }
1304 }
1305 return list;
1306 }
1307
1308 void deferUpdateBounds(int activityType) {
1309 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1310 if (stack != null) {
1311 stack.deferUpdateBounds();
1312 }
1313 }
1314
1315 void continueUpdateBounds(int activityType) {
1316 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1317 if (stack != null) {
1318 stack.continueUpdateBounds();
1319 }
1320 }
1321
1322 @Override
1323 public void onDisplayAdded(int displayId) {
1324 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
1325 synchronized (mService.mGlobalLock) {
Charles Chen3dedec32019-01-24 22:19:37 +08001326 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
Charles Chenb409e6c2019-02-12 12:30:17 +08001327 if (display == null) {
1328 return;
1329 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001330 // Do not start home before booting, or it may accidentally finish booting before it
1331 // starts. Instead, we expect home activities to be launched when the system is ready
1332 // (ActivityManagerService#systemReady).
1333 if (mService.isBooted() || mService.isBooting()) {
Charles Chen3dedec32019-01-24 22:19:37 +08001334 startSystemDecorations(display.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001335 }
1336 }
1337 }
1338
Charles Chen3dedec32019-01-24 22:19:37 +08001339 private void startSystemDecorations(final DisplayContent displayContent) {
1340 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
1341 displayContent.getDisplayPolicy().notifyDisplayReady();
1342 }
1343
Wale Ogunwaled32da472018-11-16 07:19:28 -08001344 @Override
1345 public void onDisplayRemoved(int displayId) {
1346 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
1347 if (displayId == DEFAULT_DISPLAY) {
1348 throw new IllegalArgumentException("Can't remove the primary display.");
1349 }
1350
1351 synchronized (mService.mGlobalLock) {
1352 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1353 if (activityDisplay == null) {
1354 return;
1355 }
1356
1357 activityDisplay.remove();
1358 }
1359 }
1360
1361 @Override
1362 public void onDisplayChanged(int displayId) {
1363 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
1364 synchronized (mService.mGlobalLock) {
1365 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1366 if (activityDisplay != null) {
1367 activityDisplay.onDisplayChanged();
1368 }
1369 }
1370 }
1371
1372 /** Update lists of UIDs that are present on displays and have access to them. */
1373 void updateUIDsPresentOnDisplay() {
1374 mDisplayAccessUIDs.clear();
1375 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1376 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
1377 // Only bother calculating the whitelist for private displays
1378 if (activityDisplay.isPrivate()) {
1379 mDisplayAccessUIDs.append(
1380 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs());
1381 }
1382 }
1383 // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
1384 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
1385 }
1386
1387 ActivityStack findStackBehind(ActivityStack stack) {
1388 final ActivityDisplay display = getActivityDisplay(stack.mDisplayId);
1389 if (display != null) {
1390 for (int i = display.getChildCount() - 1; i >= 0; i--) {
1391 if (display.getChildAt(i) == stack && i > 0) {
1392 return display.getChildAt(i - 1);
1393 }
1394 }
1395 }
1396 throw new IllegalStateException("Failed to find a stack behind stack=" + stack
1397 + " in=" + display);
1398 }
1399
1400 @Override
1401 protected int getChildCount() {
1402 return mActivityDisplays.size();
1403 }
1404
1405 @Override
1406 protected ActivityDisplay getChildAt(int index) {
1407 return mActivityDisplays.get(index);
1408 }
1409
1410 @Override
1411 protected ConfigurationContainer getParent() {
1412 return null;
1413 }
1414
Wale Ogunwale31acb3f2018-11-20 15:23:55 -08001415 // TODO: remove after object merge with RootWindowContainer
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001416 void onChildPositionChanged(ActivityDisplay display, int position) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001417 // Assume AM lock is held from positionChildAt of controller in each hierarchy.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001418 if (display != null) {
1419 positionChildAt(display, position);
1420 }
1421 }
1422
1423 /** Change the z-order of the given display. */
1424 private void positionChildAt(ActivityDisplay display, int position) {
1425 if (position >= mActivityDisplays.size()) {
1426 position = mActivityDisplays.size() - 1;
1427 } else if (position < 0) {
1428 position = 0;
1429 }
1430
1431 if (mActivityDisplays.isEmpty()) {
1432 mActivityDisplays.add(display);
1433 } else if (mActivityDisplays.get(position) != display) {
1434 mActivityDisplays.remove(display);
1435 mActivityDisplays.add(position, display);
1436 }
Andrii Kuliand70cdb92019-01-08 15:03:50 -08001437 updateTopResumedActivityIfNeeded();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001438 }
1439
1440 @VisibleForTesting
1441 void addChild(ActivityDisplay activityDisplay, int position) {
1442 positionChildAt(activityDisplay, position);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001443 mRootWindowContainer.positionChildAt(position, activityDisplay.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001444 }
1445
1446 void removeChild(ActivityDisplay activityDisplay) {
1447 // The caller must tell the controller of {@link ActivityDisplay} to release its container
1448 // {@link DisplayContent}. That is done in {@link ActivityDisplay#releaseSelfIfNeeded}).
1449 mActivityDisplays.remove(activityDisplay);
1450 }
1451
1452 Configuration getDisplayOverrideConfiguration(int displayId) {
1453 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1454 if (activityDisplay == null) {
1455 throw new IllegalArgumentException("No display found with id: " + displayId);
1456 }
1457
Evan Roskydfe3da72018-10-26 17:21:06 -07001458 return activityDisplay.getRequestedOverrideConfiguration();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001459 }
1460
1461 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
1462 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1463 if (activityDisplay == null) {
1464 throw new IllegalArgumentException("No display found with id: " + displayId);
1465 }
1466
Evan Roskydfe3da72018-10-26 17:21:06 -07001467 activityDisplay.onRequestedOverrideConfigurationChanged(overrideConfiguration);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001468 }
1469
1470 void prepareForShutdown() {
1471 for (int i = 0; i < mActivityDisplays.size(); i++) {
1472 createSleepToken("shutdown", mActivityDisplays.get(i).mDisplayId);
1473 }
1474 }
1475
1476 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
1477 final ActivityDisplay display = getActivityDisplay(displayId);
1478 if (display == null) {
1479 throw new IllegalArgumentException("Invalid display: " + displayId);
1480 }
1481
1482 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
1483 mSleepTokens.add(token);
1484 display.mAllSleepTokens.add(token);
1485 return token;
1486 }
1487
1488 private void removeSleepToken(SleepTokenImpl token) {
1489 mSleepTokens.remove(token);
1490
1491 final ActivityDisplay display = getActivityDisplay(token.mDisplayId);
1492 if (display != null) {
1493 display.mAllSleepTokens.remove(token);
1494 if (display.mAllSleepTokens.isEmpty()) {
1495 mService.updateSleepIfNeededLocked();
1496 }
1497 }
1498 }
1499
1500 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1501 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1502 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1503 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1504 final ActivityStack stack = display.getChildAt(stackNdx);
1505 stack.addStartingWindowsForVisibleActivities(taskSwitch);
1506 }
1507 }
1508 }
1509
1510 void invalidateTaskLayers() {
1511 mTaskLayersChanged = true;
1512 }
1513
1514 void rankTaskLayersIfNeeded() {
1515 if (!mTaskLayersChanged) {
1516 return;
1517 }
1518 mTaskLayersChanged = false;
1519 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
1520 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1521 int baseLayer = 0;
1522 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1523 final ActivityStack stack = display.getChildAt(stackNdx);
1524 baseLayer += stack.rankTaskLayers(baseLayer);
1525 }
1526 }
1527 }
1528
1529 void clearOtherAppTimeTrackers(AppTimeTracker except) {
1530 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1531 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1532 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1533 final ActivityStack stack = display.getChildAt(stackNdx);
1534 stack.clearOtherAppTimeTrackers(except);
1535 }
1536 }
1537 }
1538
1539 void scheduleDestroyAllActivities(WindowProcessController app, String reason) {
1540 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1541 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1542 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1543 final ActivityStack stack = display.getChildAt(stackNdx);
1544 stack.scheduleDestroyActivities(app, reason);
1545 }
1546 }
1547 }
1548
1549 void releaseSomeActivitiesLocked(WindowProcessController app, String reason) {
1550 // Tasks is non-null only if two or more tasks are found.
1551 ArraySet<TaskRecord> tasks = app.getReleaseSomeActivitiesTasks();
1552 if (tasks == null) {
1553 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
1554 return;
1555 }
1556 // If we have activities in multiple tasks that are in a position to be destroyed,
1557 // let's iterate through the tasks and release the oldest one.
1558 final int numDisplays = mActivityDisplays.size();
1559 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
1560 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1561 final int stackCount = display.getChildCount();
1562 // Step through all stacks starting from behind, to hit the oldest things first.
1563 for (int stackNdx = 0; stackNdx < stackCount; stackNdx++) {
1564 final ActivityStack stack = display.getChildAt(stackNdx);
1565 // Try to release activities in this stack; if we manage to, we are done.
1566 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
1567 return;
1568 }
1569 }
1570 }
1571 }
1572
1573 // Tries to put all activity stacks to sleep. Returns true if all stacks were
1574 // successfully put to sleep.
1575 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
1576 boolean allSleep = true;
1577 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1578 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1579 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
Louis Changc219bc32018-12-06 15:38:41 +08001580 // Stacks and activities could be removed while putting activities to sleep if
1581 // the app process was gone. This prevents us getting exception by accessing an
1582 // invalid stack index.
1583 if (stackNdx >= display.getChildCount()) {
1584 continue;
1585 }
1586
Wale Ogunwaled32da472018-11-16 07:19:28 -08001587 final ActivityStack stack = display.getChildAt(stackNdx);
1588 if (allowDelay) {
1589 allSleep &= stack.goToSleepIfPossible(shuttingDown);
1590 } else {
1591 stack.goToSleep();
1592 }
1593 }
1594 }
1595 return allSleep;
1596 }
1597
1598 void handleAppCrash(WindowProcessController app) {
1599 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1600 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1601 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1602 final ActivityStack stack = display.getChildAt(stackNdx);
1603 stack.handleAppCrash(app);
1604 }
1605 }
1606 }
1607
1608 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
1609 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1610 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1611 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1612 final ActivityStack stack = display.getChildAt(stackNdx);
1613 final ActivityRecord ar = stack.findActivityLocked(
1614 intent, info, compareIntentFilters);
1615 if (ar != null) {
1616 return ar;
1617 }
1618 }
1619 }
1620 return null;
1621 }
1622
1623 boolean hasAwakeDisplay() {
1624 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1625 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1626 if (!display.shouldSleep()) {
1627 return true;
1628 }
1629 }
1630 return false;
1631 }
1632
1633 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
1634 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) {
1635 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */);
1636 }
1637
1638 /**
1639 * Returns the right stack to use for launching factoring in all the input parameters.
1640 *
1641 * @param r The activity we are trying to launch. Can be null.
1642 * @param options The activity options used to the launch. Can be null.
1643 * @param candidateTask The possible task the activity might be launched in. Can be null.
1644 * @params launchParams The resolved launch params to use.
1645 *
1646 * @return The stack to use for the launch or INVALID_STACK_ID.
1647 */
1648 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
1649 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop,
1650 @Nullable LaunchParamsController.LaunchParams launchParams) {
1651 int taskId = INVALID_TASK_ID;
1652 int displayId = INVALID_DISPLAY;
1653 //Rect bounds = null;
1654
1655 // We give preference to the launch preference in activity options.
1656 if (options != null) {
1657 taskId = options.getLaunchTaskId();
1658 displayId = options.getLaunchDisplayId();
1659 }
1660
1661 // First preference for stack goes to the task Id set in the activity options. Use the stack
1662 // associated with that if possible.
1663 if (taskId != INVALID_TASK_ID) {
1664 // Temporarily set the task id to invalid in case in re-entry.
1665 options.setLaunchTaskId(INVALID_TASK_ID);
1666 final TaskRecord task = anyTaskForId(taskId,
1667 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
1668 options.setLaunchTaskId(taskId);
1669 if (task != null) {
1670 return task.getStack();
1671 }
1672 }
1673
1674 final int activityType = resolveActivityType(r, options, candidateTask);
1675 T stack;
1676
1677 // Next preference for stack goes to the display Id set the candidate display.
1678 if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
1679 displayId = launchParams.mPreferredDisplayId;
1680 }
1681 if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) {
1682 if (r != null) {
1683 stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
1684 launchParams);
1685 if (stack != null) {
1686 return stack;
1687 }
1688 }
1689 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
1690 if (display != null) {
1691 stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1692 if (stack != null) {
1693 return stack;
1694 }
1695 }
1696 }
1697
1698 // Give preference to the stack and display of the input task and activity if they match the
1699 // mode we want to launch into.
1700 stack = null;
1701 ActivityDisplay display = null;
1702 if (candidateTask != null) {
1703 stack = candidateTask.getStack();
1704 }
1705 if (stack == null && r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001706 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001707 }
1708 if (stack != null) {
1709 display = stack.getDisplay();
1710 if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) {
1711 int windowingMode = launchParams != null ? launchParams.mWindowingMode
1712 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
1713 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
1714 windowingMode = display.resolveWindowingMode(r, options, candidateTask,
1715 activityType);
1716 }
1717 if (stack.isCompatible(windowingMode, activityType)) {
1718 return stack;
1719 }
1720 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
1721 && display.getSplitScreenPrimaryStack() == stack
1722 && candidateTask == stack.topTask()) {
1723 // This is a special case when we try to launch an activity that is currently on
1724 // top of split-screen primary stack, but is targeting split-screen secondary.
1725 // In this case we don't want to move it to another stack.
1726 // TODO(b/78788972): Remove after differentiating between preferred and required
1727 // launch options.
1728 return stack;
1729 }
1730 }
1731 }
1732
1733 if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) {
1734 display = getDefaultDisplay();
1735 }
1736
1737 return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1738 }
1739
1740 /** @return true if activity record is null or can be launched on provided display. */
1741 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
1742 if (r == null) {
1743 return true;
1744 }
1745 return r.canBeLaunchedOnDisplay(displayId);
1746 }
1747
1748 /**
1749 * Get a topmost stack on the display, that is a valid launch stack for specified activity.
1750 * If there is no such stack, new dynamic stack can be created.
1751 * @param displayId Target display.
1752 * @param r Activity that should be launched there.
1753 * @param candidateTask The possible task the activity might be put in.
1754 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
1755 */
1756 private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
1757 @Nullable TaskRecord candidateTask, @Nullable ActivityOptions options,
1758 @Nullable LaunchParamsController.LaunchParams launchParams) {
1759 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1760 if (activityDisplay == null) {
1761 throw new IllegalArgumentException(
1762 "Display with displayId=" + displayId + " not found.");
1763 }
1764
1765 if (!r.canBeLaunchedOnDisplay(displayId)) {
1766 return null;
1767 }
1768
1769 // If {@code r} is already in target display and its task is the same as the candidate task,
1770 // the intention should be getting a launch stack for the reusable activity, so we can use
1771 // the existing stack.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001772 if (r.getDisplayId() == displayId && r.getTaskRecord() == candidateTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001773 return candidateTask.getStack();
1774 }
1775
Louis Chang6fb1e842018-12-03 16:07:50 +08001776 int windowingMode;
1777 if (launchParams != null) {
1778 // When launch params is not null, we always defer to its windowing mode. Sometimes
1779 // it could be unspecified, which indicates it should inherit windowing mode from
1780 // display.
1781 windowingMode = launchParams.mWindowingMode;
1782 } else {
1783 windowingMode = options != null ? options.getLaunchWindowingMode()
1784 : r.getWindowingMode();
1785 }
1786 windowingMode = activityDisplay.validateWindowingMode(windowingMode, r, candidateTask,
1787 r.getActivityType());
1788
Wale Ogunwaled32da472018-11-16 07:19:28 -08001789 // Return the topmost valid stack on the display.
1790 for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) {
1791 final ActivityStack stack = activityDisplay.getChildAt(i);
Louis Chang6fb1e842018-12-03 16:07:50 +08001792 if (isValidLaunchStack(stack, r, windowingMode)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001793 return stack;
1794 }
1795 }
1796
1797 // If there is no valid stack on the external display - check if new dynamic stack will do.
1798 if (displayId != DEFAULT_DISPLAY) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001799 final int activityType =
1800 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
1801 ? options.getLaunchActivityType() : r.getActivityType();
1802 return activityDisplay.createStack(windowingMode, activityType, true /*onTop*/);
1803 }
1804
Wale Ogunwaled32da472018-11-16 07:19:28 -08001805 return null;
1806 }
1807
1808 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
1809 @Nullable ActivityOptions options,
1810 @Nullable LaunchParamsController.LaunchParams launchParams) {
1811 return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options,
1812 launchParams);
1813 }
1814
1815 // TODO: Can probably be consolidated into getLaunchStack()...
Louis Chang6fb1e842018-12-03 16:07:50 +08001816 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001817 switch (stack.getActivityType()) {
1818 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
1819 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
1820 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
1821 }
1822 // There is a 1-to-1 relationship between stack and task when not in
1823 // primary split-windowing mode.
Louis Chang6fb1e842018-12-03 16:07:50 +08001824 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
1825 && r.supportsSplitScreenWindowingMode()
1826 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
1827 || windowingMode == WINDOWING_MODE_UNDEFINED)) {
1828 return true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001829 }
Louis Chang6fb1e842018-12-03 16:07:50 +08001830 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001831 }
1832
1833 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
1834 @Nullable TaskRecord task) {
1835 // Preference is given to the activity type for the activity then the task since the type
1836 // once set shouldn't change.
1837 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
1838 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
1839 activityType = task.getActivityType();
1840 }
1841 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
1842 return activityType;
1843 }
1844 if (options != null) {
1845 activityType = options.getLaunchActivityType();
1846 }
1847 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
1848 }
1849
1850 /**
1851 * Get next focusable stack in the system. This will search through the stack on the same
1852 * display as the current focused stack, looking for a focusable and visible stack, different
1853 * from the target stack. If no valid candidates will be found, it will then go through all
1854 * displays and stacks in last-focused order.
1855 *
1856 * @param currentFocus The stack that previously had focus.
1857 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
1858 * candidate.
1859 * @return Next focusable {@link ActivityStack}, {@code null} if not found.
1860 */
1861 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
1862 boolean ignoreCurrent) {
1863 // First look for next focusable stack on the same display
1864 final ActivityDisplay preferredDisplay = currentFocus.getDisplay();
1865 final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
1866 currentFocus, ignoreCurrent);
1867 if (preferredFocusableStack != null) {
1868 return preferredFocusableStack;
1869 }
1870 if (preferredDisplay.supportsSystemDecorations()) {
1871 // Stop looking for focusable stack on other displays because the preferred display
1872 // supports system decorations. Home activity would be launched on the same display if
1873 // no focusable stack found.
1874 return null;
1875 }
1876
1877 // Now look through all displays
1878 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1879 final ActivityDisplay display = mActivityDisplays.get(i);
1880 if (display == preferredDisplay) {
1881 // We've already checked this one
1882 continue;
1883 }
1884 final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
1885 ignoreCurrent);
1886 if (nextFocusableStack != null) {
1887 return nextFocusableStack;
1888 }
1889 }
1890
1891 return null;
1892 }
1893
1894 /**
1895 * Get next valid stack for launching provided activity in the system. This will search across
1896 * displays and stacks in last-focused order for a focusable and visible stack, except those
1897 * that are on a currently focused display.
1898 *
1899 * @param r The activity that is being launched.
1900 * @param currentFocus The display that previously had focus and thus needs to be ignored when
1901 * searching for the next candidate.
1902 * @return Next valid {@link ActivityStack}, null if not found.
1903 */
1904 ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) {
1905 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1906 final ActivityDisplay display = mActivityDisplays.get(i);
1907 if (display.mDisplayId == currentFocus) {
1908 continue;
1909 }
1910 final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r,
1911 null /* options */, null /* launchParams */);
1912 if (stack != null) {
1913 return stack;
1914 }
1915 }
1916 return null;
1917 }
1918
1919 boolean handleAppDied(WindowProcessController app) {
1920 boolean hasVisibleActivities = false;
1921 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1922 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1923 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1924 final ActivityStack stack = display.getChildAt(stackNdx);
1925 hasVisibleActivities |= stack.handleAppDiedLocked(app);
1926 }
1927 }
1928 return hasVisibleActivities;
1929 }
1930
1931 void closeSystemDialogs() {
1932 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1933 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1934 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1935 final ActivityStack stack = display.getChildAt(stackNdx);
1936 stack.closeSystemDialogsLocked();
1937 }
1938 }
1939 }
1940
1941 /** @return true if some activity was finished (or would have finished if doit were true). */
1942 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
1943 boolean doit, boolean evenPersistent, int userId) {
1944 boolean didSomething = false;
1945 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1946 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1947 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1948 final ActivityStack stack = display.getChildAt(stackNdx);
1949 if (stack.finishDisabledPackageActivitiesLocked(
1950 packageName, filterByClasses, doit, evenPersistent, userId)) {
1951 didSomething = true;
1952 }
1953 }
1954 }
1955 return didSomething;
1956 }
1957
1958 void updateActivityApplicationInfo(ApplicationInfo aInfo) {
1959 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1960 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1961 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1962 final ActivityStack stack = display.getChildAt(stackNdx);
1963 stack.updateActivityApplicationInfoLocked(aInfo);
1964 }
1965 }
1966 }
1967
1968 void finishVoiceTask(IVoiceInteractionSession session) {
1969 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1970 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1971 final int numStacks = display.getChildCount();
1972 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1973 final ActivityStack stack = display.getChildAt(stackNdx);
1974 stack.finishVoiceTask(session);
1975 }
1976 }
1977 }
1978
1979 /**
1980 * Removes stacks in the input windowing modes from the system if they are of activity type
1981 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
1982 */
1983 void removeStacksInWindowingModes(int... windowingModes) {
1984 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1985 mActivityDisplays.get(i).removeStacksInWindowingModes(windowingModes);
1986 }
1987 }
1988
1989 void removeStacksWithActivityTypes(int... activityTypes) {
1990 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1991 mActivityDisplays.get(i).removeStacksWithActivityTypes(activityTypes);
1992 }
1993 }
1994
1995 ActivityRecord topRunningActivity() {
1996 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1997 final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
1998 if (topActivity != null) {
1999 return topActivity;
2000 }
2001 }
2002 return null;
2003 }
2004
2005 boolean allResumedActivitiesIdle() {
2006 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2007 // TODO(b/117135575): Check resumed activities on all visible stacks.
2008 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2009 if (display.isSleeping()) {
2010 // No resumed activities while display is sleeping.
2011 continue;
2012 }
2013
2014 // If the focused stack is not null or not empty, there should have some activities
2015 // resuming or resumed. Make sure these activities are idle.
2016 final ActivityStack stack = display.getFocusedStack();
2017 if (stack == null || stack.numActivities() == 0) {
2018 continue;
2019 }
2020 final ActivityRecord resumedActivity = stack.getResumedActivity();
2021 if (resumedActivity == null || !resumedActivity.idle) {
2022 if (DEBUG_STATES) {
2023 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
2024 + stack.mStackId + " " + resumedActivity + " not idle");
2025 }
2026 return false;
2027 }
2028 }
2029 // Send launch end powerhint when idle
2030 sendPowerHintForLaunchEndIfNeeded();
2031 return true;
2032 }
2033
2034 boolean allResumedActivitiesVisible() {
2035 boolean foundResumed = false;
2036 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2037 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2038 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2039 final ActivityStack stack = display.getChildAt(stackNdx);
2040 final ActivityRecord r = stack.getResumedActivity();
2041 if (r != null) {
2042 if (!r.nowVisible
2043 || mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) {
2044 return false;
2045 }
2046 foundResumed = true;
2047 }
2048 }
2049 }
2050 return foundResumed;
2051 }
2052
2053 boolean allPausedActivitiesComplete() {
2054 boolean pausing = true;
2055 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2056 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2057 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2058 final ActivityStack stack = display.getChildAt(stackNdx);
2059 final ActivityRecord r = stack.mPausingActivity;
2060 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
2061 if (DEBUG_STATES) {
2062 Slog.d(TAG_STATES,
2063 "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
2064 pausing = false;
2065 } else {
2066 return false;
2067 }
2068 }
2069 }
2070 }
2071 return pausing;
2072 }
2073
2074 /**
2075 * Find all visible task stacks containing {@param userId} and intercept them with an activity
2076 * to block out the contents and possibly start a credential-confirming intent.
2077 *
2078 * @param userId user handle for the locked managed profile.
2079 */
2080 void lockAllProfileTasks(@UserIdInt int userId) {
2081 mWindowManager.deferSurfaceLayout();
2082 try {
2083 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2084 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2085 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2086 final ActivityStack stack = display.getChildAt(stackNdx);
2087 final List<TaskRecord> tasks = stack.getAllTasks();
2088 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
2089 final TaskRecord task = tasks.get(taskNdx);
2090
2091 // Check the task for a top activity belonging to userId, or returning a
2092 // result to an activity belonging to userId. Example case: a document
2093 // picker for personal files, opened by a work app, should still get locked.
2094 if (taskTopActivityIsUser(task, userId)) {
2095 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
2096 task.taskId, userId);
2097 }
2098 }
2099 }
2100 }
2101 } finally {
2102 mWindowManager.continueSurfaceLayout();
2103 }
2104 }
2105
2106 /**
2107 * Detects whether we should show a lock screen in front of this task for a locked user.
2108 * <p>
2109 * We'll do this if either of the following holds:
2110 * <ul>
2111 * <li>The top activity explicitly belongs to {@param userId}.</li>
2112 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
2113 * </ul>
2114 *
2115 * @return {@code true} if the top activity looks like it belongs to {@param userId}.
2116 */
2117 private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) {
2118 // To handle the case that work app is in the task but just is not the top one.
2119 final ActivityRecord activityRecord = task.getTopActivity();
2120 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
2121
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002122 return (activityRecord != null && activityRecord.mUserId == userId)
2123 || (resultTo != null && resultTo.mUserId == userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002124 }
2125
2126 void cancelInitializingActivities() {
2127 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2128 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2129 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2130 final ActivityStack stack = display.getChildAt(stackNdx);
2131 stack.cancelInitializingActivities();
2132 }
2133 }
2134 }
2135
2136 TaskRecord anyTaskForId(int id) {
2137 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
2138 }
2139
2140 TaskRecord anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode) {
2141 return anyTaskForId(id, matchMode, null, !ON_TOP);
2142 }
2143
2144 /**
2145 * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise.
2146 * @param id Id of the task we would like returned.
2147 * @param matchMode The mode to match the given task id in.
2148 * @param aOptions The activity options to use for restoration. Can be null.
2149 * @param onTop If the stack for the task should be the topmost on the display.
2150 */
2151 TaskRecord anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode,
2152 @Nullable ActivityOptions aOptions, boolean onTop) {
2153 // If options are set, ensure that we are attempting to actually restore a task
2154 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
2155 throw new IllegalArgumentException("Should not specify activity options for non-restore"
2156 + " lookup");
2157 }
2158
2159 int numDisplays = mActivityDisplays.size();
2160 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2161 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2162 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2163 final ActivityStack stack = display.getChildAt(stackNdx);
2164 final TaskRecord task = stack.taskForIdLocked(id);
2165 if (task == null) {
2166 continue;
2167 }
2168 if (aOptions != null) {
2169 // Resolve the stack the task should be placed in now based on options
2170 // and reparent if needed.
2171 final ActivityStack launchStack =
2172 getLaunchStack(null, aOptions, task, onTop);
2173 if (launchStack != null && stack != launchStack) {
2174 final int reparentMode = onTop
2175 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
2176 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
2177 "anyTaskForId");
2178 }
2179 }
2180 return task;
2181 }
2182 }
2183
2184 // If we are matching stack tasks only, return now
2185 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
2186 return null;
2187 }
2188
2189 // Otherwise, check the recent tasks and return if we find it there and we are not restoring
2190 // the task from recents
2191 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
2192 final TaskRecord task = mStackSupervisor.mRecentTasks.getTask(id);
2193
2194 if (task == null) {
2195 if (DEBUG_RECENTS) {
2196 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
2197 }
2198
2199 return null;
2200 }
2201
2202 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
2203 return task;
2204 }
2205
2206 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
2207 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
2208 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
2209 "Couldn't restore task id=" + id + " found in recents");
2210 return null;
2211 }
2212 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
2213 return task;
2214 }
2215
2216 ActivityRecord isInAnyStack(IBinder token) {
2217 int numDisplays = mActivityDisplays.size();
2218 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2219 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2220 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2221 final ActivityStack stack = display.getChildAt(stackNdx);
2222 final ActivityRecord r = stack.isInStackLocked(token);
2223 if (r != null) {
2224 return r;
2225 }
2226 }
2227 }
2228 return null;
2229 }
2230
2231 @VisibleForTesting
2232 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
2233 @WindowConfiguration.ActivityType int ignoreActivityType,
2234 @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
2235 boolean allowed) {
2236 mStackSupervisor.mRunningTasks.getTasks(maxNum, list, ignoreActivityType,
2237 ignoreWindowingMode, mActivityDisplays, callingUid, allowed);
2238 }
2239
2240 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
2241 boolean sendHint = forceSend;
2242
2243 if (!sendHint) {
2244 // Send power hint if we don't know what we're launching yet
2245 sendHint = targetActivity == null || targetActivity.app == null;
2246 }
2247
2248 if (!sendHint) { // targetActivity != null
2249 // Send power hint when the activity's process is different than the current resumed
2250 // activity on all displays, or if there are no resumed activities in the system.
2251 boolean noResumedActivities = true;
2252 boolean allFocusedProcessesDiffer = true;
2253 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2254 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2255 final ActivityRecord resumedActivity = activityDisplay.getResumedActivity();
2256 final WindowProcessController resumedActivityProcess =
2257 resumedActivity == null ? null : resumedActivity.app;
2258
2259 noResumedActivities &= resumedActivityProcess == null;
2260 if (resumedActivityProcess != null) {
2261 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
2262 }
2263 }
2264 sendHint = noResumedActivities || allFocusedProcessesDiffer;
2265 }
2266
2267 if (sendHint && mService.mPowerManagerInternal != null) {
2268 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
2269 mPowerHintSent = true;
2270 }
2271 }
2272
2273 void sendPowerHintForLaunchEndIfNeeded() {
2274 // Trigger launch power hint if activity is launched
2275 if (mPowerHintSent && mService.mPowerManagerInternal != null) {
2276 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
2277 mPowerHintSent = false;
2278 }
2279 }
2280
2281 private void calculateDefaultMinimalSizeOfResizeableTasks() {
2282 final Resources res = mService.mContext.getResources();
2283 final float minimalSize = res.getDimension(
2284 com.android.internal.R.dimen.default_minimal_size_resizable_task);
2285 final DisplayMetrics dm = res.getDisplayMetrics();
2286
2287 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
2288 }
2289
2290 /**
2291 * Dumps the activities matching the given {@param name} in the either the focused stack
2292 * or all visible stacks if {@param dumpVisibleStacks} is true.
2293 */
2294 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
2295 boolean dumpFocusedStackOnly) {
2296 if (dumpFocusedStackOnly) {
2297 return getTopDisplayFocusedStack().getDumpActivitiesLocked(name);
2298 } else {
2299 ArrayList<ActivityRecord> activities = new ArrayList<>();
2300 int numDisplays = mActivityDisplays.size();
2301 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2302 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2303 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2304 final ActivityStack stack = display.getChildAt(stackNdx);
2305 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
2306 activities.addAll(stack.getDumpActivitiesLocked(name));
2307 }
2308 }
2309 }
2310 return activities;
2311 }
2312 }
2313
2314 public void dump(PrintWriter pw, String prefix) {
2315 pw.print(prefix);
2316 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
2317 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2318 final ActivityDisplay display = mActivityDisplays.get(i);
2319 display.dump(pw, prefix);
2320 }
2321 }
2322
2323 /**
2324 * Dump all connected displays' configurations.
2325 * @param prefix Prefix to apply to each line of the dump.
2326 */
2327 void dumpDisplayConfigs(PrintWriter pw, String prefix) {
2328 pw.print(prefix); pw.println("Display override configurations:");
2329 final int displayCount = mActivityDisplays.size();
2330 for (int i = 0; i < displayCount; i++) {
2331 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
2332 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": ");
Evan Roskydfe3da72018-10-26 17:21:06 -07002333 pw.println(activityDisplay.getRequestedOverrideConfiguration());
Wale Ogunwaled32da472018-11-16 07:19:28 -08002334 }
2335 }
2336
2337 public void dumpDisplays(PrintWriter pw) {
2338 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2339 final ActivityDisplay display = mActivityDisplays.get(i);
2340 pw.print("[id:" + display.mDisplayId + " stacks:");
2341 display.dumpStacks(pw);
2342 pw.print("]");
2343 }
2344 }
2345
2346 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
2347 String dumpPackage) {
2348 boolean printed = false;
2349 boolean needSep = false;
2350 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2351 ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2352 pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
2353 pw.println(" (activities from top to bottom):");
2354 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2355 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2356 final ActivityStack stack = display.getChildAt(stackNdx);
2357 pw.println();
Garfield Tan347bd602018-12-21 15:11:12 -08002358 printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002359 needSep = printed;
2360 }
2361 printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep,
2362 " ResumedActivity:");
2363 }
2364
2365 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ",
2366 "Fin", false, !dumpAll,
2367 false, dumpPackage, true, " Activities waiting to finish:", null);
2368 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
2369 "Stop", false, !dumpAll,
2370 false, dumpPackage, true, " Activities waiting to stop:", null);
2371 printed |= dumpHistoryList(fd, pw,
2372 mStackSupervisor.mActivitiesWaitingForVisibleActivity, " ", "Wait",
2373 false, !dumpAll, false, dumpPackage, true,
2374 " Activities waiting for another to become visible:", null);
2375 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
2376 " ", "Sleep", false, !dumpAll,
2377 false, dumpPackage, true, " Activities waiting to sleep:", null);
2378
2379 return printed;
2380 }
2381
Nataniel Borges023ecb52019-01-16 14:15:43 -08002382 protected void writeToProto(ProtoOutputStream proto, long fieldId,
2383 @WindowTraceLogLevel int logLevel) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002384 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002385 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002386 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2387 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002388 activityDisplay.writeToProto(proto, DISPLAYS, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002389 }
2390 mStackSupervisor.getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER);
2391 // TODO(b/111541062): Update tests to look for resumed activities on all displays
2392 final ActivityStack focusedStack = getTopDisplayFocusedStack();
2393 if (focusedStack != null) {
2394 proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
2395 final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
2396 if (focusedActivity != null) {
2397 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
2398 }
2399 } else {
2400 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
2401 }
2402 proto.write(IS_HOME_RECENTS_COMPONENT,
2403 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
2404 mService.getActivityStartController().writeToProto(proto, PENDING_ACTIVITIES);
2405 proto.end(token);
2406 }
2407
2408 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
2409 private final String mTag;
2410 private final long mAcquireTime;
2411 private final int mDisplayId;
2412
2413 public SleepTokenImpl(String tag, int displayId) {
2414 mTag = tag;
2415 mDisplayId = displayId;
2416 mAcquireTime = SystemClock.uptimeMillis();
2417 }
2418
2419 @Override
2420 public void release() {
2421 synchronized (mService.mGlobalLock) {
2422 removeSleepToken(this);
2423 }
2424 }
2425
2426 @Override
2427 public String toString() {
2428 return "{\"" + mTag + "\", display " + mDisplayId
2429 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
2430 }
2431 }
2432}