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