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