blob: 0995df8693a114cc1b3592b662ce7059ac15a27f [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;
Wale Ogunwaled32da472018-11-16 07:19:28 -080051import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
52import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
53import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
54import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
55import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
56import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
57import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
58import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
59import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
60import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
61import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
62import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
63import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
64import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Louis Changcdec0802019-11-11 11:45:07 +080065import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
66import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
Wale Ogunwaled32da472018-11-16 07:19:28 -080067
68import static java.lang.Integer.MAX_VALUE;
69
70import android.annotation.IntDef;
71import android.annotation.NonNull;
72import android.annotation.Nullable;
73import android.annotation.UserIdInt;
74import android.app.ActivityManager;
75import android.app.ActivityOptions;
76import android.app.AppGlobals;
77import android.app.WindowConfiguration;
78import android.content.ComponentName;
79import android.content.Intent;
80import android.content.pm.ActivityInfo;
81import android.content.pm.ApplicationInfo;
82import android.content.pm.ResolveInfo;
83import android.content.res.Configuration;
84import android.content.res.Resources;
85import android.graphics.Rect;
86import android.hardware.display.DisplayManager;
87import android.hardware.display.DisplayManagerInternal;
88import android.hardware.power.V1_0.PowerHint;
Wale Ogunwaled32da472018-11-16 07:19:28 -080089import android.os.FactoryTest;
90import android.os.IBinder;
91import android.os.RemoteException;
92import android.os.SystemClock;
Wale Ogunwaled32da472018-11-16 07:19:28 -080093import android.os.UserHandle;
Chilun85ebc0d2019-04-15 16:00:53 +080094import android.os.storage.StorageManager;
Chilun2ef71f72018-11-16 17:57:15 +080095import android.provider.Settings;
Wale Ogunwaled32da472018-11-16 07:19:28 -080096import android.service.voice.IVoiceInteractionSession;
97import android.util.ArraySet;
98import android.util.DisplayMetrics;
99import android.util.IntArray;
Chilun2ef71f72018-11-16 17:57:15 +0800100import android.util.Pair;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800101import android.util.Slog;
102import android.util.SparseArray;
103import android.util.SparseIntArray;
104import android.util.TimeUtils;
105import android.util.proto.ProtoOutputStream;
106import android.view.Display;
107import android.view.DisplayInfo;
108
109import com.android.internal.annotations.VisibleForTesting;
Chilun2ef71f72018-11-16 17:57:15 +0800110import com.android.internal.app.ResolverActivity;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800111import com.android.server.LocalServices;
112import com.android.server.am.ActivityManagerService;
113import com.android.server.am.AppTimeTracker;
114import com.android.server.am.UserState;
Chilun8b1f1be2019-03-13 17:14:36 +0800115import com.android.server.policy.WindowManagerPolicy;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800116
117import java.io.FileDescriptor;
118import java.io.PrintWriter;
119import java.lang.annotation.Retention;
120import java.lang.annotation.RetentionPolicy;
121import java.util.ArrayList;
122import java.util.Iterator;
123import java.util.List;
124import java.util.Set;
125
126/**
127 * Root node for activity containers.
128 * TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
129 * intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
130 */
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800131class RootActivityContainer extends ConfigurationContainer
132 implements DisplayManager.DisplayListener {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800133
134 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootActivityContainer" : TAG_ATM;
135 static final String TAG_TASKS = TAG + POSTFIX_TASKS;
136 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
137 static final String TAG_STATES = TAG + POSTFIX_STATES;
138 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
139
140 /**
141 * The modes which affect which tasks are returned when calling
142 * {@link RootActivityContainer#anyTaskForId(int)}.
143 */
144 @Retention(RetentionPolicy.SOURCE)
145 @IntDef({
146 MATCH_TASK_IN_STACKS_ONLY,
147 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
148 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
149 })
150 public @interface AnyTaskForIdMatchTaskMode {}
151 // Match only tasks in the current stacks
152 static final int MATCH_TASK_IN_STACKS_ONLY = 0;
153 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
154 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
155 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
156 // provided stack id
157 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
158
159 ActivityTaskManagerService mService;
160 ActivityStackSupervisor mStackSupervisor;
161 WindowManagerService mWindowManager;
162 DisplayManager mDisplayManager;
163 private DisplayManagerInternal mDisplayManagerInternal;
Wale Ogunwale31acb3f2018-11-20 15:23:55 -0800164 // TODO: Remove after object merge with RootWindowContainer.
165 private RootWindowContainer mRootWindowContainer;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800166
167 /**
168 * List of displays which contain activities, sorted by z-order.
169 * The last entry in the list is the topmost.
170 */
171 private final ArrayList<ActivityDisplay> mActivityDisplays = new ArrayList<>();
172
173 /** Reference to default display so we can quickly look it up. */
174 private ActivityDisplay mDefaultDisplay;
175 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
176
177 /** The current user */
178 int mCurrentUser;
179 /** Stack id of the front stack when user switched, indexed by userId. */
180 SparseIntArray mUserStackInFront = new SparseIntArray(2);
181
182 /**
183 * A list of tokens that cause the top activity to be put to sleep.
184 * They are used by components that may hide and block interaction with underlying
185 * activities.
186 */
187 final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
188
189 /** Is dock currently minimized. */
190 boolean mIsDockMinimized;
191
192 /** Set when a power hint has started, but not ended. */
193 private boolean mPowerHintSent;
194
Louis Changa5d070e2019-09-04 13:20:01 +0800195 /** Used to keep ensureActivitiesVisible() from being entered recursively. */
196 private boolean mInEnsureActivitiesVisible = false;
197
Wale Ogunwaled32da472018-11-16 07:19:28 -0800198 // The default minimal size that will be used if the activity doesn't specify its minimal size.
199 // It will be calculated when the default display gets added.
200 int mDefaultMinSizeOfResizeableTaskDp = -1;
201
202 // Whether tasks have moved and we need to rank the tasks before next OOM scoring
203 private boolean mTaskLayersChanged = true;
204
205 private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
206
207 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
208 static class FindTaskResult {
209 ActivityRecord mRecord;
210 boolean mIdealMatch;
211
212 void clear() {
213 mRecord = null;
214 mIdealMatch = false;
215 }
216
217 void setTo(FindTaskResult result) {
218 mRecord = result.mRecord;
219 mIdealMatch = result.mIdealMatch;
220 }
221 }
222
223 RootActivityContainer(ActivityTaskManagerService service) {
224 mService = service;
225 mStackSupervisor = service.mStackSupervisor;
226 mStackSupervisor.mRootActivityContainer = this;
227 }
228
Wale Ogunwaled32da472018-11-16 07:19:28 -0800229 void setWindowManager(WindowManagerService wm) {
230 mWindowManager = wm;
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700231 mRootWindowContainer = mWindowManager.mRoot;
232 mRootWindowContainer.setRootActivityContainer(this);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800233 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
Charles Chen699e3602019-01-10 15:00:25 +0800234 mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800235 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
236
237 final Display[] displays = mDisplayManager.getDisplays();
238 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
239 final Display display = displays[displayNdx];
240 final ActivityDisplay activityDisplay = new ActivityDisplay(this, display);
241 if (activityDisplay.mDisplayId == DEFAULT_DISPLAY) {
242 mDefaultDisplay = activityDisplay;
243 }
244 addChild(activityDisplay, ActivityDisplay.POSITION_TOP);
245 }
246 calculateDefaultMinimalSizeOfResizeableTasks();
247
248 final ActivityDisplay defaultDisplay = getDefaultDisplay();
249
250 defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
251 positionChildAt(defaultDisplay, ActivityDisplay.POSITION_TOP);
252 }
253
254 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
255 ActivityDisplay getDefaultDisplay() {
256 return mDefaultDisplay;
257 }
258
259 /**
260 * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is
261 * defined in {@link DisplayInfo#uniqueId}.
262 *
263 * @param uniqueId the unique ID of the display
264 * @return the {@link ActivityDisplay} or {@code null} if nothing is found.
265 */
266 ActivityDisplay getActivityDisplay(String uniqueId) {
267 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
268 final ActivityDisplay display = mActivityDisplays.get(i);
269 final boolean isValid = display.mDisplay.isValid();
270 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
271 return display;
272 }
273 }
274
275 return null;
276 }
277
278 // TODO: Look into consolidating with getActivityDisplayOrCreate()
279 ActivityDisplay getActivityDisplay(int displayId) {
280 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
281 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
282 if (activityDisplay.mDisplayId == displayId) {
283 return activityDisplay;
284 }
285 }
286 return null;
287 }
288
289 /**
290 * Get an existing instance of {@link ActivityDisplay} or create new if there is a
291 * corresponding record in display manager.
292 */
293 // TODO: Look into consolidating with getActivityDisplay()
Charles Chenb409e6c2019-02-12 12:30:17 +0800294 @Nullable ActivityDisplay getActivityDisplayOrCreate(int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800295 ActivityDisplay activityDisplay = getActivityDisplay(displayId);
296 if (activityDisplay != null) {
297 return activityDisplay;
298 }
299 if (mDisplayManager == null) {
300 // The system isn't fully initialized yet.
301 return null;
302 }
303 final Display display = mDisplayManager.getDisplay(displayId);
304 if (display == null) {
305 // The display is not registered in DisplayManager.
306 return null;
307 }
308 // The display hasn't been added to ActivityManager yet, create a new record now.
309 activityDisplay = new ActivityDisplay(this, display);
310 addChild(activityDisplay, ActivityDisplay.POSITION_BOTTOM);
311 return activityDisplay;
312 }
313
Wale Ogunwaled32da472018-11-16 07:19:28 -0800314 ActivityRecord getDefaultDisplayHomeActivity() {
315 return getDefaultDisplayHomeActivityForUser(mCurrentUser);
316 }
317
318 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
319 return getActivityDisplay(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
320 }
321
322 boolean startHomeOnAllDisplays(int userId, String reason) {
323 boolean homeStarted = false;
324 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
325 final int displayId = mActivityDisplays.get(i).mDisplayId;
326 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
327 }
328 return homeStarted;
329 }
330
Louis Changdcdde952018-12-04 15:38:44 +0800331 void startHomeOnEmptyDisplays(String reason) {
332 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
333 final ActivityDisplay display = mActivityDisplays.get(i);
334 if (display.topRunningActivity() == null) {
335 startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
336 }
337 }
338 }
339
Chilun8b1f1be2019-03-13 17:14:36 +0800340 boolean startHomeOnDisplay(int userId, String reason, int displayId) {
Chilun39232092019-03-22 14:41:30 +0800341 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
342 false /* fromHomeKey */);
Chilun8b1f1be2019-03-13 17:14:36 +0800343 }
344
Wale Ogunwaled32da472018-11-16 07:19:28 -0800345 /**
Chilun2ef71f72018-11-16 17:57:15 +0800346 * This starts home activity on displays that can have system decorations based on displayId -
347 * Default display always use primary home component.
348 * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
349 * according to the priorities listed below.
350 * - If default home is not set, always use the secondary home defined in the config.
351 * - Use currently selected primary home activity.
352 * - Use the activity in the same package as currently selected primary home activity.
353 * If there are multiple activities matched, use first one.
354 * - Use the secondary home defined in the config.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800355 */
Chilun39232092019-03-22 14:41:30 +0800356 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
357 boolean fromHomeKey) {
Chilun8b1f1be2019-03-13 17:14:36 +0800358 // Fallback to top focused display if the displayId is invalid.
359 if (displayId == INVALID_DISPLAY) {
Wale Ogunwalefef90a02019-11-06 17:56:33 -0800360 final ActivityStack stack = getTopDisplayFocusedStack();
361 displayId = stack != null ? stack.mDisplayId : DEFAULT_DISPLAY;
Chilun8b1f1be2019-03-13 17:14:36 +0800362 }
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 */)) {
Wale Ogunwale21e06482019-11-18 05:14:15 -0800679 final ActivityRecord top = stack.getTopNonFinishingActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800680 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);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700860 stack.switchUser(userId);
Louis Changcdec0802019-11-11 11:45:07 +0800861 Task task = stack.topTask();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800862 if (task != null) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700863 stack.positionChildAtTop(task);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800864 }
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 Ogunwalebebd8cd2019-10-28 15:53:31 -0700933 stack.reparent(activityDisplay.mDisplayContent, onTop);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800934 // 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();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800967
Wale Ogunwaled32da472018-11-16 07:19:28 -0800968 try {
Louis Changcdec0802019-11-11 11:45:07 +0800969 final Task task = r.getTask();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800970
Ben Lin6db8fb22019-10-18 16:03:44 -0700971 final ActivityStack pinnedStack = display.getPinnedStack();
972 // This will change the pinned stack's windowing mode to its original mode, ensuring
973 // we only have one stack that is in pinned mode.
974 if (pinnedStack != null) {
975 pinnedStack.dismissPip();
976 }
977
978 final boolean singleActivity = task.getChildCount() == 1;
979
980 final ActivityStack stack;
981 if (singleActivity) {
982 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800983 } else {
Ben Lin6db8fb22019-10-18 16:03:44 -0700984 // In the case of multiple activities, we will create a new stack for it and then
985 // move the PIP activity into the stack.
986 // We will then perform a windowing mode change for both scenarios.
987 stack = display.createStack(
988 r.getActivityStack().getRequestedOverrideWindowingMode(),
989 r.getActivityType(), ON_TOP);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800990 // There are multiple activities in the task and moving the top activity should
991 // reveal/leave the other activities in their original task.
992
993 // Currently, we don't support reparenting activities across tasks in two different
994 // stacks, so instead, just create a new task in the same stack, reparent the
995 // activity into that task, and then reparent the whole task to the new stack. This
996 // ensures that all the necessary work to migrate states in the old and new stacks
997 // is also done.
Louis Changcdec0802019-11-11 11:45:07 +0800998 final Task newTask = task.getStack().createTask(
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800999 mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001000 r.intent, null, null, true);
1001 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
1002
1003 // Defer resume until below, and do not schedule PiP changes until we animate below
1004 newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
1005 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
1006 }
1007
Ben Lin6db8fb22019-10-18 16:03:44 -07001008 stack.setWindowingMode(WINDOWING_MODE_PINNED);
1009
Wale Ogunwaled32da472018-11-16 07:19:28 -08001010 // Reset the state that indicates it can enter PiP while pausing after we've moved it
1011 // to the pinned stack
1012 r.supportsEnterPipOnTaskSwitch = false;
1013 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08001014 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001015 }
1016
Hongwei Wang43a752b2019-09-17 20:20:30 +00001017 // Notify the pinned stack controller to prepare the PiP animation, expect callback
1018 // delivered from SystemUI to WM to start the animation.
1019 final PinnedStackController pinnedStackController =
1020 display.mDisplayContent.getPinnedStackController();
1021 pinnedStackController.prepareAnimation(sourceHintBounds, aspectRatio,
1022 null /* stackBounds */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001023
Hongwei Wang43a752b2019-09-17 20:20:30 +00001024 // TODO: revisit the following statement after the animation is moved from WM to SysUI.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001025 // Update the visibility of all activities after the they have been reparented to the new
1026 // stack. This MUST run after the animation above is scheduled to ensure that the windows
1027 // drawn signal is scheduled after the bounds animation start call on the bounds animator
1028 // thread.
1029 ensureActivitiesVisible(null, 0, false /* preserveWindows */);
1030 resumeFocusedStacksTopActivities();
1031
1032 mService.getTaskChangeNotificationController().notifyActivityPinned(r);
1033 }
1034
1035 void executeAppTransitionForAllDisplay() {
1036 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1037 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001038 display.mDisplayContent.executeAppTransition();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001039 }
1040 }
1041
1042 void setDockedStackMinimized(boolean minimized) {
1043 // Get currently focused stack before setting mIsDockMinimized. We do this because if
1044 // split-screen is active, primary stack will not be focusable (see #isFocusable) while
1045 // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
1046 final ActivityStack current = getTopDisplayFocusedStack();
1047 mIsDockMinimized = minimized;
1048 if (mIsDockMinimized) {
1049 if (current.inSplitScreenPrimaryWindowingMode()) {
1050 // The primary split-screen stack can't be focused while it is minimize, so move
1051 // focus to something else.
1052 current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
1053 }
1054 }
1055 }
1056
1057 ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
1058 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
1059 mTmpFindTaskResult.clear();
1060
1061 // Looking up task on preferred display first
1062 final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId);
1063 if (preferredDisplay != null) {
1064 preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult);
1065 if (mTmpFindTaskResult.mIdealMatch) {
1066 return mTmpFindTaskResult.mRecord;
1067 }
1068 }
1069
1070 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1071 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1072 if (display.mDisplayId == preferredDisplayId) {
1073 continue;
1074 }
1075
1076 display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult);
1077 if (mTmpFindTaskResult.mIdealMatch) {
1078 return mTmpFindTaskResult.mRecord;
1079 }
1080 }
1081
1082 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
1083 return mTmpFindTaskResult.mRecord;
1084 }
1085
1086 /**
1087 * Finish the topmost activities in all stacks that belong to the crashed app.
1088 * @param app The app that crashed.
1089 * @param reason Reason to perform this action.
1090 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
1091 */
1092 int finishTopCrashedActivities(WindowProcessController app, String reason) {
Louis Changcdec0802019-11-11 11:45:07 +08001093 Task finishedTask = null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001094 ActivityStack focusedStack = getTopDisplayFocusedStack();
1095 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1096 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1097 // It is possible that request to finish activity might also remove its task and stack,
1098 // so we need to be careful with indexes in the loop and check child count every time.
1099 for (int stackNdx = 0; stackNdx < display.getChildCount(); ++stackNdx) {
1100 final ActivityStack stack = display.getChildAt(stackNdx);
Louis Changcdec0802019-11-11 11:45:07 +08001101 final Task t = stack.finishTopCrashedActivityLocked(app, reason);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001102 if (stack == focusedStack || finishedTask == null) {
1103 finishedTask = t;
1104 }
1105 }
1106 }
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001107 return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001108 }
1109
1110 boolean resumeFocusedStacksTopActivities() {
1111 return resumeFocusedStacksTopActivities(null, null, null);
1112 }
1113
1114 boolean resumeFocusedStacksTopActivities(
1115 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1116
1117 if (!mStackSupervisor.readyToResume()) {
1118 return false;
1119 }
1120
Andrii Kulian6b321512019-01-23 06:37:00 +00001121 boolean result = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001122 if (targetStack != null && (targetStack.isTopStackOnDisplay()
1123 || getTopDisplayFocusedStack() == targetStack)) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001124 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001125 }
1126
Wale Ogunwaled32da472018-11-16 07:19:28 -08001127 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
Andrii Kulian6b321512019-01-23 06:37:00 +00001128 boolean resumedOnDisplay = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001129 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
Andrii Kulian6b321512019-01-23 06:37:00 +00001130 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1131 final ActivityStack stack = display.getChildAt(stackNdx);
1132 final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
1133 if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
1134 continue;
1135 }
Louis Changc50a9362019-02-12 12:35:24 +08001136 if (stack == targetStack) {
1137 // Simply update the result for targetStack because the targetStack had
1138 // already resumed in above. We don't want to resume it again, especially in
1139 // some cases, it would cause a second launch failure if app process was dead.
1140 resumedOnDisplay |= result;
1141 continue;
1142 }
Jorim Jaggia5cf6802019-04-26 19:43:11 +02001143 if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
1144 // Kick off any lingering app transitions form the MoveTaskToFront operation,
1145 // but only consider the top task and stack on that display.
Andrii Kulian6b321512019-01-23 06:37:00 +00001146 stack.executeAppTransition(targetOptions);
1147 } else {
1148 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
1149 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001150 }
Andrii Kulian6b321512019-01-23 06:37:00 +00001151 if (!resumedOnDisplay) {
1152 // In cases when there are no valid activities (e.g. device just booted or launcher
1153 // crashed) it's possible that nothing was resumed on a display. Requesting resume
1154 // of top activity in focused stack explicitly will make sure that at least home
1155 // activity is started and resumed, and no recursion occurs.
1156 final ActivityStack focusedStack = display.getFocusedStack();
1157 if (focusedStack != null) {
wilsonshih4c9824a2019-10-25 18:47:50 +08001158 result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
Riddle Hsua0175ab2019-11-12 23:52:32 +08001159 } else if (targetStack == null && !display.hasChild()) {
1160 result |= resumeHomeActivity(null /* prev */, "empty-display",
1161 display.mDisplayId);
Andrii Kulian6b321512019-01-23 06:37:00 +00001162 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001163 }
1164 }
1165
Andrii Kulian6b321512019-01-23 06:37:00 +00001166 return result;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001167 }
1168
1169 void applySleepTokens(boolean applyToStacks) {
1170 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1171 // Set the sleeping state of the display.
1172 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1173 final boolean displayShouldSleep = display.shouldSleep();
1174 if (displayShouldSleep == display.isSleeping()) {
1175 continue;
1176 }
1177 display.setIsSleeping(displayShouldSleep);
1178
1179 if (!applyToStacks) {
1180 continue;
1181 }
1182
1183 // Set the sleeping state of the stacks on the display.
1184 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1185 final ActivityStack stack = display.getChildAt(stackNdx);
1186 if (displayShouldSleep) {
1187 stack.goToSleepIfPossible(false /* shuttingDown */);
1188 } else {
Issei Suzukicac2a502019-04-16 16:52:50 +02001189 // When the display which can only contain one task turns on, start a special
1190 // transition. {@link AppTransitionController#handleAppTransitionReady} later
1191 // picks up the transition, and schedules
1192 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
1193 // triggered after contents are drawn on the display.
1194 if (display.isSingleTaskInstance()) {
1195 display.mDisplayContent.prepareAppTransition(
1196 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
1197 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001198 stack.awakeFromSleepingLocked();
1199 if (stack.isFocusedStackOnDisplay()
1200 && !mStackSupervisor.getKeyguardController()
1201 .isKeyguardOrAodShowing(display.mDisplayId)) {
1202 // If the keyguard is unlocked - resume immediately.
1203 // It is possible that the display will not be awake at the time we
1204 // process the keyguard going away, which can happen before the sleep token
1205 // is released. As a result, it is important we resume the activity here.
1206 resumeFocusedStacksTopActivities();
1207 }
1208 }
1209 }
1210
1211 if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) {
1212 continue;
1213 }
1214 // The display is awake now, so clean up the going to sleep list.
1215 for (Iterator<ActivityRecord> it =
1216 mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) {
1217 final ActivityRecord r = it.next();
1218 if (r.getDisplayId() == display.mDisplayId) {
1219 it.remove();
1220 }
1221 }
1222 }
1223 }
1224
1225 protected <T extends ActivityStack> T getStack(int stackId) {
1226 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1227 final T stack = mActivityDisplays.get(i).getStack(stackId);
1228 if (stack != null) {
1229 return stack;
1230 }
1231 }
1232 return null;
1233 }
1234
1235 /** @see ActivityDisplay#getStack(int, int) */
1236 private <T extends ActivityStack> T getStack(int windowingMode, int activityType) {
1237 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1238 final T stack = mActivityDisplays.get(i).getStack(windowingMode, activityType);
1239 if (stack != null) {
1240 return stack;
1241 }
1242 }
1243 return null;
1244 }
1245
1246 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
1247 final int displayId = stack.mDisplayId;
1248 final ActivityDisplay display = getActivityDisplay(displayId);
1249 ActivityManager.StackInfo info = new ActivityManager.StackInfo();
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001250 stack.getBounds(info.bounds);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001251 info.displayId = displayId;
1252 info.stackId = stack.mStackId;
Evan Rosky282ee672019-11-13 15:50:46 -08001253 info.stackToken = stack.mRemoteToken;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001254 info.userId = stack.mCurrentUser;
1255 info.visible = stack.shouldBeVisible(null);
1256 // A stack might be not attached to a display.
1257 info.position = display != null ? display.getIndexOf(stack) : 0;
1258 info.configuration.setTo(stack.getConfiguration());
1259
Louis Changcdec0802019-11-11 11:45:07 +08001260 ArrayList<Task> tasks = stack.getAllTasks();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001261 final int numTasks = tasks.size();
1262 int[] taskIds = new int[numTasks];
1263 String[] taskNames = new String[numTasks];
1264 Rect[] taskBounds = new Rect[numTasks];
1265 int[] taskUserIds = new int[numTasks];
1266 for (int i = 0; i < numTasks; ++i) {
Louis Changcdec0802019-11-11 11:45:07 +08001267 final Task task = tasks.get(i);
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001268 taskIds[i] = task.mTaskId;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001269 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
1270 : task.realActivity != null ? task.realActivity.flattenToString()
Wale Ogunwale21e06482019-11-18 05:14:15 -08001271 : task.getTopNonFinishingActivity() != null
1272 ? task.getTopNonFinishingActivity().packageName : "unknown";
Wale Ogunwale2322bed2019-10-10 17:24:19 +02001273 taskBounds[i] = mService.getTaskBounds(task.mTaskId);
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07001274 taskUserIds[i] = task.mUserId;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001275 }
1276 info.taskIds = taskIds;
1277 info.taskNames = taskNames;
1278 info.taskBounds = taskBounds;
1279 info.taskUserIds = taskUserIds;
1280
1281 final ActivityRecord top = stack.topRunningActivityLocked();
1282 info.topActivity = top != null ? top.intent.getComponent() : null;
1283 return info;
1284 }
1285
1286 ActivityManager.StackInfo getStackInfo(int stackId) {
1287 ActivityStack stack = getStack(stackId);
1288 if (stack != null) {
1289 return getStackInfo(stack);
1290 }
1291 return null;
1292 }
1293
1294 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
1295 final ActivityStack stack = getStack(windowingMode, activityType);
1296 return (stack != null) ? getStackInfo(stack) : null;
1297 }
1298
1299 ArrayList<ActivityManager.StackInfo> getAllStackInfos() {
1300 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
1301 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
1302 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1303 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1304 final ActivityStack stack = display.getChildAt(stackNdx);
1305 list.add(getStackInfo(stack));
1306 }
1307 }
1308 return list;
1309 }
1310
1311 void deferUpdateBounds(int activityType) {
1312 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1313 if (stack != null) {
1314 stack.deferUpdateBounds();
1315 }
1316 }
1317
1318 void continueUpdateBounds(int activityType) {
1319 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
1320 if (stack != null) {
1321 stack.continueUpdateBounds();
1322 }
1323 }
1324
1325 @Override
1326 public void onDisplayAdded(int displayId) {
1327 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
1328 synchronized (mService.mGlobalLock) {
Charles Chen3dedec32019-01-24 22:19:37 +08001329 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
Charles Chenb409e6c2019-02-12 12:30:17 +08001330 if (display == null) {
1331 return;
1332 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001333 // Do not start home before booting, or it may accidentally finish booting before it
1334 // starts. Instead, we expect home activities to be launched when the system is ready
1335 // (ActivityManagerService#systemReady).
1336 if (mService.isBooted() || mService.isBooting()) {
Charles Chen3dedec32019-01-24 22:19:37 +08001337 startSystemDecorations(display.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001338 }
1339 }
1340 }
1341
Charles Chen3dedec32019-01-24 22:19:37 +08001342 private void startSystemDecorations(final DisplayContent displayContent) {
1343 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
1344 displayContent.getDisplayPolicy().notifyDisplayReady();
1345 }
1346
Wale Ogunwaled32da472018-11-16 07:19:28 -08001347 @Override
1348 public void onDisplayRemoved(int displayId) {
1349 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
1350 if (displayId == DEFAULT_DISPLAY) {
1351 throw new IllegalArgumentException("Can't remove the primary display.");
1352 }
1353
1354 synchronized (mService.mGlobalLock) {
1355 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1356 if (activityDisplay == null) {
1357 return;
1358 }
1359
1360 activityDisplay.remove();
1361 }
1362 }
1363
1364 @Override
1365 public void onDisplayChanged(int displayId) {
1366 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
1367 synchronized (mService.mGlobalLock) {
1368 final ActivityDisplay activityDisplay = getActivityDisplay(displayId);
1369 if (activityDisplay != null) {
1370 activityDisplay.onDisplayChanged();
1371 }
1372 }
1373 }
1374
1375 /** Update lists of UIDs that are present on displays and have access to them. */
1376 void updateUIDsPresentOnDisplay() {
1377 mDisplayAccessUIDs.clear();
1378 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1379 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
1380 // Only bother calculating the whitelist for private displays
1381 if (activityDisplay.isPrivate()) {
1382 mDisplayAccessUIDs.append(
1383 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs());
1384 }
1385 }
1386 // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
1387 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
1388 }
1389
1390 ActivityStack findStackBehind(ActivityStack stack) {
1391 final ActivityDisplay display = getActivityDisplay(stack.mDisplayId);
1392 if (display != null) {
1393 for (int i = display.getChildCount() - 1; i >= 0; i--) {
1394 if (display.getChildAt(i) == stack && i > 0) {
1395 return display.getChildAt(i - 1);
1396 }
1397 }
1398 }
1399 throw new IllegalStateException("Failed to find a stack behind stack=" + stack
1400 + " in=" + display);
1401 }
1402
1403 @Override
1404 protected int getChildCount() {
1405 return mActivityDisplays.size();
1406 }
1407
1408 @Override
1409 protected ActivityDisplay getChildAt(int index) {
1410 return mActivityDisplays.get(index);
1411 }
1412
1413 @Override
1414 protected ConfigurationContainer getParent() {
1415 return null;
1416 }
1417
Wale Ogunwale31acb3f2018-11-20 15:23:55 -08001418 // TODO: remove after object merge with RootWindowContainer
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001419 void onChildPositionChanged(ActivityDisplay display, int position) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001420 // Assume AM lock is held from positionChildAt of controller in each hierarchy.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001421 if (display != null) {
1422 positionChildAt(display, position);
1423 }
1424 }
1425
1426 /** Change the z-order of the given display. */
1427 private void positionChildAt(ActivityDisplay display, int position) {
1428 if (position >= mActivityDisplays.size()) {
1429 position = mActivityDisplays.size() - 1;
1430 } else if (position < 0) {
1431 position = 0;
1432 }
1433
1434 if (mActivityDisplays.isEmpty()) {
1435 mActivityDisplays.add(display);
1436 } else if (mActivityDisplays.get(position) != display) {
1437 mActivityDisplays.remove(display);
1438 mActivityDisplays.add(position, display);
1439 }
Andrii Kulian86e70fc2019-02-12 11:04:10 +00001440 mStackSupervisor.updateTopResumedActivityIfNeeded();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001441 }
1442
1443 @VisibleForTesting
1444 void addChild(ActivityDisplay activityDisplay, int position) {
1445 positionChildAt(activityDisplay, position);
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001446 mRootWindowContainer.positionChildAt(position, activityDisplay.mDisplayContent);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001447 }
1448
1449 void removeChild(ActivityDisplay activityDisplay) {
1450 // The caller must tell the controller of {@link ActivityDisplay} to release its container
1451 // {@link DisplayContent}. That is done in {@link ActivityDisplay#releaseSelfIfNeeded}).
1452 mActivityDisplays.remove(activityDisplay);
1453 }
1454
1455 Configuration getDisplayOverrideConfiguration(int displayId) {
1456 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1457 if (activityDisplay == null) {
1458 throw new IllegalArgumentException("No display found with id: " + displayId);
1459 }
1460
Evan Roskydfe3da72018-10-26 17:21:06 -07001461 return activityDisplay.getRequestedOverrideConfiguration();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001462 }
1463
1464 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
1465 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1466 if (activityDisplay == null) {
1467 throw new IllegalArgumentException("No display found with id: " + displayId);
1468 }
1469
Evan Roskydfe3da72018-10-26 17:21:06 -07001470 activityDisplay.onRequestedOverrideConfigurationChanged(overrideConfiguration);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001471 }
1472
1473 void prepareForShutdown() {
1474 for (int i = 0; i < mActivityDisplays.size(); i++) {
1475 createSleepToken("shutdown", mActivityDisplays.get(i).mDisplayId);
1476 }
1477 }
1478
1479 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
1480 final ActivityDisplay display = getActivityDisplay(displayId);
1481 if (display == null) {
1482 throw new IllegalArgumentException("Invalid display: " + displayId);
1483 }
1484
1485 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
1486 mSleepTokens.add(token);
1487 display.mAllSleepTokens.add(token);
1488 return token;
1489 }
1490
1491 private void removeSleepToken(SleepTokenImpl token) {
1492 mSleepTokens.remove(token);
1493
1494 final ActivityDisplay display = getActivityDisplay(token.mDisplayId);
1495 if (display != null) {
1496 display.mAllSleepTokens.remove(token);
1497 if (display.mAllSleepTokens.isEmpty()) {
1498 mService.updateSleepIfNeededLocked();
1499 }
1500 }
1501 }
1502
1503 void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
1504 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1505 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1506 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1507 final ActivityStack stack = display.getChildAt(stackNdx);
1508 stack.addStartingWindowsForVisibleActivities(taskSwitch);
1509 }
1510 }
1511 }
1512
1513 void invalidateTaskLayers() {
1514 mTaskLayersChanged = true;
1515 }
1516
1517 void rankTaskLayersIfNeeded() {
1518 if (!mTaskLayersChanged) {
1519 return;
1520 }
1521 mTaskLayersChanged = false;
1522 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
1523 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1524 int baseLayer = 0;
1525 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1526 final ActivityStack stack = display.getChildAt(stackNdx);
1527 baseLayer += stack.rankTaskLayers(baseLayer);
1528 }
1529 }
1530 }
1531
1532 void clearOtherAppTimeTrackers(AppTimeTracker except) {
1533 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1534 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1535 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1536 final ActivityStack stack = display.getChildAt(stackNdx);
1537 stack.clearOtherAppTimeTrackers(except);
1538 }
1539 }
1540 }
1541
1542 void scheduleDestroyAllActivities(WindowProcessController app, String reason) {
1543 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1544 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1545 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1546 final ActivityStack stack = display.getChildAt(stackNdx);
1547 stack.scheduleDestroyActivities(app, reason);
1548 }
1549 }
1550 }
1551
1552 void releaseSomeActivitiesLocked(WindowProcessController app, String reason) {
1553 // Tasks is non-null only if two or more tasks are found.
Louis Changcdec0802019-11-11 11:45:07 +08001554 ArraySet<Task> tasks = app.getReleaseSomeActivitiesTasks();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001555 if (tasks == null) {
1556 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
1557 return;
1558 }
1559 // If we have activities in multiple tasks that are in a position to be destroyed,
1560 // let's iterate through the tasks and release the oldest one.
1561 final int numDisplays = mActivityDisplays.size();
1562 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
1563 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1564 final int stackCount = display.getChildCount();
1565 // Step through all stacks starting from behind, to hit the oldest things first.
1566 for (int stackNdx = 0; stackNdx < stackCount; stackNdx++) {
1567 final ActivityStack stack = display.getChildAt(stackNdx);
1568 // Try to release activities in this stack; if we manage to, we are done.
1569 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
1570 return;
1571 }
1572 }
1573 }
1574 }
1575
1576 // Tries to put all activity stacks to sleep. Returns true if all stacks were
1577 // successfully put to sleep.
1578 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
1579 boolean allSleep = true;
1580 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1581 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1582 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
Louis Changc219bc32018-12-06 15:38:41 +08001583 // Stacks and activities could be removed while putting activities to sleep if
1584 // the app process was gone. This prevents us getting exception by accessing an
1585 // invalid stack index.
1586 if (stackNdx >= display.getChildCount()) {
1587 continue;
1588 }
1589
Wale Ogunwaled32da472018-11-16 07:19:28 -08001590 final ActivityStack stack = display.getChildAt(stackNdx);
1591 if (allowDelay) {
1592 allSleep &= stack.goToSleepIfPossible(shuttingDown);
1593 } else {
1594 stack.goToSleep();
1595 }
1596 }
1597 }
1598 return allSleep;
1599 }
1600
1601 void handleAppCrash(WindowProcessController app) {
1602 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1603 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1604 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1605 final ActivityStack stack = display.getChildAt(stackNdx);
1606 stack.handleAppCrash(app);
1607 }
1608 }
1609 }
1610
1611 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
1612 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1613 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1614 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1615 final ActivityStack stack = display.getChildAt(stackNdx);
1616 final ActivityRecord ar = stack.findActivityLocked(
1617 intent, info, compareIntentFilters);
1618 if (ar != null) {
1619 return ar;
1620 }
1621 }
1622 }
1623 return null;
1624 }
1625
1626 boolean hasAwakeDisplay() {
1627 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1628 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1629 if (!display.shouldSleep()) {
1630 return true;
1631 }
1632 }
1633 return false;
1634 }
1635
Wale Ogunwale8577a052019-10-26 23:22:34 -07001636 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001637 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
lumarkf65e02d2019-09-14 19:25:21 +08001638 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
1639 -1 /* no realCallingPid */, -1 /* no realCallingUid */);
Wale Ogunwaled32da472018-11-16 07:19:28 -08001640 }
1641
1642 /**
1643 * Returns the right stack to use for launching factoring in all the input parameters.
1644 *
1645 * @param r The activity we are trying to launch. Can be null.
1646 * @param options The activity options used to the launch. Can be null.
1647 * @param candidateTask The possible task the activity might be launched in. Can be null.
lumarkf65e02d2019-09-14 19:25:21 +08001648 * @param launchParams The resolved launch params to use.
1649 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
1650 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
Wale Ogunwaled32da472018-11-16 07:19:28 -08001651 *
1652 * @return The stack to use for the launch or INVALID_STACK_ID.
1653 */
Wale Ogunwale8577a052019-10-26 23:22:34 -07001654 ActivityStack getLaunchStack(@Nullable ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001655 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
lumarkf65e02d2019-09-14 19:25:21 +08001656 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
1657 int realCallingUid) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001658 int taskId = INVALID_TASK_ID;
1659 int displayId = INVALID_DISPLAY;
1660 //Rect bounds = null;
1661
1662 // We give preference to the launch preference in activity options.
1663 if (options != null) {
1664 taskId = options.getLaunchTaskId();
1665 displayId = options.getLaunchDisplayId();
1666 }
1667
1668 // First preference for stack goes to the task Id set in the activity options. Use the stack
1669 // associated with that if possible.
1670 if (taskId != INVALID_TASK_ID) {
1671 // Temporarily set the task id to invalid in case in re-entry.
1672 options.setLaunchTaskId(INVALID_TASK_ID);
Louis Changcdec0802019-11-11 11:45:07 +08001673 final Task task = anyTaskForId(taskId,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001674 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
1675 options.setLaunchTaskId(taskId);
1676 if (task != null) {
1677 return task.getStack();
1678 }
1679 }
1680
1681 final int activityType = resolveActivityType(r, options, candidateTask);
Wale Ogunwale8577a052019-10-26 23:22:34 -07001682 ActivityStack stack;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001683
1684 // Next preference for stack goes to the display Id set the candidate display.
1685 if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
1686 displayId = launchParams.mPreferredDisplayId;
1687 }
lumarkf65e02d2019-09-14 19:25:21 +08001688 final boolean canLaunchOnDisplayFromStartRequest =
1689 realCallingPid != 0 && realCallingUid > 0 && r != null
1690 && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid,
1691 realCallingUid, r.info);
1692 // Checking if the activity's launch caller, or the realCallerId of the activity from
1693 // start request (i.e. entity that invokes PendingIntent) is allowed to launch on the
1694 // display.
1695 if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
1696 || canLaunchOnDisplayFromStartRequest)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001697 if (r != null) {
Wale Ogunwale8577a052019-10-26 23:22:34 -07001698 stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001699 launchParams);
1700 if (stack != null) {
1701 return stack;
1702 }
1703 }
1704 final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
1705 if (display != null) {
1706 stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1707 if (stack != null) {
1708 return stack;
1709 }
1710 }
1711 }
1712
1713 // Give preference to the stack and display of the input task and activity if they match the
1714 // mode we want to launch into.
1715 stack = null;
1716 ActivityDisplay display = null;
1717 if (candidateTask != null) {
1718 stack = candidateTask.getStack();
1719 }
1720 if (stack == null && r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001721 stack = r.getActivityStack();
Wale Ogunwaled32da472018-11-16 07:19:28 -08001722 }
1723 if (stack != null) {
1724 display = stack.getDisplay();
1725 if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) {
1726 int windowingMode = launchParams != null ? launchParams.mWindowingMode
1727 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
1728 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
1729 windowingMode = display.resolveWindowingMode(r, options, candidateTask,
1730 activityType);
1731 }
1732 if (stack.isCompatible(windowingMode, activityType)) {
1733 return stack;
1734 }
1735 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
1736 && display.getSplitScreenPrimaryStack() == stack
1737 && candidateTask == stack.topTask()) {
1738 // This is a special case when we try to launch an activity that is currently on
1739 // top of split-screen primary stack, but is targeting split-screen secondary.
1740 // In this case we don't want to move it to another stack.
1741 // TODO(b/78788972): Remove after differentiating between preferred and required
1742 // launch options.
1743 return stack;
1744 }
1745 }
1746 }
1747
1748 if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) {
1749 display = getDefaultDisplay();
1750 }
1751
1752 return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
1753 }
1754
1755 /** @return true if activity record is null or can be launched on provided display. */
1756 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
1757 if (r == null) {
1758 return true;
1759 }
1760 return r.canBeLaunchedOnDisplay(displayId);
1761 }
1762
1763 /**
1764 * Get a topmost stack on the display, that is a valid launch stack for specified activity.
1765 * If there is no such stack, new dynamic stack can be created.
1766 * @param displayId Target display.
1767 * @param r Activity that should be launched there.
1768 * @param candidateTask The possible task the activity might be put in.
1769 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
1770 */
1771 private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
Louis Changcdec0802019-11-11 11:45:07 +08001772 @Nullable Task candidateTask, @Nullable ActivityOptions options,
Wale Ogunwaled32da472018-11-16 07:19:28 -08001773 @Nullable LaunchParamsController.LaunchParams launchParams) {
1774 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId);
1775 if (activityDisplay == null) {
1776 throw new IllegalArgumentException(
1777 "Display with displayId=" + displayId + " not found.");
1778 }
1779
1780 if (!r.canBeLaunchedOnDisplay(displayId)) {
1781 return null;
1782 }
1783
1784 // If {@code r} is already in target display and its task is the same as the candidate task,
1785 // the intention should be getting a launch stack for the reusable activity, so we can use
1786 // the existing stack.
Louis Changcdec0802019-11-11 11:45:07 +08001787 if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
Louis Changf3070c52019-10-09 15:57:30 +08001788 final int attachedDisplayId = r.getDisplayId();
1789 if (attachedDisplayId == INVALID_DISPLAY || attachedDisplayId == displayId) {
1790 return candidateTask.getStack();
1791 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001792 }
1793
Louis Chang6fb1e842018-12-03 16:07:50 +08001794 int windowingMode;
1795 if (launchParams != null) {
1796 // When launch params is not null, we always defer to its windowing mode. Sometimes
1797 // it could be unspecified, which indicates it should inherit windowing mode from
1798 // display.
1799 windowingMode = launchParams.mWindowingMode;
1800 } else {
1801 windowingMode = options != null ? options.getLaunchWindowingMode()
1802 : r.getWindowingMode();
1803 }
1804 windowingMode = activityDisplay.validateWindowingMode(windowingMode, r, candidateTask,
1805 r.getActivityType());
1806
Wale Ogunwaled32da472018-11-16 07:19:28 -08001807 // Return the topmost valid stack on the display.
1808 for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) {
1809 final ActivityStack stack = activityDisplay.getChildAt(i);
Louis Chang6fb1e842018-12-03 16:07:50 +08001810 if (isValidLaunchStack(stack, r, windowingMode)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001811 return stack;
1812 }
1813 }
1814
1815 // If there is no valid stack on the external display - check if new dynamic stack will do.
1816 if (displayId != DEFAULT_DISPLAY) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001817 final int activityType =
1818 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
1819 ? options.getLaunchActivityType() : r.getActivityType();
1820 return activityDisplay.createStack(windowingMode, activityType, true /*onTop*/);
1821 }
1822
Wale Ogunwaled32da472018-11-16 07:19:28 -08001823 return null;
1824 }
1825
1826 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
1827 @Nullable ActivityOptions options,
1828 @Nullable LaunchParamsController.LaunchParams launchParams) {
1829 return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options,
1830 launchParams);
1831 }
1832
1833 // TODO: Can probably be consolidated into getLaunchStack()...
Louis Chang6fb1e842018-12-03 16:07:50 +08001834 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001835 switch (stack.getActivityType()) {
1836 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
1837 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
1838 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
1839 }
1840 // There is a 1-to-1 relationship between stack and task when not in
1841 // primary split-windowing mode.
Louis Chang6fb1e842018-12-03 16:07:50 +08001842 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
1843 && r.supportsSplitScreenWindowingMode()
1844 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
1845 || windowingMode == WINDOWING_MODE_UNDEFINED)) {
1846 return true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001847 }
Louis Chang6fb1e842018-12-03 16:07:50 +08001848 return false;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001849 }
1850
1851 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
Louis Changcdec0802019-11-11 11:45:07 +08001852 @Nullable Task task) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001853 // Preference is given to the activity type for the activity then the task since the type
1854 // once set shouldn't change.
1855 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
1856 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
1857 activityType = task.getActivityType();
1858 }
1859 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
1860 return activityType;
1861 }
1862 if (options != null) {
1863 activityType = options.getLaunchActivityType();
1864 }
1865 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
1866 }
1867
1868 /**
1869 * Get next focusable stack in the system. This will search through the stack on the same
1870 * display as the current focused stack, looking for a focusable and visible stack, different
1871 * from the target stack. If no valid candidates will be found, it will then go through all
1872 * displays and stacks in last-focused order.
1873 *
1874 * @param currentFocus The stack that previously had focus.
1875 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
1876 * candidate.
1877 * @return Next focusable {@link ActivityStack}, {@code null} if not found.
1878 */
1879 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
1880 boolean ignoreCurrent) {
1881 // First look for next focusable stack on the same display
Wale Ogunwale2322bed2019-10-10 17:24:19 +02001882 ActivityDisplay preferredDisplay = currentFocus.getDisplay();
1883 if (preferredDisplay == null) {
1884 // Stack is currently detached because it is being removed. Use the previous display it
1885 // was on.
1886 preferredDisplay = getActivityDisplay(currentFocus.mPrevDisplayId);
1887 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001888 final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
1889 currentFocus, ignoreCurrent);
1890 if (preferredFocusableStack != null) {
1891 return preferredFocusableStack;
1892 }
1893 if (preferredDisplay.supportsSystemDecorations()) {
1894 // Stop looking for focusable stack on other displays because the preferred display
1895 // supports system decorations. Home activity would be launched on the same display if
1896 // no focusable stack found.
1897 return null;
1898 }
1899
1900 // Now look through all displays
1901 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1902 final ActivityDisplay display = mActivityDisplays.get(i);
1903 if (display == preferredDisplay) {
1904 // We've already checked this one
1905 continue;
1906 }
1907 final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
1908 ignoreCurrent);
1909 if (nextFocusableStack != null) {
1910 return nextFocusableStack;
1911 }
1912 }
1913
1914 return null;
1915 }
1916
1917 /**
1918 * Get next valid stack for launching provided activity in the system. This will search across
1919 * displays and stacks in last-focused order for a focusable and visible stack, except those
1920 * that are on a currently focused display.
1921 *
1922 * @param r The activity that is being launched.
1923 * @param currentFocus The display that previously had focus and thus needs to be ignored when
1924 * searching for the next candidate.
1925 * @return Next valid {@link ActivityStack}, null if not found.
1926 */
1927 ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) {
1928 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
1929 final ActivityDisplay display = mActivityDisplays.get(i);
1930 if (display.mDisplayId == currentFocus) {
1931 continue;
1932 }
1933 final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r,
1934 null /* options */, null /* launchParams */);
1935 if (stack != null) {
1936 return stack;
1937 }
1938 }
1939 return null;
1940 }
1941
1942 boolean handleAppDied(WindowProcessController app) {
1943 boolean hasVisibleActivities = false;
1944 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1945 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1946 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1947 final ActivityStack stack = display.getChildAt(stackNdx);
1948 hasVisibleActivities |= stack.handleAppDiedLocked(app);
1949 }
1950 }
1951 return hasVisibleActivities;
1952 }
1953
1954 void closeSystemDialogs() {
1955 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1956 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1957 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1958 final ActivityStack stack = display.getChildAt(stackNdx);
1959 stack.closeSystemDialogsLocked();
1960 }
1961 }
1962 }
1963
1964 /** @return true if some activity was finished (or would have finished if doit were true). */
1965 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
1966 boolean doit, boolean evenPersistent, int userId) {
1967 boolean didSomething = false;
1968 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1969 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1970 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1971 final ActivityStack stack = display.getChildAt(stackNdx);
1972 if (stack.finishDisabledPackageActivitiesLocked(
1973 packageName, filterByClasses, doit, evenPersistent, userId)) {
1974 didSomething = true;
1975 }
1976 }
1977 }
1978 return didSomething;
1979 }
1980
1981 void updateActivityApplicationInfo(ApplicationInfo aInfo) {
1982 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1983 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1984 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1985 final ActivityStack stack = display.getChildAt(stackNdx);
1986 stack.updateActivityApplicationInfoLocked(aInfo);
1987 }
1988 }
1989 }
1990
1991 void finishVoiceTask(IVoiceInteractionSession session) {
1992 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1993 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
1994 final int numStacks = display.getChildCount();
1995 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1996 final ActivityStack stack = display.getChildAt(stackNdx);
1997 stack.finishVoiceTask(session);
1998 }
1999 }
2000 }
2001
2002 /**
2003 * Removes stacks in the input windowing modes from the system if they are of activity type
2004 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2005 */
2006 void removeStacksInWindowingModes(int... windowingModes) {
2007 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2008 mActivityDisplays.get(i).removeStacksInWindowingModes(windowingModes);
2009 }
2010 }
2011
2012 void removeStacksWithActivityTypes(int... activityTypes) {
2013 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2014 mActivityDisplays.get(i).removeStacksWithActivityTypes(activityTypes);
2015 }
2016 }
2017
2018 ActivityRecord topRunningActivity() {
2019 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2020 final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
2021 if (topActivity != null) {
2022 return topActivity;
2023 }
2024 }
2025 return null;
2026 }
2027
2028 boolean allResumedActivitiesIdle() {
2029 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2030 // TODO(b/117135575): Check resumed activities on all visible stacks.
2031 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2032 if (display.isSleeping()) {
2033 // No resumed activities while display is sleeping.
2034 continue;
2035 }
2036
2037 // If the focused stack is not null or not empty, there should have some activities
2038 // resuming or resumed. Make sure these activities are idle.
2039 final ActivityStack stack = display.getFocusedStack();
2040 if (stack == null || stack.numActivities() == 0) {
2041 continue;
2042 }
2043 final ActivityRecord resumedActivity = stack.getResumedActivity();
2044 if (resumedActivity == null || !resumedActivity.idle) {
2045 if (DEBUG_STATES) {
2046 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
2047 + stack.mStackId + " " + resumedActivity + " not idle");
2048 }
2049 return false;
2050 }
2051 }
2052 // Send launch end powerhint when idle
2053 sendPowerHintForLaunchEndIfNeeded();
2054 return true;
2055 }
2056
2057 boolean allResumedActivitiesVisible() {
2058 boolean foundResumed = false;
2059 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2060 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2061 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2062 final ActivityStack stack = display.getChildAt(stackNdx);
2063 final ActivityRecord r = stack.getResumedActivity();
2064 if (r != null) {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002065 if (!r.nowVisible) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002066 return false;
2067 }
2068 foundResumed = true;
2069 }
2070 }
2071 }
2072 return foundResumed;
2073 }
2074
2075 boolean allPausedActivitiesComplete() {
2076 boolean pausing = true;
2077 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2078 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2079 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2080 final ActivityStack stack = display.getChildAt(stackNdx);
2081 final ActivityRecord r = stack.mPausingActivity;
2082 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
2083 if (DEBUG_STATES) {
2084 Slog.d(TAG_STATES,
2085 "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
2086 pausing = false;
2087 } else {
2088 return false;
2089 }
2090 }
2091 }
2092 }
2093 return pausing;
2094 }
2095
2096 /**
2097 * Find all visible task stacks containing {@param userId} and intercept them with an activity
2098 * to block out the contents and possibly start a credential-confirming intent.
2099 *
2100 * @param userId user handle for the locked managed profile.
2101 */
2102 void lockAllProfileTasks(@UserIdInt int userId) {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002103 mService.deferWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002104 try {
2105 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2106 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2107 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2108 final ActivityStack stack = display.getChildAt(stackNdx);
Louis Changcdec0802019-11-11 11:45:07 +08002109 final List<Task> tasks = stack.getAllTasks();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002110 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
Louis Changcdec0802019-11-11 11:45:07 +08002111 final Task task = tasks.get(taskNdx);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002112
2113 // Check the task for a top activity belonging to userId, or returning a
2114 // result to an activity belonging to userId. Example case: a document
2115 // picker for personal files, opened by a work app, should still get locked.
2116 if (taskTopActivityIsUser(task, userId)) {
2117 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -07002118 task.mTaskId, userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002119 }
2120 }
2121 }
2122 }
2123 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +08002124 mService.continueWindowLayout();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002125 }
2126 }
2127
2128 /**
2129 * Detects whether we should show a lock screen in front of this task for a locked user.
2130 * <p>
2131 * We'll do this if either of the following holds:
2132 * <ul>
2133 * <li>The top activity explicitly belongs to {@param userId}.</li>
2134 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
2135 * </ul>
2136 *
2137 * @return {@code true} if the top activity looks like it belongs to {@param userId}.
2138 */
Louis Changcdec0802019-11-11 11:45:07 +08002139 private boolean taskTopActivityIsUser(Task task, @UserIdInt int userId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002140 // To handle the case that work app is in the task but just is not the top one.
Wale Ogunwale21e06482019-11-18 05:14:15 -08002141 final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002142 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
2143
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002144 return (activityRecord != null && activityRecord.mUserId == userId)
2145 || (resultTo != null && resultTo.mUserId == userId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002146 }
2147
2148 void cancelInitializingActivities() {
2149 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2150 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2151 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2152 final ActivityStack stack = display.getChildAt(stackNdx);
2153 stack.cancelInitializingActivities();
2154 }
2155 }
2156 }
2157
Louis Changcdec0802019-11-11 11:45:07 +08002158 Task anyTaskForId(int id) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002159 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
2160 }
2161
Louis Changcdec0802019-11-11 11:45:07 +08002162 Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002163 return anyTaskForId(id, matchMode, null, !ON_TOP);
2164 }
2165
2166 /**
Louis Changcdec0802019-11-11 11:45:07 +08002167 * Returns a {@link Task} for the input id if available. {@code null} otherwise.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002168 * @param id Id of the task we would like returned.
2169 * @param matchMode The mode to match the given task id in.
2170 * @param aOptions The activity options to use for restoration. Can be null.
2171 * @param onTop If the stack for the task should be the topmost on the display.
2172 */
Louis Changcdec0802019-11-11 11:45:07 +08002173 Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode,
Wale Ogunwaled32da472018-11-16 07:19:28 -08002174 @Nullable ActivityOptions aOptions, boolean onTop) {
2175 // If options are set, ensure that we are attempting to actually restore a task
2176 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
2177 throw new IllegalArgumentException("Should not specify activity options for non-restore"
2178 + " lookup");
2179 }
2180
2181 int numDisplays = mActivityDisplays.size();
2182 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2183 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2184 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2185 final ActivityStack stack = display.getChildAt(stackNdx);
Louis Changcdec0802019-11-11 11:45:07 +08002186 final Task task = stack.taskForIdLocked(id);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002187 if (task == null) {
2188 continue;
2189 }
2190 if (aOptions != null) {
2191 // Resolve the stack the task should be placed in now based on options
2192 // and reparent if needed.
2193 final ActivityStack launchStack =
2194 getLaunchStack(null, aOptions, task, onTop);
2195 if (launchStack != null && stack != launchStack) {
2196 final int reparentMode = onTop
2197 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
2198 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
2199 "anyTaskForId");
2200 }
2201 }
2202 return task;
2203 }
2204 }
2205
2206 // If we are matching stack tasks only, return now
2207 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
2208 return null;
2209 }
2210
2211 // Otherwise, check the recent tasks and return if we find it there and we are not restoring
2212 // the task from recents
2213 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
Louis Changcdec0802019-11-11 11:45:07 +08002214 final Task task = mStackSupervisor.mRecentTasks.getTask(id);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002215
2216 if (task == null) {
2217 if (DEBUG_RECENTS) {
2218 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
2219 }
2220
2221 return null;
2222 }
2223
2224 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
2225 return task;
2226 }
2227
2228 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
2229 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
2230 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
2231 "Couldn't restore task id=" + id + " found in recents");
2232 return null;
2233 }
2234 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
2235 return task;
2236 }
2237
2238 ActivityRecord isInAnyStack(IBinder token) {
2239 int numDisplays = mActivityDisplays.size();
2240 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2241 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2242 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2243 final ActivityStack stack = display.getChildAt(stackNdx);
2244 final ActivityRecord r = stack.isInStackLocked(token);
2245 if (r != null) {
2246 return r;
2247 }
2248 }
2249 }
2250 return null;
2251 }
2252
2253 @VisibleForTesting
2254 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
2255 @WindowConfiguration.ActivityType int ignoreActivityType,
2256 @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -07002257 boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -07002258 mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -07002259 ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser, profileIds);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002260 }
2261
2262 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
2263 boolean sendHint = forceSend;
2264
2265 if (!sendHint) {
2266 // Send power hint if we don't know what we're launching yet
2267 sendHint = targetActivity == null || targetActivity.app == null;
2268 }
2269
2270 if (!sendHint) { // targetActivity != null
2271 // Send power hint when the activity's process is different than the current resumed
2272 // activity on all displays, or if there are no resumed activities in the system.
2273 boolean noResumedActivities = true;
2274 boolean allFocusedProcessesDiffer = true;
2275 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2276 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2277 final ActivityRecord resumedActivity = activityDisplay.getResumedActivity();
2278 final WindowProcessController resumedActivityProcess =
2279 resumedActivity == null ? null : resumedActivity.app;
2280
2281 noResumedActivities &= resumedActivityProcess == null;
2282 if (resumedActivityProcess != null) {
2283 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
2284 }
2285 }
2286 sendHint = noResumedActivities || allFocusedProcessesDiffer;
2287 }
2288
2289 if (sendHint && mService.mPowerManagerInternal != null) {
2290 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
2291 mPowerHintSent = true;
2292 }
2293 }
2294
2295 void sendPowerHintForLaunchEndIfNeeded() {
2296 // Trigger launch power hint if activity is launched
2297 if (mPowerHintSent && mService.mPowerManagerInternal != null) {
2298 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
2299 mPowerHintSent = false;
2300 }
2301 }
2302
2303 private void calculateDefaultMinimalSizeOfResizeableTasks() {
2304 final Resources res = mService.mContext.getResources();
2305 final float minimalSize = res.getDimension(
2306 com.android.internal.R.dimen.default_minimal_size_resizable_task);
2307 final DisplayMetrics dm = res.getDisplayMetrics();
2308
2309 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
2310 }
2311
2312 /**
2313 * Dumps the activities matching the given {@param name} in the either the focused stack
2314 * or all visible stacks if {@param dumpVisibleStacks} is true.
2315 */
2316 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
2317 boolean dumpFocusedStackOnly) {
2318 if (dumpFocusedStackOnly) {
2319 return getTopDisplayFocusedStack().getDumpActivitiesLocked(name);
2320 } else {
2321 ArrayList<ActivityRecord> activities = new ArrayList<>();
2322 int numDisplays = mActivityDisplays.size();
2323 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2324 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2325 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2326 final ActivityStack stack = display.getChildAt(stackNdx);
2327 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
2328 activities.addAll(stack.getDumpActivitiesLocked(name));
2329 }
2330 }
2331 }
2332 return activities;
2333 }
2334 }
2335
2336 public void dump(PrintWriter pw, String prefix) {
2337 pw.print(prefix);
2338 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
2339 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2340 final ActivityDisplay display = mActivityDisplays.get(i);
2341 display.dump(pw, prefix);
2342 }
2343 }
2344
2345 /**
2346 * Dump all connected displays' configurations.
2347 * @param prefix Prefix to apply to each line of the dump.
2348 */
2349 void dumpDisplayConfigs(PrintWriter pw, String prefix) {
2350 pw.print(prefix); pw.println("Display override configurations:");
2351 final int displayCount = mActivityDisplays.size();
2352 for (int i = 0; i < displayCount; i++) {
2353 final ActivityDisplay activityDisplay = mActivityDisplays.get(i);
2354 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": ");
Evan Roskydfe3da72018-10-26 17:21:06 -07002355 pw.println(activityDisplay.getRequestedOverrideConfiguration());
Wale Ogunwaled32da472018-11-16 07:19:28 -08002356 }
2357 }
2358
2359 public void dumpDisplays(PrintWriter pw) {
2360 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
2361 final ActivityDisplay display = mActivityDisplays.get(i);
2362 pw.print("[id:" + display.mDisplayId + " stacks:");
2363 display.dumpStacks(pw);
2364 pw.print("]");
2365 }
2366 }
2367
2368 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
2369 String dumpPackage) {
2370 boolean printed = false;
2371 boolean needSep = false;
2372 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2373 ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
2374 pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
2375 pw.println(" (activities from top to bottom):");
2376 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
2377 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2378 final ActivityStack stack = display.getChildAt(stackNdx);
2379 pw.println();
Garfield Tan347bd602018-12-21 15:11:12 -08002380 printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002381 needSep = printed;
2382 }
2383 printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep,
2384 " ResumedActivity:");
2385 }
2386
2387 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ",
2388 "Fin", false, !dumpAll,
2389 false, dumpPackage, true, " Activities waiting to finish:", null);
2390 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
2391 "Stop", false, !dumpAll,
2392 false, dumpPackage, true, " Activities waiting to stop:", null);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002393 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
2394 " ", "Sleep", false, !dumpAll,
2395 false, dumpPackage, true, " Activities waiting to sleep:", null);
2396
2397 return printed;
2398 }
2399
Nataniel Borges023ecb52019-01-16 14:15:43 -08002400 protected void writeToProto(ProtoOutputStream proto, long fieldId,
2401 @WindowTraceLogLevel int logLevel) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002402 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002403 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002404 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2405 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
Nataniel Borges023ecb52019-01-16 14:15:43 -08002406 activityDisplay.writeToProto(proto, DISPLAYS, logLevel);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002407 }
2408 mStackSupervisor.getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER);
2409 // TODO(b/111541062): Update tests to look for resumed activities on all displays
2410 final ActivityStack focusedStack = getTopDisplayFocusedStack();
2411 if (focusedStack != null) {
2412 proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
2413 final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
2414 if (focusedActivity != null) {
2415 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
2416 }
2417 } else {
2418 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
2419 }
2420 proto.write(IS_HOME_RECENTS_COMPONENT,
2421 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
2422 mService.getActivityStartController().writeToProto(proto, PENDING_ACTIVITIES);
2423 proto.end(token);
2424 }
2425
2426 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
2427 private final String mTag;
2428 private final long mAcquireTime;
2429 private final int mDisplayId;
2430
2431 public SleepTokenImpl(String tag, int displayId) {
2432 mTag = tag;
2433 mDisplayId = displayId;
2434 mAcquireTime = SystemClock.uptimeMillis();
2435 }
2436
2437 @Override
2438 public void release() {
2439 synchronized (mService.mGlobalLock) {
2440 removeSleepToken(this);
2441 }
2442 }
2443
2444 @Override
2445 public String toString() {
2446 return "{\"" + mTag + "\", display " + mDisplayId
2447 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
2448 }
2449 }
2450}