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