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