blob: 60833c38c9c1d175a8f43083670cb8c78a66fc45 [file] [log] [blame]
Wale Ogunwaled32da472018-11-16 07:19:28 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
19import static android.app.ActivityTaskManager.INVALID_STACK_ID;
20import static android.app.ActivityTaskManager.INVALID_TASK_ID;
21import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
22import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
23import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
24import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
25import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
26import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
27import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
28import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
29import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwaled32da472018-11-16 07:19:28 -080030import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwaled32da472018-11-16 07:19:28 -080031import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
32import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
33import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Wale Ogunwaled32da472018-11-16 07:19:28 -080034import static android.view.Display.DEFAULT_DISPLAY;
35import static android.view.Display.INVALID_DISPLAY;
Issei Suzukicac2a502019-04-16 16:52:50 +020036import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
Wale Ogunwaled32da472018-11-16 07:19:28 -080037
38import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
39import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
40import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
41import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
42import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
43import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
44import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
45import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
46import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
47import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
48import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
49import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
50import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
51import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
52import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
53import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
54import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
55import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
56import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
57import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
58import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
59import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
60import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
61import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
62import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
63import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
64import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
65import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
66import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
67import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
68
69import static java.lang.Integer.MAX_VALUE;
70
71import android.annotation.IntDef;
72import android.annotation.NonNull;
73import android.annotation.Nullable;
74import android.annotation.UserIdInt;
75import android.app.ActivityManager;
76import android.app.ActivityOptions;
77import android.app.AppGlobals;
78import android.app.WindowConfiguration;
79import android.content.ComponentName;
80import android.content.Intent;
81import android.content.pm.ActivityInfo;
82import android.content.pm.ApplicationInfo;
83import android.content.pm.ResolveInfo;
84import android.content.res.Configuration;
85import android.content.res.Resources;
86import android.graphics.Rect;
87import android.hardware.display.DisplayManager;
88import android.hardware.display.DisplayManagerInternal;
89import android.hardware.power.V1_0.PowerHint;
Wale Ogunwaled32da472018-11-16 07:19:28 -080090import android.os.FactoryTest;
91import android.os.IBinder;
92import android.os.RemoteException;
93import android.os.SystemClock;
Wale Ogunwaled32da472018-11-16 07:19:28 -080094import android.os.UserHandle;
Chilun85ebc0d2019-04-15 16:00:53 +080095import android.os.storage.StorageManager;
Chilun2ef71f72018-11-16 17:57:15 +080096import android.provider.Settings;
Wale Ogunwaled32da472018-11-16 07:19:28 -080097import android.service.voice.IVoiceInteractionSession;
98import android.util.ArraySet;
99import android.util.DisplayMetrics;
100import android.util.IntArray;
Chilun2ef71f72018-11-16 17:57:15 +0800101import android.util.Pair;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800102import android.util.Slog;
103import android.util.SparseArray;
104import android.util.SparseIntArray;
105import android.util.TimeUtils;
106import android.util.proto.ProtoOutputStream;
107import android.view.Display;
108import android.view.DisplayInfo;
109
110import com.android.internal.annotations.VisibleForTesting;
Chilun2ef71f72018-11-16 17:57:15 +0800111import com.android.internal.app.ResolverActivity;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800112import com.android.server.LocalServices;
113import com.android.server.am.ActivityManagerService;
114import com.android.server.am.AppTimeTracker;
115import com.android.server.am.UserState;
Chilun8b1f1be2019-03-13 17:14:36 +0800116import com.android.server.policy.WindowManagerPolicy;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800117
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
Louis Changa5d070e2019-09-04 13:20:01 +0800196 /** Used to keep ensureActivitiesVisible() from being entered recursively. */
197 private boolean mInEnsureActivitiesVisible = false;
198
Wale Ogunwaled32da472018-11-16 07:19:28 -0800199 // The default minimal size that will be used if the activity doesn't specify its minimal size.
200 // It will be calculated when the default display gets added.
201 int mDefaultMinSizeOfResizeableTaskDp = -1;
202
203 // Whether tasks have moved and we need to rank the tasks before next OOM scoring
204 private boolean mTaskLayersChanged = true;
205
206 private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
207
208 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
209 static class FindTaskResult {
210 ActivityRecord mRecord;
211 boolean mIdealMatch;
212
213 void clear() {
214 mRecord = null;
215 mIdealMatch = false;
216 }
217
218 void setTo(FindTaskResult result) {
219 mRecord = result.mRecord;
220 mIdealMatch = result.mIdealMatch;
221 }
222 }
223
224 RootActivityContainer(ActivityTaskManagerService service) {
225 mService = service;
226 mStackSupervisor = service.mStackSupervisor;
227 mStackSupervisor.mRootActivityContainer = this;
228 }
229
Wale Ogunwaled32da472018-11-16 07:19:28 -0800230 void setWindowManager(WindowManagerService wm) {
231 mWindowManager = wm;
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700232 mRootWindowContainer = mWindowManager.mRoot;
233 mRootWindowContainer.setRootActivityContainer(this);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800234 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
Charles Chen699e3602019-01-10 15:00:25 +0800235 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800236 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
237
238 final Display[] displays = mDisplayManager.getDisplays();
239 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
240 final Display display = displays[displayNdx];
241 final ActivityDisplay activityDisplay = new ActivityDisplay(this, display);
242 if (activityDisplay.mDisplayId == DEFAULT_DISPLAY) {
243 mDefaultDisplay = activityDisplay;
244 }
245 addChild(activityDisplay, ActivityDisplay.POSITION_TOP);
246 }
247 calculateDefaultMinimalSizeOfResizeableTasks();
248
249 final ActivityDisplay defaultDisplay = getDefaultDisplay();
250
251 defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
252 positionChildAt(defaultDisplay, ActivityDisplay.POSITION_TOP);
253 }
254
255 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
256 ActivityDisplay getDefaultDisplay() {
257 return mDefaultDisplay;
258 }
259
260 /**
261 * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is
262 * defined in {@link DisplayInfo#uniqueId}.
263 *
264 * @param uniqueId the unique ID of the display
265 * @return the {@link ActivityDisplay} or {@code null} if nothing is found.
266 */
267 ActivityDisplay getActivityDisplay(String uniqueId) {
268 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
269 final ActivityDisplay display = mActivityDisplays.get(i);
270 final boolean isValid = display.mDisplay.isValid();
271 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
272 return display;
273 }
274 }
275
276 return null;
277 }
278
279 // TODO: Look into consolidating with getActivityDisplayOrCreate()
280 ActivityDisplay getActivityDisplay(int displayId) {
281 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
282 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
283 if (activityDisplay.mDisplayId == displayId) {
284 return activityDisplay;
285 }
286 }
287 return null;
288 }
289
290 /**
291 * Get an existing instance of {@link ActivityDisplay} or create new if there is a
292 * corresponding record in display manager.
293 */
294 // TODO: Look into consolidating with getActivityDisplay()
Charles Chenb409e6c2019-02-12 12:30:17 +0800295 @Nullable ActivityDisplay getActivityDisplayOrCreate(int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800296 ActivityDisplay activityDisplay = getActivityDisplay(displayId);
297 if (activityDisplay != null) {
298 return activityDisplay;
299 }
300 if (mDisplayManager == null) {
301 // The system isn't fully initialized yet.
302 return null;
303 }
304 final Display display = mDisplayManager.getDisplay(displayId);
305 if (display == null) {
306 // The display is not registered in DisplayManager.
307 return null;
308 }
309 // The display hasn't been added to ActivityManager yet, create a new record now.
310 activityDisplay = new ActivityDisplay(this, display);
311 addChild(activityDisplay, ActivityDisplay.POSITION_BOTTOM);
312 return activityDisplay;
313 }
314
Wale Ogunwaled32da472018-11-16 07:19:28 -0800315 ActivityRecord getDefaultDisplayHomeActivity() {
316 return getDefaultDisplayHomeActivityForUser(mCurrentUser);
317 }
318
319 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
320 return getActivityDisplay(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
321 }
322
323 boolean startHomeOnAllDisplays(int userId, String reason) {
324 boolean homeStarted = false;
325 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
326 final int displayId = mActivityDisplays.get(i).mDisplayId;
327 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
328 }
329 return homeStarted;
330 }
331
Louis Changdcdde952018-12-04 15:38:44 +0800332 void startHomeOnEmptyDisplays(String reason) {
333 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
334 final ActivityDisplay display = mActivityDisplays.get(i);
335 if (display.topRunningActivity() == null) {
336 startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
337 }
338 }
339 }
340
Chilun8b1f1be2019-03-13 17:14:36 +0800341 boolean startHomeOnDisplay(int userId, String reason, int displayId) {
Chilun39232092019-03-22 14:41:30 +0800342 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
343 false /* fromHomeKey */);
Chilun8b1f1be2019-03-13 17:14:36 +0800344 }
345
Wale Ogunwaled32da472018-11-16 07:19:28 -0800346 /**
Chilun2ef71f72018-11-16 17:57:15 +0800347 * This starts home activity on displays that can have system decorations based on displayId -
348 * Default display always use primary home component.
349 * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
350 * according to the priorities listed below.
351 * - If default home is not set, always use the secondary home defined in the config.
352 * - Use currently selected primary home activity.
353 * - Use the activity in the same package as currently selected primary home activity.
354 * If there are multiple activities matched, use first one.
355 * - Use the secondary home defined in the config.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800356 */
Chilun39232092019-03-22 14:41:30 +0800357 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
358 boolean fromHomeKey) {
Chilun8b1f1be2019-03-13 17:14:36 +0800359 // Fallback to top focused display if the displayId is invalid.
360 if (displayId == INVALID_DISPLAY) {
361 displayId = getTopDisplayFocusedStack().mDisplayId;
362 }
363
Chilun85ebc0d2019-04-15 16:00:53 +0800364 Intent homeIntent = null;
365 ActivityInfo aInfo = null;
Chilun2ef71f72018-11-16 17:57:15 +0800366 if (displayId == DEFAULT_DISPLAY) {
367 homeIntent = mService.getHomeIntent();
368 aInfo = resolveHomeActivity(userId, homeIntent);
Chilun85ebc0d2019-04-15 16:00:53 +0800369 } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Chilun2ef71f72018-11-16 17:57:15 +0800370 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
371 aInfo = info.first;
372 homeIntent = info.second;
373 }
Chilun85ebc0d2019-04-15 16:00:53 +0800374 if (aInfo == null || homeIntent == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800375 return false;
376 }
377
Chilun39232092019-03-22 14:41:30 +0800378 if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800379 return false;
380 }
381
Chilun2ef71f72018-11-16 17:57:15 +0800382 // Updates the home component of the intent.
383 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
384 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
Chilun8b1f1be2019-03-13 17:14:36 +0800385 // Updates the extra information of the intent.
386 if (fromHomeKey) {
387 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
388 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800389 // Update the reason for ANR debugging to verify if the user activity is the one that
390 // actually launched.
391 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
Chilun2ef71f72018-11-16 17:57:15 +0800392 aInfo.applicationInfo.uid) + ":" + displayId;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800393 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
394 displayId);
395 return true;
396 }
397
398 /**
Chilun2ef71f72018-11-16 17:57:15 +0800399 * This resolves the home activity info.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800400 * @return the home activity info if any.
401 */
Chilun2ef71f72018-11-16 17:57:15 +0800402 @VisibleForTesting
403 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800404 final int flags = ActivityManagerService.STOCK_PM_FLAGS;
405 final ComponentName comp = homeIntent.getComponent();
406 ActivityInfo aInfo = null;
407 try {
408 if (comp != null) {
409 // Factory test.
410 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
411 } else {
412 final String resolvedType =
413 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
414 final ResolveInfo info = AppGlobals.getPackageManager()
415 .resolveIntent(homeIntent, resolvedType, flags, userId);
416 if (info != null) {
417 aInfo = info.activityInfo;
418 }
419 }
420 } catch (RemoteException e) {
421 // ignore
422 }
423
424 if (aInfo == null) {
425 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
426 return null;
427 }
428
Wale Ogunwaled32da472018-11-16 07:19:28 -0800429 aInfo = new ActivityInfo(aInfo);
430 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800431 return aInfo;
432 }
433
Chilun2ef71f72018-11-16 17:57:15 +0800434 @VisibleForTesting
435 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) {
436 if (displayId == DEFAULT_DISPLAY) {
437 throw new IllegalArgumentException(
438 "resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY");
439 }
440 // Resolve activities in the same package as currently selected primary home activity.
441 Intent homeIntent = mService.getHomeIntent();
442 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
443 if (aInfo != null) {
444 if (ResolverActivity.class.getName().equals(aInfo.name)) {
445 // Always fallback to secondary home component if default home is not set.
446 aInfo = null;
447 } else {
448 // Look for secondary home activities in the currently selected default home
449 // package.
450 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
451 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
452 final int size = resolutions.size();
453 final String targetName = aInfo.name;
454 aInfo = null;
455 for (int i = 0; i < size; i++) {
456 ResolveInfo resolveInfo = resolutions.get(i);
457 // We need to traverse all resolutions to check if the currently selected
458 // default home activity is present.
459 if (resolveInfo.activityInfo.name.equals(targetName)) {
460 aInfo = resolveInfo.activityInfo;
461 break;
462 }
463 }
464 if (aInfo == null && size > 0) {
465 // First one is the best.
466 aInfo = resolutions.get(0).activityInfo;
467 }
468 }
469 }
470
471 if (aInfo != null) {
472 if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
473 aInfo = null;
474 }
475 }
476
477 // Fallback to secondary home component.
478 if (aInfo == null) {
479 homeIntent = mService.getSecondaryHomeIntent(null);
480 aInfo = resolveHomeActivity(userId, homeIntent);
481 }
482 return Pair.create(aInfo, homeIntent);
483 }
484
485 /**
486 * Retrieve all activities that match the given intent.
487 * The list should already ordered from best to worst matched.
488 * {@link android.content.pm.PackageManager#queryIntentActivities}
489 */
490 @VisibleForTesting
491 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
492 List<ResolveInfo> resolutions;
493 try {
494 final String resolvedType =
495 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
496 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
497 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
498
499 } catch (RemoteException e) {
500 resolutions = new ArrayList<>();
501 }
502 return resolutions;
503 }
504
Wale Ogunwaled32da472018-11-16 07:19:28 -0800505 boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
506 if (!mService.isBooting() && !mService.isBooted()) {
507 // Not ready yet!
508 return false;
509 }
510
511 if (displayId == INVALID_DISPLAY) {
512 displayId = DEFAULT_DISPLAY;
513 }
514
515 final ActivityRecord r = getActivityDisplay(displayId).getHomeActivity();
516 final String myReason = reason + " resumeHomeActivity";
517
518 // Only resume home activity if isn't finishing.
519 if (r != null && !r.finishing) {
520 r.moveFocusableActivityToTop(myReason);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800521 return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800522 }
523 return startHomeOnDisplay(mCurrentUser, myReason, displayId);
524 }
525
526 /**
Chilun85ebc0d2019-04-15 16:00:53 +0800527 * Check if the display is valid for secondary home activity.
528 * @param displayId The id of the target display.
529 * @return {@code true} if allow to launch, {@code false} otherwise.
530 */
531 boolean shouldPlaceSecondaryHomeOnDisplay(int displayId) {
532 if (displayId == DEFAULT_DISPLAY) {
533 throw new IllegalArgumentException(
534 "shouldPlaceSecondaryHomeOnDisplay: Should not be DEFAULT_DISPLAY");
535 } else if (displayId == INVALID_DISPLAY) {
536 return false;
537 }
538
539 if (!mService.mSupportsMultiDisplay) {
540 // Can't launch home on secondary display if device does not support multi-display.
541 return false;
542 }
543
544 final boolean deviceProvisioned = Settings.Global.getInt(
545 mService.mContext.getContentResolver(),
546 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
547 if (!deviceProvisioned) {
548 // Can't launch home on secondary display before device is provisioned.
549 return false;
550 }
551
552 if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
553 // Can't launch home on secondary displays if device is still locked.
554 return false;
555 }
556
557 final ActivityDisplay display = getActivityDisplay(displayId);
558 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
559 // Can't launch home on display that doesn't support system decorations.
560 return false;
561 }
562
563 return true;
564 }
565
566 /**
Wale Ogunwaled32da472018-11-16 07:19:28 -0800567 * Check if home activity start should be allowed on a display.
568 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
569 * @param displayId The id of the target display.
570 * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
571 * @return {@code true} if allow to launch, {@code false} otherwise.
572 */
573 boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId,
574 boolean allowInstrumenting) {
575 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
576 && mService.mTopAction == null) {
577 // We are running in factory test mode, but unable to find the factory test app, so
578 // just sit around displaying the error message and don't try to start anything.
579 return false;
580 }
581
582 final WindowProcessController app =
583 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
584 if (!allowInstrumenting && app != null && app.isInstrumenting()) {
585 // Don't do this if the home app is currently being instrumented.
586 return false;
587 }
588
589 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
590 && displayId == mService.mVr2dDisplayId)) {
591 // No restrictions to default display or vr 2d display.
592 return true;
593 }
594
Chilun85ebc0d2019-04-15 16:00:53 +0800595 if (!shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800596 return false;
597 }
598
599 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
Chilun2ef71f72018-11-16 17:57:15 +0800600 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800601 if (!supportMultipleInstance) {
Chilun2ef71f72018-11-16 17:57:15 +0800602 // Can't launch home on secondary displays if it requested to be single instance.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800603 return false;
604 }
605
606 return true;
607 }
608
609 /**
610 * Ensure all activities visibility, update orientation and configuration.
611 *
612 * @param starting The currently starting activity or {@code null} if there is none.
613 * @param displayId The id of the display where operation is executed.
614 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
615 * {@code true} if config changed.
616 * @param deferResume Whether to defer resume while updating config.
617 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
618 * because of configuration update.
619 */
620 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
621 boolean markFrozenIfConfigChanged, boolean deferResume) {
622 // First ensure visibility without updating the config just yet. We need this to know what
623 // activities are affecting configuration now.
624 // Passing null here for 'starting' param value, so that visibility of actual starting
625 // activity will be properly updated.
626 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
627 false /* preserveWindows */, false /* notifyClients */);
628
629 if (displayId == INVALID_DISPLAY) {
630 // The caller didn't provide a valid display id, skip updating config.
631 return true;
632 }
633
634 // Force-update the orientation from the WindowManager, since we need the true configuration
635 // to send to the client now.
Garfield Tan90b04282018-12-11 14:04:42 -0800636 final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId);
637 Configuration config = null;
638 if (displayContent != null) {
Riddle Hsuccf09402019-08-13 00:33:06 +0800639 config = displayContent.updateOrientation(
Garfield Tan90b04282018-12-11 14:04:42 -0800640 getDisplayOverrideConfiguration(displayId),
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800641 starting != null && starting.mayFreezeScreenLocked()
Garfield Tan90b04282018-12-11 14:04:42 -0800642 ? starting.appToken : null,
643 true /* forceUpdate */);
644 }
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800645 // Visibilities may change so let the starting activity have a chance to report. Can't do it
646 // when visibility is changed in each AppWindowToken because it may trigger wrong
647 // configuration push because the visibility of some activities may not be updated yet.
648 if (starting != null) {
649 starting.reportDescendantOrientationChangeIfNeeded();
650 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800651 if (starting != null && markFrozenIfConfigChanged && config != null) {
652 starting.frozenBeforeDestroy = true;
653 }
654
Riddle Hsud1549d22019-10-07 17:00:47 +0800655 if (displayContent != null && displayContent.mActivityDisplay != null) {
Shivam Agrawal1d3db652019-07-01 15:26:11 -0700656 // Update the configuration of the activities on the display.
Riddle Hsud1549d22019-10-07 17:00:47 +0800657 return displayContent.mActivityDisplay.updateDisplayOverrideConfigurationLocked(config,
Shivam Agrawal1d3db652019-07-01 15:26:11 -0700658 starting, deferResume, null /* result */);
659 } else {
660 return true;
661 }
Wale Ogunwaled32da472018-11-16 07:19:28 -0800662 }
663
664 /**
665 * @return a list of activities which are the top ones in each visible stack. The first
666 * entry will be the focused activity.
667 */
668 List<IBinder> getTopVisibleActivities() {
669 final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
670 final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
671 // Traverse all displays.
672 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
673 final ActivityDisplay display = mActivityDisplays.get(i);
674 // Traverse all stacks on a display.
675 for (int j = display.getChildCount() - 1; j >= 0; --j) {
676 final ActivityStack stack = display.getChildAt(j);
677 // Get top activity from a visible stack and add it to the list.
678 if (stack.shouldBeVisible(null /* starting */)) {
679 final ActivityRecord top = stack.getTopActivity();
680 if (top != null) {
681 if (stack == topFocusedStack) {
682 topActivityTokens.add(0, top.appToken);
683 } else {
684 topActivityTokens.add(top.appToken);
685 }
686 }
687 }
688 }
689 }
690 return topActivityTokens;
691 }
692
693 ActivityStack getTopDisplayFocusedStack() {
694 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
695 final ActivityStack focusedStack = mActivityDisplays.get(i).getFocusedStack();
696 if (focusedStack != null) {
697 return focusedStack;
698 }
699 }
700 return null;
701 }
702
703 ActivityRecord getTopResumedActivity() {
704 final ActivityStack focusedStack = getTopDisplayFocusedStack();
705 if (focusedStack == null) {
706 return null;
707 }
708 final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
709 if (resumedActivity != null && resumedActivity.app != null) {
710 return resumedActivity;
711 }
712 // The top focused stack might not have a resumed activity yet - look on all displays in
713 // focus order.
714 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
715 final ActivityDisplay display = mActivityDisplays.get(i);
716 final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity();
717 if (resumedActivityOnDisplay != null) {
718 return resumedActivityOnDisplay;
719 }
720 }
721 return null;
722 }
723
724 boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
725 if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) {
726 return false;
727 }
728
729 return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
730 }
731
732 boolean isTopDisplayFocusedStack(ActivityStack stack) {
733 return stack != null && stack == getTopDisplayFocusedStack();
734 }
735
736 void updatePreviousProcess(ActivityRecord r) {
737 // Now that this process has stopped, we may want to consider it to be the previous app to
738 // try to keep around in case the user wants to return to it.
739
740 // First, found out what is currently the foreground app, so that we don't blow away the
741 // previous app if this activity is being hosted by the process that is actually still the
742 // foreground.
743 WindowProcessController fgApp = null;
744 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
745 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
746 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
747 final ActivityStack stack = display.getChildAt(stackNdx);
748 if (isTopDisplayFocusedStack(stack)) {
749 final ActivityRecord resumedActivity = stack.getResumedActivity();
750 if (resumedActivity != null) {
751 fgApp = resumedActivity.app;
752 } else if (stack.mPausingActivity != null) {
753 fgApp = stack.mPausingActivity.app;
754 }
755 break;
756 }
757 }
758 }
759
760 // Now set this one as the previous process, only if that really makes sense to.
761 if (r.hasProcess() && fgApp != null && r.app != fgApp
762 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
763 && r.app != mService.mHomeProcess) {
764 mService.mPreviousProcess = r.app;
765 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
766 }
767 }
768
769 boolean attachApplication(WindowProcessController app) throws RemoteException {
770 final String processName = app.mName;
771 boolean didSomething = false;
772 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
773 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
774 final ActivityStack stack = display.getFocusedStack();
775 if (stack != null) {
776 stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
777 final ActivityRecord top = stack.topRunningActivityLocked();
778 final int size = mTmpActivityList.size();
779 for (int i = 0; i < size; i++) {
780 final ActivityRecord activity = mTmpActivityList.get(i);
781 if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
782 && processName.equals(activity.processName)) {
783 try {
784 if (mStackSupervisor.realStartActivityLocked(activity, app,
785 top == activity /* andResume */, true /* checkConfig */)) {
786 didSomething = true;
787 }
788 } catch (RemoteException e) {
789 Slog.w(TAG, "Exception in new application when starting activity "
790 + top.intent.getComponent().flattenToShortString(), e);
791 throw e;
792 }
793 }
794 }
795 }
796 }
797 if (!didSomething) {
798 ensureActivitiesVisible(null, 0, false /* preserve_windows */);
799 }
800 return didSomething;
801 }
802
803 /**
804 * Make sure that all activities that need to be visible in the system actually are and update
805 * their configuration.
806 */
807 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
808 boolean preserveWindows) {
809 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
810 }
811
812 /**
813 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
814 */
815 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
816 boolean preserveWindows, boolean notifyClients) {
Louis Changa5d070e2019-09-04 13:20:01 +0800817 if (mInEnsureActivitiesVisible) {
818 // Don't do recursive work.
819 return;
820 }
821 mInEnsureActivitiesVisible = true;
822
Wale Ogunwaled32da472018-11-16 07:19:28 -0800823 try {
Louis Changa5d070e2019-09-04 13:20:01 +0800824 mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800825 // First the front stacks. In case any are not fullscreen and are in front of home.
826 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
827 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Louis Chang77ce34d2019-01-03 15:45:12 +0800828 display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
829 notifyClients);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800830 }
831 } finally {
832 mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
Louis Changa5d070e2019-09-04 13:20:01 +0800833 mInEnsureActivitiesVisible = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800834 }
835 }
836
837 boolean switchUser(int userId, UserState uss) {
838 final int focusStackId = getTopDisplayFocusedStack().getStackId();
839 // We dismiss the docked stack whenever we switch users.
840 final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
841 if (dockedStack != null) {
842 mStackSupervisor.moveTasksToFullscreenStackLocked(
843 dockedStack, dockedStack.isFocusedStackOnDisplay());
844 }
845 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
846 // also cause all tasks to be moved to the fullscreen stack at a position that is
847 // appropriate.
848 removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
849
850 mUserStackInFront.put(mCurrentUser, focusStackId);
851 final int restoreStackId =
852 mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId);
853 mCurrentUser = userId;
854
855 mStackSupervisor.mStartingUsers.add(uss);
856 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
857 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
858 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
859 final ActivityStack stack = display.getChildAt(stackNdx);
860 stack.switchUserLocked(userId);
861 TaskRecord task = stack.topTask();
862 if (task != null) {
863 stack.positionChildWindowContainerAtTop(task);
864 }
865 }
866 }
867
868 ActivityStack stack = getStack(restoreStackId);
869 if (stack == null) {
870 stack = getDefaultDisplay().getHomeStack();
871 }
872 final boolean homeInFront = stack.isActivityTypeHome();
873 if (stack.isOnHomeDisplay()) {
874 stack.moveToFront("switchUserOnHomeDisplay");
875 } else {
876 // Stack was moved to another display while user was swapped out.
877 resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
878 }
879 return homeInFront;
880 }
881
882 void removeUser(int userId) {
883 mUserStackInFront.delete(userId);
884 }
885
886 /**
887 * Update the last used stack id for non-current user (current user's last
888 * used stack is the focused stack)
889 */
890 void updateUserStack(int userId, ActivityStack stack) {
891 if (userId != mCurrentUser) {
892 mUserStackInFront.put(userId, stack != null ? stack.getStackId()
893 : getDefaultDisplay().getHomeStack().mStackId);
894 }
895 }
896
Wale Ogunwaled32da472018-11-16 07:19:28 -0800897 /**
898 * Move stack with all its existing content to specified display.
899 * @param stackId Id of stack to move.
900 * @param displayId Id of display to move stack to.
901 * @param onTop Indicates whether container should be place on top or on bottom.
902 */
903 void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
904 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
905 if (activityDisplay == null) {
906 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
907 + displayId);
908 }
909 final ActivityStack stack = getStack(stackId);
910 if (stack == null) {
911 throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId="
912 + stackId);
913 }
914
915 final ActivityDisplay currentDisplay = stack.getDisplay();
916 if (currentDisplay == null) {
917 throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack
918 + " is not attached to any display.");
919 }
920
921 if (currentDisplay.mDisplayId == displayId) {
922 throw new IllegalArgumentException("Trying to move stack=" + stack
923 + " to its current displayId=" + displayId);
924 }
925
Wale Ogunwale9e737db2018-12-17 15:42:37 -0800926 if (activityDisplay.isSingleTaskInstance() && activityDisplay.getChildCount() > 0) {
927 // We don't allow moving stacks to single instance display that already has a child.
928 Slog.e(TAG, "Can not move stack=" + stack
929 + " to single task instance display=" + activityDisplay);
930 return;
931 }
932
Wale Ogunwaled32da472018-11-16 07:19:28 -0800933 stack.reparent(activityDisplay, onTop, false /* displayRemoved */);
934 // TODO(multi-display): resize stacks properly if moved from split-screen.
935 }
936
937 boolean moveTopStackActivityToPinnedStack(int stackId) {
938 final ActivityStack stack = getStack(stackId);
939 if (stack == null) {
940 throw new IllegalArgumentException(
941 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
942 }
943
944 final ActivityRecord r = stack.topRunningActivityLocked();
945 if (r == null) {
946 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
947 + " in stack=" + stack);
948 return false;
949 }
950
951 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
952 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
953 + " r=" + r);
954 return false;
955 }
956
957 moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */,
958 "moveTopActivityToPinnedStack");
959 return true;
960 }
961
962 void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
963 String reason) {
Riddle Hsua0022cd2019-09-09 21:12:41 +0800964 mService.deferWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800965
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800966 final ActivityDisplay display = r.getActivityStack().getDisplay();
Yunfan Chen279f5582018-12-12 15:24:50 -0800967 ActivityStack stack = display.getPinnedStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800968
969 // This will clear the pinned stack by moving an existing task to the full screen stack,
970 // ensuring only one task is present.
971 if (stack != null) {
972 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, !ON_TOP);
973 }
974
975 // Need to make sure the pinned stack exist so we can resize it below...
976 stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP);
977
Wale Ogunwaled32da472018-11-16 07:19:28 -0800978 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800979 final TaskRecord task = r.getTaskRecord();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800980 // Resize the pinned stack to match the current size of the task the activity we are
981 // going to be moving is currently contained in. We do this to have the right starting
982 // animation bounds for the pinned stack to the desired bounds the caller wants.
Evan Roskydbe2ce52019-07-18 11:13:17 -0700983 stack.resize(task.getRequestedOverrideBounds(), null /* tempTaskBounds */,
984 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, !DEFER_RESUME);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800985
Wale Ogunwale1a06f152019-10-11 11:26:30 +0200986 if (task.getChildCount() == 1) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800987 // Defer resume until below, and do not schedule PiP changes until we animate below
988 task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME,
989 false /* schedulePictureInPictureModeChange */, reason);
990 } else {
991 // There are multiple activities in the task and moving the top activity should
992 // reveal/leave the other activities in their original task.
993
994 // Currently, we don't support reparenting activities across tasks in two different
995 // stacks, so instead, just create a new task in the same stack, reparent the
996 // activity into that task, and then reparent the whole task to the new stack. This
997 // ensures that all the necessary work to migrate states in the old and new stacks
998 // is also done.
999 final TaskRecord newTask = task.getStack().createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001000 mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001001 r.intent, null, null, true);
1002 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
1003
1004 // Defer resume until below, and do not schedule PiP changes until we animate below
1005 newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
1006 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
1007 }
1008
1009 // Reset the state that indicates it can enter PiP while pausing after we've moved it
1010 // to the pinned stack
1011 r.supportsEnterPipOnTaskSwitch = false;
1012 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001013 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001014 }
1015
Hongwei Wang43a752b2019-09-17 20:20:30 +00001016 // Notify the pinned stack controller to prepare the PiP animation, expect callback
1017 // delivered from SystemUI to WM to start the animation.
1018 final PinnedStackController pinnedStackController =
1019 display.mDisplayContent.getPinnedStackController();
1020 pinnedStackController.prepareAnimation(sourceHintBounds, aspectRatio,
1021 null /* stackBounds */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001022
Hongwei Wang43a752b2019-09-17 20:20:30 +00001023 // TODO: revisit the following statement after the animation is moved from WM to SysUI.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001024 // Update the visibility of all activities after the they have been reparented to the new
1025 // stack. This MUST run after the animation above is scheduled to ensure that the windows
1026 // drawn signal is scheduled after the bounds animation start call on the bounds animator
1027 // thread.
1028 ensureActivitiesVisible(null, 0, false /* preserveWindows */);
1029 resumeFocusedStacksTopActivities();
1030
1031 mService.getTaskChangeNotificationController().notifyActivityPinned(r);
1032 }
1033
1034 void executeAppTransitionForAllDisplay() {
1035 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1036 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001037 display.mDisplayContent.executeAppTransition();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001038 }
1039 }
1040
1041 void setDockedStackMinimized(boolean minimized) {
1042 // Get currently focused stack before setting mIsDockMinimized. We do this because if
1043 // split-screen is active, primary stack will not be focusable (see #isFocusable) while
1044 // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
1045 final ActivityStack current = getTopDisplayFocusedStack();
1046 mIsDockMinimized = minimized;
1047 if (mIsDockMinimized) {
1048 if (current.inSplitScreenPrimaryWindowingMode()) {
1049 // The primary split-screen stack can't be focused while it is minimize, so move
1050 // focus to something else.
1051 current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
1052 }
1053 }
1054 }
1055
1056 ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
1057 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
1058 mTmpFindTaskResult.clear();
1059
1060 // Looking up task on preferred display first
1061 final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId);
1062 if (preferredDisplay != null) {
1063 preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult);
1064 if (mTmpFindTaskResult.mIdealMatch) {
1065 return mTmpFindTaskResult.mRecord;
1066 }
1067 }
1068
1069 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1070 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1071 if (display.mDisplayId == preferredDisplayId) {
1072 continue;
1073 }
1074
1075 display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult);
1076 if (mTmpFindTaskResult.mIdealMatch) {
1077 return mTmpFindTaskResult.mRecord;
1078 }
1079 }
1080
1081 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
1082 return mTmpFindTaskResult.mRecord;
1083 }
1084
1085 /**
1086 * Finish the topmost activities in all stacks that belong to the crashed app.
1087 * @param app The app that crashed.
1088 * @param reason Reason to perform this action.
1089 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
1090 */
1091 int finishTopCrashedActivities(WindowProcessController app, String reason) {
1092 TaskRecord finishedTask = null;
1093 ActivityStack focusedStack = getTopDisplayFocusedStack();
1094 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1095 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1096 // It is possible that request to finish activity might also remove its task and stack,
1097 // so we need to be careful with indexes in the loop and check child count every time.
1098 for (int stackNdx = 0; stackNdx < display.getChildCount(); ++stackNdx) {
1099 final ActivityStack stack = display.getChildAt(stackNdx);
1100 final TaskRecord t = stack.finishTopCrashedActivityLocked(app, reason);
1101 if (stack == focusedStack || finishedTask == null) {
1102 finishedTask = t;
1103 }
1104 }
1105 }
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001106 return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001107 }
1108
1109 boolean resumeFocusedStacksTopActivities() {
1110 return resumeFocusedStacksTopActivities(null, null, null);
1111 }
1112
1113 boolean resumeFocusedStacksTopActivities(
1114 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1115
1116 if (!mStackSupervisor.readyToResume()) {
1117 return false;
1118 }
1119
Andrii Kulian6b321512019-01-23 06:37:00 +00001120 boolean result = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001121 if (targetStack != null && (targetStack.isTopStackOnDisplay()
1122 || getTopDisplayFocusedStack() == targetStack)) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001123 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001124 }
1125
Wale Ogunwaled32da472018-11-16 07:19:28 -08001126 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001127 boolean resumedOnDisplay = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001128 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Andrii Kulian6b321512019-01-23 06:37:00 +00001129 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1130 final ActivityStack stack = display.getChildAt(stackNdx);
1131 final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
1132 if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
1133 continue;
1134 }
Louis Changc50a9362019-02-12 12:35:24 +08001135 if (stack == targetStack) {
1136 // Simply update the result for targetStack because the targetStack had
1137 // already resumed in above. We don't want to resume it again, especially in
1138 // some cases, it would cause a second launch failure if app process was dead.
1139 resumedOnDisplay |= result;
1140 continue;
1141 }
Jorim Jaggia5cf6802019-04-26 19:43:11 +02001142 if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
1143 // Kick off any lingering app transitions form the MoveTaskToFront operation,
1144 // but only consider the top task and stack on that display.
Andrii Kulian6b321512019-01-23 06:37:00 +00001145 stack.executeAppTransition(targetOptions);
1146 } else {
1147 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
1148 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001149 }
Andrii Kulian6b321512019-01-23 06:37:00 +00001150 if (!resumedOnDisplay) {
1151 // In cases when there are no valid activities (e.g. device just booted or launcher
1152 // crashed) it's possible that nothing was resumed on a display. Requesting resume
1153 // of top activity in focused stack explicitly will make sure that at least home
1154 // activity is started and resumed, and no recursion occurs.
1155 final ActivityStack focusedStack = display.getFocusedStack();
1156 if (focusedStack != null) {
1157 focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1158 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001159 }
1160 }
1161
Andrii Kulian6b321512019-01-23 06:37:00 +00001162 return result;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001163 }
1164
1165 void applySleepTokens(boolean applyToStacks) {
1166 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1167 // Set the sleeping state of the display.
1168 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1169 final boolean displayShouldSleep = display.shouldSleep();
1170 if (displayShouldSleep == display.isSleeping()) {
1171 continue;
1172 }
1173 display.setIsSleeping(displayShouldSleep);
1174
1175 if (!applyToStacks) {
1176 continue;
1177 }
1178
1179 // Set the sleeping state of the stacks on the display.
1180 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1181 final ActivityStack stack = display.getChildAt(stackNdx);
1182 if (displayShouldSleep) {
1183 stack.goToSleepIfPossible(false /* shuttingDown */);
1184 } else {
Issei Suzukicac2a502019-04-16 16:52:50 +02001185 // When the display which can only contain one task turns on, start a special
1186 // transition. {@link AppTransitionController#handleAppTransitionReady} later
1187 // picks up the transition, and schedules
1188 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
1189 // triggered after contents are drawn on the display.
1190 if (display.isSingleTaskInstance()) {
1191 display.mDisplayContent.prepareAppTransition(
1192 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
1193 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001194 stack.awakeFromSleepingLocked();
1195 if (stack.isFocusedStackOnDisplay()
1196 && !mStackSupervisor.getKeyguardController()
1197 .isKeyguardOrAodShowing(display.mDisplayId)) {
1198 // If the keyguard is unlocked - resume immediately.
1199 // It is possible that the display will not be awake at the time we
1200 // process the keyguard going away, which can happen before the sleep token
1201 // is released. As a result, it is important we resume the activity here.
1202 resumeFocusedStacksTopActivities();
1203 }
1204 }
1205 }
1206
1207 if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) {
1208 continue;
1209 }
1210 // The display is awake now, so clean up the going to sleep list.
1211 for (Iterator<ActivityRecord> it =
1212 mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) {
1213 final ActivityRecord r = it.next();
1214 if (r.getDisplayId() == display.mDisplayId) {
1215 it.remove();
1216 }
1217 }
1218 }
1219 }
1220
1221 protected <T extends ActivityStack> T getStack(int stackId) {
1222 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1223 final T stack = mActivityDisplays.get(i).getStack(stackId);
1224 if (stack != null) {
1225 return stack;
1226 }
1227 }
1228 return null;
1229 }
1230
1231 /** @see ActivityDisplay#getStack(int, int) */
1232 private <T extends ActivityStack> T getStack(int windowingMode, int activityType) {
1233 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1234 final T stack = mActivityDisplays.get(i).getStack(windowingMode, activityType);
1235 if (stack != null) {
1236 return stack;
1237 }
1238 }
1239 return null;
1240 }
1241
1242 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
1243 final int displayId = stack.mDisplayId;
1244 final ActivityDisplay display = getActivityDisplay(displayId);
1245 ActivityManager.StackInfo info = new ActivityManager.StackInfo();
1246 stack.getWindowContainerBounds(info.bounds);
1247 info.displayId = displayId;
1248 info.stackId = stack.mStackId;
1249 info.userId = stack.mCurrentUser;
1250 info.visible = stack.shouldBeVisible(null);
1251 // A stack might be not attached to a display.
1252 info.position = display != null ? display.getIndexOf(stack) : 0;
1253 info.configuration.setTo(stack.getConfiguration());
1254
1255 ArrayList<TaskRecord> tasks = stack.getAllTasks();
1256 final int numTasks = tasks.size();
1257 int[] taskIds = new int[numTasks];
1258 String[] taskNames = new String[numTasks];
1259 Rect[] taskBounds = new Rect[numTasks];
1260 int[] taskUserIds = new int[numTasks];
1261 for (int i = 0; i < numTasks; ++i) {
1262 final TaskRecord task = tasks.get(i);
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001263 taskIds[i] = task.mTaskId;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001264 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
1265 : task.realActivity != null ? task.realActivity.flattenToString()
1266 : task.getTopActivity() != null ? task.getTopActivity().packageName
1267 : "unknown";
1268 taskBounds[i] = new Rect();
1269 task.getWindowContainerBounds(taskBounds[i]);
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001270 taskUserIds[i] = task.mUserId;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001271 }
1272 info.taskIds = taskIds;
1273 info.taskNames = taskNames;
1274 info.taskBounds = taskBounds;
1275 info.taskUserIds = taskUserIds;
1276
1277 final ActivityRecord top = stack.topRunningActivityLocked();
1278 info.topActivity = top != null ? top.intent.getComponent() : null;
1279 return info;
1280 }
1281
1282 ActivityManager.StackInfo getStackInfo(int stackId) {
1283 ActivityStack stack = getStack(stackId);
1284 if (stack != null) {
1285 return getStackInfo(stack);
1286 }
1287 return null;
1288 }
1289
1290 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
1291 final ActivityStack stack = getStack(windowingMode, activityType);
1292 return (stack != null) ? getStackInfo(stack) : null;
1293 }
1294
1295 ArrayList<ActivityManager.StackInfo> getAllStackInfos() {
1296 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
1297 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
1298 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1299 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1300 final ActivityStack stack = display.getChildAt(stackNdx);
1301 list.add(getStackInfo(stack));
1302 }
1303 }
1304 return list;
1305 }
1306
1307 void deferUpdateBounds(int activityType) {
1308 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1309 if (stack != null) {
1310 stack.deferUpdateBounds();
1311 }
1312 }
1313
1314 void continueUpdateBounds(int activityType) {
1315 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1316 if (stack != null) {
1317 stack.continueUpdateBounds();
1318 }
1319 }
1320
1321 @Override
1322 public void onDisplayAdded(int displayId) {
1323 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
1324 synchronized (mService.mGlobalLock) {
Charles Chen3dedec32019-01-24 22:19:37 +08001325 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
Charles Chenb409e6c2019-02-12 12:30:17 +08001326 if (display == null) {
1327 return;
1328 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001329 // Do not start home before booting, or it may accidentally finish booting before it
1330 // starts. Instead, we expect home activities to be launched when the system is ready
1331 // (ActivityManagerService#systemReady).
1332 if (mService.isBooted() || mService.isBooting()) {
Charles Chen3dedec32019-01-24 22:19:37 +08001333 startSystemDecorations(display.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001334 }
1335 }
1336 }
1337
Charles Chen3dedec32019-01-24 22:19:37 +08001338 private void startSystemDecorations(final DisplayContent displayContent) {
1339 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
1340 displayContent.getDisplayPolicy().notifyDisplayReady();
1341 }
1342
Wale Ogunwaled32da472018-11-16 07:19:28 -08001343 @Override
1344 public void onDisplayRemoved(int displayId) {
1345 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
1346 if (displayId == DEFAULT_DISPLAY) {
1347 throw new IllegalArgumentException("Can't remove the primary display.");
1348 }
1349
1350 synchronized (mService.mGlobalLock) {
1351 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1352 if (activityDisplay == null) {
1353 return;
1354 }
1355
1356 activityDisplay.remove();
1357 }
1358 }
1359
1360 @Override
1361 public void onDisplayChanged(int displayId) {
1362 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
1363 synchronized (mService.mGlobalLock) {
1364 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1365 if (activityDisplay != null) {
1366 activityDisplay.onDisplayChanged();
1367 }
1368 }
1369 }
1370
1371 /** Update lists of UIDs that are present on displays and have access to them. */
1372 void updateUIDsPresentOnDisplay() {
1373 mDisplayAccessUIDs.clear();
1374 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1375 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
1376 // Only bother calculating the whitelist for private displays
1377 if (activityDisplay.isPrivate()) {
1378 mDisplayAccessUIDs.append(
1379 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs());
1380 }
1381 }
1382 // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
1383 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
1384 }
1385
1386 ActivityStack findStackBehind(ActivityStack stack) {
1387 final ActivityDisplay display = getActivityDisplay(stack.mDisplayId);
1388 if (display != null) {
1389 for (int i = display.getChildCount() - 1; i >= 0; i--) {
1390 if (display.getChildAt(i) == stack && i > 0) {
1391 return display.getChildAt(i - 1);
1392 }
1393 }
1394 }
1395 throw new IllegalStateException("Failed to find a stack behind stack=" + stack
1396 + " in=" + display);
1397 }
1398
1399 @Override
1400 protected int getChildCount() {
1401 return mActivityDisplays.size();
1402 }
1403
1404 @Override
1405 protected ActivityDisplay getChildAt(int index) {
1406 return mActivityDisplays.get(index);
1407 }
1408
1409 @Override
1410 protected ConfigurationContainer getParent() {
1411 return null;
1412 }
1413
Wale Ogunwale31acb3f2018-11-20 15:23:55 -08001414 // TODO: remove after object merge with RootWindowContainer
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001415 void onChildPositionChanged(ActivityDisplay display, int position) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001416 // Assume AM lock is held from positionChildAt of controller in each hierarchy.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001417 if (display != null) {
1418 positionChildAt(display, position);
1419 }
1420 }
1421
1422 /** Change the z-order of the given display. */
1423 private void positionChildAt(ActivityDisplay display, int position) {
1424 if (position >= mActivityDisplays.size()) {
1425 position = mActivityDisplays.size() - 1;
1426 } else if (position < 0) {
1427 position = 0;
1428 }
1429
1430 if (mActivityDisplays.isEmpty()) {
1431 mActivityDisplays.add(display);
1432 } else if (mActivityDisplays.get(position) != display) {
1433 mActivityDisplays.remove(display);
1434 mActivityDisplays.add(position, display);
1435 }
Andrii Kulian86e70fc2019-02-12 11:04:10 +00001436 mStackSupervisor.updateTopResumedActivityIfNeeded();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001437 }
1438
1439 @VisibleForTesting
1440 void addChild(ActivityDisplay activityDisplay, int position) {
1441 positionChildAt(activityDisplay, position);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001442 mRootWindowContainer.positionChildAt(position, activityDisplay.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001443 }
1444
1445 void removeChild(ActivityDisplay activityDisplay) {
1446 // The caller must tell the controller of {@link ActivityDisplay} to release its container
1447 // {@link DisplayContent}. That is done in {@link ActivityDisplay#releaseSelfIfNeeded}).
1448 mActivityDisplays.remove(activityDisplay);
1449 }
1450
1451 Configuration getDisplayOverrideConfiguration(int displayId) {
1452 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1453 if (activityDisplay == null) {
1454 throw new IllegalArgumentException("No display found with id: " + displayId);
1455 }
1456
Evan Roskydfe3da72018-10-26 17:21:06 -07001457 return activityDisplay.getRequestedOverrideConfiguration();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001458 }
1459
1460 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
1461 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1462 if (activityDisplay == null) {
1463 throw new IllegalArgumentException("No display found with id: " + displayId);
1464 }
1465
Evan Roskydfe3da72018-10-26 17:21:06 -07001466 activityDisplay.onRequestedOverrideConfigurationChanged(overrideConfiguration);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001467 }
1468
1469 void prepareForShutdown() {
1470 for (int i = 0; i < mActivityDisplays.size(); i++) {
1471 createSleepToken("shutdown", mActivityDisplays.get(i).mDisplayId);
1472 }
1473 }
1474
1475 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
1476 final ActivityDisplay display = getActivityDisplay(displayId);
1477 if (display == null) {
1478 throw new IllegalArgumentException("Invalid display: " + displayId);
1479 }
1480
1481 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
1482 mSleepTokens.add(token);
1483 display.mAllSleepTokens.add(token);
1484 return token;
1485 }
1486
1487 private void removeSleepToken(SleepTokenImpl token) {
1488 mSleepTokens.remove(token);
1489
1490 final ActivityDisplay display = getActivityDisplay(token.mDisplayId);
1491 if (display != null) {
1492 display.mAllSleepTokens.remove(token);
1493 if (display.mAllSleepTokens.isEmpty()) {
1494 mService.updateSleepIfNeededLocked();
1495 }
1496 }
1497 }
1498
1499 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1500 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1501 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1502 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1503 final ActivityStack stack = display.getChildAt(stackNdx);
1504 stack.addStartingWindowsForVisibleActivities(taskSwitch);
1505 }
1506 }
1507 }
1508
1509 void invalidateTaskLayers() {
1510 mTaskLayersChanged = true;
1511 }
1512
1513 void rankTaskLayersIfNeeded() {
1514 if (!mTaskLayersChanged) {
1515 return;
1516 }
1517 mTaskLayersChanged = false;
1518 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
1519 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1520 int baseLayer = 0;
1521 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1522 final ActivityStack stack = display.getChildAt(stackNdx);
1523 baseLayer += stack.rankTaskLayers(baseLayer);
1524 }
1525 }
1526 }
1527
1528 void clearOtherAppTimeTrackers(AppTimeTracker except) {
1529 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1530 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1531 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1532 final ActivityStack stack = display.getChildAt(stackNdx);
1533 stack.clearOtherAppTimeTrackers(except);
1534 }
1535 }
1536 }
1537
1538 void scheduleDestroyAllActivities(WindowProcessController app, String reason) {
1539 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1540 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1541 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1542 final ActivityStack stack = display.getChildAt(stackNdx);
1543 stack.scheduleDestroyActivities(app, reason);
1544 }
1545 }
1546 }
1547
1548 void releaseSomeActivitiesLocked(WindowProcessController app, String reason) {
1549 // Tasks is non-null only if two or more tasks are found.
1550 ArraySet<TaskRecord> tasks = app.getReleaseSomeActivitiesTasks();
1551 if (tasks == null) {
1552 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
1553 return;
1554 }
1555 // If we have activities in multiple tasks that are in a position to be destroyed,
1556 // let's iterate through the tasks and release the oldest one.
1557 final int numDisplays = mActivityDisplays.size();
1558 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
1559 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1560 final int stackCount = display.getChildCount();
1561 // Step through all stacks starting from behind, to hit the oldest things first.
1562 for (int stackNdx = 0; stackNdx < stackCount; stackNdx++) {
1563 final ActivityStack stack = display.getChildAt(stackNdx);
1564 // Try to release activities in this stack; if we manage to, we are done.
1565 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
1566 return;
1567 }
1568 }
1569 }
1570 }
1571
1572 // Tries to put all activity stacks to sleep. Returns true if all stacks were
1573 // successfully put to sleep.
1574 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
1575 boolean allSleep = true;
1576 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1577 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1578 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
Louis Changc219bc32018-12-06 15:38:41 +08001579 // Stacks and activities could be removed while putting activities to sleep if
1580 // the app process was gone. This prevents us getting exception by accessing an
1581 // invalid stack index.
1582 if (stackNdx >= display.getChildCount()) {
1583 continue;
1584 }
1585
Wale Ogunwaled32da472018-11-16 07:19:28 -08001586 final ActivityStack stack = display.getChildAt(stackNdx);
1587 if (allowDelay) {
1588 allSleep &= stack.goToSleepIfPossible(shuttingDown);
1589 } else {
1590 stack.goToSleep();
1591 }
1592 }
1593 }
1594 return allSleep;
1595 }
1596
1597 void handleAppCrash(WindowProcessController app) {
1598 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1599 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1600 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1601 final ActivityStack stack = display.getChildAt(stackNdx);
1602 stack.handleAppCrash(app);
1603 }
1604 }
1605 }
1606
1607 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
1608 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1609 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1610 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1611 final ActivityStack stack = display.getChildAt(stackNdx);
1612 final ActivityRecord ar = stack.findActivityLocked(
1613 intent, info, compareIntentFilters);
1614 if (ar != null) {
1615 return ar;
1616 }
1617 }
1618 }
1619 return null;
1620 }
1621
1622 boolean hasAwakeDisplay() {
1623 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1624 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1625 if (!display.shouldSleep()) {
1626 return true;
1627 }
1628 }
1629 return false;
1630 }
1631
1632 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
1633 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) {
lumarkf65e02d2019-09-14 19:25:21 +08001634 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
1635 -1 /* no realCallingPid */, -1 /* no realCallingUid */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001636 }
1637
1638 /**
1639 * Returns the right stack to use for launching factoring in all the input parameters.
1640 *
1641 * @param r The activity we are trying to launch. Can be null.
1642 * @param options The activity options used to the launch. Can be null.
1643 * @param candidateTask The possible task the activity might be launched in. Can be null.
lumarkf65e02d2019-09-14 19:25:21 +08001644 * @param launchParams The resolved launch params to use.
1645 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
1646 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
Wale Ogunwaled32da472018-11-16 07:19:28 -08001647 *
1648 * @return The stack to use for the launch or INVALID_STACK_ID.
1649 */
1650 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
1651 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop,
lumarkf65e02d2019-09-14 19:25:21 +08001652 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
1653 int realCallingUid) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001654 int taskId = INVALID_TASK_ID;
1655 int displayId = INVALID_DISPLAY;
1656 //Rect bounds = null;
1657
1658 // We give preference to the launch preference in activity options.
1659 if (options != null) {
1660 taskId = options.getLaunchTaskId();
1661 displayId = options.getLaunchDisplayId();
1662 }
1663
1664 // First preference for stack goes to the task Id set in the activity options. Use the stack
1665 // associated with that if possible.
1666 if (taskId != INVALID_TASK_ID) {
1667 // Temporarily set the task id to invalid in case in re-entry.
1668 options.setLaunchTaskId(INVALID_TASK_ID);
1669 final TaskRecord task = anyTaskForId(taskId,
1670 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
1671 options.setLaunchTaskId(taskId);
1672 if (task != null) {
1673 return task.getStack();
1674 }
1675 }
1676
1677 final int activityType = resolveActivityType(r, options, candidateTask);
1678 T stack;
1679
1680 // Next preference for stack goes to the display Id set the candidate display.
1681 if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
1682 displayId = launchParams.mPreferredDisplayId;
1683 }
lumarkf65e02d2019-09-14 19:25:21 +08001684 final boolean canLaunchOnDisplayFromStartRequest =
1685 realCallingPid != 0 && realCallingUid > 0 && r != null
1686 && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid,
1687 realCallingUid, r.info);
1688 // Checking if the activity's launch caller, or the realCallerId of the activity from
1689 // start request (i.e. entity that invokes PendingIntent) is allowed to launch on the
1690 // display.
1691 if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
1692 || canLaunchOnDisplayFromStartRequest)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001693 if (r != null) {
1694 stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
1695 launchParams);
1696 if (stack != null) {
1697 return stack;
1698 }
1699 }
1700 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
1701 if (display != null) {
1702 stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1703 if (stack != null) {
1704 return stack;
1705 }
1706 }
1707 }
1708
1709 // Give preference to the stack and display of the input task and activity if they match the
1710 // mode we want to launch into.
1711 stack = null;
1712 ActivityDisplay display = null;
1713 if (candidateTask != null) {
1714 stack = candidateTask.getStack();
1715 }
1716 if (stack == null && r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001717 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001718 }
1719 if (stack != null) {
1720 display = stack.getDisplay();
1721 if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) {
1722 int windowingMode = launchParams != null ? launchParams.mWindowingMode
1723 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
1724 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
1725 windowingMode = display.resolveWindowingMode(r, options, candidateTask,
1726 activityType);
1727 }
1728 if (stack.isCompatible(windowingMode, activityType)) {
1729 return stack;
1730 }
1731 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
1732 && display.getSplitScreenPrimaryStack() == stack
1733 && candidateTask == stack.topTask()) {
1734 // This is a special case when we try to launch an activity that is currently on
1735 // top of split-screen primary stack, but is targeting split-screen secondary.
1736 // In this case we don't want to move it to another stack.
1737 // TODO(b/78788972): Remove after differentiating between preferred and required
1738 // launch options.
1739 return stack;
1740 }
1741 }
1742 }
1743
1744 if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) {
1745 display = getDefaultDisplay();
1746 }
1747
1748 return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1749 }
1750
1751 /** @return true if activity record is null or can be launched on provided display. */
1752 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
1753 if (r == null) {
1754 return true;
1755 }
1756 return r.canBeLaunchedOnDisplay(displayId);
1757 }
1758
1759 /**
1760 * Get a topmost stack on the display, that is a valid launch stack for specified activity.
1761 * If there is no such stack, new dynamic stack can be created.
1762 * @param displayId Target display.
1763 * @param r Activity that should be launched there.
1764 * @param candidateTask The possible task the activity might be put in.
1765 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
1766 */
1767 private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
1768 @Nullable TaskRecord candidateTask, @Nullable ActivityOptions options,
1769 @Nullable LaunchParamsController.LaunchParams launchParams) {
1770 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1771 if (activityDisplay == null) {
1772 throw new IllegalArgumentException(
1773 "Display with displayId=" + displayId + " not found.");
1774 }
1775
1776 if (!r.canBeLaunchedOnDisplay(displayId)) {
1777 return null;
1778 }
1779
1780 // If {@code r} is already in target display and its task is the same as the candidate task,
1781 // the intention should be getting a launch stack for the reusable activity, so we can use
1782 // the existing stack.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001783 if (r.getDisplayId() == displayId && r.getTaskRecord() == candidateTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001784 return candidateTask.getStack();
1785 }
1786
Louis Chang6fb1e842018-12-03 16:07:50 +08001787 int windowingMode;
1788 if (launchParams != null) {
1789 // When launch params is not null, we always defer to its windowing mode. Sometimes
1790 // it could be unspecified, which indicates it should inherit windowing mode from
1791 // display.
1792 windowingMode = launchParams.mWindowingMode;
1793 } else {
1794 windowingMode = options != null ? options.getLaunchWindowingMode()
1795 : r.getWindowingMode();
1796 }
1797 windowingMode = activityDisplay.validateWindowingMode(windowingMode, r, candidateTask,
1798 r.getActivityType());
1799
Wale Ogunwaled32da472018-11-16 07:19:28 -08001800 // Return the topmost valid stack on the display.
1801 for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) {
1802 final ActivityStack stack = activityDisplay.getChildAt(i);
Louis Chang6fb1e842018-12-03 16:07:50 +08001803 if (isValidLaunchStack(stack, r, windowingMode)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001804 return stack;
1805 }
1806 }
1807
1808 // If there is no valid stack on the external display - check if new dynamic stack will do.
1809 if (displayId != DEFAULT_DISPLAY) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001810 final int activityType =
1811 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
1812 ? options.getLaunchActivityType() : r.getActivityType();
1813 return activityDisplay.createStack(windowingMode, activityType, true /*onTop*/);
1814 }
1815
Wale Ogunwaled32da472018-11-16 07:19:28 -08001816 return null;
1817 }
1818
1819 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
1820 @Nullable ActivityOptions options,
1821 @Nullable LaunchParamsController.LaunchParams launchParams) {
1822 return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options,
1823 launchParams);
1824 }
1825
1826 // TODO: Can probably be consolidated into getLaunchStack()...
Louis Chang6fb1e842018-12-03 16:07:50 +08001827 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001828 switch (stack.getActivityType()) {
1829 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
1830 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
1831 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
1832 }
1833 // There is a 1-to-1 relationship between stack and task when not in
1834 // primary split-windowing mode.
Louis Chang6fb1e842018-12-03 16:07:50 +08001835 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
1836 && r.supportsSplitScreenWindowingMode()
1837 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
1838 || windowingMode == WINDOWING_MODE_UNDEFINED)) {
1839 return true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001840 }
Louis Chang6fb1e842018-12-03 16:07:50 +08001841 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001842 }
1843
1844 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
1845 @Nullable TaskRecord task) {
1846 // Preference is given to the activity type for the activity then the task since the type
1847 // once set shouldn't change.
1848 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
1849 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
1850 activityType = task.getActivityType();
1851 }
1852 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
1853 return activityType;
1854 }
1855 if (options != null) {
1856 activityType = options.getLaunchActivityType();
1857 }
1858 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
1859 }
1860
1861 /**
1862 * Get next focusable stack in the system. This will search through the stack on the same
1863 * display as the current focused stack, looking for a focusable and visible stack, different
1864 * from the target stack. If no valid candidates will be found, it will then go through all
1865 * displays and stacks in last-focused order.
1866 *
1867 * @param currentFocus The stack that previously had focus.
1868 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
1869 * candidate.
1870 * @return Next focusable {@link ActivityStack}, {@code null} if not found.
1871 */
1872 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
1873 boolean ignoreCurrent) {
1874 // First look for next focusable stack on the same display
1875 final ActivityDisplay preferredDisplay = currentFocus.getDisplay();
1876 final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
1877 currentFocus, ignoreCurrent);
1878 if (preferredFocusableStack != null) {
1879 return preferredFocusableStack;
1880 }
1881 if (preferredDisplay.supportsSystemDecorations()) {
1882 // Stop looking for focusable stack on other displays because the preferred display
1883 // supports system decorations. Home activity would be launched on the same display if
1884 // no focusable stack found.
1885 return null;
1886 }
1887
1888 // Now look through all displays
1889 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1890 final ActivityDisplay display = mActivityDisplays.get(i);
1891 if (display == preferredDisplay) {
1892 // We've already checked this one
1893 continue;
1894 }
1895 final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
1896 ignoreCurrent);
1897 if (nextFocusableStack != null) {
1898 return nextFocusableStack;
1899 }
1900 }
1901
1902 return null;
1903 }
1904
1905 /**
1906 * Get next valid stack for launching provided activity in the system. This will search across
1907 * displays and stacks in last-focused order for a focusable and visible stack, except those
1908 * that are on a currently focused display.
1909 *
1910 * @param r The activity that is being launched.
1911 * @param currentFocus The display that previously had focus and thus needs to be ignored when
1912 * searching for the next candidate.
1913 * @return Next valid {@link ActivityStack}, null if not found.
1914 */
1915 ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) {
1916 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1917 final ActivityDisplay display = mActivityDisplays.get(i);
1918 if (display.mDisplayId == currentFocus) {
1919 continue;
1920 }
1921 final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r,
1922 null /* options */, null /* launchParams */);
1923 if (stack != null) {
1924 return stack;
1925 }
1926 }
1927 return null;
1928 }
1929
1930 boolean handleAppDied(WindowProcessController app) {
1931 boolean hasVisibleActivities = false;
1932 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1933 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1934 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1935 final ActivityStack stack = display.getChildAt(stackNdx);
1936 hasVisibleActivities |= stack.handleAppDiedLocked(app);
1937 }
1938 }
1939 return hasVisibleActivities;
1940 }
1941
1942 void closeSystemDialogs() {
1943 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1944 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1945 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1946 final ActivityStack stack = display.getChildAt(stackNdx);
1947 stack.closeSystemDialogsLocked();
1948 }
1949 }
1950 }
1951
1952 /** @return true if some activity was finished (or would have finished if doit were true). */
1953 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
1954 boolean doit, boolean evenPersistent, int userId) {
1955 boolean didSomething = false;
1956 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1957 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1958 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1959 final ActivityStack stack = display.getChildAt(stackNdx);
1960 if (stack.finishDisabledPackageActivitiesLocked(
1961 packageName, filterByClasses, doit, evenPersistent, userId)) {
1962 didSomething = true;
1963 }
1964 }
1965 }
1966 return didSomething;
1967 }
1968
1969 void updateActivityApplicationInfo(ApplicationInfo aInfo) {
1970 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1971 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1972 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1973 final ActivityStack stack = display.getChildAt(stackNdx);
1974 stack.updateActivityApplicationInfoLocked(aInfo);
1975 }
1976 }
1977 }
1978
1979 void finishVoiceTask(IVoiceInteractionSession session) {
1980 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1981 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1982 final int numStacks = display.getChildCount();
1983 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1984 final ActivityStack stack = display.getChildAt(stackNdx);
1985 stack.finishVoiceTask(session);
1986 }
1987 }
1988 }
1989
1990 /**
1991 * Removes stacks in the input windowing modes from the system if they are of activity type
1992 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
1993 */
1994 void removeStacksInWindowingModes(int... windowingModes) {
1995 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1996 mActivityDisplays.get(i).removeStacksInWindowingModes(windowingModes);
1997 }
1998 }
1999
2000 void removeStacksWithActivityTypes(int... activityTypes) {
2001 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2002 mActivityDisplays.get(i).removeStacksWithActivityTypes(activityTypes);
2003 }
2004 }
2005
2006 ActivityRecord topRunningActivity() {
2007 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2008 final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
2009 if (topActivity != null) {
2010 return topActivity;
2011 }
2012 }
2013 return null;
2014 }
2015
2016 boolean allResumedActivitiesIdle() {
2017 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2018 // TODO(b/117135575): Check resumed activities on all visible stacks.
2019 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2020 if (display.isSleeping()) {
2021 // No resumed activities while display is sleeping.
2022 continue;
2023 }
2024
2025 // If the focused stack is not null or not empty, there should have some activities
2026 // resuming or resumed. Make sure these activities are idle.
2027 final ActivityStack stack = display.getFocusedStack();
2028 if (stack == null || stack.numActivities() == 0) {
2029 continue;
2030 }
2031 final ActivityRecord resumedActivity = stack.getResumedActivity();
2032 if (resumedActivity == null || !resumedActivity.idle) {
2033 if (DEBUG_STATES) {
2034 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
2035 + stack.mStackId + " " + resumedActivity + " not idle");
2036 }
2037 return false;
2038 }
2039 }
2040 // Send launch end powerhint when idle
2041 sendPowerHintForLaunchEndIfNeeded();
2042 return true;
2043 }
2044
2045 boolean allResumedActivitiesVisible() {
2046 boolean foundResumed = false;
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 ActivityRecord r = stack.getResumedActivity();
2052 if (r != null) {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002053 if (!r.nowVisible) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002054 return false;
2055 }
2056 foundResumed = true;
2057 }
2058 }
2059 }
2060 return foundResumed;
2061 }
2062
2063 boolean allPausedActivitiesComplete() {
2064 boolean pausing = true;
2065 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2066 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2067 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2068 final ActivityStack stack = display.getChildAt(stackNdx);
2069 final ActivityRecord r = stack.mPausingActivity;
2070 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
2071 if (DEBUG_STATES) {
2072 Slog.d(TAG_STATES,
2073 "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
2074 pausing = false;
2075 } else {
2076 return false;
2077 }
2078 }
2079 }
2080 }
2081 return pausing;
2082 }
2083
2084 /**
2085 * Find all visible task stacks containing {@param userId} and intercept them with an activity
2086 * to block out the contents and possibly start a credential-confirming intent.
2087 *
2088 * @param userId user handle for the locked managed profile.
2089 */
2090 void lockAllProfileTasks(@UserIdInt int userId) {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002091 mService.deferWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002092 try {
2093 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2094 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2095 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2096 final ActivityStack stack = display.getChildAt(stackNdx);
2097 final List<TaskRecord> tasks = stack.getAllTasks();
2098 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
2099 final TaskRecord task = tasks.get(taskNdx);
2100
2101 // Check the task for a top activity belonging to userId, or returning a
2102 // result to an activity belonging to userId. Example case: a document
2103 // picker for personal files, opened by a work app, should still get locked.
2104 if (taskTopActivityIsUser(task, userId)) {
2105 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07002106 task.mTaskId, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002107 }
2108 }
2109 }
2110 }
2111 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002112 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002113 }
2114 }
2115
2116 /**
2117 * Detects whether we should show a lock screen in front of this task for a locked user.
2118 * <p>
2119 * We'll do this if either of the following holds:
2120 * <ul>
2121 * <li>The top activity explicitly belongs to {@param userId}.</li>
2122 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
2123 * </ul>
2124 *
2125 * @return {@code true} if the top activity looks like it belongs to {@param userId}.
2126 */
2127 private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) {
2128 // To handle the case that work app is in the task but just is not the top one.
2129 final ActivityRecord activityRecord = task.getTopActivity();
2130 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
2131
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002132 return (activityRecord != null && activityRecord.mUserId == userId)
2133 || (resultTo != null && resultTo.mUserId == userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002134 }
2135
2136 void cancelInitializingActivities() {
2137 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2138 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2139 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2140 final ActivityStack stack = display.getChildAt(stackNdx);
2141 stack.cancelInitializingActivities();
2142 }
2143 }
2144 }
2145
2146 TaskRecord anyTaskForId(int id) {
2147 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
2148 }
2149
2150 TaskRecord anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode) {
2151 return anyTaskForId(id, matchMode, null, !ON_TOP);
2152 }
2153
2154 /**
2155 * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise.
2156 * @param id Id of the task we would like returned.
2157 * @param matchMode The mode to match the given task id in.
2158 * @param aOptions The activity options to use for restoration. Can be null.
2159 * @param onTop If the stack for the task should be the topmost on the display.
2160 */
2161 TaskRecord anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode,
2162 @Nullable ActivityOptions aOptions, boolean onTop) {
2163 // If options are set, ensure that we are attempting to actually restore a task
2164 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
2165 throw new IllegalArgumentException("Should not specify activity options for non-restore"
2166 + " lookup");
2167 }
2168
2169 int numDisplays = mActivityDisplays.size();
2170 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2171 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2172 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2173 final ActivityStack stack = display.getChildAt(stackNdx);
2174 final TaskRecord task = stack.taskForIdLocked(id);
2175 if (task == null) {
2176 continue;
2177 }
2178 if (aOptions != null) {
2179 // Resolve the stack the task should be placed in now based on options
2180 // and reparent if needed.
2181 final ActivityStack launchStack =
2182 getLaunchStack(null, aOptions, task, onTop);
2183 if (launchStack != null && stack != launchStack) {
2184 final int reparentMode = onTop
2185 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
2186 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
2187 "anyTaskForId");
2188 }
2189 }
2190 return task;
2191 }
2192 }
2193
2194 // If we are matching stack tasks only, return now
2195 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
2196 return null;
2197 }
2198
2199 // Otherwise, check the recent tasks and return if we find it there and we are not restoring
2200 // the task from recents
2201 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
2202 final TaskRecord task = mStackSupervisor.mRecentTasks.getTask(id);
2203
2204 if (task == null) {
2205 if (DEBUG_RECENTS) {
2206 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
2207 }
2208
2209 return null;
2210 }
2211
2212 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
2213 return task;
2214 }
2215
2216 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
2217 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
2218 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
2219 "Couldn't restore task id=" + id + " found in recents");
2220 return null;
2221 }
2222 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
2223 return task;
2224 }
2225
2226 ActivityRecord isInAnyStack(IBinder token) {
2227 int numDisplays = mActivityDisplays.size();
2228 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2229 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2230 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2231 final ActivityStack stack = display.getChildAt(stackNdx);
2232 final ActivityRecord r = stack.isInStackLocked(token);
2233 if (r != null) {
2234 return r;
2235 }
2236 }
2237 }
2238 return null;
2239 }
2240
2241 @VisibleForTesting
2242 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
2243 @WindowConfiguration.ActivityType int ignoreActivityType,
2244 @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -07002245 boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -07002246 mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -07002247 ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser, profileIds);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002248 }
2249
2250 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
2251 boolean sendHint = forceSend;
2252
2253 if (!sendHint) {
2254 // Send power hint if we don't know what we're launching yet
2255 sendHint = targetActivity == null || targetActivity.app == null;
2256 }
2257
2258 if (!sendHint) { // targetActivity != null
2259 // Send power hint when the activity's process is different than the current resumed
2260 // activity on all displays, or if there are no resumed activities in the system.
2261 boolean noResumedActivities = true;
2262 boolean allFocusedProcessesDiffer = true;
2263 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2264 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2265 final ActivityRecord resumedActivity = activityDisplay.getResumedActivity();
2266 final WindowProcessController resumedActivityProcess =
2267 resumedActivity == null ? null : resumedActivity.app;
2268
2269 noResumedActivities &= resumedActivityProcess == null;
2270 if (resumedActivityProcess != null) {
2271 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
2272 }
2273 }
2274 sendHint = noResumedActivities || allFocusedProcessesDiffer;
2275 }
2276
2277 if (sendHint && mService.mPowerManagerInternal != null) {
2278 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
2279 mPowerHintSent = true;
2280 }
2281 }
2282
2283 void sendPowerHintForLaunchEndIfNeeded() {
2284 // Trigger launch power hint if activity is launched
2285 if (mPowerHintSent && mService.mPowerManagerInternal != null) {
2286 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
2287 mPowerHintSent = false;
2288 }
2289 }
2290
2291 private void calculateDefaultMinimalSizeOfResizeableTasks() {
2292 final Resources res = mService.mContext.getResources();
2293 final float minimalSize = res.getDimension(
2294 com.android.internal.R.dimen.default_minimal_size_resizable_task);
2295 final DisplayMetrics dm = res.getDisplayMetrics();
2296
2297 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
2298 }
2299
2300 /**
2301 * Dumps the activities matching the given {@param name} in the either the focused stack
2302 * or all visible stacks if {@param dumpVisibleStacks} is true.
2303 */
2304 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
2305 boolean dumpFocusedStackOnly) {
2306 if (dumpFocusedStackOnly) {
2307 return getTopDisplayFocusedStack().getDumpActivitiesLocked(name);
2308 } else {
2309 ArrayList<ActivityRecord> activities = new ArrayList<>();
2310 int numDisplays = mActivityDisplays.size();
2311 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2312 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2313 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2314 final ActivityStack stack = display.getChildAt(stackNdx);
2315 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
2316 activities.addAll(stack.getDumpActivitiesLocked(name));
2317 }
2318 }
2319 }
2320 return activities;
2321 }
2322 }
2323
2324 public void dump(PrintWriter pw, String prefix) {
2325 pw.print(prefix);
2326 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
2327 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2328 final ActivityDisplay display = mActivityDisplays.get(i);
2329 display.dump(pw, prefix);
2330 }
2331 }
2332
2333 /**
2334 * Dump all connected displays' configurations.
2335 * @param prefix Prefix to apply to each line of the dump.
2336 */
2337 void dumpDisplayConfigs(PrintWriter pw, String prefix) {
2338 pw.print(prefix); pw.println("Display override configurations:");
2339 final int displayCount = mActivityDisplays.size();
2340 for (int i = 0; i < displayCount; i++) {
2341 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
2342 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": ");
Evan Roskydfe3da72018-10-26 17:21:06 -07002343 pw.println(activityDisplay.getRequestedOverrideConfiguration());
Wale Ogunwaled32da472018-11-16 07:19:28 -08002344 }
2345 }
2346
2347 public void dumpDisplays(PrintWriter pw) {
2348 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2349 final ActivityDisplay display = mActivityDisplays.get(i);
2350 pw.print("[id:" + display.mDisplayId + " stacks:");
2351 display.dumpStacks(pw);
2352 pw.print("]");
2353 }
2354 }
2355
2356 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
2357 String dumpPackage) {
2358 boolean printed = false;
2359 boolean needSep = false;
2360 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2361 ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2362 pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
2363 pw.println(" (activities from top to bottom):");
2364 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2365 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2366 final ActivityStack stack = display.getChildAt(stackNdx);
2367 pw.println();
Garfield Tan347bd602018-12-21 15:11:12 -08002368 printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002369 needSep = printed;
2370 }
2371 printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep,
2372 " ResumedActivity:");
2373 }
2374
2375 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ",
2376 "Fin", false, !dumpAll,
2377 false, dumpPackage, true, " Activities waiting to finish:", null);
2378 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
2379 "Stop", false, !dumpAll,
2380 false, dumpPackage, true, " Activities waiting to stop:", null);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002381 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
2382 " ", "Sleep", false, !dumpAll,
2383 false, dumpPackage, true, " Activities waiting to sleep:", null);
2384
2385 return printed;
2386 }
2387
Nataniel Borges023ecb52019-01-16 14:15:43 -08002388 protected void writeToProto(ProtoOutputStream proto, long fieldId,
2389 @WindowTraceLogLevel int logLevel) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002390 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002391 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002392 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2393 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002394 activityDisplay.writeToProto(proto, DISPLAYS, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002395 }
2396 mStackSupervisor.getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER);
2397 // TODO(b/111541062): Update tests to look for resumed activities on all displays
2398 final ActivityStack focusedStack = getTopDisplayFocusedStack();
2399 if (focusedStack != null) {
2400 proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
2401 final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
2402 if (focusedActivity != null) {
2403 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
2404 }
2405 } else {
2406 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
2407 }
2408 proto.write(IS_HOME_RECENTS_COMPONENT,
2409 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
2410 mService.getActivityStartController().writeToProto(proto, PENDING_ACTIVITIES);
2411 proto.end(token);
2412 }
2413
2414 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
2415 private final String mTag;
2416 private final long mAcquireTime;
2417 private final int mDisplayId;
2418
2419 public SleepTokenImpl(String tag, int displayId) {
2420 mTag = tag;
2421 mDisplayId = displayId;
2422 mAcquireTime = SystemClock.uptimeMillis();
2423 }
2424
2425 @Override
2426 public void release() {
2427 synchronized (mService.mGlobalLock) {
2428 removeSleepToken(this);
2429 }
2430 }
2431
2432 @Override
2433 public String toString() {
2434 return "{\"" + mTag + "\", display " + mDisplayId
2435 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
2436 }
2437 }
2438}