Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright (C) 2013 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.am;
     18 
     19 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
     20 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
     21 import static android.Manifest.permission.START_ANY_ACTIVITY;
     22 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
     23 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
     24 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
     25 import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
     26 import static android.app.ActivityManager.START_TASK_TO_FRONT;
     27 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
     28 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
     29 import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
     30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
     31 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
     32 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
     33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
     34 import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
     35 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
     36 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
     37 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
     38 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
     39 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
     40 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
     41 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
     42 import static android.os.Process.SYSTEM_UID;
     43 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
     44 import static android.view.Display.DEFAULT_DISPLAY;
     45 import static android.view.Display.FLAG_PRIVATE;
     46 import static android.view.Display.INVALID_DISPLAY;
     47 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
     48 import static android.view.Display.TYPE_VIRTUAL;
     49 
     50 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
     51 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
     52 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
     53 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
     54 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
     55 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
     56 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
     57 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
     58 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
     59 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
     60 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
     61 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
     62 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
     63 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
     64 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
     65 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
     66 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
     67 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
     68 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
     69 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
     70 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
     71 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
     72 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
     73 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
     74 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
     75 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
     76 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
     77 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
     78 import static com.android.server.am.ActivityManagerService.ANIMATE;
     79 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
     80 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
     81 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
     82 import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
     83 import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
     84 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
     85 import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
     86 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
     87 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
     88 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
     89 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
     90 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
     91 import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
     92 import static com.android.server.am.ActivityStack.STACK_VISIBLE;
     93 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
     94 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
     95 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
     96 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
     97 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
     98 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
     99 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
    100 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
    101 import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
    102 import static java.lang.Integer.MAX_VALUE;
    103 
    104 import android.Manifest;
    105 import android.annotation.IntDef;
    106 import android.annotation.NonNull;
    107 import android.annotation.UserIdInt;
    108 import android.app.Activity;
    109 import android.app.ActivityManager;
    110 import android.app.ActivityManager.RunningTaskInfo;
    111 import android.app.ActivityManager.StackId;
    112 import android.app.ActivityManager.StackInfo;
    113 import android.app.ActivityOptions;
    114 import android.app.AppOpsManager;
    115 import android.app.IActivityContainerCallback;
    116 import android.app.ProfilerInfo;
    117 import android.app.ResultInfo;
    118 import android.app.StatusBarManager;
    119 import android.app.WaitResult;
    120 import android.app.admin.IDevicePolicyManager;
    121 import android.content.ComponentName;
    122 import android.content.Context;
    123 import android.content.IIntentSender;
    124 import android.content.Intent;
    125 import android.content.pm.ActivityInfo;
    126 import android.content.pm.ApplicationInfo;
    127 import android.content.pm.PackageInfo;
    128 import android.content.pm.PackageManager;
    129 import android.content.pm.ResolveInfo;
    130 import android.content.pm.UserInfo;
    131 import android.content.res.Configuration;
    132 import android.graphics.Rect;
    133 import android.hardware.display.DisplayManager;
    134 import android.hardware.display.DisplayManager.DisplayListener;
    135 import android.hardware.display.DisplayManagerGlobal;
    136 import android.hardware.display.DisplayManagerInternal;
    137 import android.hardware.display.VirtualDisplay;
    138 import android.hardware.input.InputManager;
    139 import android.hardware.input.InputManagerInternal;
    140 import android.os.Binder;
    141 import android.os.Bundle;
    142 import android.os.Debug;
    143 import android.os.Handler;
    144 import android.os.IBinder;
    145 import android.os.Looper;
    146 import android.os.Message;
    147 import android.os.ParcelFileDescriptor;
    148 import android.os.PowerManager;
    149 import android.os.Process;
    150 import android.os.RemoteException;
    151 import android.os.ServiceManager;
    152 import android.os.SystemClock;
    153 import android.os.Trace;
    154 import android.os.TransactionTooLargeException;
    155 import android.os.UserHandle;
    156 import android.os.UserManager;
    157 import android.os.WorkSource;
    158 import android.provider.MediaStore;
    159 import android.provider.Settings;
    160 import android.provider.Settings.SettingNotFoundException;
    161 import android.service.voice.IVoiceInteractionSession;
    162 import android.util.ArrayMap;
    163 import android.util.ArraySet;
    164 import android.util.EventLog;
    165 import android.util.IntArray;
    166 import android.util.MergedConfiguration;
    167 import android.util.Slog;
    168 import android.util.SparseArray;
    169 import android.util.SparseIntArray;
    170 import android.view.Display;
    171 import android.view.InputEvent;
    172 import android.view.Surface;
    173 
    174 import com.android.internal.content.ReferrerIntent;
    175 import com.android.internal.logging.MetricsLogger;
    176 import com.android.internal.os.TransferPipe;
    177 import com.android.internal.statusbar.IStatusBarService;
    178 import com.android.internal.util.ArrayUtils;
    179 import com.android.internal.widget.LockPatternUtils;
    180 import com.android.server.LocalServices;
    181 import com.android.server.am.ActivityStack.ActivityState;
    182 import com.android.server.wm.PinnedStackWindowController;
    183 import com.android.server.wm.WindowManagerService;
    184 
    185 import java.io.FileDescriptor;
    186 import java.io.IOException;
    187 import java.io.PrintWriter;
    188 import java.lang.annotation.Retention;
    189 import java.lang.annotation.RetentionPolicy;
    190 import java.util.ArrayList;
    191 import java.util.Arrays;
    192 import java.util.List;
    193 import java.util.Set;
    194 
    195 public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
    196     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
    197     private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
    198     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
    199     private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
    200     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
    201     private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
    202     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
    203     private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
    204     private static final String TAG_STACK = TAG + POSTFIX_STACK;
    205     private static final String TAG_STATES = TAG + POSTFIX_STATES;
    206     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
    207     static final String TAG_TASKS = TAG + POSTFIX_TASKS;
    208     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
    209 
    210     /** How long we wait until giving up on the last activity telling us it is idle. */
    211     static final int IDLE_TIMEOUT = 10 * 1000;
    212 
    213     /** How long we can hold the sleep wake lock before giving up. */
    214     static final int SLEEP_TIMEOUT = 5 * 1000;
    215 
    216     // How long we can hold the launch wake lock before giving up.
    217     static final int LAUNCH_TIMEOUT = 10 * 1000;
    218 
    219     static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
    220     static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
    221     static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
    222     static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
    223     static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
    224     static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
    225     static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
    226     static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
    227     static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
    228     static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
    229     static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
    230     static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
    231     static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
    232     static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
    233     static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
    234     static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
    235 
    236     private static final String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
    237 
    238     private static final String LOCK_TASK_TAG = "Lock-to-App";
    239 
    240     // Used to indicate if an object (e.g. stack) that we are trying to get
    241     // should be created if it doesn't exist already.
    242     static final boolean CREATE_IF_NEEDED = true;
    243 
    244     // Used to indicate that windows of activities should be preserved during the resize.
    245     static final boolean PRESERVE_WINDOWS = true;
    246 
    247     // Used to indicate if an object (e.g. task) should be moved/created
    248     // at the top of its container (e.g. stack).
    249     static final boolean ON_TOP = true;
    250 
    251     // Used to indicate that an objects (e.g. task) removal from its container
    252     // (e.g. stack) is due to it moving to another container.
    253     static final boolean MOVING = true;
    254 
    255     // Force the focus to change to the stack we are moving a task to..
    256     static final boolean FORCE_FOCUS = true;
    257 
    258     // Don't execute any calls to resume.
    259     static final boolean DEFER_RESUME = true;
    260 
    261     // Used to indicate that a task is removed it should also be removed from recents.
    262     static final boolean REMOVE_FROM_RECENTS = true;
    263 
    264     // Used to indicate that pausing an activity should occur immediately without waiting for
    265     // the activity callback indicating that it has completed pausing
    266     static final boolean PAUSE_IMMEDIATELY = true;
    267 
    268     /**
    269      * The modes which affect which tasks are returned when calling
    270      * {@link ActivityStackSupervisor#anyTaskForIdLocked(int)}.
    271      */
    272     @Retention(RetentionPolicy.SOURCE)
    273     @IntDef({
    274             MATCH_TASK_IN_STACKS_ONLY,
    275             MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
    276             MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
    277     })
    278     public @interface AnyTaskForIdMatchTaskMode {}
    279     // Match only tasks in the current stacks
    280     static final int MATCH_TASK_IN_STACKS_ONLY = 0;
    281     // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
    282     static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
    283     // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
    284     // provided stack id
    285     static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
    286 
    287     // Activity actions an app cannot start if it uses a permission which is not granted.
    288     private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
    289             new ArrayMap<>();
    290 
    291     static {
    292         ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE,
    293                 Manifest.permission.CAMERA);
    294         ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE,
    295                 Manifest.permission.CAMERA);
    296         ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL,
    297                 Manifest.permission.CALL_PHONE);
    298     }
    299 
    300     /** Action restriction: launching the activity is not restricted. */
    301     private static final int ACTIVITY_RESTRICTION_NONE = 0;
    302     /** Action restriction: launching the activity is restricted by a permission. */
    303     private static final int ACTIVITY_RESTRICTION_PERMISSION = 1;
    304     /** Action restriction: launching the activity is restricted by an app op. */
    305     private static final int ACTIVITY_RESTRICTION_APPOP = 2;
    306 
    307     /** Status Bar Service **/
    308     private IBinder mToken = new Binder();
    309     private IStatusBarService mStatusBarService;
    310     private IDevicePolicyManager mDevicePolicyManager;
    311 
    312     // For debugging to make sure the caller when acquiring/releasing our
    313     // wake lock is the system process.
    314     static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
    315     /** The number of distinct task ids that can be assigned to the tasks of a single user */
    316     private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;
    317 
    318     final ActivityManagerService mService;
    319 
    320     private RecentTasks mRecentTasks;
    321 
    322     final ActivityStackSupervisorHandler mHandler;
    323 
    324     /** Short cut */
    325     WindowManagerService mWindowManager;
    326     DisplayManager mDisplayManager;
    327 
    328     /** Counter for next free stack ID to use for dynamic activity stacks. */
    329     private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID;
    330 
    331     /**
    332      * Maps the task identifier that activities are currently being started in to the userId of the
    333      * task. Each time a new task is created, the entry for the userId of the task is incremented
    334      */
    335     private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20);
    336 
    337     /** The current user */
    338     int mCurrentUser;
    339 
    340     /** The stack containing the launcher app. Assumed to always be attached to
    341      * Display.DEFAULT_DISPLAY. */
    342     ActivityStack mHomeStack;
    343 
    344     /** The stack currently receiving input or launching the next activity. */
    345     ActivityStack mFocusedStack;
    346 
    347     /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
    348      * been resumed. If stacks are changing position this will hold the old stack until the new
    349      * stack becomes resumed after which it will be set to mFocusedStack. */
    350     private ActivityStack mLastFocusedStack;
    351 
    352     /** List of activities that are waiting for a new activity to become visible before completing
    353      * whatever operation they are supposed to do. */
    354     // TODO: Remove mActivitiesWaitingForVisibleActivity list and just remove activity from
    355     // mStoppingActivities when something else comes up.
    356     final ArrayList<ActivityRecord> mActivitiesWaitingForVisibleActivity = new ArrayList<>();
    357 
    358     /** List of processes waiting to find out when a specific activity becomes visible. */
    359     private final ArrayList<WaitInfo> mWaitingForActivityVisible = new ArrayList<>();
    360 
    361     /** List of processes waiting to find out about the next launched activity. */
    362     final ArrayList<WaitResult> mWaitingActivityLaunched = new ArrayList<>();
    363 
    364     /** List of activities that are ready to be stopped, but waiting for the next activity to
    365      * settle down before doing so. */
    366     final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
    367 
    368     /** List of activities that are ready to be finished, but waiting for the previous activity to
    369      * settle down before doing so.  It contains ActivityRecord objects. */
    370     final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
    371 
    372     /** List of activities that are in the process of going to sleep. */
    373     final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
    374 
    375     /** List of activities whose multi-window mode changed that we need to report to the
    376      * application */
    377     final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>();
    378 
    379     /** List of activities whose picture-in-picture mode changed that we need to report to the
    380      * application */
    381     final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
    382 
    383     /** The target stack bounds for the picture-in-picture mode changed that we need to report to
    384      * the application */
    385     Rect mPipModeChangedTargetStackBounds;
    386 
    387     /** Used on user changes */
    388     final ArrayList<UserState> mStartingUsers = new ArrayList<>();
    389 
    390     /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
    391      * is being brought in front of us. */
    392     boolean mUserLeaving = false;
    393 
    394     /** Set when we have taken too long waiting to go to sleep. */
    395     boolean mSleepTimeout = false;
    396 
    397     /**
    398      * We don't want to allow the device to go to sleep while in the process
    399      * of launching an activity.  This is primarily to allow alarm intent
    400      * receivers to launch an activity and get that to run before the device
    401      * goes back to sleep.
    402      */
    403     PowerManager.WakeLock mLaunchingActivity;
    404 
    405     /**
    406      * Set when the system is going to sleep, until we have
    407      * successfully paused the current activity and released our wake lock.
    408      * At that point the system is allowed to actually sleep.
    409      */
    410     PowerManager.WakeLock mGoingToSleep;
    411 
    412     /** Stack id of the front stack when user switched, indexed by userId. */
    413     SparseIntArray mUserStackInFront = new SparseIntArray(2);
    414 
    415     // TODO: Add listener for removal of references.
    416     /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
    417     SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>();
    418 
    419     // TODO: There should be an ActivityDisplayController coordinating am/wm interaction.
    420     /** Mapping from displayId to display current state */
    421     private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>();
    422 
    423     private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
    424 
    425     private DisplayManagerInternal mDisplayManagerInternal;
    426     private InputManagerInternal mInputManagerInternal;
    427 
    428     /** The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks
    429      * may be finished until there is only one entry left. If this is empty the system is not
    430      * in lockTask mode. */
    431     ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>();
    432     /** Store the current lock task mode. Possible values:
    433      * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
    434      * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
    435      */
    436     private int mLockTaskModeState;
    437     /**
    438      * Notifies the user when entering/exiting lock-task.
    439      */
    440     private LockTaskNotify mLockTaskNotify;
    441 
    442     /** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */
    443     boolean inResumeTopActivity;
    444 
    445     /**
    446      * Temporary rect used during docked stack resize calculation so we don't need to create a new
    447      * object each time.
    448      */
    449     private final Rect tempRect = new Rect();
    450 
    451     // The default minimal size that will be used if the activity doesn't specify its minimal size.
    452     // It will be calculated when the default display gets added.
    453     int mDefaultMinSizeOfResizeableTask = -1;
    454 
    455     // Whether tasks have moved and we need to rank the tasks before next OOM scoring
    456     private boolean mTaskLayersChanged = true;
    457 
    458     final ActivityMetricsLogger mActivityMetricsLogger;
    459 
    460     @Override
    461     protected int getChildCount() {
    462         return mActivityDisplays.size();
    463     }
    464 
    465     @Override
    466     protected ActivityDisplay getChildAt(int index) {
    467         return mActivityDisplays.valueAt(index);
    468     }
    469 
    470     @Override
    471     protected ConfigurationContainer getParent() {
    472         return null;
    473     }
    474 
    475     Configuration getDisplayOverrideConfiguration(int displayId) {
    476         final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
    477         if (activityDisplay == null) {
    478             throw new IllegalArgumentException("No display found with id: " + displayId);
    479         }
    480 
    481         return activityDisplay.getOverrideConfiguration();
    482     }
    483 
    484     void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
    485         final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
    486         if (activityDisplay == null) {
    487             throw new IllegalArgumentException("No display found with id: " + displayId);
    488         }
    489 
    490         activityDisplay.onOverrideConfigurationChanged(overrideConfiguration);
    491     }
    492 
    493     /** Check if placing task or activity on specified display is allowed. */
    494     boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable) {
    495         return displayId == DEFAULT_DISPLAY || (mService.mSupportsMultiDisplay
    496                 && (resizeable || displayConfigMatchesGlobal(displayId)));
    497     }
    498 
    499     /**
    500      * Check if configuration of specified display matches current global config.
    501      * Used to check if we can put a non-resizeable activity on a secondary display and it will get
    502      * the same config as on the default display.
    503      * @param displayId Id of the display to check.
    504      * @return {@code true} if configuration matches.
    505      */
    506     private boolean displayConfigMatchesGlobal(int displayId) {
    507         if (displayId == DEFAULT_DISPLAY) {
    508             return true;
    509         }
    510         if (displayId == INVALID_DISPLAY) {
    511             return false;
    512         }
    513         final ActivityDisplay targetDisplay = getActivityDisplayOrCreateLocked(displayId);
    514         if (targetDisplay == null) {
    515             throw new IllegalArgumentException("No display found with id: " + displayId);
    516         }
    517         return getConfiguration().equals(targetDisplay.getConfiguration());
    518     }
    519 
    520     static class FindTaskResult {
    521         ActivityRecord r;
    522         boolean matchedByRootAffinity;
    523     }
    524     private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
    525 
    526     /**
    527      * Temp storage for display ids sorted in focus order.
    528      * Maps position to id. Using {@link SparseIntArray} instead of {@link ArrayList} because
    529      * it's more efficient, as the number of displays is usually small.
    530      */
    531     private SparseIntArray mTmpOrderedDisplayIds = new SparseIntArray();
    532 
    533     /**
    534      * Used to keep track whether app visibilities got changed since the last pause. Useful to
    535      * determine whether to invoke the task stack change listener after pausing.
    536      */
    537     boolean mAppVisibilitiesChangedSinceLastPause;
    538 
    539     /**
    540      * Set of tasks that are in resizing mode during an app transition to fill the "void".
    541      */
    542     private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>();
    543 
    544 
    545     /**
    546      * If set to {@code false} all calls to resize the docked stack {@link #resizeDockedStackLocked}
    547      * will be ignored. Useful for the case where the caller is handling resizing of other stack and
    548      * moving tasks around and doesn't want dock stack to be resized due to an automatic trigger
    549      * like the docked stack going empty.
    550      */
    551     private boolean mAllowDockedStackResize = true;
    552 
    553     /**
    554      * Is dock currently minimized.
    555      */
    556     boolean mIsDockMinimized;
    557 
    558     final KeyguardController mKeyguardController;
    559 
    560     /**
    561      * Description of a request to start a new activity, which has been held
    562      * due to app switches being disabled.
    563      */
    564     static class PendingActivityLaunch {
    565         final ActivityRecord r;
    566         final ActivityRecord sourceRecord;
    567         final int startFlags;
    568         final ActivityStack stack;
    569         final ProcessRecord callerApp;
    570 
    571         PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
    572                 int _startFlags, ActivityStack _stack, ProcessRecord _callerApp) {
    573             r = _r;
    574             sourceRecord = _sourceRecord;
    575             startFlags = _startFlags;
    576             stack = _stack;
    577             callerApp = _callerApp;
    578         }
    579 
    580         void sendErrorResult(String message) {
    581             try {
    582                 if (callerApp.thread != null) {
    583                     callerApp.thread.scheduleCrash(message);
    584                 }
    585             } catch (RemoteException e) {
    586                 Slog.e(TAG, "Exception scheduling crash of failed "
    587                         + "activity launcher sourceRecord=" + sourceRecord, e);
    588             }
    589         }
    590     }
    591 
    592     public ActivityStackSupervisor(ActivityManagerService service, Looper looper) {
    593         mService = service;
    594         mHandler = new ActivityStackSupervisorHandler(looper);
    595         mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
    596         mKeyguardController = new KeyguardController(service, this);
    597     }
    598 
    599     void setRecentTasks(RecentTasks recentTasks) {
    600         mRecentTasks = recentTasks;
    601     }
    602 
    603     /**
    604      * At the time when the constructor runs, the power manager has not yet been
    605      * initialized.  So we initialize our wakelocks afterwards.
    606      */
    607     void initPowerManagement() {
    608         PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
    609         mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
    610         mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*launch*");
    611         mLaunchingActivity.setReferenceCounted(false);
    612     }
    613 
    614     // This function returns a IStatusBarService. The value is from ServiceManager.
    615     // getService and is cached.
    616     private IStatusBarService getStatusBarService() {
    617         synchronized (mService) {
    618             if (mStatusBarService == null) {
    619                 mStatusBarService = IStatusBarService.Stub.asInterface(
    620                     ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
    621                 if (mStatusBarService == null) {
    622                     Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
    623                 }
    624             }
    625             return mStatusBarService;
    626         }
    627     }
    628 
    629     private IDevicePolicyManager getDevicePolicyManager() {
    630         synchronized (mService) {
    631             if (mDevicePolicyManager == null) {
    632                 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
    633                     ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE));
    634                 if (mDevicePolicyManager == null) {
    635                     Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
    636                 }
    637             }
    638             return mDevicePolicyManager;
    639         }
    640     }
    641 
    642     void setWindowManager(WindowManagerService wm) {
    643         synchronized (mService) {
    644             mWindowManager = wm;
    645             mKeyguardController.setWindowManager(wm);
    646 
    647             mDisplayManager =
    648                     (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
    649             mDisplayManager.registerDisplayListener(this, null);
    650             mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
    651 
    652             Display[] displays = mDisplayManager.getDisplays();
    653             for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
    654                 final int displayId = displays[displayNdx].getDisplayId();
    655                 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
    656                 if (activityDisplay.mDisplay == null) {
    657                     throw new IllegalStateException("Default Display does not exist");
    658                 }
    659                 mActivityDisplays.put(displayId, activityDisplay);
    660                 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
    661             }
    662 
    663             mHomeStack = mFocusedStack = mLastFocusedStack =
    664                     getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
    665 
    666             mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
    667         }
    668     }
    669 
    670     ActivityStack getFocusedStack() {
    671         return mFocusedStack;
    672     }
    673 
    674     ActivityStack getLastStack() {
    675         return mLastFocusedStack;
    676     }
    677 
    678     boolean isFocusedStack(ActivityStack stack) {
    679         if (stack == null) {
    680             return false;
    681         }
    682 
    683         final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
    684         if (parent != null) {
    685             stack = parent.getStack();
    686         }
    687         return stack == mFocusedStack;
    688     }
    689 
    690     /** The top most stack on its display. */
    691     boolean isFrontStackOnDisplay(ActivityStack stack) {
    692         return isFrontOfStackList(stack, stack.mActivityContainer.mActivityDisplay.mStacks);
    693     }
    694 
    695     private boolean isFrontOfStackList(ActivityStack stack, List<ActivityStack> stackList) {
    696         if (stack == null) {
    697             return false;
    698         }
    699 
    700         final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
    701         if (parent != null) {
    702             stack = parent.getStack();
    703         }
    704         return stack == stackList.get((stackList.size() - 1));
    705     }
    706 
    707     /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */
    708     void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) {
    709         if (!focusCandidate.isFocusable()) {
    710             // The focus candidate isn't focusable. Move focus to the top stack that is focusable.
    711             focusCandidate = getNextFocusableStackLocked(focusCandidate);
    712         }
    713 
    714         if (focusCandidate != mFocusedStack) {
    715             mLastFocusedStack = mFocusedStack;
    716             mFocusedStack = focusCandidate;
    717 
    718             EventLogTags.writeAmFocusedStack(
    719                     mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(),
    720                     mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason);
    721         }
    722 
    723         final ActivityRecord r = topRunningActivityLocked();
    724         if (mService.mBooting || !mService.mBooted) {
    725             if (r != null && r.idle) {
    726                 checkFinishBootingLocked();
    727             }
    728         }
    729     }
    730 
    731     void moveHomeStackToFront(String reason) {
    732         mHomeStack.moveToFront(reason);
    733     }
    734 
    735     void moveRecentsStackToFront(String reason) {
    736         final ActivityStack recentsStack = getStack(RECENTS_STACK_ID);
    737         if (recentsStack != null) {
    738             recentsStack.moveToFront(reason);
    739         }
    740     }
    741 
    742     /** Returns true if the focus activity was adjusted to the home stack top activity. */
    743     boolean moveHomeStackTaskToTop(String reason) {
    744         mHomeStack.moveHomeStackTaskToTop();
    745 
    746         final ActivityRecord top = getHomeActivity();
    747         if (top == null) {
    748             return false;
    749         }
    750         moveFocusableActivityStackToFrontLocked(top, reason);
    751         return true;
    752     }
    753 
    754     boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
    755         if (!mService.mBooting && !mService.mBooted) {
    756             // Not ready yet!
    757             return false;
    758         }
    759 
    760         if (prev != null) {
    761             prev.getTask().setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
    762         }
    763 
    764         mHomeStack.moveHomeStackTaskToTop();
    765         ActivityRecord r = getHomeActivity();
    766         final String myReason = reason + " resumeHomeStackTask";
    767 
    768         // Only resume home activity if isn't finishing.
    769         if (r != null && !r.finishing) {
    770             moveFocusableActivityStackToFrontLocked(r, myReason);
    771             return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
    772         }
    773         return mService.startHomeActivityLocked(mCurrentUser, myReason);
    774     }
    775 
    776     TaskRecord anyTaskForIdLocked(int id) {
    777         return anyTaskForIdLocked(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
    778                 INVALID_STACK_ID);
    779     }
    780 
    781     /**
    782      * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise.
    783      * @param id Id of the task we would like returned.
    784      * @param matchMode The mode to match the given task id in.
    785      * @param stackId The stack to restore the task to (default launch stack will be used if
    786      *                stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}). Only
    787      *                valid if the matchMode is
    788      *                {@link #MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE}.
    789      */
    790     TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode, int stackId) {
    791         // If there is a stack id set, ensure that we are attempting to actually restore a task
    792         if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE &&
    793                 stackId != INVALID_STACK_ID) {
    794             throw new IllegalArgumentException("Should not specify stackId for non-restore lookup");
    795         }
    796 
    797         int numDisplays = mActivityDisplays.size();
    798         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
    799             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    800             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    801                 ActivityStack stack = stacks.get(stackNdx);
    802                 final TaskRecord task = stack.taskForIdLocked(id);
    803                 if (task != null) {
    804                     return task;
    805                 }
    806             }
    807         }
    808 
    809         // If we are matching stack tasks only, return now
    810         if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
    811             return null;
    812         }
    813 
    814         // Otherwise, check the recent tasks and return if we find it there and we are not restoring
    815         // the task from recents
    816         if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
    817         final TaskRecord task = mRecentTasks.taskForIdLocked(id);
    818 
    819         if (task == null) {
    820             if (DEBUG_RECENTS) {
    821                 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
    822             }
    823 
    824             return null;
    825         }
    826 
    827         if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
    828             return task;
    829         }
    830 
    831         // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
    832         if (!restoreRecentTaskLocked(task, stackId)) {
    833             if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
    834                     "Couldn't restore task id=" + id + " found in recents");
    835             return null;
    836         }
    837         if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
    838         return task;
    839     }
    840 
    841     ActivityRecord isInAnyStackLocked(IBinder token) {
    842         int numDisplays = mActivityDisplays.size();
    843         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
    844             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    845             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    846                 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
    847                 if (r != null) {
    848                     return r;
    849                 }
    850             }
    851         }
    852         return null;
    853     }
    854 
    855     /**
    856      * Detects whether we should show a lock screen in front of this task for a locked user.
    857      * <p>
    858      * We'll do this if either of the following holds:
    859      * <ul>
    860      *   <li>The top activity explicitly belongs to {@param userId}.</li>
    861      *   <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
    862      * </ul>
    863      *
    864      * @return {@code true} if the top activity looks like it belongs to {@param userId}.
    865      */
    866     private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) {
    867         // To handle the case that work app is in the task but just is not the top one.
    868         final ActivityRecord activityRecord = task.getTopActivity();
    869         final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
    870 
    871         return (activityRecord != null && activityRecord.userId == userId)
    872                 || (resultTo != null && resultTo.userId == userId);
    873     }
    874 
    875     /**
    876      * Find all visible task stacks containing {@param userId} and intercept them with an activity
    877      * to block out the contents and possibly start a credential-confirming intent.
    878      *
    879      * @param userId user handle for the locked managed profile.
    880      */
    881     void lockAllProfileTasks(@UserIdInt int userId) {
    882         mWindowManager.deferSurfaceLayout();
    883         try {
    884             final List<ActivityStack> stacks = getStacks();
    885             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; stackNdx--) {
    886                 final List<TaskRecord> tasks = stacks.get(stackNdx).getAllTasks();
    887                 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
    888                     final TaskRecord task = tasks.get(taskNdx);
    889 
    890                     // Check the task for a top activity belonging to userId, or returning a result
    891                     // to an activity belonging to userId. Example case: a document picker for
    892                     // personal files, opened by a work app, should still get locked.
    893                     if (taskTopActivityIsUser(task, userId)) {
    894                         mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
    895                                 task.taskId, userId);
    896                     }
    897                 }
    898             }
    899         } finally {
    900             mWindowManager.continueSurfaceLayout();
    901         }
    902     }
    903 
    904     void setNextTaskIdForUserLocked(int taskId, int userId) {
    905         final int currentTaskId = mCurTaskIdForUser.get(userId, -1);
    906         if (taskId > currentTaskId) {
    907             mCurTaskIdForUser.put(userId, taskId);
    908         }
    909     }
    910 
    911     static int nextTaskIdForUser(int taskId, int userId) {
    912         int nextTaskId = taskId + 1;
    913         if (nextTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) {
    914             // Wrap around as there will be smaller task ids that are available now.
    915             nextTaskId -= MAX_TASK_IDS_PER_USER;
    916         }
    917         return nextTaskId;
    918     }
    919 
    920     int getNextTaskIdForUserLocked(int userId) {
    921         final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER);
    922         // for a userId u, a taskId can only be in the range
    923         // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER
    924         // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
    925         int candidateTaskId = nextTaskIdForUser(currentTaskId, userId);
    926         while (mRecentTasks.taskIdTakenForUserLocked(candidateTaskId, userId)
    927                 || anyTaskForIdLocked(candidateTaskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
    928                         INVALID_STACK_ID) != null) {
    929             candidateTaskId = nextTaskIdForUser(candidateTaskId, userId);
    930             if (candidateTaskId == currentTaskId) {
    931                 // Something wrong!
    932                 // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user
    933                 throw new IllegalStateException("Cannot get an available task id."
    934                         + " Reached limit of " + MAX_TASK_IDS_PER_USER
    935                         + " running tasks per user.");
    936             }
    937         }
    938         mCurTaskIdForUser.put(userId, candidateTaskId);
    939         return candidateTaskId;
    940     }
    941 
    942     ActivityRecord getResumedActivityLocked() {
    943         ActivityStack stack = mFocusedStack;
    944         if (stack == null) {
    945             return null;
    946         }
    947         ActivityRecord resumedActivity = stack.mResumedActivity;
    948         if (resumedActivity == null || resumedActivity.app == null) {
    949             resumedActivity = stack.mPausingActivity;
    950             if (resumedActivity == null || resumedActivity.app == null) {
    951                 resumedActivity = stack.topRunningActivityLocked();
    952             }
    953         }
    954         return resumedActivity;
    955     }
    956 
    957     boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    958         final String processName = app.processName;
    959         boolean didSomething = false;
    960         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    961             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    962             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    963                 final ActivityStack stack = stacks.get(stackNdx);
    964                 if (!isFocusedStack(stack)) {
    965                     continue;
    966                 }
    967                 ActivityRecord hr = stack.topRunningActivityLocked();
    968                 if (hr != null) {
    969                     if (hr.app == null && app.uid == hr.info.applicationInfo.uid
    970                             && processName.equals(hr.processName)) {
    971                         try {
    972                             if (realStartActivityLocked(hr, app, true, true)) {
    973                                 didSomething = true;
    974                             }
    975                         } catch (RemoteException e) {
    976                             Slog.w(TAG, "Exception in new application when starting activity "
    977                                   + hr.intent.getComponent().flattenToShortString(), e);
    978                             throw e;
    979                         }
    980                     }
    981                 }
    982             }
    983         }
    984         if (!didSomething) {
    985             ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    986         }
    987         return didSomething;
    988     }
    989 
    990     boolean allResumedActivitiesIdle() {
    991         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    992             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    993             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    994                 final ActivityStack stack = stacks.get(stackNdx);
    995                 if (!isFocusedStack(stack) || stack.numActivities() == 0) {
    996                     continue;
    997                 }
    998                 final ActivityRecord resumedActivity = stack.mResumedActivity;
    999                 if (resumedActivity == null || !resumedActivity.idle) {
   1000                     if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
   1001                              + stack.mStackId + " " + resumedActivity + " not idle");
   1002                     return false;
   1003                 }
   1004             }
   1005         }
   1006         // Send launch end powerhint when idle
   1007         mService.mActivityStarter.sendPowerHintForLaunchEndIfNeeded();
   1008         return true;
   1009     }
   1010 
   1011     boolean allResumedActivitiesComplete() {
   1012         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1013             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1014             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1015                 final ActivityStack stack = stacks.get(stackNdx);
   1016                 if (isFocusedStack(stack)) {
   1017                     final ActivityRecord r = stack.mResumedActivity;
   1018                     if (r != null && r.state != RESUMED) {
   1019                         return false;
   1020                     }
   1021                 }
   1022             }
   1023         }
   1024         // TODO: Not sure if this should check if all Paused are complete too.
   1025         if (DEBUG_STACK) Slog.d(TAG_STACK,
   1026                 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
   1027                 mLastFocusedStack + " to=" + mFocusedStack);
   1028         mLastFocusedStack = mFocusedStack;
   1029         return true;
   1030     }
   1031 
   1032     boolean allResumedActivitiesVisible() {
   1033         boolean foundResumed = false;
   1034         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1035             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1036             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1037                 final ActivityStack stack = stacks.get(stackNdx);
   1038                 final ActivityRecord r = stack.mResumedActivity;
   1039                 if (r != null) {
   1040                     if (!r.nowVisible || mActivitiesWaitingForVisibleActivity.contains(r)) {
   1041                         return false;
   1042                     }
   1043                     foundResumed = true;
   1044                 }
   1045             }
   1046         }
   1047         return foundResumed;
   1048     }
   1049 
   1050     /**
   1051      * Pause all activities in either all of the stacks or just the back stacks.
   1052      * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
   1053      * @param resuming The resuming activity.
   1054      * @param dontWait The resuming activity isn't going to wait for all activities to be paused
   1055      *                 before resuming.
   1056      * @return true if any activity was paused as a result of this call.
   1057      */
   1058     boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
   1059         boolean someActivityPaused = false;
   1060         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1061             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1062             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1063                 final ActivityStack stack = stacks.get(stackNdx);
   1064                 if (!isFocusedStack(stack) && stack.mResumedActivity != null) {
   1065                     if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
   1066                             " mResumedActivity=" + stack.mResumedActivity);
   1067                     someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
   1068                             dontWait);
   1069                 }
   1070             }
   1071         }
   1072         return someActivityPaused;
   1073     }
   1074 
   1075     boolean allPausedActivitiesComplete() {
   1076         boolean pausing = true;
   1077         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1078             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1079             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1080                 final ActivityStack stack = stacks.get(stackNdx);
   1081                 final ActivityRecord r = stack.mPausingActivity;
   1082                 if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) {
   1083                     if (DEBUG_STATES) {
   1084                         Slog.d(TAG_STATES,
   1085                                 "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
   1086                         pausing = false;
   1087                     } else {
   1088                         return false;
   1089                     }
   1090                 }
   1091             }
   1092         }
   1093         return pausing;
   1094     }
   1095 
   1096     void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
   1097             ActivityRecord resuming, boolean dontWait) {
   1098         // TODO: Put all stacks in supervisor and iterate through them instead.
   1099         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1100             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1101             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1102                 final ActivityStack stack = stacks.get(stackNdx);
   1103                 if (stack.mResumedActivity != null &&
   1104                         stack.mActivityContainer.mParentActivity == parent) {
   1105                     stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
   1106                 }
   1107             }
   1108         }
   1109     }
   1110 
   1111     void cancelInitializingActivities() {
   1112         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1113             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1114             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1115                 stacks.get(stackNdx).cancelInitializingActivities();
   1116             }
   1117         }
   1118     }
   1119 
   1120     void waitActivityVisible(ComponentName name, WaitResult result) {
   1121         final WaitInfo waitInfo = new WaitInfo(name, result);
   1122         mWaitingForActivityVisible.add(waitInfo);
   1123     }
   1124 
   1125     void cleanupActivity(ActivityRecord r) {
   1126         // Make sure this record is no longer in the pending finishes list.
   1127         // This could happen, for example, if we are trimming activities
   1128         // down to the max limit while they are still waiting to finish.
   1129         mFinishingActivities.remove(r);
   1130         mActivitiesWaitingForVisibleActivity.remove(r);
   1131 
   1132         for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
   1133             if (mWaitingForActivityVisible.get(i).matches(r.realActivity)) {
   1134                 mWaitingForActivityVisible.remove(i);
   1135             }
   1136         }
   1137     }
   1138 
   1139     void reportActivityVisibleLocked(ActivityRecord r) {
   1140         sendWaitingVisibleReportLocked(r);
   1141     }
   1142 
   1143     void sendWaitingVisibleReportLocked(ActivityRecord r) {
   1144         boolean changed = false;
   1145         for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
   1146             final WaitInfo w = mWaitingForActivityVisible.get(i);
   1147             if (w.matches(r.realActivity)) {
   1148                 final WaitResult result = w.getResult();
   1149                 changed = true;
   1150                 result.timeout = false;
   1151                 result.who = w.getComponent();
   1152                 result.totalTime = SystemClock.uptimeMillis() - result.thisTime;
   1153                 result.thisTime = result.totalTime;
   1154                 mWaitingForActivityVisible.remove(w);
   1155             }
   1156         }
   1157         if (changed) {
   1158             mService.notifyAll();
   1159         }
   1160     }
   1161 
   1162     void reportTaskToFrontNoLaunch(ActivityRecord r) {
   1163         boolean changed = false;
   1164         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
   1165             WaitResult w = mWaitingActivityLaunched.remove(i);
   1166             if (w.who == null) {
   1167                 changed = true;
   1168                 // Set result to START_TASK_TO_FRONT so that startActivityMayWait() knows that
   1169                 // the starting activity ends up moving another activity to front, and it should
   1170                 // wait for this new activity to become visible instead.
   1171                 // Do not modify other fields.
   1172                 w.result = START_TASK_TO_FRONT;
   1173             }
   1174         }
   1175         if (changed) {
   1176             mService.notifyAll();
   1177         }
   1178     }
   1179 
   1180     void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
   1181             long thisTime, long totalTime) {
   1182         boolean changed = false;
   1183         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
   1184             WaitResult w = mWaitingActivityLaunched.remove(i);
   1185             if (w.who == null) {
   1186                 changed = true;
   1187                 w.timeout = timeout;
   1188                 if (r != null) {
   1189                     w.who = new ComponentName(r.info.packageName, r.info.name);
   1190                 }
   1191                 w.thisTime = thisTime;
   1192                 w.totalTime = totalTime;
   1193                 // Do not modify w.result.
   1194             }
   1195         }
   1196         if (changed) {
   1197             mService.notifyAll();
   1198         }
   1199     }
   1200 
   1201     ActivityRecord topRunningActivityLocked() {
   1202         final ActivityStack focusedStack = mFocusedStack;
   1203         ActivityRecord r = focusedStack.topRunningActivityLocked();
   1204         if (r != null) {
   1205             return r;
   1206         }
   1207 
   1208         // Look in other non-focused and non-home stacks.
   1209         mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
   1210 
   1211         for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
   1212             final int displayId = mTmpOrderedDisplayIds.get(i);
   1213             final List<ActivityStack> stacks = mActivityDisplays.get(displayId).mStacks;
   1214             if (stacks == null) {
   1215                 continue;
   1216             }
   1217             for (int j = stacks.size() - 1; j >= 0; --j) {
   1218                 final ActivityStack stack = stacks.get(j);
   1219                 if (stack != focusedStack && isFrontStackOnDisplay(stack) && stack.isFocusable()) {
   1220                     r = stack.topRunningActivityLocked();
   1221                     if (r != null) {
   1222                         return r;
   1223                     }
   1224                 }
   1225             }
   1226         }
   1227         return null;
   1228     }
   1229 
   1230     void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) {
   1231         // Gather all of the running tasks for each stack into runningTaskLists.
   1232         ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
   1233                 new ArrayList<ArrayList<RunningTaskInfo>>();
   1234         final int numDisplays = mActivityDisplays.size();
   1235         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
   1236             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1237             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1238                 final ActivityStack stack = stacks.get(stackNdx);
   1239                 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>();
   1240                 runningTaskLists.add(stackTaskList);
   1241                 stack.getTasksLocked(stackTaskList, callingUid, allowed);
   1242             }
   1243         }
   1244 
   1245         // The lists are already sorted from most recent to oldest. Just pull the most recent off
   1246         // each list and add it to list. Stop when all lists are empty or maxNum reached.
   1247         while (maxNum > 0) {
   1248             long mostRecentActiveTime = Long.MIN_VALUE;
   1249             ArrayList<RunningTaskInfo> selectedStackList = null;
   1250             final int numTaskLists = runningTaskLists.size();
   1251             for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
   1252                 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
   1253                 if (!stackTaskList.isEmpty()) {
   1254                     final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
   1255                     if (lastActiveTime > mostRecentActiveTime) {
   1256                         mostRecentActiveTime = lastActiveTime;
   1257                         selectedStackList = stackTaskList;
   1258                     }
   1259                 }
   1260             }
   1261             if (selectedStackList != null) {
   1262                 list.add(selectedStackList.remove(0));
   1263                 --maxNum;
   1264             } else {
   1265                 break;
   1266             }
   1267         }
   1268     }
   1269 
   1270     ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
   1271             ProfilerInfo profilerInfo) {
   1272         final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;
   1273         if (aInfo != null) {
   1274             // Store the found target back into the intent, because now that
   1275             // we have it we never want to do this again.  For example, if the
   1276             // user navigates back to this point in the history, we should
   1277             // always restart the exact same activity.
   1278             intent.setComponent(new ComponentName(
   1279                     aInfo.applicationInfo.packageName, aInfo.name));
   1280 
   1281             // Don't debug things in the system process
   1282             if (!aInfo.processName.equals("system")) {
   1283                 if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
   1284                     mService.setDebugApp(aInfo.processName, true, false);
   1285                 }
   1286 
   1287                 if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
   1288                     mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
   1289                 }
   1290 
   1291                 if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
   1292                     mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
   1293                 }
   1294 
   1295                 if (profilerInfo != null) {
   1296                     mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
   1297                 }
   1298             }
   1299             final String intentLaunchToken = intent.getLaunchToken();
   1300             if (aInfo.launchToken == null && intentLaunchToken != null) {
   1301                 aInfo.launchToken = intentLaunchToken;
   1302             }
   1303         }
   1304         return aInfo;
   1305     }
   1306 
   1307     ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
   1308         return resolveIntent(intent, resolvedType, userId, 0);
   1309     }
   1310 
   1311     ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
   1312         synchronized (mService) {
   1313             return mService.getPackageManagerInternalLocked().resolveIntent(intent, resolvedType,
   1314                     PackageManager.MATCH_INSTANT | PackageManager.MATCH_DEFAULT_ONLY | flags
   1315                     | ActivityManagerService.STOCK_PM_FLAGS, userId);
   1316         }
   1317     }
   1318 
   1319     ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
   1320             ProfilerInfo profilerInfo, int userId) {
   1321         final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId);
   1322         return resolveActivity(intent, rInfo, startFlags, profilerInfo);
   1323     }
   1324 
   1325     final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
   1326             boolean andResume, boolean checkConfig) throws RemoteException {
   1327 
   1328         if (!allPausedActivitiesComplete()) {
   1329             // While there are activities pausing we skipping starting any new activities until
   1330             // pauses are complete. NOTE: that we also do this for activities that are starting in
   1331             // the paused state because they will first be resumed then paused on the client side.
   1332             if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
   1333                     "realStartActivityLocked: Skipping start of r=" + r
   1334                     + " some activities pausing...");
   1335             return false;
   1336         }
   1337 
   1338         r.startFreezingScreenLocked(app, 0);
   1339         if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */, true /* isTop */)) {
   1340             // We only set the visibility to true if the activity is allowed to be visible based on
   1341             // keyguard state. This avoids setting this into motion in window manager that is later
   1342             // cancelled due to later calls to ensure visible activities that set visibility back to
   1343             // false.
   1344             r.setVisibility(true);
   1345         }
   1346 
   1347         // schedule launch ticks to collect information about slow apps.
   1348         r.startLaunchTickingLocked();
   1349 
   1350         // Have the window manager re-evaluate the orientation of the screen based on the new
   1351         // activity order.  Note that as a result of this, it can call back into the activity
   1352         // manager with a new orientation.  We don't care about that, because the activity is not
   1353         // currently running so we are just restarting it anyway.
   1354         if (checkConfig) {
   1355             final int displayId = r.getDisplayId();
   1356             final Configuration config = mWindowManager.updateOrientationFromAppTokens(
   1357                     getDisplayOverrideConfiguration(displayId),
   1358                     r.mayFreezeScreenLocked(app) ? r.appToken : null, displayId);
   1359             // Deferring resume here because we're going to launch new activity shortly.
   1360             // We don't want to perform a redundant launch of the same record while ensuring
   1361             // configurations and trying to resume top activity of focused stack.
   1362             mService.updateDisplayOverrideConfigurationLocked(config, r, true /* deferResume */,
   1363                     displayId);
   1364         }
   1365 
   1366         if (mKeyguardController.isKeyguardLocked()) {
   1367             r.notifyUnknownVisibilityLaunched();
   1368         }
   1369         final int applicationInfoUid =
   1370                 (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
   1371         if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) {
   1372             Slog.wtf(TAG,
   1373                     "User ID for activity changing for " + r
   1374                             + " appInfo.uid=" + r.appInfo.uid
   1375                             + " info.ai.uid=" + applicationInfoUid
   1376                             + " old=" + r.app + " new=" + app);
   1377         }
   1378 
   1379         r.app = app;
   1380         app.waitingToKill = null;
   1381         r.launchCount++;
   1382         r.lastLaunchTime = SystemClock.uptimeMillis();
   1383 
   1384         if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
   1385 
   1386         int idx = app.activities.indexOf(r);
   1387         if (idx < 0) {
   1388             app.activities.add(r);
   1389         }
   1390         mService.updateLruProcessLocked(app, true, null);
   1391         mService.updateOomAdjLocked();
   1392 
   1393         final TaskRecord task = r.getTask();
   1394         if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
   1395                 task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
   1396             setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
   1397         }
   1398 
   1399         final ActivityStack stack = task.getStack();
   1400         try {
   1401             if (app.thread == null) {
   1402                 throw new RemoteException();
   1403             }
   1404             List<ResultInfo> results = null;
   1405             List<ReferrerIntent> newIntents = null;
   1406             if (andResume) {
   1407                 // We don't need to deliver new intents and/or set results if activity is going
   1408                 // to pause immediately after launch.
   1409                 results = r.results;
   1410                 newIntents = r.newIntents;
   1411             }
   1412             if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
   1413                     "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
   1414                     + " newIntents=" + newIntents + " andResume=" + andResume);
   1415             EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId,
   1416                     System.identityHashCode(r), task.taskId, r.shortComponentName);
   1417             if (r.isHomeActivity()) {
   1418                 // Home process is the root process of the task.
   1419                 mService.mHomeProcess = task.mActivities.get(0).app;
   1420             }
   1421             mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
   1422                                       PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
   1423             r.sleeping = false;
   1424             r.forceNewConfig = false;
   1425             mService.showUnsupportedZoomDialogIfNeededLocked(r);
   1426             mService.showAskCompatModeDialogLocked(r);
   1427             r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
   1428             ProfilerInfo profilerInfo = null;
   1429             if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
   1430                 if (mService.mProfileProc == null || mService.mProfileProc == app) {
   1431                     mService.mProfileProc = app;
   1432                     final String profileFile = mService.mProfileFile;
   1433                     if (profileFile != null) {
   1434                         ParcelFileDescriptor profileFd = mService.mProfileFd;
   1435                         if (profileFd != null) {
   1436                             try {
   1437                                 profileFd = profileFd.dup();
   1438                             } catch (IOException e) {
   1439                                 if (profileFd != null) {
   1440                                     try {
   1441                                         profileFd.close();
   1442                                     } catch (IOException o) {
   1443                                     }
   1444                                     profileFd = null;
   1445                                 }
   1446                             }
   1447                         }
   1448 
   1449                         profilerInfo = new ProfilerInfo(profileFile, profileFd,
   1450                                 mService.mSamplingInterval, mService.mAutoStopProfiler,
   1451                                 mService.mStreamingOutput);
   1452                     }
   1453                 }
   1454             }
   1455 
   1456             app.hasShownUi = true;
   1457             app.pendingUiClean = true;
   1458             app.forceProcessStateUpTo(mService.mTopProcessState);
   1459             // Because we could be starting an Activity in the system process this may not go across
   1460             // a Binder interface which would create a new Configuration. Consequently we have to
   1461             // always create a new Configuration here.
   1462 
   1463             final MergedConfiguration mergedConfiguration = new MergedConfiguration(
   1464                     mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
   1465             r.setLastReportedConfiguration(mergedConfiguration);
   1466 
   1467             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
   1468                     System.identityHashCode(r), r.info,
   1469                     // TODO: Have this take the merged configuration instead of separate global and
   1470                     // override configs.
   1471                     mergedConfiguration.getGlobalConfiguration(),
   1472                     mergedConfiguration.getOverrideConfiguration(), r.compat,
   1473                     r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
   1474                     r.persistentState, results, newIntents, !andResume,
   1475                     mService.isNextTransitionForward(), profilerInfo);
   1476 
   1477             if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
   1478                 // This may be a heavy-weight process!  Note that the package
   1479                 // manager will ensure that only activity can run in the main
   1480                 // process of the .apk, which is the only thing that will be
   1481                 // considered heavy-weight.
   1482                 if (app.processName.equals(app.info.packageName)) {
   1483                     if (mService.mHeavyWeightProcess != null
   1484                             && mService.mHeavyWeightProcess != app) {
   1485                         Slog.w(TAG, "Starting new heavy weight process " + app
   1486                                 + " when already running "
   1487                                 + mService.mHeavyWeightProcess);
   1488                     }
   1489                     mService.mHeavyWeightProcess = app;
   1490                     Message msg = mService.mHandler.obtainMessage(
   1491                             ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
   1492                     msg.obj = r;
   1493                     mService.mHandler.sendMessage(msg);
   1494                 }
   1495             }
   1496 
   1497         } catch (RemoteException e) {
   1498             if (r.launchFailed) {
   1499                 // This is the second time we failed -- finish activity
   1500                 // and give up.
   1501                 Slog.e(TAG, "Second failure launching "
   1502                       + r.intent.getComponent().flattenToShortString()
   1503                       + ", giving up", e);
   1504                 mService.appDiedLocked(app);
   1505                 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
   1506                         "2nd-crash", false);
   1507                 return false;
   1508             }
   1509 
   1510             // This is the first time we failed -- restart process and
   1511             // retry.
   1512             r.launchFailed = true;
   1513             app.activities.remove(r);
   1514             throw e;
   1515         }
   1516 
   1517         r.launchFailed = false;
   1518         if (stack.updateLRUListLocked(r)) {
   1519             Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
   1520         }
   1521 
   1522         if (andResume) {
   1523             // As part of the process of launching, ActivityThread also performs
   1524             // a resume.
   1525             stack.minimalResumeActivityLocked(r);
   1526         } else {
   1527             // This activity is not starting in the resumed state... which should look like we asked
   1528             // it to pause+stop (but remain visible), and it has done so and reported back the
   1529             // current icicle and other state.
   1530             if (DEBUG_STATES) Slog.v(TAG_STATES,
   1531                     "Moving to PAUSED: " + r + " (starting in paused state)");
   1532             r.state = PAUSED;
   1533         }
   1534 
   1535         // Launch the new version setup screen if needed.  We do this -after-
   1536         // launching the initial activity (that is, home), so that it can have
   1537         // a chance to initialize itself while in the background, making the
   1538         // switch back to it faster and look better.
   1539         if (isFocusedStack(stack)) {
   1540             mService.startSetupActivityLocked();
   1541         }
   1542 
   1543         // Update any services we are bound to that might care about whether
   1544         // their client may have activities.
   1545         if (r.app != null) {
   1546             mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
   1547         }
   1548 
   1549         return true;
   1550     }
   1551 
   1552     void startSpecificActivityLocked(ActivityRecord r,
   1553             boolean andResume, boolean checkConfig) {
   1554         // Is this activity's application already running?
   1555         ProcessRecord app = mService.getProcessRecordLocked(r.processName,
   1556                 r.info.applicationInfo.uid, true);
   1557 
   1558         r.getStack().setLaunchTime(r);
   1559 
   1560         if (app != null && app.thread != null) {
   1561             try {
   1562                 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
   1563                         || !"android".equals(r.info.packageName)) {
   1564                     // Don't add this if it is a platform component that is marked
   1565                     // to run in multiple processes, because this is actually
   1566                     // part of the framework so doesn't make sense to track as a
   1567                     // separate apk in the process.
   1568                     app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
   1569                             mService.mProcessStats);
   1570                 }
   1571                 realStartActivityLocked(r, app, andResume, checkConfig);
   1572                 return;
   1573             } catch (RemoteException e) {
   1574                 Slog.w(TAG, "Exception when starting activity "
   1575                         + r.intent.getComponent().flattenToShortString(), e);
   1576             }
   1577 
   1578             // If a dead object exception was thrown -- fall through to
   1579             // restart the application.
   1580         }
   1581 
   1582         mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
   1583                 "activity", r.intent.getComponent(), false, false, true);
   1584     }
   1585 
   1586     boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo,
   1587             String resultWho, int requestCode, int callingPid, int callingUid,
   1588             String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp,
   1589             ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options) {
   1590         final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
   1591                 callingUid);
   1592         if (startAnyPerm == PERMISSION_GRANTED) {
   1593             return true;
   1594         }
   1595         final int componentRestriction = getComponentRestrictionForCallingPackage(
   1596                 aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity);
   1597         final int actionRestriction = getActionRestrictionForCallingPackage(
   1598                 intent.getAction(), callingPackage, callingPid, callingUid);
   1599         if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
   1600                 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
   1601             if (resultRecord != null) {
   1602                 resultStack.sendActivityResultLocked(-1,
   1603                         resultRecord, resultWho, requestCode,
   1604                         Activity.RESULT_CANCELED, null);
   1605             }
   1606             final String msg;
   1607             if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
   1608                 msg = "Permission Denial: starting " + intent.toString()
   1609                         + " from " + callerApp + " (pid=" + callingPid
   1610                         + ", uid=" + callingUid + ")" + " with revoked permission "
   1611                         + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
   1612             } else if (!aInfo.exported) {
   1613                 msg = "Permission Denial: starting " + intent.toString()
   1614                         + " from " + callerApp + " (pid=" + callingPid
   1615                         + ", uid=" + callingUid + ")"
   1616                         + " not exported from uid " + aInfo.applicationInfo.uid;
   1617             } else {
   1618                 msg = "Permission Denial: starting " + intent.toString()
   1619                         + " from " + callerApp + " (pid=" + callingPid
   1620                         + ", uid=" + callingUid + ")"
   1621                         + " requires " + aInfo.permission;
   1622             }
   1623             Slog.w(TAG, msg);
   1624             throw new SecurityException(msg);
   1625         }
   1626 
   1627         if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
   1628             final String message = "Appop Denial: starting " + intent.toString()
   1629                     + " from " + callerApp + " (pid=" + callingPid
   1630                     + ", uid=" + callingUid + ")"
   1631                     + " requires " + AppOpsManager.permissionToOp(
   1632                             ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
   1633             Slog.w(TAG, message);
   1634             return false;
   1635         } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
   1636             final String message = "Appop Denial: starting " + intent.toString()
   1637                     + " from " + callerApp + " (pid=" + callingPid
   1638                     + ", uid=" + callingUid + ")"
   1639                     + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
   1640             Slog.w(TAG, message);
   1641             return false;
   1642         }
   1643         if (options != null) {
   1644             if (options.getLaunchTaskId() != INVALID_STACK_ID) {
   1645                 final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS,
   1646                         callingPid, callingUid);
   1647                 if (startInTaskPerm != PERMISSION_GRANTED) {
   1648                     final String msg = "Permission Denial: starting " + intent.toString()
   1649                             + " from " + callerApp + " (pid=" + callingPid
   1650                             + ", uid=" + callingUid + ") with launchTaskId="
   1651                             + options.getLaunchTaskId();
   1652                     Slog.w(TAG, msg);
   1653                     throw new SecurityException(msg);
   1654                 }
   1655             }
   1656             // Check if someone tries to launch an activity on a private display with a different
   1657             // owner.
   1658             final int launchDisplayId = options.getLaunchDisplayId();
   1659             if (launchDisplayId != INVALID_DISPLAY
   1660                     && !isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, launchDisplayId)) {
   1661                 final String msg = "Permission Denial: starting " + intent.toString()
   1662                         + " from " + callerApp + " (pid=" + callingPid
   1663                         + ", uid=" + callingUid + ") with launchDisplayId="
   1664                         + launchDisplayId;
   1665                 Slog.w(TAG, msg);
   1666                 throw new SecurityException(msg);
   1667             }
   1668         }
   1669 
   1670         return true;
   1671     }
   1672 
   1673     /** Check if caller is allowed to launch activities on specified display. */
   1674     boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId) {
   1675         if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId
   1676                 + " callingPid=" + callingPid + " callingUid=" + callingUid);
   1677 
   1678         final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(launchDisplayId);
   1679         if (activityDisplay == null) {
   1680             Slog.w(TAG, "Launch on display check: display not found");
   1681             return false;
   1682         }
   1683 
   1684         // Check if the caller can manage activity stacks.
   1685         final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
   1686                 callingUid);
   1687         if (startAnyPerm == PERMISSION_GRANTED) {
   1688             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
   1689                     + " allow launch any on display");
   1690             return true;
   1691         }
   1692 
   1693         if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL
   1694                 && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID) {
   1695             // Limit launching on virtual displays, because their contents can be read from Surface
   1696             // by apps that created them.
   1697             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
   1698                     + " disallow launch on virtual display for not-embedded activity");
   1699             return false;
   1700         }
   1701 
   1702         if (!activityDisplay.isPrivate()) {
   1703             // Anyone can launch on a public display.
   1704             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
   1705                     + " allow launch on public display");
   1706             return true;
   1707         }
   1708 
   1709         // Check if the caller is the owner of the display.
   1710         if (activityDisplay.mDisplay.getOwnerUid() == callingUid) {
   1711             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
   1712                     + " allow launch for owner of the display");
   1713             return true;
   1714         }
   1715 
   1716         // Check if caller is present on display
   1717         if (activityDisplay.isUidPresent(callingUid)) {
   1718             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
   1719                     + " allow launch for caller present on the display");
   1720             return true;
   1721         }
   1722 
   1723         Slog.w(TAG, "Launch on display check: denied");
   1724         return false;
   1725     }
   1726 
   1727     /** Update lists of UIDs that are present on displays and have access to them. */
   1728     void updateUIDsPresentOnDisplay() {
   1729         mDisplayAccessUIDs.clear();
   1730         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1731             final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
   1732             // Only bother calculating the whitelist for private displays
   1733             if (activityDisplay.isPrivate()) {
   1734                 mDisplayAccessUIDs.append(
   1735                         activityDisplay.mDisplayId, activityDisplay.getPresentUIDs());
   1736             }
   1737         }
   1738         // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
   1739         mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
   1740     }
   1741 
   1742     UserInfo getUserInfo(int userId) {
   1743         final long identity = Binder.clearCallingIdentity();
   1744         try {
   1745             return UserManager.get(mService.mContext).getUserInfo(userId);
   1746         } finally {
   1747             Binder.restoreCallingIdentity(identity);
   1748         }
   1749     }
   1750 
   1751     private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
   1752             String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
   1753         if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
   1754                 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
   1755                 == PackageManager.PERMISSION_DENIED) {
   1756             return ACTIVITY_RESTRICTION_PERMISSION;
   1757         }
   1758 
   1759         if (activityInfo.permission == null) {
   1760             return ACTIVITY_RESTRICTION_NONE;
   1761         }
   1762 
   1763         final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
   1764         if (opCode == AppOpsManager.OP_NONE) {
   1765             return ACTIVITY_RESTRICTION_NONE;
   1766         }
   1767 
   1768         if (mService.mAppOpsService.noteOperation(opCode, callingUid,
   1769                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
   1770             if (!ignoreTargetSecurity) {
   1771                 return ACTIVITY_RESTRICTION_APPOP;
   1772             }
   1773         }
   1774 
   1775         return ACTIVITY_RESTRICTION_NONE;
   1776     }
   1777 
   1778     private int getActionRestrictionForCallingPackage(String action,
   1779             String callingPackage, int callingPid, int callingUid) {
   1780         if (action == null) {
   1781             return ACTIVITY_RESTRICTION_NONE;
   1782         }
   1783 
   1784         String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
   1785         if (permission == null) {
   1786             return ACTIVITY_RESTRICTION_NONE;
   1787         }
   1788 
   1789         final PackageInfo packageInfo;
   1790         try {
   1791             packageInfo = mService.mContext.getPackageManager()
   1792                     .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
   1793         } catch (PackageManager.NameNotFoundException e) {
   1794             Slog.i(TAG, "Cannot find package info for " + callingPackage);
   1795             return ACTIVITY_RESTRICTION_NONE;
   1796         }
   1797 
   1798         if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
   1799             return ACTIVITY_RESTRICTION_NONE;
   1800         }
   1801 
   1802         if (mService.checkPermission(permission, callingPid, callingUid) ==
   1803                 PackageManager.PERMISSION_DENIED) {
   1804             return ACTIVITY_RESTRICTION_PERMISSION;
   1805         }
   1806 
   1807         final int opCode = AppOpsManager.permissionToOpCode(permission);
   1808         if (opCode == AppOpsManager.OP_NONE) {
   1809             return ACTIVITY_RESTRICTION_NONE;
   1810         }
   1811 
   1812         if (mService.mAppOpsService.noteOperation(opCode, callingUid,
   1813                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
   1814             return ACTIVITY_RESTRICTION_APPOP;
   1815         }
   1816 
   1817         return ACTIVITY_RESTRICTION_NONE;
   1818     }
   1819 
   1820     void setLaunchSource(int uid) {
   1821         mLaunchingActivity.setWorkSource(new WorkSource(uid));
   1822     }
   1823 
   1824     void acquireLaunchWakelock() {
   1825         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
   1826             throw new IllegalStateException("Calling must be system uid");
   1827         }
   1828         mLaunchingActivity.acquire();
   1829         if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
   1830             // To be safe, don't allow the wake lock to be held for too long.
   1831             mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
   1832         }
   1833     }
   1834 
   1835     /**
   1836      * Called when the frontmost task is idle.
   1837      * @return the state of mService.mBooting before this was called.
   1838      */
   1839     private boolean checkFinishBootingLocked() {
   1840         final boolean booting = mService.mBooting;
   1841         boolean enableScreen = false;
   1842         mService.mBooting = false;
   1843         if (!mService.mBooted) {
   1844             mService.mBooted = true;
   1845             enableScreen = true;
   1846         }
   1847         if (booting || enableScreen) {
   1848             mService.postFinishBooting(booting, enableScreen);
   1849         }
   1850         return booting;
   1851     }
   1852 
   1853     // Checked.
   1854     final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
   1855             boolean processPausingActivities, Configuration config) {
   1856         if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
   1857 
   1858         ArrayList<ActivityRecord> finishes = null;
   1859         ArrayList<UserState> startingUsers = null;
   1860         int NS = 0;
   1861         int NF = 0;
   1862         boolean booting = false;
   1863         boolean activityRemoved = false;
   1864 
   1865         ActivityRecord r = ActivityRecord.forTokenLocked(token);
   1866         if (r != null) {
   1867             if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
   1868                     + Debug.getCallers(4));
   1869             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
   1870             r.finishLaunchTickingLocked();
   1871             if (fromTimeout) {
   1872                 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
   1873             }
   1874 
   1875             // This is a hack to semi-deal with a race condition
   1876             // in the client where it can be constructed with a
   1877             // newer configuration from when we asked it to launch.
   1878             // We'll update with whatever configuration it now says
   1879             // it used to launch.
   1880             if (config != null) {
   1881                 r.setLastReportedGlobalConfiguration(config);
   1882             }
   1883 
   1884             // We are now idle.  If someone is waiting for a thumbnail from
   1885             // us, we can now deliver.
   1886             r.idle = true;
   1887 
   1888             //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
   1889             if (isFocusedStack(r.getStack()) || fromTimeout) {
   1890                 booting = checkFinishBootingLocked();
   1891             }
   1892         }
   1893 
   1894         if (allResumedActivitiesIdle()) {
   1895             if (r != null) {
   1896                 mService.scheduleAppGcsLocked();
   1897             }
   1898 
   1899             if (mLaunchingActivity.isHeld()) {
   1900                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   1901                 if (VALIDATE_WAKE_LOCK_CALLER &&
   1902                         Binder.getCallingUid() != Process.myUid()) {
   1903                     throw new IllegalStateException("Calling must be system uid");
   1904                 }
   1905                 mLaunchingActivity.release();
   1906             }
   1907             ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   1908         }
   1909 
   1910         // Atomically retrieve all of the other things to do.
   1911         final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
   1912                 true /* remove */, processPausingActivities);
   1913         NS = stops != null ? stops.size() : 0;
   1914         if ((NF = mFinishingActivities.size()) > 0) {
   1915             finishes = new ArrayList<>(mFinishingActivities);
   1916             mFinishingActivities.clear();
   1917         }
   1918 
   1919         if (mStartingUsers.size() > 0) {
   1920             startingUsers = new ArrayList<>(mStartingUsers);
   1921             mStartingUsers.clear();
   1922         }
   1923 
   1924         // Stop any activities that are scheduled to do so but have been
   1925         // waiting for the next one to start.
   1926         for (int i = 0; i < NS; i++) {
   1927             r = stops.get(i);
   1928             final ActivityStack stack = r.getStack();
   1929             if (stack != null) {
   1930                 if (r.finishing) {
   1931                     stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
   1932                 } else {
   1933                     stack.stopActivityLocked(r);
   1934                 }
   1935             }
   1936         }
   1937 
   1938         // Finish any activities that are scheduled to do so but have been
   1939         // waiting for the next one to start.
   1940         for (int i = 0; i < NF; i++) {
   1941             r = finishes.get(i);
   1942             final ActivityStack stack = r.getStack();
   1943             if (stack != null) {
   1944                 activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
   1945             }
   1946         }
   1947 
   1948         if (!booting) {
   1949             // Complete user switch
   1950             if (startingUsers != null) {
   1951                 for (int i = 0; i < startingUsers.size(); i++) {
   1952                     mService.mUserController.finishUserSwitch(startingUsers.get(i));
   1953                 }
   1954             }
   1955         }
   1956 
   1957         mService.trimApplications();
   1958         //dump();
   1959         //mWindowManager.dump();
   1960 
   1961         if (activityRemoved) {
   1962             resumeFocusedStackTopActivityLocked();
   1963         }
   1964 
   1965         return r;
   1966     }
   1967 
   1968     boolean handleAppDiedLocked(ProcessRecord app) {
   1969         boolean hasVisibleActivities = false;
   1970         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1971             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1972             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1973                 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
   1974             }
   1975         }
   1976         return hasVisibleActivities;
   1977     }
   1978 
   1979     void closeSystemDialogsLocked() {
   1980         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   1981             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   1982             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1983                 stacks.get(stackNdx).closeSystemDialogsLocked();
   1984             }
   1985         }
   1986     }
   1987 
   1988     void removeUserLocked(int userId) {
   1989         mUserStackInFront.delete(userId);
   1990     }
   1991 
   1992     /**
   1993      * Update the last used stack id for non-current user (current user's last
   1994      * used stack is the focused stack)
   1995      */
   1996     void updateUserStackLocked(int userId, ActivityStack stack) {
   1997         if (userId != mCurrentUser) {
   1998             mUserStackInFront.put(userId, stack != null ? stack.getStackId() : HOME_STACK_ID);
   1999         }
   2000     }
   2001 
   2002     /**
   2003      * @return true if some activity was finished (or would have finished if doit were true).
   2004      */
   2005     boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
   2006             boolean doit, boolean evenPersistent, int userId) {
   2007         boolean didSomething = false;
   2008         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2009             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2010             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2011                 final ActivityStack stack = stacks.get(stackNdx);
   2012                 if (stack.finishDisabledPackageActivitiesLocked(
   2013                         packageName, filterByClasses, doit, evenPersistent, userId)) {
   2014                     didSomething = true;
   2015                 }
   2016             }
   2017         }
   2018         return didSomething;
   2019     }
   2020 
   2021     void updatePreviousProcessLocked(ActivityRecord r) {
   2022         // Now that this process has stopped, we may want to consider
   2023         // it to be the previous app to try to keep around in case
   2024         // the user wants to return to it.
   2025 
   2026         // First, found out what is currently the foreground app, so that
   2027         // we don't blow away the previous app if this activity is being
   2028         // hosted by the process that is actually still the foreground.
   2029         ProcessRecord fgApp = null;
   2030         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2031             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2032             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2033                 final ActivityStack stack = stacks.get(stackNdx);
   2034                 if (isFocusedStack(stack)) {
   2035                     if (stack.mResumedActivity != null) {
   2036                         fgApp = stack.mResumedActivity.app;
   2037                     } else if (stack.mPausingActivity != null) {
   2038                         fgApp = stack.mPausingActivity.app;
   2039                     }
   2040                     break;
   2041                 }
   2042             }
   2043         }
   2044 
   2045         // Now set this one as the previous process, only if that really
   2046         // makes sense to.
   2047         if (r.app != null && fgApp != null && r.app != fgApp
   2048                 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
   2049                 && r.app != mService.mHomeProcess) {
   2050             mService.mPreviousProcess = r.app;
   2051             mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
   2052         }
   2053     }
   2054 
   2055     boolean resumeFocusedStackTopActivityLocked() {
   2056         return resumeFocusedStackTopActivityLocked(null, null, null);
   2057     }
   2058 
   2059     boolean resumeFocusedStackTopActivityLocked(
   2060             ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
   2061         if (targetStack != null && isFocusedStack(targetStack)) {
   2062             return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
   2063         }
   2064         final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
   2065         if (r == null || r.state != RESUMED) {
   2066             mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
   2067         } else if (r.state == RESUMED) {
   2068             // Kick off any lingering app transitions form the MoveTaskToFront operation.
   2069             mFocusedStack.executeAppTransition(targetOptions);
   2070         }
   2071         return false;
   2072     }
   2073 
   2074     void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
   2075         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2076             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2077             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2078                 stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo);
   2079             }
   2080         }
   2081     }
   2082 
   2083     TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
   2084         TaskRecord finishedTask = null;
   2085         ActivityStack focusedStack = getFocusedStack();
   2086         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2087             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2088             final int numStacks = stacks.size();
   2089             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2090                 final ActivityStack stack = stacks.get(stackNdx);
   2091                 TaskRecord t = stack.finishTopRunningActivityLocked(app, reason);
   2092                 if (stack == focusedStack || finishedTask == null) {
   2093                     finishedTask = t;
   2094                 }
   2095             }
   2096         }
   2097         return finishedTask;
   2098     }
   2099 
   2100     void finishVoiceTask(IVoiceInteractionSession session) {
   2101         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2102             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2103             final int numStacks = stacks.size();
   2104             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2105                 final ActivityStack stack = stacks.get(stackNdx);
   2106                 stack.finishVoiceTask(session);
   2107             }
   2108         }
   2109     }
   2110 
   2111     void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options,
   2112             String reason, boolean forceNonResizeable) {
   2113         if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   2114             mUserLeaving = true;
   2115         }
   2116         if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   2117             // Caller wants the home activity moved with it.  To accomplish this,
   2118             // we'll just indicate that this task returns to the home task.
   2119             task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
   2120         }
   2121         ActivityStack currentStack = task.getStack();
   2122         if (currentStack == null) {
   2123             Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
   2124                     + task + " to front. Stack is null");
   2125             return;
   2126         }
   2127 
   2128         if (task.isResizeable() && options != null) {
   2129             int stackId = options.getLaunchStackId();
   2130             if (canUseActivityOptionsLaunchBounds(options, stackId)) {
   2131                 final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds());
   2132                 task.updateOverrideConfiguration(bounds);
   2133                 if (stackId == INVALID_STACK_ID) {
   2134                     stackId = task.getLaunchStackId();
   2135                 }
   2136                 if (stackId != currentStack.mStackId) {
   2137                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
   2138                             DEFER_RESUME, "findTaskToMoveToFrontLocked");
   2139                     stackId = currentStack.mStackId;
   2140                     // moveTaskToStackUncheckedLocked() should already placed the task on top,
   2141                     // still need moveTaskToFrontLocked() below for any transition settings.
   2142                 }
   2143                 if (StackId.resizeStackWithLaunchBounds(stackId)) {
   2144                     resizeStackLocked(stackId, bounds,
   2145                             null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
   2146                             !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME);
   2147                 } else {
   2148                     // WM resizeTask must be done after the task is moved to the correct stack,
   2149                     // because Task's setBounds() also updates dim layer's bounds, but that has
   2150                     // dependency on the stack.
   2151                     task.resizeWindowContainer();
   2152                 }
   2153             }
   2154         }
   2155 
   2156         final ActivityRecord r = task.getTopActivity();
   2157         currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
   2158                 r == null ? null : r.appTimeTracker, reason);
   2159 
   2160         if (DEBUG_STACK) Slog.d(TAG_STACK,
   2161                 "findTaskToMoveToFront: moved to front of stack=" + currentStack);
   2162 
   2163         handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, DEFAULT_DISPLAY,
   2164                 currentStack.mStackId, forceNonResizeable);
   2165     }
   2166 
   2167     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
   2168         // We use the launch bounds in the activity options is the device supports freeform
   2169         // window management or is launching into the pinned stack.
   2170         if (options.getLaunchBounds() == null) {
   2171             return false;
   2172         }
   2173         return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID)
   2174                 || mService.mSupportsFreeformWindowManagement;
   2175     }
   2176 
   2177     protected <T extends ActivityStack> T getStack(int stackId) {
   2178         return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
   2179     }
   2180 
   2181     protected <T extends ActivityStack> T getStack(int stackId, boolean createStaticStackIfNeeded,
   2182             boolean createOnTop) {
   2183         final ActivityContainer activityContainer = mActivityContainers.get(stackId);
   2184         if (activityContainer != null) {
   2185             return (T) activityContainer.mStack;
   2186         }
   2187         if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
   2188             return null;
   2189         }
   2190         if (stackId == DOCKED_STACK_ID) {
   2191             // Make sure recents stack exist when creating a dock stack as it normally need to be on
   2192             // the other side of the docked stack and we make visibility decisions based on that.
   2193             getStack(RECENTS_STACK_ID, CREATE_IF_NEEDED, createOnTop);
   2194         }
   2195         return (T) createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
   2196     }
   2197 
   2198     /**
   2199      * Get a topmost stack on the display, that is a valid launch stack for specified activity.
   2200      * If there is no such stack, new dynamic stack can be created.
   2201      * @param displayId Target display.
   2202      * @param r Activity that should be launched there.
   2203      * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
   2204      */
   2205     ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r) {
   2206         final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
   2207         if (activityDisplay == null) {
   2208             throw new IllegalArgumentException(
   2209                     "Display with displayId=" + displayId + " not found.");
   2210         }
   2211 
   2212         // Return the topmost valid stack on the display.
   2213         for (int i = activityDisplay.mStacks.size() - 1; i >= 0; --i) {
   2214             final ActivityStack stack = activityDisplay.mStacks.get(i);
   2215             if (mService.mActivityStarter.isValidLaunchStackId(stack.mStackId, displayId, r)) {
   2216                 return stack;
   2217             }
   2218         }
   2219 
   2220         // If there is no valid stack on the external display - check if new dynamic stack will do.
   2221         if (displayId != Display.DEFAULT_DISPLAY) {
   2222             final int newDynamicStackId = getNextStackId();
   2223             if (mService.mActivityStarter.isValidLaunchStackId(newDynamicStackId, displayId, r)) {
   2224                 return createStackOnDisplay(newDynamicStackId, displayId, true /*onTop*/);
   2225             }
   2226         }
   2227 
   2228         Slog.w(TAG, "getValidLaunchStackOnDisplay: can't launch on displayId " + displayId);
   2229         return null;
   2230     }
   2231 
   2232     ArrayList<ActivityStack> getStacks() {
   2233         ArrayList<ActivityStack> allStacks = new ArrayList<>();
   2234         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2235             allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
   2236         }
   2237         return allStacks;
   2238     }
   2239 
   2240     ArrayList<ActivityStack> getStacksOnDefaultDisplay() {
   2241         return mActivityDisplays.valueAt(DEFAULT_DISPLAY).mStacks;
   2242     }
   2243 
   2244     /**
   2245      * Get next focusable stack in the system. This will search across displays and stacks
   2246      * in last-focused order for a focusable and visible stack, different from the target stack.
   2247      *
   2248      * @param currentFocus The stack that previously had focus and thus needs to be ignored when
   2249      *                     searching for next candidate.
   2250      * @return Next focusable {@link ActivityStack}, null if not found.
   2251      */
   2252     ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus) {
   2253         mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
   2254 
   2255         for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
   2256             final int displayId = mTmpOrderedDisplayIds.get(i);
   2257             // If a display is registered in WM, it must also be available in AM.
   2258             @SuppressWarnings("ConstantConditions")
   2259             final List<ActivityStack> stacks = getActivityDisplayOrCreateLocked(displayId).mStacks;
   2260             for (int j = stacks.size() - 1; j >= 0; --j) {
   2261                 final ActivityStack stack = stacks.get(j);
   2262                 if (stack != currentFocus && stack.isFocusable()
   2263                         && stack.shouldBeVisible(null) != STACK_INVISIBLE) {
   2264                     return stack;
   2265                 }
   2266             }
   2267         }
   2268 
   2269         return null;
   2270     }
   2271 
   2272     /**
   2273      * Get next valid stack for launching provided activity in the system. This will search across
   2274      * displays and stacks in last-focused order for a focusable and visible stack, except those
   2275      * that are on a currently focused display.
   2276      *
   2277      * @param r The activity that is being launched.
   2278      * @param currentFocus The display that previously had focus and thus needs to be ignored when
   2279      *                     searching for the next candidate.
   2280      * @return Next valid {@link ActivityStack}, null if not found.
   2281      */
   2282     ActivityStack getNextValidLaunchStackLocked(@NonNull ActivityRecord r, int currentFocus) {
   2283         mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
   2284         for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
   2285             final int displayId = mTmpOrderedDisplayIds.get(i);
   2286             if (displayId == currentFocus) {
   2287                 continue;
   2288             }
   2289             final ActivityStack stack = getValidLaunchStackOnDisplay(displayId, r);
   2290             if (stack != null) {
   2291                 return stack;
   2292             }
   2293         }
   2294         return null;
   2295     }
   2296 
   2297     ActivityRecord getHomeActivity() {
   2298         return getHomeActivityForUser(mCurrentUser);
   2299     }
   2300 
   2301     ActivityRecord getHomeActivityForUser(int userId) {
   2302         final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
   2303         for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
   2304             final TaskRecord task = tasks.get(taskNdx);
   2305             if (task.isHomeTask()) {
   2306                 final ArrayList<ActivityRecord> activities = task.mActivities;
   2307                 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   2308                     final ActivityRecord r = activities.get(activityNdx);
   2309                     if (r.isHomeActivity()
   2310                             && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
   2311                         return r;
   2312                     }
   2313                 }
   2314             }
   2315         }
   2316         return null;
   2317     }
   2318 
   2319     /**
   2320      * Returns if a stack should be treated as if it's docked. Returns true if the stack is
   2321      * the docked stack itself, or if it's side-by-side to the docked stack.
   2322      */
   2323     boolean isStackDockedInEffect(int stackId) {
   2324         return stackId == DOCKED_STACK_ID ||
   2325                 (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null);
   2326     }
   2327 
   2328     ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
   2329             IActivityContainerCallback callback) {
   2330         ActivityContainer activityContainer =
   2331                 new VirtualActivityContainer(parentActivity, callback);
   2332         mActivityContainers.put(activityContainer.mStackId, activityContainer);
   2333         if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
   2334                 "createActivityContainer: " + activityContainer);
   2335         parentActivity.mChildContainers.add(activityContainer);
   2336         return activityContainer;
   2337     }
   2338 
   2339     void removeChildActivityContainers(ActivityRecord parentActivity) {
   2340         final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
   2341         for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
   2342             ActivityContainer container = childStacks.remove(containerNdx);
   2343             if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
   2344                     + container);
   2345             container.release();
   2346         }
   2347     }
   2348 
   2349     void deleteActivityContainerRecord(int stackId) {
   2350         if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
   2351                 "deleteActivityContainerRecord: callers=" + Debug.getCallers(4));
   2352         mActivityContainers.remove(stackId);
   2353     }
   2354 
   2355     void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
   2356             boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) {
   2357         if (stackId == DOCKED_STACK_ID) {
   2358             resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null,
   2359                     preserveWindows, deferResume);
   2360             return;
   2361         }
   2362         final ActivityStack stack = getStack(stackId);
   2363         if (stack == null) {
   2364             Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
   2365             return;
   2366         }
   2367 
   2368         if (!allowResizeInDockedMode && !StackId.tasksAreFloating(stackId) &&
   2369                 getStack(DOCKED_STACK_ID) != null) {
   2370             // If the docked stack exists, don't resize non-floating stacks independently of the
   2371             // size computed from the docked stack size (otherwise they will be out of sync)
   2372             return;
   2373         }
   2374 
   2375         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
   2376         mWindowManager.deferSurfaceLayout();
   2377         try {
   2378             stack.resize(bounds, tempTaskBounds, tempTaskInsetBounds);
   2379             if (!deferResume) {
   2380                 stack.ensureVisibleActivitiesConfigurationLocked(
   2381                         stack.topRunningActivityLocked(), preserveWindows);
   2382             }
   2383         } finally {
   2384             mWindowManager.continueSurfaceLayout();
   2385             Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
   2386         }
   2387     }
   2388 
   2389     void deferUpdateBounds(int stackId) {
   2390         final ActivityStack stack = getStack(stackId);
   2391         if (stack != null) {
   2392             stack.deferUpdateBounds();
   2393         }
   2394     }
   2395 
   2396     void continueUpdateBounds(int stackId) {
   2397         final ActivityStack stack = getStack(stackId);
   2398         if (stack != null) {
   2399             stack.continueUpdateBounds();
   2400         }
   2401     }
   2402 
   2403     void notifyAppTransitionDone() {
   2404         continueUpdateBounds(RECENTS_STACK_ID);
   2405         for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
   2406             final int taskId = mResizingTasksDuringAnimation.valueAt(i);
   2407             final TaskRecord task =
   2408                     anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
   2409             if (task != null) {
   2410                 task.setTaskDockedResizing(false);
   2411             }
   2412         }
   2413         mResizingTasksDuringAnimation.clear();
   2414     }
   2415 
   2416     private void moveTasksToFullscreenStackInSurfaceTransaction(int fromStackId,
   2417             boolean onTop) {
   2418 
   2419         final ActivityStack stack = getStack(fromStackId);
   2420         if (stack == null) {
   2421             return;
   2422         }
   2423 
   2424         mWindowManager.deferSurfaceLayout();
   2425         try {
   2426             if (fromStackId == DOCKED_STACK_ID) {
   2427                 // We are moving all tasks from the docked stack to the fullscreen stack,
   2428                 // which is dismissing the docked stack, so resize all other stacks to
   2429                 // fullscreen here already so we don't end up with resize trashing.
   2430                 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
   2431                     if (StackId.isResizeableByDockedStack(i)) {
   2432                         ActivityStack otherStack = getStack(i);
   2433                         if (otherStack != null) {
   2434                             resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS,
   2435                                     true /* allowResizeInDockedMode */, DEFER_RESUME);
   2436                         }
   2437                     }
   2438                 }
   2439 
   2440                 // Also disable docked stack resizing since we have manually adjusted the
   2441                 // size of other stacks above and we don't want to trigger a docked stack
   2442                 // resize when we remove task from it below and it is detached from the
   2443                 // display because it no longer contains any tasks.
   2444                 mAllowDockedStackResize = false;
   2445             } else if (fromStackId == PINNED_STACK_ID) {
   2446                 if (onTop) {
   2447                     // Log if we are expanding the PiP to fullscreen
   2448                     MetricsLogger.action(mService.mContext,
   2449                             ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN);
   2450                 }
   2451             }
   2452             ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
   2453             final boolean isFullscreenStackVisible = fullscreenStack != null &&
   2454                     fullscreenStack.shouldBeVisible(null) == STACK_VISIBLE;
   2455             // If we are moving from the pinned stack, then the animation takes care of updating
   2456             // the picture-in-picture mode.
   2457             final boolean schedulePictureInPictureModeChange = (fromStackId == PINNED_STACK_ID);
   2458             final ArrayList<TaskRecord> tasks = stack.getAllTasks();
   2459             final int size = tasks.size();
   2460             if (onTop) {
   2461                 for (int i = 0; i < size; i++) {
   2462                     final TaskRecord task = tasks.get(i);
   2463                     final boolean isTopTask = i == (size - 1);
   2464                     if (fromStackId == PINNED_STACK_ID) {
   2465                         // Update the return-to to reflect where the pinned stack task was moved
   2466                         // from so that we retain the stack that was previously visible if the
   2467                         // pinned stack is recreated. See moveActivityToPinnedStackLocked().
   2468                         task.setTaskToReturnTo(isFullscreenStackVisible && onTop ?
   2469                                 APPLICATION_ACTIVITY_TYPE : HOME_ACTIVITY_TYPE);
   2470                     }
   2471                     // Defer resume until all the tasks have been moved to the fullscreen stack
   2472                     task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
   2473                             REPARENT_MOVE_STACK_TO_FRONT, isTopTask /* animate */, DEFER_RESUME,
   2474                             schedulePictureInPictureModeChange,
   2475                             "moveTasksToFullscreenStack - onTop");
   2476                 }
   2477             } else {
   2478                 for (int i = 0; i < size; i++) {
   2479                     final TaskRecord task = tasks.get(i);
   2480                     // Position the tasks in the fullscreen stack in order at the bottom of the
   2481                     // stack. Also defer resume until all the tasks have been moved to the
   2482                     // fullscreen stack.
   2483                     task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, i /* position */,
   2484                             REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME,
   2485                             schedulePictureInPictureModeChange,
   2486                             "moveTasksToFullscreenStack - NOT_onTop");
   2487                 }
   2488             }
   2489 
   2490             ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
   2491             resumeFocusedStackTopActivityLocked();
   2492         } finally {
   2493             mAllowDockedStackResize = true;
   2494             mWindowManager.continueSurfaceLayout();
   2495         }
   2496     }
   2497 
   2498     void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) {
   2499         mWindowManager.inSurfaceTransaction(
   2500                 () -> moveTasksToFullscreenStackInSurfaceTransaction(fromStackId, onTop));
   2501     }
   2502 
   2503     void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
   2504             Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
   2505             boolean preserveWindows) {
   2506         resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
   2507                 tempOtherTaskBounds, tempOtherTaskInsetBounds, preserveWindows,
   2508                 false /* deferResume */);
   2509     }
   2510 
   2511     void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
   2512             Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
   2513             boolean preserveWindows, boolean deferResume) {
   2514 
   2515         if (!mAllowDockedStackResize) {
   2516             // Docked stack resize currently disabled.
   2517             return;
   2518         }
   2519 
   2520         final ActivityStack stack = getStack(DOCKED_STACK_ID);
   2521         if (stack == null) {
   2522             Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
   2523             return;
   2524         }
   2525 
   2526         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack");
   2527         mWindowManager.deferSurfaceLayout();
   2528         try {
   2529             // Don't allow re-entry while resizing. E.g. due to docked stack detaching.
   2530             mAllowDockedStackResize = false;
   2531             ActivityRecord r = stack.topRunningActivityLocked();
   2532             stack.resize(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds);
   2533 
   2534             // TODO: Checking for isAttached might not be needed as if the user passes in null
   2535             // dockedBounds then they want the docked stack to be dismissed.
   2536             if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) {
   2537                 // The dock stack either was dismissed or went fullscreen, which is kinda the same.
   2538                 // In this case we make all other static stacks fullscreen and move all
   2539                 // docked stack tasks to the fullscreen stack.
   2540                 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP);
   2541 
   2542                 // stack shouldn't contain anymore activities, so nothing to resume.
   2543                 r = null;
   2544             } else {
   2545                 // Docked stacks occupy a dedicated region on screen so the size of all other
   2546                 // static stacks need to be adjusted so they don't overlap with the docked stack.
   2547                 // We get the bounds to use from window manager which has been adjusted for any
   2548                 // screen controls and is also the same for all stacks.
   2549                 final Rect otherTaskRect = new Rect();
   2550                 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
   2551                     final ActivityStack current = getStack(i);
   2552                     if (current != null && StackId.isResizeableByDockedStack(i)) {
   2553                         current.getStackDockedModeBounds(
   2554                                 tempOtherTaskBounds /* currentTempTaskBounds */,
   2555                                 tempRect /* outStackBounds */,
   2556                                 otherTaskRect /* outTempTaskBounds */, true /* ignoreVisibility */);
   2557 
   2558                         resizeStackLocked(i, !tempRect.isEmpty() ? tempRect : null,
   2559                                 !otherTaskRect.isEmpty() ? otherTaskRect : tempOtherTaskBounds,
   2560                                 tempOtherTaskInsetBounds, preserveWindows,
   2561                                 true /* allowResizeInDockedMode */, deferResume);
   2562                     }
   2563                 }
   2564             }
   2565             if (!deferResume) {
   2566                 stack.ensureVisibleActivitiesConfigurationLocked(r, preserveWindows);
   2567             }
   2568         } finally {
   2569             mAllowDockedStackResize = true;
   2570             mWindowManager.continueSurfaceLayout();
   2571             Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
   2572         }
   2573     }
   2574 
   2575     void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
   2576         final PinnedActivityStack stack = getStack(PINNED_STACK_ID);
   2577         if (stack == null) {
   2578             Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
   2579             return;
   2580         }
   2581 
   2582         // It is possible for the bounds animation from the WM to call this but be delayed by
   2583         // another AM call that is holding the AMS lock. In such a case, the pinnedBounds may be
   2584         // incorrect if AMS.resizeStackWithBoundsFromWindowManager() is already called while waiting
   2585         // for the AMS lock to be freed. So check and make sure these bounds are still good.
   2586         final PinnedStackWindowController stackController = stack.getWindowContainerController();
   2587         if (stackController.pinnedStackResizeDisallowed()) {
   2588             return;
   2589         }
   2590 
   2591         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack");
   2592         mWindowManager.deferSurfaceLayout();
   2593         try {
   2594             ActivityRecord r = stack.topRunningActivityLocked();
   2595             Rect insetBounds = null;
   2596             if (tempPinnedTaskBounds != null) {
   2597                 // We always use 0,0 as the position for the inset rect because
   2598                 // if we are getting insets at all in the pinned stack it must mean
   2599                 // we are headed for fullscreen.
   2600                 insetBounds = tempRect;
   2601                 insetBounds.top = 0;
   2602                 insetBounds.left = 0;
   2603                 insetBounds.right = tempPinnedTaskBounds.width();
   2604                 insetBounds.bottom = tempPinnedTaskBounds.height();
   2605             }
   2606             stack.resize(pinnedBounds, tempPinnedTaskBounds, insetBounds);
   2607             stack.ensureVisibleActivitiesConfigurationLocked(r, false);
   2608         } finally {
   2609             mWindowManager.continueSurfaceLayout();
   2610             Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
   2611         }
   2612     }
   2613 
   2614     ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
   2615         final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
   2616         if (activityDisplay == null) {
   2617             return null;
   2618         }
   2619 
   2620         final ActivityContainer activityContainer =
   2621                 new ActivityContainer(stackId, activityDisplay, onTop);
   2622         return activityContainer.mStack;
   2623     }
   2624 
   2625 
   2626     void removeStackInSurfaceTransaction(int stackId) {
   2627         final ActivityStack stack = getStack(stackId);
   2628         if (stack == null) {
   2629             return;
   2630         }
   2631 
   2632         final ArrayList<TaskRecord> tasks = stack.getAllTasks();
   2633         if (stack.getStackId() == PINNED_STACK_ID) {
   2634             /**
   2635              * Workaround: Force-stop all the activities in the pinned stack before we reparent them
   2636              * to the fullscreen stack.  This is to guarantee that when we are removing a stack,
   2637              * that the client receives onStop() before it is reparented.  We do this by detaching
   2638              * the stack from the display so that it will be considered invisible when
   2639              * ensureActivitiesVisibleLocked() is called, and all of its activitys will be marked
   2640              * invisible as well and added to the stopping list.  After which we process the
   2641              * stopping list by handling the idle.
   2642              */
   2643             final PinnedActivityStack pinnedStack = (PinnedActivityStack) stack;
   2644             pinnedStack.mForceHidden = true;
   2645             pinnedStack.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
   2646             pinnedStack.mForceHidden = false;
   2647             activityIdleInternalLocked(null, false /* fromTimeout */,
   2648                     true /* processPausingActivites */, null /* configuration */);
   2649 
   2650             // Move all the tasks to the bottom of the fullscreen stack
   2651             moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);
   2652         } else {
   2653             for (int i = tasks.size() - 1; i >= 0; i--) {
   2654                 removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
   2655                         REMOVE_FROM_RECENTS);
   2656             }
   2657         }
   2658     }
   2659 
   2660     /**
   2661      * Removes the stack associated with the given {@param stackId}.  If the {@param stackId} is the
   2662      * pinned stack, then its tasks are not explicitly removed when the stack is destroyed, but
   2663      * instead moved back onto the fullscreen stack.
   2664      */
   2665     void removeStackLocked(int stackId) {
   2666         mWindowManager.inSurfaceTransaction(
   2667                 () -> removeStackInSurfaceTransaction(stackId));
   2668     }
   2669 
   2670     /**
   2671      * See {@link #removeTaskByIdLocked(int, boolean, boolean, boolean)}
   2672      */
   2673     boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) {
   2674         return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY);
   2675     }
   2676 
   2677     /**
   2678      * Removes the task with the specified task id.
   2679      *
   2680      * @param taskId Identifier of the task to be removed.
   2681      * @param killProcess Kill any process associated with the task if possible.
   2682      * @param removeFromRecents Whether to also remove the task from recents.
   2683      * @param pauseImmediately Pauses all task activities immediately without waiting for the
   2684      *                         pause-complete callback from the activity.
   2685      * @return Returns true if the given task was found and removed.
   2686      */
   2687     boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents,
   2688             boolean pauseImmediately) {
   2689         final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
   2690                 INVALID_STACK_ID);
   2691         if (tr != null) {
   2692             tr.removeTaskActivitiesLocked(pauseImmediately);
   2693             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
   2694             if (tr.isPersistable) {
   2695                 mService.notifyTaskPersisterLocked(null, true);
   2696             }
   2697             return true;
   2698         }
   2699         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
   2700         return false;
   2701     }
   2702 
   2703     void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents) {
   2704         if (removeFromRecents) {
   2705             mRecentTasks.remove(tr);
   2706             tr.removedFromRecents();
   2707         }
   2708         ComponentName component = tr.getBaseIntent().getComponent();
   2709         if (component == null) {
   2710             Slog.w(TAG, "No component for base intent of task: " + tr);
   2711             return;
   2712         }
   2713 
   2714         // Find any running services associated with this app and stop if needed.
   2715         mService.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
   2716 
   2717         if (!killProcess) {
   2718             return;
   2719         }
   2720 
   2721         // Determine if the process(es) for this task should be killed.
   2722         final String pkg = component.getPackageName();
   2723         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
   2724         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mService.mProcessNames.getMap();
   2725         for (int i = 0; i < pmap.size(); i++) {
   2726 
   2727             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   2728             for (int j = 0; j < uids.size(); j++) {
   2729                 ProcessRecord proc = uids.valueAt(j);
   2730                 if (proc.userId != tr.userId) {
   2731                     // Don't kill process for a different user.
   2732                     continue;
   2733                 }
   2734                 if (proc == mService.mHomeProcess) {
   2735                     // Don't kill the home process along with tasks from the same package.
   2736                     continue;
   2737                 }
   2738                 if (!proc.pkgList.containsKey(pkg)) {
   2739                     // Don't kill process that is not associated with this task.
   2740                     continue;
   2741                 }
   2742 
   2743                 for (int k = 0; k < proc.activities.size(); k++) {
   2744                     TaskRecord otherTask = proc.activities.get(k).getTask();
   2745                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
   2746                         // Don't kill process(es) that has an activity in a different task that is
   2747                         // also in recents.
   2748                         return;
   2749                     }
   2750                 }
   2751 
   2752                 if (proc.foregroundServices) {
   2753                     // Don't kill process(es) with foreground service.
   2754                     return;
   2755                 }
   2756 
   2757                 // Add process to kill list.
   2758                 procsToKill.add(proc);
   2759             }
   2760         }
   2761 
   2762         // Kill the running processes.
   2763         for (int i = 0; i < procsToKill.size(); i++) {
   2764             ProcessRecord pr = procsToKill.get(i);
   2765             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   2766                     && pr.curReceivers.isEmpty()) {
   2767                 pr.kill("remove task", true);
   2768             } else {
   2769                 // We delay killing processes that are not in the background or running a receiver.
   2770                 pr.waitingToKill = "remove task";
   2771             }
   2772         }
   2773     }
   2774 
   2775     int getNextStackId() {
   2776         while (true) {
   2777             if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID
   2778                     && getStack(mNextFreeStackId) == null) {
   2779                 break;
   2780             }
   2781             mNextFreeStackId++;
   2782         }
   2783         return mNextFreeStackId;
   2784     }
   2785 
   2786     /**
   2787      * Restores a recent task to a stack
   2788      * @param task The recent task to be restored.
   2789      * @param stackId The stack to restore the task to (default launch stack will be used
   2790      *                if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}
   2791      *                or is not a static stack).
   2792      * @return true if the task has been restored successfully.
   2793      */
   2794     boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
   2795         if (!StackId.isStaticStack(stackId)) {
   2796             // If stack is not static (or stack id is invalid) - use the default one.
   2797             // This means that tasks that were on external displays will be restored on the
   2798             // primary display.
   2799             stackId = task.getLaunchStackId();
   2800         } else if (stackId == DOCKED_STACK_ID && !task.supportsSplitScreen()) {
   2801             // Preferred stack is the docked stack, but the task can't go in the docked stack.
   2802             // Put it in the fullscreen stack.
   2803             stackId = FULLSCREEN_WORKSPACE_STACK_ID;
   2804         }
   2805 
   2806         final ActivityStack currentStack = task.getStack();
   2807         if (currentStack != null) {
   2808             // Task has already been restored once. See if we need to do anything more
   2809             if (currentStack.mStackId == stackId) {
   2810                 // Nothing else to do since it is already restored in the right stack.
   2811                 return true;
   2812             }
   2813             // Remove current stack association, so we can re-associate the task with the
   2814             // right stack below.
   2815             currentStack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING);
   2816         }
   2817 
   2818         final ActivityStack stack =
   2819                 getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
   2820 
   2821         if (stack == null) {
   2822             // What does this mean??? Not sure how we would get here...
   2823             if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
   2824                     "Unable to find/create stack to restore recent task=" + task);
   2825             return false;
   2826         }
   2827 
   2828         stack.addTask(task, false /* toTop */, "restoreRecentTask");
   2829         // TODO: move call for creation here and other place into Stack.addTask()
   2830         task.createWindowContainer(false /* toTop */, true /* showForAllUsers */);
   2831         if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
   2832                 "Added restored task=" + task + " to stack=" + stack);
   2833         final ArrayList<ActivityRecord> activities = task.mActivities;
   2834         for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   2835             activities.get(activityNdx).createWindowContainer();
   2836         }
   2837         return true;
   2838     }
   2839 
   2840     /**
   2841      * Move stack with all its existing content to specified display.
   2842      * @param stackId Id of stack to move.
   2843      * @param displayId Id of display to move stack to.
   2844      * @param onTop Indicates whether container should be place on top or on bottom.
   2845      */
   2846     void moveStackToDisplayLocked(int stackId, int displayId, boolean onTop) {
   2847         final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
   2848         if (activityDisplay == null) {
   2849             throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId="
   2850                     + displayId);
   2851         }
   2852         final ActivityContainer activityContainer = mActivityContainers.get(stackId);
   2853         if (activityContainer != null) {
   2854             if (activityContainer.isAttachedLocked()) {
   2855                 if (activityContainer.getDisplayId() == displayId) {
   2856                     throw new IllegalArgumentException("Trying to move stackId=" + stackId
   2857                             + " to its current displayId=" + displayId);
   2858                 }
   2859 
   2860                 activityContainer.moveToDisplayLocked(activityDisplay, onTop);
   2861             } else {
   2862                 throw new IllegalStateException("moveStackToDisplayLocked: Stack with stackId="
   2863                         + stackId + " is not attached to any display.");
   2864             }
   2865         } else {
   2866             throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown stackId="
   2867                     + stackId);
   2868         }
   2869         // TODO(multi-display): resize stacks properly if moved from split-screen.
   2870     }
   2871 
   2872     /**
   2873      * Returns the reparent target stack, creating the stack if necessary.  This call also enforces
   2874      * the various checks on tasks that are going to be reparented from one stack to another.
   2875      */
   2876     ActivityStack getReparentTargetStack(TaskRecord task, int stackId, boolean toTop) {
   2877         final ActivityStack prevStack = task.getStack();
   2878 
   2879         // Check that we aren't reparenting to the same stack that the task is already in
   2880         if (prevStack != null && prevStack.mStackId == stackId) {
   2881             Slog.w(TAG, "Can not reparent to same stack, task=" + task
   2882                     + " already in stackId=" + stackId);
   2883             return prevStack;
   2884         }
   2885 
   2886         // Ensure that we aren't trying to move into a multi-window stack without multi-window
   2887         // support
   2888         if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) {
   2889             throw new IllegalArgumentException("Device doesn't support multi-window, can not"
   2890                     + " reparent task=" + task + " to stackId=" + stackId);
   2891         }
   2892 
   2893         // Ensure that we're not moving a task to a dynamic stack if device doesn't support
   2894         // multi-display.
   2895         // TODO(multi-display): Support non-dynamic stacks on secondary displays.
   2896         // TODO: Check ActivityView after fixing b/35349678.
   2897         if (StackId.isDynamicStack(stackId) && !mService.mSupportsMultiDisplay) {
   2898             throw new IllegalArgumentException("Device doesn't support multi-display, can not"
   2899                     + " reparent task=" + task + " to stackId=" + stackId);
   2900         }
   2901 
   2902         // Ensure that we aren't trying to move into a freeform stack without freeform
   2903         // support
   2904         if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
   2905             throw new IllegalArgumentException("Device doesn't support freeform, can not reparent"
   2906                     + " task=" + task);
   2907         }
   2908 
   2909         // We don't allow moving a unresizeable task to the docked stack since the docked stack is
   2910         // used for split-screen mode and will cause things like the docked divider to show up. We
   2911         // instead leave the task in its current stack or move it to the fullscreen stack if it
   2912         // isn't currently in a stack.
   2913         if (stackId == DOCKED_STACK_ID && !task.isResizeable()) {
   2914             stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
   2915             Slog.w(TAG, "Can not move unresizeable task=" + task + " to docked stack."
   2916                     + " Moving to stackId=" + stackId + " instead.");
   2917         }
   2918 
   2919         // Temporarily disable resizeablility of the task as we don't want it to be resized if, for
   2920         // example, a docked stack is created which will lead to the stack we are moving from being
   2921         // resized and and its resizeable tasks being resized.
   2922         try {
   2923             task.mTemporarilyUnresizable = true;
   2924             return getStack(stackId, CREATE_IF_NEEDED, toTop);
   2925         } finally {
   2926             task.mTemporarilyUnresizable = false;
   2927         }
   2928     }
   2929 
   2930     boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect destBounds) {
   2931         final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
   2932         if (stack == null) {
   2933             throw new IllegalArgumentException(
   2934                     "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId);
   2935         }
   2936 
   2937         final ActivityRecord r = stack.topRunningActivityLocked();
   2938         if (r == null) {
   2939             Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity"
   2940                     + " in stack=" + stack);
   2941             return false;
   2942         }
   2943 
   2944         if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
   2945             Slog.w(TAG,
   2946                     "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for "
   2947                             + " r=" + r);
   2948             return false;
   2949         }
   2950 
   2951         moveActivityToPinnedStackLocked(r, null /* sourceBounds */, 0f /* aspectRatio */,
   2952                 true /* moveHomeStackToFront */, "moveTopActivityToPinnedStack");
   2953         return true;
   2954     }
   2955 
   2956     void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
   2957             boolean moveHomeStackToFront, String reason) {
   2958 
   2959         mWindowManager.deferSurfaceLayout();
   2960 
   2961         // This will clear the pinned stack by moving an existing task to the full screen stack,
   2962         // ensuring only one task is present.
   2963         moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);
   2964 
   2965         // Need to make sure the pinned stack exist so we can resize it below...
   2966         final PinnedActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
   2967 
   2968         try {
   2969             final TaskRecord task = r.getTask();
   2970 
   2971             if (r == task.getStack().getVisibleBehindActivity()) {
   2972                 // An activity can't be pinned and visible behind at the same time. Go ahead and
   2973                 // release it from been visible behind before pinning.
   2974                 requestVisibleBehindLocked(r, false);
   2975             }
   2976 
   2977             // Resize the pinned stack to match the current size of the task the activity we are
   2978             // going to be moving is currently contained in. We do this to have the right starting
   2979             // animation bounds for the pinned stack to the desired bounds the caller wants.
   2980             resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
   2981                     null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
   2982                     true /* allowResizeInDockedMode */, !DEFER_RESUME);
   2983 
   2984             if (task.mActivities.size() == 1) {
   2985                 // There is only one activity in the task. So, we can just move the task over to
   2986                 // the stack without re-parenting the activity in a different task.  We don't
   2987                 // move the home stack forward if we are currently entering picture-in-picture
   2988                 // while pausing because that changes the focused stack and may prevent the new
   2989                 // starting activity from resuming.
   2990                 if (moveHomeStackToFront && task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE
   2991                         && (r.state == RESUMED || !r.supportsPictureInPictureWhilePausing)) {
   2992                     // Move the home stack forward if the task we just moved to the pinned stack
   2993                     // was launched from home so home should be visible behind it.
   2994                     moveHomeStackToFront(reason);
   2995                 }
   2996                 // Defer resume until below, and do not schedule PiP changes until we animate below
   2997                 task.reparent(PINNED_STACK_ID, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
   2998                         DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
   2999             } else {
   3000                 // There are multiple activities in the task and moving the top activity should
   3001                 // reveal/leave the other activities in their original task.
   3002 
   3003                 // Currently, we don't support reparenting activities across tasks in two different
   3004                 // stacks, so instead, just create a new task in the same stack, reparent the
   3005                 // activity into that task, and then reparent the whole task to the new stack. This
   3006                 // ensures that all the necessary work to migrate states in the old and new stacks
   3007                 // is also done.
   3008                 final TaskRecord newTask = task.getStack().createTaskRecord(
   3009                         getNextTaskIdForUserLocked(r.userId), r.info, r.intent, null, null, true,
   3010                         r.mActivityType);
   3011                 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
   3012 
   3013                 // Defer resume until below, and do not schedule PiP changes until we animate below
   3014                 newTask.reparent(PINNED_STACK_ID, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
   3015                         DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
   3016             }
   3017 
   3018             // Reset the state that indicates it can enter PiP while pausing after we've moved it
   3019             // to the pinned stack
   3020             r.supportsPictureInPictureWhilePausing = false;
   3021         } finally {
   3022             mWindowManager.continueSurfaceLayout();
   3023         }
   3024 
   3025         // Calculate the default bounds (don't use existing stack bounds as we may have just created
   3026         // the stack, and schedule the start of the animation into PiP (the bounds animator that
   3027         // is triggered by this is posted on another thread)
   3028         final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio);
   3029 
   3030         stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
   3031                 true /* fromFullscreen */);
   3032 
   3033         // Update the visibility of all activities after the they have been reparented to the new
   3034         // stack.  This MUST run after the animation above is scheduled to ensure that the windows
   3035         // drawn signal is scheduled after the bounds animation start call on the bounds animator
   3036         // thread.
   3037         ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   3038         resumeFocusedStackTopActivityLocked();
   3039 
   3040         mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName,
   3041                 r.getTask().taskId);
   3042     }
   3043 
   3044     /** Move activity with its stack to front and make the stack focused. */
   3045     boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) {
   3046         if (r == null || !r.isFocusable()) {
   3047             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
   3048                     "moveActivityStackToFront: unfocusable r=" + r);
   3049             return false;
   3050         }
   3051 
   3052         final TaskRecord task = r.getTask();
   3053         final ActivityStack stack = r.getStack();
   3054         if (stack == null) {
   3055             Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: r="
   3056                     + r + " task=" + task);
   3057             return false;
   3058         }
   3059 
   3060         if (stack == mFocusedStack && stack.topRunningActivityLocked() == r) {
   3061             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
   3062                     "moveActivityStackToFront: already on top, r=" + r);
   3063             return false;
   3064         }
   3065 
   3066         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
   3067                 "moveActivityStackToFront: r=" + r);
   3068 
   3069         stack.moveToFront(reason, task);
   3070         return true;
   3071     }
   3072 
   3073     ActivityRecord findTaskLocked(ActivityRecord r, int displayId) {
   3074         mTmpFindTaskResult.r = null;
   3075         mTmpFindTaskResult.matchedByRootAffinity = false;
   3076         ActivityRecord affinityMatch = null;
   3077         if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
   3078         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3079             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3080             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3081                 final ActivityStack stack = stacks.get(stackNdx);
   3082                 if (!checkActivityBelongsInStack(r, stack)) {
   3083                     if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) "
   3084                             + stack);
   3085                     continue;
   3086                 }
   3087                 if (!stack.mActivityContainer.isEligibleForNewTasks()) {
   3088                     if (DEBUG_TASKS) Slog.d(TAG_TASKS,
   3089                             "Skipping stack: (new task not allowed) " + stack);
   3090                     continue;
   3091                 }
   3092                 stack.findTaskLocked(r, mTmpFindTaskResult);
   3093                 // It is possible to have tasks in multiple stacks with the same root affinity, so
   3094                 // we should keep looking after finding an affinity match to see if there is a
   3095                 // better match in another stack. Also, task affinity isn't a good enough reason
   3096                 // to target a display which isn't the source of the intent, so skip any affinity
   3097                 // matches not on the specified display.
   3098                 if (mTmpFindTaskResult.r != null) {
   3099                     if (!mTmpFindTaskResult.matchedByRootAffinity) {
   3100                         return mTmpFindTaskResult.r;
   3101                     } else if (mTmpFindTaskResult.r.getDisplayId() == displayId) {
   3102                         // Note: since the traversing through the stacks is top down, the floating
   3103                         // tasks should always have lower priority than any affinity-matching tasks
   3104                         // in the fullscreen stacks
   3105                         affinityMatch = mTmpFindTaskResult.r;
   3106                     }
   3107                 }
   3108             }
   3109         }
   3110 
   3111         if (DEBUG_TASKS && affinityMatch == null) Slog.d(TAG_TASKS, "No task found");
   3112         return affinityMatch;
   3113     }
   3114 
   3115     /**
   3116      * Checks that for the given activity {@param r}, its activity type matches the {@param stack}
   3117      * type.
   3118      */
   3119     private boolean checkActivityBelongsInStack(ActivityRecord r, ActivityStack stack) {
   3120         if (r.isHomeActivity()) {
   3121             return stack.isHomeStack();
   3122         } else if (r.isRecentsActivity()) {
   3123             return stack.isRecentsStack();
   3124         } else if (r.isAssistantActivity()) {
   3125             return stack.isAssistantStack();
   3126         }
   3127         return true;
   3128     }
   3129 
   3130     ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
   3131                                       boolean compareIntentFilters) {
   3132         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3133             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3134             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3135                 final ActivityRecord ar = stacks.get(stackNdx)
   3136                         .findActivityLocked(intent, info, compareIntentFilters);
   3137                 if (ar != null) {
   3138                     return ar;
   3139                 }
   3140             }
   3141         }
   3142         return null;
   3143     }
   3144 
   3145     void goingToSleepLocked() {
   3146         scheduleSleepTimeout();
   3147         if (!mGoingToSleep.isHeld()) {
   3148             mGoingToSleep.acquire();
   3149             if (mLaunchingActivity.isHeld()) {
   3150                 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
   3151                     throw new IllegalStateException("Calling must be system uid");
   3152                 }
   3153                 mLaunchingActivity.release();
   3154                 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   3155             }
   3156         }
   3157         checkReadyForSleepLocked();
   3158     }
   3159 
   3160     boolean shutdownLocked(int timeout) {
   3161         goingToSleepLocked();
   3162 
   3163         boolean timedout = false;
   3164         final long endTime = System.currentTimeMillis() + timeout;
   3165         while (true) {
   3166             boolean cantShutdown = false;
   3167             for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3168                 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3169                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3170                     cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
   3171                 }
   3172             }
   3173             if (cantShutdown) {
   3174                 long timeRemaining = endTime - System.currentTimeMillis();
   3175                 if (timeRemaining > 0) {
   3176                     try {
   3177                         mService.wait(timeRemaining);
   3178                     } catch (InterruptedException e) {
   3179                     }
   3180                 } else {
   3181                     Slog.w(TAG, "Activity manager shutdown timed out");
   3182                     timedout = true;
   3183                     break;
   3184                 }
   3185             } else {
   3186                 break;
   3187             }
   3188         }
   3189 
   3190         // Force checkReadyForSleep to complete.
   3191         mSleepTimeout = true;
   3192         checkReadyForSleepLocked();
   3193 
   3194         return timedout;
   3195     }
   3196 
   3197     void comeOutOfSleepIfNeededLocked() {
   3198         removeSleepTimeouts();
   3199         if (mGoingToSleep.isHeld()) {
   3200             mGoingToSleep.release();
   3201         }
   3202         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3203             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3204             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3205                 final ActivityStack stack = stacks.get(stackNdx);
   3206                 stack.awakeFromSleepingLocked();
   3207                 if (isFocusedStack(stack)) {
   3208                     resumeFocusedStackTopActivityLocked();
   3209                 }
   3210             }
   3211         }
   3212         mGoingToSleepActivities.clear();
   3213     }
   3214 
   3215     void activitySleptLocked(ActivityRecord r) {
   3216         mGoingToSleepActivities.remove(r);
   3217         checkReadyForSleepLocked();
   3218     }
   3219 
   3220     void checkReadyForSleepLocked() {
   3221         if (!mService.isSleepingOrShuttingDownLocked()) {
   3222             // Do not care.
   3223             return;
   3224         }
   3225 
   3226         if (!mSleepTimeout) {
   3227             boolean dontSleep = false;
   3228             for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3229                 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3230                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3231                     dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
   3232                 }
   3233             }
   3234 
   3235             if (mStoppingActivities.size() > 0) {
   3236                 // Still need to tell some activities to stop; can't sleep yet.
   3237                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
   3238                         + mStoppingActivities.size() + " activities");
   3239                 scheduleIdleLocked();
   3240                 dontSleep = true;
   3241             }
   3242 
   3243             if (mGoingToSleepActivities.size() > 0) {
   3244                 // Still need to tell some activities to sleep; can't sleep yet.
   3245                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
   3246                         + mGoingToSleepActivities.size() + " activities");
   3247                 dontSleep = true;
   3248             }
   3249 
   3250             if (dontSleep) {
   3251                 return;
   3252             }
   3253         }
   3254 
   3255         // Send launch end powerhint before going sleep
   3256         mService.mActivityStarter.sendPowerHintForLaunchEndIfNeeded();
   3257 
   3258         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3259             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3260             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3261                 stacks.get(stackNdx).goToSleep();
   3262             }
   3263         }
   3264 
   3265         removeSleepTimeouts();
   3266 
   3267         if (mGoingToSleep.isHeld()) {
   3268             mGoingToSleep.release();
   3269         }
   3270         if (mService.mShuttingDown) {
   3271             mService.notifyAll();
   3272         }
   3273     }
   3274 
   3275     boolean reportResumedActivityLocked(ActivityRecord r) {
   3276         final ActivityStack stack = r.getStack();
   3277         if (isFocusedStack(stack)) {
   3278             mService.updateUsageStats(r, true);
   3279         }
   3280         if (allResumedActivitiesComplete()) {
   3281             ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   3282             mWindowManager.executeAppTransition();
   3283             return true;
   3284         }
   3285         return false;
   3286     }
   3287 
   3288     void handleAppCrashLocked(ProcessRecord app) {
   3289         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3290             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3291             int stackNdx = stacks.size() - 1;
   3292             while (stackNdx >= 0) {
   3293                 stacks.get(stackNdx).handleAppCrashLocked(app);
   3294                 stackNdx--;
   3295             }
   3296         }
   3297     }
   3298 
   3299     boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
   3300         final ActivityStack stack = r.getStack();
   3301         if (stack == null) {
   3302             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   3303                     "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
   3304             return false;
   3305         }
   3306 
   3307         if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) {
   3308             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r
   3309                     + " visible=" + visible + " stackId=" + stack.mStackId
   3310                     + " can't contain visible behind activities");
   3311             return false;
   3312         }
   3313 
   3314         final boolean isVisible = stack.hasVisibleBehindActivity();
   3315         if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   3316                 "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
   3317 
   3318         final ActivityRecord top = topRunningActivityLocked();
   3319         if (top == null || top == r || (visible == isVisible)) {
   3320             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
   3321             stack.setVisibleBehindActivity(visible ? r : null);
   3322             return true;
   3323         }
   3324 
   3325         // A non-top activity is reporting a visibility change.
   3326         if (visible && top.fullscreen) {
   3327             // Let the caller know that it can't be seen.
   3328             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   3329                     "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
   3330                     + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
   3331                     + top.app.thread);
   3332             return false;
   3333         } else if (!visible && stack.getVisibleBehindActivity() != r) {
   3334             // Only the activity set as currently visible behind should actively reset its
   3335             // visible behind state.
   3336             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   3337                     "requestVisibleBehind: returning visible=" + visible
   3338                     + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
   3339                     + " r=" + r);
   3340             return false;
   3341         }
   3342 
   3343         stack.setVisibleBehindActivity(visible ? r : null);
   3344         if (!visible) {
   3345             // If there is a translucent home activity, we need to force it stop being translucent,
   3346             // because we can't depend on the application to necessarily perform that operation.
   3347             // Check out b/14469711 for details.
   3348             final ActivityRecord next = stack.findNextTranslucentActivity(r);
   3349             if (next != null && next.isHomeActivity()) {
   3350                 mService.convertFromTranslucent(next.appToken);
   3351             }
   3352         }
   3353         if (top.app != null && top.app.thread != null) {
   3354             // Notify the top app of the change.
   3355             try {
   3356                 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
   3357             } catch (RemoteException e) {
   3358             }
   3359         }
   3360         return true;
   3361     }
   3362 
   3363     // Called when WindowManager has finished animating the launchingBehind activity to the back.
   3364     private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
   3365         final TaskRecord task = r.getTask();
   3366         final ActivityStack stack = task.getStack();
   3367 
   3368         r.mLaunchTaskBehind = false;
   3369         task.setLastThumbnailLocked(r.screenshotActivityLocked());
   3370         mRecentTasks.addLocked(task);
   3371         mService.mTaskChangeNotificationController.notifyTaskStackChanged();
   3372         r.setVisibility(false);
   3373 
   3374         // When launching tasks behind, update the last active time of the top task after the new
   3375         // task has been shown briefly
   3376         final ActivityRecord top = stack.topActivity();
   3377         if (top != null) {
   3378             top.getTask().touchActiveTime();
   3379         }
   3380     }
   3381 
   3382     void scheduleLaunchTaskBehindComplete(IBinder token) {
   3383         mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
   3384     }
   3385 
   3386     void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
   3387             boolean preserveWindows) {
   3388         mKeyguardController.beginActivityVisibilityUpdate();
   3389         try {
   3390             // First the front stacks. In case any are not fullscreen and are in front of home.
   3391             for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3392                 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3393                 final int topStackNdx = stacks.size() - 1;
   3394                 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
   3395                     final ActivityStack stack = stacks.get(stackNdx);
   3396                     stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
   3397                 }
   3398             }
   3399         } finally {
   3400             mKeyguardController.endActivityVisibilityUpdate();
   3401         }
   3402     }
   3403 
   3404     void addStartingWindowsForVisibleActivities(boolean taskSwitch) {
   3405         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3406             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3407             final int topStackNdx = stacks.size() - 1;
   3408             for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
   3409                 final ActivityStack stack = stacks.get(stackNdx);
   3410                 stack.addStartingWindowsForVisibleActivities(taskSwitch);
   3411             }
   3412         }
   3413     }
   3414 
   3415     void invalidateTaskLayers() {
   3416         mTaskLayersChanged = true;
   3417     }
   3418 
   3419     void rankTaskLayersIfNeeded() {
   3420         if (!mTaskLayersChanged) {
   3421             return;
   3422         }
   3423         mTaskLayersChanged = false;
   3424         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) {
   3425             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3426             int baseLayer = 0;
   3427             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3428                 baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer);
   3429             }
   3430         }
   3431     }
   3432 
   3433     void clearOtherAppTimeTrackers(AppTimeTracker except) {
   3434         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3435             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3436             final int topStackNdx = stacks.size() - 1;
   3437             for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
   3438                 final ActivityStack stack = stacks.get(stackNdx);
   3439                 stack.clearOtherAppTimeTrackers(except);
   3440             }
   3441         }
   3442     }
   3443 
   3444     void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
   3445         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3446             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3447             final int numStacks = stacks.size();
   3448             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   3449                 final ActivityStack stack = stacks.get(stackNdx);
   3450                 stack.scheduleDestroyActivities(app, reason);
   3451             }
   3452         }
   3453     }
   3454 
   3455     void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
   3456         // Examine all activities currently running in the process.
   3457         TaskRecord firstTask = null;
   3458         // Tasks is non-null only if two or more tasks are found.
   3459         ArraySet<TaskRecord> tasks = null;
   3460         if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
   3461         for (int i = 0; i < app.activities.size(); i++) {
   3462             ActivityRecord r = app.activities.get(i);
   3463             // First, if we find an activity that is in the process of being destroyed,
   3464             // then we just aren't going to do anything for now; we want things to settle
   3465             // down before we try to prune more activities.
   3466             if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
   3467                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
   3468                 return;
   3469             }
   3470             // Don't consider any activies that are currently not in a state where they
   3471             // can be destroyed.
   3472             if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
   3473                     || r.state == PAUSED || r.state == STOPPING) {
   3474                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
   3475                 continue;
   3476             }
   3477 
   3478             final TaskRecord task = r.getTask();
   3479             if (task != null) {
   3480                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task
   3481                         + " from " + r);
   3482                 if (firstTask == null) {
   3483                     firstTask = task;
   3484                 } else if (firstTask != task) {
   3485                     if (tasks == null) {
   3486                         tasks = new ArraySet<>();
   3487                         tasks.add(firstTask);
   3488                     }
   3489                     tasks.add(task);
   3490                 }
   3491             }
   3492         }
   3493         if (tasks == null) {
   3494             if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
   3495             return;
   3496         }
   3497         // If we have activities in multiple tasks that are in a position to be destroyed,
   3498         // let's iterate through the tasks and release the oldest one.
   3499         final int numDisplays = mActivityDisplays.size();
   3500         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
   3501             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3502             // Step through all stacks starting from behind, to hit the oldest things first.
   3503             for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
   3504                 final ActivityStack stack = stacks.get(stackNdx);
   3505                 // Try to release activities in this stack; if we manage to, we are done.
   3506                 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
   3507                     return;
   3508                 }
   3509             }
   3510         }
   3511     }
   3512 
   3513     boolean switchUserLocked(int userId, UserState uss) {
   3514         final int focusStackId = mFocusedStack.getStackId();
   3515         // We dismiss the docked stack whenever we switch users.
   3516         moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, focusStackId == DOCKED_STACK_ID);
   3517         // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
   3518         // also cause all tasks to be moved to the fullscreen stack at a position that is
   3519         // appropriate.
   3520         removeStackLocked(PINNED_STACK_ID);
   3521 
   3522         mUserStackInFront.put(mCurrentUser, focusStackId);
   3523         final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
   3524         mCurrentUser = userId;
   3525 
   3526         mStartingUsers.add(uss);
   3527         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3528             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3529             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3530                 final ActivityStack stack = stacks.get(stackNdx);
   3531                 stack.switchUserLocked(userId);
   3532                 TaskRecord task = stack.topTask();
   3533                 if (task != null) {
   3534                     stack.positionChildWindowContainerAtTop(task);
   3535                 }
   3536             }
   3537         }
   3538 
   3539         ActivityStack stack = getStack(restoreStackId);
   3540         if (stack == null) {
   3541             stack = mHomeStack;
   3542         }
   3543         final boolean homeInFront = stack.isHomeStack();
   3544         if (stack.isOnHomeDisplay()) {
   3545             stack.moveToFront("switchUserOnHomeDisplay");
   3546         } else {
   3547             // Stack was moved to another display while user was swapped out.
   3548             resumeHomeStackTask(null, "switchUserOnOtherDisplay");
   3549         }
   3550         return homeInFront;
   3551     }
   3552 
   3553     /** Checks whether the userid is a profile of the current user. */
   3554     boolean isCurrentProfileLocked(int userId) {
   3555         if (userId == mCurrentUser) return true;
   3556         return mService.mUserController.isCurrentProfileLocked(userId);
   3557     }
   3558 
   3559     /**
   3560      * Returns whether a stopping activity is present that should be stopped after visible, rather
   3561      * than idle.
   3562      * @return {@code true} if such activity is present. {@code false} otherwise.
   3563      */
   3564     boolean isStoppingNoHistoryActivity() {
   3565         // Activities that are marked as nohistory should be stopped immediately after the resumed
   3566         // activity has become visible.
   3567         for (ActivityRecord record : mStoppingActivities) {
   3568             if (record.isNoHistory()) {
   3569                 return true;
   3570             }
   3571         }
   3572 
   3573         return false;
   3574     }
   3575 
   3576     final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity,
   3577             boolean remove, boolean processPausingActivities) {
   3578         ArrayList<ActivityRecord> stops = null;
   3579 
   3580         final boolean nowVisible = allResumedActivitiesVisible();
   3581         for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
   3582             ActivityRecord s = mStoppingActivities.get(activityNdx);
   3583             boolean waitingVisible = mActivitiesWaitingForVisibleActivity.contains(s);
   3584             if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
   3585                     + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
   3586             if (waitingVisible && nowVisible) {
   3587                 mActivitiesWaitingForVisibleActivity.remove(s);
   3588                 waitingVisible = false;
   3589                 if (s.finishing) {
   3590                     // If this activity is finishing, it is sitting on top of
   3591                     // everyone else but we now know it is no longer needed...
   3592                     // so get rid of it.  Otherwise, we need to go through the
   3593                     // normal flow and hide it once we determine that it is
   3594                     // hidden by the activities in front of it.
   3595                     if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
   3596                     s.setVisibility(false);
   3597                 }
   3598             }
   3599             if ((!waitingVisible || mService.isSleepingOrShuttingDownLocked()) && remove) {
   3600                 if (!processPausingActivities && s.state == PAUSING) {
   3601                     // Defer processing pausing activities in this iteration and reschedule
   3602                     // a delayed idle to reprocess it again
   3603                     removeTimeoutsForActivityLocked(idleActivity);
   3604                     scheduleIdleTimeoutLocked(idleActivity);
   3605                     continue;
   3606                 }
   3607 
   3608                 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
   3609                 if (stops == null) {
   3610                     stops = new ArrayList<>();
   3611                 }
   3612                 stops.add(s);
   3613                 mStoppingActivities.remove(activityNdx);
   3614             }
   3615         }
   3616 
   3617         return stops;
   3618     }
   3619 
   3620     void validateTopActivitiesLocked() {
   3621         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3622             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3623             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3624                 final ActivityStack stack = stacks.get(stackNdx);
   3625                 final ActivityRecord r = stack.topRunningActivityLocked();
   3626                 final ActivityState state = r == null ? DESTROYED : r.state;
   3627                 if (isFocusedStack(stack)) {
   3628                     if (r == null) Slog.e(TAG,
   3629                             "validateTop...: null top activity, stack=" + stack);
   3630                     else {
   3631                         final ActivityRecord pausing = stack.mPausingActivity;
   3632                         if (pausing != null && pausing == r) Slog.e(TAG,
   3633                                 "validateTop...: top stack has pausing activity r=" + r
   3634                                 + " state=" + state);
   3635                         if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
   3636                                 "validateTop...: activity in front not resumed r=" + r
   3637                                 + " state=" + state);
   3638                     }
   3639                 } else {
   3640                     final ActivityRecord resumed = stack.mResumedActivity;
   3641                     if (resumed != null && resumed == r) Slog.e(TAG,
   3642                             "validateTop...: back stack has resumed activity r=" + r
   3643                             + " state=" + state);
   3644                     if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
   3645                             "validateTop...: activity in back resumed r=" + r + " state=" + state);
   3646                 }
   3647             }
   3648         }
   3649     }
   3650 
   3651     private String lockTaskModeToString() {
   3652         switch (mLockTaskModeState) {
   3653             case LOCK_TASK_MODE_LOCKED:
   3654                 return "LOCKED";
   3655             case LOCK_TASK_MODE_PINNED:
   3656                 return "PINNED";
   3657             case LOCK_TASK_MODE_NONE:
   3658                 return "NONE";
   3659             default: return "unknown=" + mLockTaskModeState;
   3660         }
   3661     }
   3662 
   3663     public void dump(PrintWriter pw, String prefix) {
   3664         pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
   3665                 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
   3666         pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
   3667         pw.print(prefix);
   3668         pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
   3669         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
   3670         pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
   3671         pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
   3672         final SparseArray<String[]> packages = mService.mLockTaskPackages;
   3673         if (packages.size() > 0) {
   3674             pw.print(prefix); pw.println("mLockTaskPackages (userId:packages)=");
   3675             for (int i = 0; i < packages.size(); ++i) {
   3676                 pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
   3677                 pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
   3678             }
   3679         }
   3680         if (!mWaitingForActivityVisible.isEmpty()) {
   3681             pw.print(prefix); pw.println("mWaitingForActivityVisible=");
   3682             for (int i = 0; i < mWaitingForActivityVisible.size(); ++i) {
   3683                 pw.print(prefix); pw.print(prefix); mWaitingForActivityVisible.get(i).dump(pw, prefix);
   3684             }
   3685         }
   3686 
   3687         pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
   3688         mKeyguardController.dump(pw, prefix);
   3689     }
   3690 
   3691     /**
   3692      * Dump all connected displays' configurations.
   3693      * @param prefix Prefix to apply to each line of the dump.
   3694      */
   3695     void dumpDisplayConfigs(PrintWriter pw, String prefix) {
   3696         pw.print(prefix); pw.println("Display override configurations:");
   3697         final int displayCount = mActivityDisplays.size();
   3698         for (int i = 0; i < displayCount; i++) {
   3699             final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(i);
   3700             pw.print(prefix); pw.print("  "); pw.print(activityDisplay.mDisplayId); pw.print(": ");
   3701                     pw.println(activityDisplay.getOverrideConfiguration());
   3702         }
   3703     }
   3704 
   3705     /**
   3706      * Dumps the activities matching the given {@param name} in the either the focused stack
   3707      * or all visible stacks if {@param dumpVisibleStacks} is true.
   3708      */
   3709     ArrayList<ActivityRecord> getDumpActivitiesLocked(String name, boolean dumpVisibleStacksOnly,
   3710             boolean dumpFocusedStackOnly) {
   3711         if (dumpFocusedStackOnly) {
   3712             return mFocusedStack.getDumpActivitiesLocked(name);
   3713         } else {
   3714             ArrayList<ActivityRecord> activities = new ArrayList<>();
   3715             int numDisplays = mActivityDisplays.size();
   3716             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
   3717                 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3718                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3719                     ActivityStack stack = stacks.get(stackNdx);
   3720                     if (!dumpVisibleStacksOnly ||
   3721                             stack.shouldBeVisible(null) == STACK_VISIBLE) {
   3722                         activities.addAll(stack.getDumpActivitiesLocked(name));
   3723                     }
   3724                 }
   3725             }
   3726             return activities;
   3727         }
   3728     }
   3729 
   3730     static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
   3731             boolean needSep, String prefix) {
   3732         if (activity != null) {
   3733             if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
   3734                 if (needSep) {
   3735                     pw.println();
   3736                 }
   3737                 pw.print(prefix);
   3738                 pw.println(activity);
   3739                 return true;
   3740             }
   3741         }
   3742         return false;
   3743     }
   3744 
   3745     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
   3746             boolean dumpClient, String dumpPackage) {
   3747         boolean printed = false;
   3748         boolean needSep = false;
   3749         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
   3750             ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
   3751             pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
   3752                     pw.println(" (activities from top to bottom):");
   3753             ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
   3754             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3755                 final ActivityStack stack = stacks.get(stackNdx);
   3756                 StringBuilder stackHeader = new StringBuilder(128);
   3757                 stackHeader.append("  Stack #");
   3758                 stackHeader.append(stack.mStackId);
   3759                 stackHeader.append(":");
   3760                 stackHeader.append("\n");
   3761                 stackHeader.append("  mFullscreen=" + stack.mFullscreen);
   3762                 stackHeader.append("\n");
   3763                 stackHeader.append("  mBounds=" + stack.mBounds);
   3764 
   3765                 final boolean printedStackHeader = stack.dumpActivitiesLocked(fd, pw, dumpAll,
   3766                         dumpClient, dumpPackage, needSep, stackHeader.toString());
   3767                 printed |= printedStackHeader;
   3768                 if (!printedStackHeader) {
   3769                     // Ensure we always dump the stack header even if there are no activities
   3770                     pw.println();
   3771                     pw.println(stackHeader);
   3772                 }
   3773 
   3774                 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
   3775                         !dumpAll, false, dumpPackage, true,
   3776                         "    Running activities (most recent first):", null);
   3777 
   3778                 needSep = printed;
   3779                 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
   3780                         "    mPausingActivity: ");
   3781                 if (pr) {
   3782                     printed = true;
   3783                     needSep = false;
   3784                 }
   3785                 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
   3786                         "    mResumedActivity: ");
   3787                 if (pr) {
   3788                     printed = true;
   3789                     needSep = false;
   3790                 }
   3791                 if (dumpAll) {
   3792                     pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
   3793                             "    mLastPausedActivity: ");
   3794                     if (pr) {
   3795                         printed = true;
   3796                         needSep = true;
   3797                     }
   3798                     printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
   3799                             needSep, "    mLastNoHistoryActivity: ");
   3800                 }
   3801                 needSep = printed;
   3802             }
   3803         }
   3804 
   3805         printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
   3806                 false, dumpPackage, true, "  Activities waiting to finish:", null);
   3807         printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
   3808                 false, dumpPackage, true, "  Activities waiting to stop:", null);
   3809         printed |= dumpHistoryList(fd, pw, mActivitiesWaitingForVisibleActivity, "  ", "Wait",
   3810                 false, !dumpAll, false, dumpPackage, true,
   3811                 "  Activities waiting for another to become visible:", null);
   3812         printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
   3813                 false, dumpPackage, true, "  Activities waiting to sleep:", null);
   3814         printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
   3815                 false, dumpPackage, true, "  Activities waiting to sleep:", null);
   3816 
   3817         return printed;
   3818     }
   3819 
   3820     static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
   3821             String prefix, String label, boolean complete, boolean brief, boolean client,
   3822             String dumpPackage, boolean needNL, String header1, String header2) {
   3823         TaskRecord lastTask = null;
   3824         String innerPrefix = null;
   3825         String[] args = null;
   3826         boolean printed = false;
   3827         for (int i=list.size()-1; i>=0; i--) {
   3828             final ActivityRecord r = list.get(i);
   3829             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   3830                 continue;
   3831             }
   3832             if (innerPrefix == null) {
   3833                 innerPrefix = prefix + "      ";
   3834                 args = new String[0];
   3835             }
   3836             printed = true;
   3837             final boolean full = !brief && (complete || !r.isInHistory());
   3838             if (needNL) {
   3839                 pw.println("");
   3840                 needNL = false;
   3841             }
   3842             if (header1 != null) {
   3843                 pw.println(header1);
   3844                 header1 = null;
   3845             }
   3846             if (header2 != null) {
   3847                 pw.println(header2);
   3848                 header2 = null;
   3849             }
   3850             if (lastTask != r.getTask()) {
   3851                 lastTask = r.getTask();
   3852                 pw.print(prefix);
   3853                 pw.print(full ? "* " : "  ");
   3854                 pw.println(lastTask);
   3855                 if (full) {
   3856                     lastTask.dump(pw, prefix + "  ");
   3857                 } else if (complete) {
   3858                     // Complete + brief == give a summary.  Isn't that obvious?!?
   3859                     if (lastTask.intent != null) {
   3860                         pw.print(prefix); pw.print("  ");
   3861                                 pw.println(lastTask.intent.toInsecureStringWithClip());
   3862                     }
   3863                 }
   3864             }
   3865             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   3866             pw.print(" #"); pw.print(i); pw.print(": ");
   3867             pw.println(r);
   3868             if (full) {
   3869                 r.dump(pw, innerPrefix);
   3870             } else if (complete) {
   3871                 // Complete + brief == give a summary.  Isn't that obvious?!?
   3872                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   3873                 if (r.app != null) {
   3874                     pw.print(innerPrefix); pw.println(r.app);
   3875                 }
   3876             }
   3877             if (client && r.app != null && r.app.thread != null) {
   3878                 // flush anything that is already in the PrintWriter since the thread is going
   3879                 // to write to the file descriptor directly
   3880                 pw.flush();
   3881                 try {
   3882                     TransferPipe tp = new TransferPipe();
   3883                     try {
   3884                         r.app.thread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args);
   3885                         // Short timeout, since blocking here can
   3886                         // deadlock with the application.
   3887                         tp.go(fd, 2000);
   3888                     } finally {
   3889                         tp.kill();
   3890                     }
   3891                 } catch (IOException e) {
   3892                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   3893                 } catch (RemoteException e) {
   3894                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   3895                 }
   3896                 needNL = true;
   3897             }
   3898         }
   3899         return printed;
   3900     }
   3901 
   3902     void scheduleIdleTimeoutLocked(ActivityRecord next) {
   3903         if (DEBUG_IDLE) Slog.d(TAG_IDLE,
   3904                 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
   3905         Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
   3906         mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
   3907     }
   3908 
   3909     final void scheduleIdleLocked() {
   3910         mHandler.sendEmptyMessage(IDLE_NOW_MSG);
   3911     }
   3912 
   3913     void removeTimeoutsForActivityLocked(ActivityRecord r) {
   3914         if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
   3915                 + Debug.getCallers(4));
   3916         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
   3917     }
   3918 
   3919     final void scheduleResumeTopActivities() {
   3920         if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
   3921             mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
   3922         }
   3923     }
   3924 
   3925     void removeSleepTimeouts() {
   3926         mSleepTimeout = false;
   3927         mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
   3928     }
   3929 
   3930     final void scheduleSleepTimeout() {
   3931         removeSleepTimeouts();
   3932         mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
   3933     }
   3934 
   3935     @Override
   3936     public void onDisplayAdded(int displayId) {
   3937         if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
   3938         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
   3939     }
   3940 
   3941     @Override
   3942     public void onDisplayRemoved(int displayId) {
   3943         if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
   3944         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
   3945     }
   3946 
   3947     @Override
   3948     public void onDisplayChanged(int displayId) {
   3949         if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
   3950         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
   3951     }
   3952 
   3953     private void handleDisplayAdded(int displayId) {
   3954         synchronized (mService) {
   3955             getActivityDisplayOrCreateLocked(displayId);
   3956         }
   3957     }
   3958 
   3959     /** Check if display with specified id is added to the list. */
   3960     boolean isDisplayAdded(int displayId) {
   3961         return getActivityDisplayOrCreateLocked(displayId) != null;
   3962     }
   3963 
   3964     /**
   3965      * Get an existing instance of {@link ActivityDisplay} or create new if there is a
   3966      * corresponding record in display manager.
   3967      */
   3968     private ActivityDisplay getActivityDisplayOrCreateLocked(int displayId) {
   3969         ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
   3970         if (activityDisplay != null) {
   3971             return activityDisplay;
   3972         }
   3973         if (mDisplayManager == null) {
   3974             // The system isn't fully initialized yet.
   3975             return null;
   3976         }
   3977         final Display display = mDisplayManager.getDisplay(displayId);
   3978         if (display == null) {
   3979             // The display is not registered in DisplayManager.
   3980             return null;
   3981         }
   3982         // The display hasn't been added to ActivityManager yet, create a new record now.
   3983         activityDisplay = new ActivityDisplay(displayId);
   3984         if (activityDisplay.mDisplay == null) {
   3985             Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
   3986             return null;
   3987         }
   3988         mActivityDisplays.put(displayId, activityDisplay);
   3989         calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
   3990         mWindowManager.onDisplayAdded(displayId);
   3991         return activityDisplay;
   3992     }
   3993 
   3994     private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
   3995         mDefaultMinSizeOfResizeableTask =
   3996                 mService.mContext.getResources().getDimensionPixelSize(
   3997                         com.android.internal.R.dimen.default_minimal_size_resizable_task);
   3998     }
   3999 
   4000     private void handleDisplayRemoved(int displayId) {
   4001         if (displayId == DEFAULT_DISPLAY) {
   4002             throw new IllegalArgumentException("Can't remove the primary display.");
   4003         }
   4004 
   4005         synchronized (mService) {
   4006             ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
   4007             if (activityDisplay != null) {
   4008                 final boolean destroyContentOnRemoval
   4009                         = activityDisplay.shouldDestroyContentOnRemove();
   4010                 final ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
   4011                 while (!stacks.isEmpty()) {
   4012                     final ActivityStack stack = stacks.get(0);
   4013                     if (destroyContentOnRemoval) {
   4014                         moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY,
   4015                                 false /* onTop */);
   4016                         stack.finishAllActivitiesLocked(true /* immediately */);
   4017                     } else {
   4018                         // Moving all tasks to fullscreen stack, because it's guaranteed to be
   4019                         // a valid launch stack for all activities. This way the task history from
   4020                         // external display will be preserved on primary after move.
   4021                         moveTasksToFullscreenStackLocked(stack.getStackId(), true /* onTop */);
   4022                     }
   4023                 }
   4024                 mActivityDisplays.remove(displayId);
   4025                 mWindowManager.onDisplayRemoved(displayId);
   4026             }
   4027         }
   4028     }
   4029 
   4030     private void handleDisplayChanged(int displayId) {
   4031         synchronized (mService) {
   4032             ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
   4033             if (activityDisplay != null) {
   4034                 // TODO: Update the bounds.
   4035             }
   4036             mWindowManager.onDisplayChanged(displayId);
   4037         }
   4038     }
   4039 
   4040     private StackInfo getStackInfoLocked(ActivityStack stack) {
   4041         final int displayId = stack.mDisplayId;
   4042         final ActivityDisplay display = mActivityDisplays.get(displayId);
   4043         StackInfo info = new StackInfo();
   4044         stack.getWindowContainerBounds(info.bounds);
   4045         info.displayId = displayId;
   4046         info.stackId = stack.mStackId;
   4047         info.userId = stack.mCurrentUser;
   4048         info.visible = stack.shouldBeVisible(null) == STACK_VISIBLE;
   4049         // A stack might be not attached to a display.
   4050         info.position = display != null
   4051                 ? display.mStacks.indexOf(stack)
   4052                 : 0;
   4053 
   4054         ArrayList<TaskRecord> tasks = stack.getAllTasks();
   4055         final int numTasks = tasks.size();
   4056         int[] taskIds = new int[numTasks];
   4057         String[] taskNames = new String[numTasks];
   4058         Rect[] taskBounds = new Rect[numTasks];
   4059         int[] taskUserIds = new int[numTasks];
   4060         for (int i = 0; i < numTasks; ++i) {
   4061             final TaskRecord task = tasks.get(i);
   4062             taskIds[i] = task.taskId;
   4063             taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
   4064                     : task.realActivity != null ? task.realActivity.flattenToString()
   4065                     : task.getTopActivity() != null ? task.getTopActivity().packageName
   4066                     : "unknown";
   4067             taskBounds[i] = new Rect();
   4068             task.getWindowContainerBounds(taskBounds[i]);
   4069             taskUserIds[i] = task.userId;
   4070         }
   4071         info.taskIds = taskIds;
   4072         info.taskNames = taskNames;
   4073         info.taskBounds = taskBounds;
   4074         info.taskUserIds = taskUserIds;
   4075 
   4076         final ActivityRecord top = stack.topRunningActivityLocked();
   4077         info.topActivity = top != null ? top.intent.getComponent() : null;
   4078         return info;
   4079     }
   4080 
   4081     StackInfo getStackInfoLocked(int stackId) {
   4082         ActivityStack stack = getStack(stackId);
   4083         if (stack != null) {
   4084             return getStackInfoLocked(stack);
   4085         }
   4086         return null;
   4087     }
   4088 
   4089     ArrayList<StackInfo> getAllStackInfosLocked() {
   4090         ArrayList<StackInfo> list = new ArrayList<>();
   4091         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
   4092             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   4093             for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
   4094                 list.add(getStackInfoLocked(stacks.get(ndx)));
   4095             }
   4096         }
   4097         return list;
   4098     }
   4099 
   4100     TaskRecord getLockedTaskLocked() {
   4101         final int top = mLockTaskModeTasks.size() - 1;
   4102         if (top >= 0) {
   4103             return mLockTaskModeTasks.get(top);
   4104         }
   4105         return null;
   4106     }
   4107 
   4108     boolean isLockedTask(TaskRecord task) {
   4109         return mLockTaskModeTasks.contains(task);
   4110     }
   4111 
   4112     boolean isLastLockedTask(TaskRecord task) {
   4113         return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
   4114     }
   4115 
   4116     void removeLockedTaskLocked(final TaskRecord task) {
   4117         if (!mLockTaskModeTasks.remove(task)) {
   4118             return;
   4119         }
   4120         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
   4121         if (mLockTaskModeTasks.isEmpty()) {
   4122             // Last one.
   4123             if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
   4124                     " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
   4125             final Message lockTaskMsg = Message.obtain();
   4126             lockTaskMsg.arg1 = task.userId;
   4127             lockTaskMsg.what = LOCK_TASK_END_MSG;
   4128             mHandler.sendMessage(lockTaskMsg);
   4129         }
   4130     }
   4131 
   4132     void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId,
   4133             int preferredDisplayId, int actualStackId) {
   4134         handleNonResizableTaskIfNeeded(task, preferredStackId, preferredDisplayId, actualStackId,
   4135                 false /* forceNonResizable */);
   4136     }
   4137 
   4138     private void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId,
   4139             int preferredDisplayId, int actualStackId, boolean forceNonResizable) {
   4140         final boolean isSecondaryDisplayPreferred =
   4141                 (preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY)
   4142                 || StackId.isDynamicStack(preferredStackId);
   4143         if (((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
   4144                 && !isSecondaryDisplayPreferred) || task.isHomeTask()) {
   4145             return;
   4146         }
   4147 
   4148         // Handle incorrect launch/move to secondary display if needed.
   4149         final boolean launchOnSecondaryDisplayFailed;
   4150         if (isSecondaryDisplayPreferred) {
   4151             final int actualDisplayId = task.getStack().mDisplayId;
   4152             if (!task.canBeLaunchedOnDisplay(actualDisplayId)) {
   4153                 // The task landed on an inappropriate display somehow, move it to the default
   4154                 // display.
   4155                 // TODO(multi-display): Find proper stack for the task on the default display.
   4156                 mService.moveTaskToStack(task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
   4157                         true /* toTop */);
   4158                 launchOnSecondaryDisplayFailed = true;
   4159             } else {
   4160                 // The task might have landed on a display different from requested.
   4161                 launchOnSecondaryDisplayFailed = actualDisplayId == DEFAULT_DISPLAY
   4162                         || (preferredDisplayId != INVALID_DISPLAY
   4163                             && preferredDisplayId != actualDisplayId);
   4164             }
   4165         } else {
   4166             // The task wasn't requested to be on a secondary display.
   4167             launchOnSecondaryDisplayFailed = false;
   4168         }
   4169 
   4170         final ActivityRecord topActivity = task.getTopActivity();
   4171         if (launchOnSecondaryDisplayFailed || !task.supportsSplitScreen() || forceNonResizable) {
   4172             if (launchOnSecondaryDisplayFailed) {
   4173                 // Display a warning toast that we tried to put a non-resizeable task on a secondary
   4174                 // display with config different from global config.
   4175                 mService.mTaskChangeNotificationController
   4176                         .notifyActivityLaunchOnSecondaryDisplayFailed();
   4177             } else {
   4178                 // Display a warning toast that we tried to put a non-dockable task in the docked
   4179                 // stack.
   4180                 mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack();
   4181             }
   4182 
   4183             // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
   4184             // we need to move it to top of fullscreen stack, otherwise it will be covered.
   4185             moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID);
   4186         } else if (topActivity != null && topActivity.isNonResizableOrForcedResizable()
   4187                 && !topActivity.noDisplay) {
   4188             final String packageName = topActivity.appInfo.packageName;
   4189             final int reason = isSecondaryDisplayPreferred
   4190                     ? FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY
   4191                     : FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
   4192             mService.mTaskChangeNotificationController.notifyActivityForcedResizable(
   4193                     task.taskId, reason, packageName);
   4194         }
   4195     }
   4196 
   4197     void showLockTaskToast() {
   4198         if (mLockTaskNotify != null) {
   4199             mLockTaskNotify.showToast(mLockTaskModeState);
   4200         }
   4201     }
   4202 
   4203     void showLockTaskEscapeMessageLocked(TaskRecord task) {
   4204         if (mLockTaskModeTasks.contains(task)) {
   4205             mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
   4206         }
   4207     }
   4208 
   4209     void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
   4210             boolean andResume) {
   4211         if (task == null) {
   4212             // Take out of lock task mode if necessary
   4213             final TaskRecord lockedTask = getLockedTaskLocked();
   4214             if (lockedTask != null) {
   4215                 removeLockedTaskLocked(lockedTask);
   4216                 if (!mLockTaskModeTasks.isEmpty()) {
   4217                     // There are locked tasks remaining, can only finish this task, not unlock it.
   4218                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
   4219                             "setLockTaskModeLocked: Tasks remaining, can't unlock");
   4220                     lockedTask.performClearTaskLocked();
   4221                     resumeFocusedStackTopActivityLocked();
   4222                     return;
   4223                 }
   4224             }
   4225             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
   4226                     "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
   4227             return;
   4228         }
   4229 
   4230         // Should have already been checked, but do it again.
   4231         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
   4232             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
   4233                     "setLockTaskModeLocked: Can't lock due to auth");
   4234             return;
   4235         }
   4236         if (isLockTaskModeViolation(task)) {
   4237             Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
   4238             return;
   4239         }
   4240 
   4241         if (mLockTaskModeTasks.isEmpty()) {
   4242             // First locktask.
   4243             final Message lockTaskMsg = Message.obtain();
   4244             lockTaskMsg.obj = task.intent.getComponent().getPackageName();
   4245             lockTaskMsg.arg1 = task.userId;
   4246             lockTaskMsg.what = LOCK_TASK_START_MSG;
   4247             lockTaskMsg.arg2 = lockTaskModeState;
   4248             mHandler.sendMessage(lockTaskMsg);
   4249         }
   4250         // Add it or move it to the top.
   4251         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
   4252                 " Callers=" + Debug.getCallers(4));
   4253         mLockTaskModeTasks.remove(task);
   4254         mLockTaskModeTasks.add(task);
   4255 
   4256         if (task.mLockTaskUid == -1) {
   4257             task.mLockTaskUid = task.effectiveUid;
   4258         }
   4259 
   4260         if (andResume) {
   4261             findTaskToMoveToFrontLocked(task, 0, null, reason,
   4262                     lockTaskModeState != LOCK_TASK_MODE_NONE);
   4263             resumeFocusedStackTopActivityLocked();
   4264             mWindowManager.executeAppTransition();
   4265         } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
   4266             handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, DEFAULT_DISPLAY,
   4267                     task.getStackId(), true /* forceNonResizable */);
   4268         }
   4269     }
   4270 
   4271     boolean isLockTaskModeViolation(TaskRecord task) {
   4272         return isLockTaskModeViolation(task, false);
   4273     }
   4274 
   4275     boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
   4276         if (getLockedTaskLocked() == task && !isNewClearTask) {
   4277             return false;
   4278         }
   4279         final int lockTaskAuth = task.mLockTaskAuth;
   4280         switch (lockTaskAuth) {
   4281             case LOCK_TASK_AUTH_DONT_LOCK:
   4282                 return !mLockTaskModeTasks.isEmpty();
   4283             case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
   4284             case LOCK_TASK_AUTH_LAUNCHABLE:
   4285             case LOCK_TASK_AUTH_WHITELISTED:
   4286                 return false;
   4287             case LOCK_TASK_AUTH_PINNABLE:
   4288                 // Pinnable tasks can't be launched on top of locktask tasks.
   4289                 return !mLockTaskModeTasks.isEmpty();
   4290             default:
   4291                 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
   4292                 return true;
   4293         }
   4294     }
   4295 
   4296     void onLockTaskPackagesUpdatedLocked() {
   4297         boolean didSomething = false;
   4298         for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
   4299             final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
   4300             final boolean wasWhitelisted =
   4301                     (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
   4302                     (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
   4303             lockedTask.setLockTaskAuth();
   4304             final boolean isWhitelisted =
   4305                     (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
   4306                     (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
   4307             if (wasWhitelisted && !isWhitelisted) {
   4308                 // Lost whitelisting authorization. End it now.
   4309                 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
   4310                         lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
   4311                 removeLockedTaskLocked(lockedTask);
   4312                 lockedTask.performClearTaskLocked();
   4313                 didSomething = true;
   4314             }
   4315         }
   4316         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   4317             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   4318             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   4319                 final ActivityStack stack = stacks.get(stackNdx);
   4320                 stack.onLockTaskPackagesUpdatedLocked();
   4321             }
   4322         }
   4323         final ActivityRecord r = topRunningActivityLocked();
   4324         final TaskRecord task = r != null ? r.getTask() : null;
   4325         if (mLockTaskModeTasks.isEmpty() && task != null
   4326                 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
   4327             // This task must have just been authorized.
   4328             if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
   4329                     "onLockTaskPackagesUpdated: starting new locktask task=" + task);
   4330             setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
   4331                     false);
   4332             didSomething = true;
   4333         }
   4334         if (didSomething) {
   4335             resumeFocusedStackTopActivityLocked();
   4336         }
   4337     }
   4338 
   4339     int getLockTaskModeState() {
   4340         return mLockTaskModeState;
   4341     }
   4342 
   4343     void activityRelaunchedLocked(IBinder token) {
   4344         mWindowManager.notifyAppRelaunchingFinished(token);
   4345         if (mService.isSleepingOrShuttingDownLocked()) {
   4346             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4347             if (r != null) {
   4348                 r.setSleeping(true, true);
   4349             }
   4350         }
   4351     }
   4352 
   4353     void activityRelaunchingLocked(ActivityRecord r) {
   4354         mWindowManager.notifyAppRelaunching(r.appToken);
   4355     }
   4356 
   4357     void logStackState() {
   4358         mActivityMetricsLogger.logWindowState();
   4359     }
   4360 
   4361     void scheduleUpdateMultiWindowMode(TaskRecord task) {
   4362         // If the stack is animating in a way where we will be forcing a multi-mode change at the
   4363         // end, then ensure that we defer all in between multi-window mode changes
   4364         if (task.getStack().deferScheduleMultiWindowModeChanged()) {
   4365             return;
   4366         }
   4367 
   4368         for (int i = task.mActivities.size() - 1; i >= 0; i--) {
   4369             final ActivityRecord r = task.mActivities.get(i);
   4370             if (r.app != null && r.app.thread != null) {
   4371                 mMultiWindowModeChangedActivities.add(r);
   4372             }
   4373         }
   4374 
   4375         if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
   4376             mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
   4377         }
   4378     }
   4379 
   4380     void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, ActivityStack prevStack) {
   4381         final ActivityStack stack = task.getStack();
   4382         if (prevStack == null || prevStack == stack
   4383                 || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
   4384             return;
   4385         }
   4386 
   4387         scheduleUpdatePictureInPictureModeIfNeeded(task, stack.mBounds, false /* immediate */);
   4388     }
   4389 
   4390     void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, Rect targetStackBounds,
   4391             boolean immediate) {
   4392 
   4393         if (immediate) {
   4394             mHandler.removeMessages(REPORT_PIP_MODE_CHANGED_MSG);
   4395             for (int i = task.mActivities.size() - 1; i >= 0; i--) {
   4396                 final ActivityRecord r = task.mActivities.get(i);
   4397                 if (r.app != null && r.app.thread != null) {
   4398                     r.updatePictureInPictureMode(targetStackBounds);
   4399                 }
   4400             }
   4401         } else {
   4402             for (int i = task.mActivities.size() - 1; i >= 0; i--) {
   4403                 final ActivityRecord r = task.mActivities.get(i);
   4404                 if (r.app != null && r.app.thread != null) {
   4405                     mPipModeChangedActivities.add(r);
   4406                 }
   4407             }
   4408             mPipModeChangedTargetStackBounds = targetStackBounds;
   4409 
   4410             if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
   4411                 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
   4412             }
   4413         }
   4414     }
   4415 
   4416     void setDockedStackMinimized(boolean minimized) {
   4417         mIsDockMinimized = minimized;
   4418     }
   4419 
   4420     private final class ActivityStackSupervisorHandler extends Handler {
   4421 
   4422         public ActivityStackSupervisorHandler(Looper looper) {
   4423             super(looper);
   4424         }
   4425 
   4426         void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
   4427             synchronized (mService) {
   4428                 activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
   4429                         processPausingActivities, null);
   4430             }
   4431         }
   4432 
   4433         @Override
   4434         public void handleMessage(Message msg) {
   4435             switch (msg.what) {
   4436                 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
   4437                     synchronized (mService) {
   4438                         for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
   4439                             final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
   4440                             r.updateMultiWindowMode();
   4441                         }
   4442                     }
   4443                 } break;
   4444                 case REPORT_PIP_MODE_CHANGED_MSG: {
   4445                     synchronized (mService) {
   4446                         for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
   4447                             final ActivityRecord r = mPipModeChangedActivities.remove(i);
   4448                             r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds);
   4449                         }
   4450                     }
   4451                 } break;
   4452                 case IDLE_TIMEOUT_MSG: {
   4453                     if (DEBUG_IDLE) Slog.d(TAG_IDLE,
   4454                             "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
   4455                     if (mService.mDidDexOpt) {
   4456                         mService.mDidDexOpt = false;
   4457                         Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
   4458                         nmsg.obj = msg.obj;
   4459                         mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
   4460                         return;
   4461                     }
   4462                     // We don't at this point know if the activity is fullscreen,
   4463                     // so we need to be conservative and assume it isn't.
   4464                     activityIdleInternal((ActivityRecord) msg.obj,
   4465                             true /* processPausingActivities */);
   4466                 } break;
   4467                 case IDLE_NOW_MSG: {
   4468                     if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
   4469                     activityIdleInternal((ActivityRecord) msg.obj,
   4470                             false /* processPausingActivities */);
   4471                 } break;
   4472                 case RESUME_TOP_ACTIVITY_MSG: {
   4473                     synchronized (mService) {
   4474                         resumeFocusedStackTopActivityLocked();
   4475                     }
   4476                 } break;
   4477                 case SLEEP_TIMEOUT_MSG: {
   4478                     synchronized (mService) {
   4479                         if (mService.isSleepingOrShuttingDownLocked()) {
   4480                             Slog.w(TAG, "Sleep timeout!  Sleeping now.");
   4481                             mSleepTimeout = true;
   4482                             checkReadyForSleepLocked();
   4483                         }
   4484                     }
   4485                 } break;
   4486                 case LAUNCH_TIMEOUT_MSG: {
   4487                     if (mService.mDidDexOpt) {
   4488                         mService.mDidDexOpt = false;
   4489                         mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
   4490                         return;
   4491                     }
   4492                     synchronized (mService) {
   4493                         if (mLaunchingActivity.isHeld()) {
   4494                             Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
   4495                             if (VALIDATE_WAKE_LOCK_CALLER
   4496                                     && Binder.getCallingUid() != Process.myUid()) {
   4497                                 throw new IllegalStateException("Calling must be system uid");
   4498                             }
   4499                             mLaunchingActivity.release();
   4500                         }
   4501                     }
   4502                 } break;
   4503                 case HANDLE_DISPLAY_ADDED: {
   4504                     handleDisplayAdded(msg.arg1);
   4505                 } break;
   4506                 case HANDLE_DISPLAY_CHANGED: {
   4507                     handleDisplayChanged(msg.arg1);
   4508                 } break;
   4509                 case HANDLE_DISPLAY_REMOVED: {
   4510                     handleDisplayRemoved(msg.arg1);
   4511                 } break;
   4512                 case CONTAINER_CALLBACK_VISIBILITY: {
   4513                     final ActivityContainer container = (ActivityContainer) msg.obj;
   4514                     final IActivityContainerCallback callback = container.mCallback;
   4515                     if (callback != null) {
   4516                         try {
   4517                             callback.setVisible(container.asBinder(), msg.arg1 == 1);
   4518                         } catch (RemoteException e) {
   4519                         }
   4520                     }
   4521                 } break;
   4522                 case LOCK_TASK_START_MSG: {
   4523                     // When lock task starts, we disable the status bars.
   4524                     try {
   4525                         if (mLockTaskNotify == null) {
   4526                             mLockTaskNotify = new LockTaskNotify(mService.mContext);
   4527                         }
   4528                         mLockTaskNotify.show(true);
   4529                         mLockTaskModeState = msg.arg2;
   4530                         if (getStatusBarService() != null) {
   4531                             int flags = 0;
   4532                             if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
   4533                                 flags = StatusBarManager.DISABLE_MASK
   4534                                         & (~StatusBarManager.DISABLE_BACK);
   4535                             } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
   4536                                 flags = StatusBarManager.DISABLE_MASK
   4537                                         & (~StatusBarManager.DISABLE_BACK)
   4538                                         & (~StatusBarManager.DISABLE_HOME)
   4539                                         & (~StatusBarManager.DISABLE_RECENT);
   4540                             }
   4541                             getStatusBarService().disable(flags, mToken,
   4542                                     mService.mContext.getPackageName());
   4543                         }
   4544                         mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
   4545                         if (getDevicePolicyManager() != null) {
   4546                             getDevicePolicyManager().notifyLockTaskModeChanged(true,
   4547                                     (String)msg.obj, msg.arg1);
   4548                         }
   4549                     } catch (RemoteException ex) {
   4550                         throw new RuntimeException(ex);
   4551                     }
   4552                 } break;
   4553                 case LOCK_TASK_END_MSG: {
   4554                     // When lock task ends, we enable the status bars.
   4555                     try {
   4556                         if (getStatusBarService() != null) {
   4557                             getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
   4558                                     mService.mContext.getPackageName());
   4559                         }
   4560                         mWindowManager.reenableKeyguard(mToken);
   4561                         if (getDevicePolicyManager() != null) {
   4562                             getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
   4563                                     msg.arg1);
   4564                         }
   4565                         if (mLockTaskNotify == null) {
   4566                             mLockTaskNotify = new LockTaskNotify(mService.mContext);
   4567                         }
   4568                         mLockTaskNotify.show(false);
   4569                         try {
   4570                             boolean shouldLockKeyguard = Settings.Secure.getInt(
   4571                                     mService.mContext.getContentResolver(),
   4572                                     Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
   4573                             if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
   4574                                 mWindowManager.lockNow(null);
   4575                                 mWindowManager.dismissKeyguard(null /* callback */);
   4576                                 new LockPatternUtils(mService.mContext)
   4577                                         .requireCredentialEntry(UserHandle.USER_ALL);
   4578                             }
   4579                         } catch (SettingNotFoundException e) {
   4580                             // No setting, don't lock.
   4581                         }
   4582                     } catch (RemoteException ex) {
   4583                         throw new RuntimeException(ex);
   4584                     } finally {
   4585                         mLockTaskModeState = LOCK_TASK_MODE_NONE;
   4586                     }
   4587                 } break;
   4588                 case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
   4589                     if (mLockTaskNotify == null) {
   4590                         mLockTaskNotify = new LockTaskNotify(mService.mContext);
   4591                     }
   4592                     mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
   4593                 } break;
   4594                 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
   4595                     final ActivityContainer container = (ActivityContainer) msg.obj;
   4596                     final IActivityContainerCallback callback = container.mCallback;
   4597                     if (callback != null) {
   4598                         try {
   4599                             callback.onAllActivitiesComplete(container.asBinder());
   4600                         } catch (RemoteException e) {
   4601                         }
   4602                     }
   4603                 } break;
   4604                 case LAUNCH_TASK_BEHIND_COMPLETE: {
   4605                     synchronized (mService) {
   4606                         ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
   4607                         if (r != null) {
   4608                             handleLaunchTaskBehindCompleteLocked(r);
   4609                         }
   4610                     }
   4611                 } break;
   4612 
   4613             }
   4614         }
   4615     }
   4616 
   4617     class ActivityContainer extends android.app.IActivityContainer.Stub {
   4618         final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK |
   4619                 FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
   4620         final int mStackId;
   4621         IActivityContainerCallback mCallback = null;
   4622         ActivityStack mStack;
   4623         ActivityRecord mParentActivity = null;
   4624         String mIdString;
   4625 
   4626         boolean mVisible = true;
   4627 
   4628         /** Display this ActivityStack is currently on. Null if not attached to a Display. */
   4629         ActivityDisplay mActivityDisplay;
   4630 
   4631         final static int CONTAINER_STATE_HAS_SURFACE = 0;
   4632         final static int CONTAINER_STATE_NO_SURFACE = 1;
   4633         final static int CONTAINER_STATE_FINISHING = 2;
   4634         int mContainerState = CONTAINER_STATE_HAS_SURFACE;
   4635 
   4636         ActivityContainer(int stackId, ActivityDisplay activityDisplay, boolean onTop) {
   4637             synchronized (mService) {
   4638                 mStackId = stackId;
   4639                 mActivityDisplay = activityDisplay;
   4640                 mIdString = "ActivtyContainer{" + mStackId + "}";
   4641 
   4642                 createStack(stackId, onTop);
   4643                 if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
   4644             }
   4645         }
   4646 
   4647         protected void createStack(int stackId, boolean onTop) {
   4648             switch (stackId) {
   4649                 case PINNED_STACK_ID:
   4650                     new PinnedActivityStack(this, mRecentTasks, onTop);
   4651                     break;
   4652                 default:
   4653                     new ActivityStack(this, mRecentTasks, onTop);
   4654                     break;
   4655             }
   4656         }
   4657 
   4658         /**
   4659          * Adds the stack to specified display. Also calls WindowManager to do the same from
   4660          * {@link ActivityStack#reparent(ActivityDisplay, boolean)}.
   4661          * @param activityDisplay The display to add the stack to.
   4662          */
   4663         void addToDisplayLocked(ActivityDisplay activityDisplay) {
   4664             if (DEBUG_STACK) Slog.d(TAG_STACK, "addToDisplayLocked: " + this
   4665                     + " to display=" + activityDisplay);
   4666             if (mActivityDisplay != null) {
   4667                 throw new IllegalStateException("ActivityContainer is already attached, " +
   4668                         "displayId=" + mActivityDisplay.mDisplayId);
   4669             }
   4670             mActivityDisplay = activityDisplay;
   4671             mStack.reparent(activityDisplay, true /* onTop */);
   4672         }
   4673 
   4674         @Override
   4675         public void addToDisplay(int displayId) {
   4676             synchronized (mService) {
   4677                 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
   4678                 if (activityDisplay == null) {
   4679                     return;
   4680                 }
   4681                 addToDisplayLocked(activityDisplay);
   4682             }
   4683         }
   4684 
   4685         @Override
   4686         public int getDisplayId() {
   4687             synchronized (mService) {
   4688                 if (mActivityDisplay != null) {
   4689                     return mActivityDisplay.mDisplayId;
   4690                 }
   4691             }
   4692             return -1;
   4693         }
   4694 
   4695         @Override
   4696         public int getStackId() {
   4697             synchronized (mService) {
   4698                 return mStackId;
   4699             }
   4700         }
   4701 
   4702         @Override
   4703         public boolean injectEvent(InputEvent event) {
   4704             final long origId = Binder.clearCallingIdentity();
   4705             try {
   4706                 synchronized (mService) {
   4707                     if (mActivityDisplay != null) {
   4708                         return mInputManagerInternal.injectInputEvent(event,
   4709                                 mActivityDisplay.mDisplayId,
   4710                                 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
   4711                     }
   4712                 }
   4713                 return false;
   4714             } finally {
   4715                 Binder.restoreCallingIdentity(origId);
   4716             }
   4717         }
   4718 
   4719         @Override
   4720         public void release() {
   4721             synchronized (mService) {
   4722                 if (mContainerState == CONTAINER_STATE_FINISHING) {
   4723                     return;
   4724                 }
   4725                 mContainerState = CONTAINER_STATE_FINISHING;
   4726 
   4727                 long origId = Binder.clearCallingIdentity();
   4728                 try {
   4729                     mStack.finishAllActivitiesLocked(false);
   4730                     mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack);
   4731                 } finally {
   4732                     Binder.restoreCallingIdentity(origId);
   4733                 }
   4734             }
   4735         }
   4736 
   4737         /**
   4738          * Remove the stack completely. Must be called only when there are no tasks left in it,
   4739          * as this method does not finish running activities.
   4740          */
   4741         void removeLocked() {
   4742             if (DEBUG_STACK) Slog.d(TAG_STACK, "removeLocked: " + this + " from display="
   4743                     + mActivityDisplay + " Callers=" + Debug.getCallers(2));
   4744             if (mActivityDisplay != null) {
   4745                 removeFromDisplayLocked();
   4746             }
   4747             mStack.remove();
   4748         }
   4749 
   4750         /**
   4751          * Remove the stack from its current {@link ActivityDisplay}, so it can be either destroyed
   4752          * completely or re-parented.
   4753          */
   4754         private void removeFromDisplayLocked() {
   4755             if (DEBUG_STACK) Slog.d(TAG_STACK, "removeFromDisplayLocked: " + this
   4756                     + " current displayId=" + mActivityDisplay.mDisplayId);
   4757 
   4758             mActivityDisplay.detachStack(mStack);
   4759             mActivityDisplay = null;
   4760         }
   4761 
   4762         /**
   4763          * Move the stack to specified display.
   4764          * @param activityDisplay Target display to move the stack to.
   4765          * @param onTop Indicates whether container should be place on top or on bottom.
   4766          */
   4767         void moveToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
   4768             if (DEBUG_STACK) Slog.d(TAG_STACK, "moveToDisplayLocked: " + this + " from display="
   4769                     + mActivityDisplay + " to display=" + activityDisplay
   4770                     + " Callers=" + Debug.getCallers(2));
   4771 
   4772             removeFromDisplayLocked();
   4773 
   4774             mActivityDisplay = activityDisplay;
   4775             mStack.reparent(activityDisplay, onTop);
   4776         }
   4777 
   4778         @Override
   4779         public final int startActivity(Intent intent) {
   4780             return mService.startActivity(intent, this);
   4781         }
   4782 
   4783         @Override
   4784         public final int startActivityIntentSender(IIntentSender intentSender)
   4785                 throws TransactionTooLargeException {
   4786             mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
   4787 
   4788             if (!(intentSender instanceof PendingIntentRecord)) {
   4789                 throw new IllegalArgumentException("Bad PendingIntent object");
   4790             }
   4791 
   4792             final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
   4793                     Binder.getCallingUid(), mCurrentUser, false,
   4794                     ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
   4795 
   4796             final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
   4797             checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
   4798                     pendingIntent.key.requestResolvedType);
   4799 
   4800             return pendingIntent.sendInner(0, null, null, null, null, null, null, null, 0,
   4801                     FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
   4802         }
   4803 
   4804         void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
   4805             ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
   4806             if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
   4807                 throw new SecurityException(
   4808                         "Attempt to embed activity that has not set allowEmbedded=\"true\"");
   4809             }
   4810         }
   4811 
   4812         @Override
   4813         public IBinder asBinder() {
   4814             return this;
   4815         }
   4816 
   4817         @Override
   4818         public void setSurface(Surface surface, int width, int height, int density) {
   4819             mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
   4820         }
   4821 
   4822         ActivityStackSupervisor getOuter() {
   4823             return ActivityStackSupervisor.this;
   4824         }
   4825 
   4826         boolean isAttachedLocked() {
   4827             return mActivityDisplay != null;
   4828         }
   4829 
   4830         // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
   4831         void setVisible(boolean visible) {
   4832             if (mVisible != visible) {
   4833                 mVisible = visible;
   4834                 if (mCallback != null) {
   4835                     mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
   4836                             0 /* unused */, this).sendToTarget();
   4837                 }
   4838             }
   4839         }
   4840 
   4841         void setDrawn() {
   4842         }
   4843 
   4844         // You can always start a new task on a regular ActivityStack.
   4845         boolean isEligibleForNewTasks() {
   4846             return true;
   4847         }
   4848 
   4849         void onTaskListEmptyLocked() {
   4850             removeLocked();
   4851             mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
   4852         }
   4853 
   4854         @Override
   4855         public String toString() {
   4856             return mIdString + (mActivityDisplay == null ? "N" : "A");
   4857         }
   4858     }
   4859 
   4860     private class VirtualActivityContainer extends ActivityContainer {
   4861         Surface mSurface;
   4862         boolean mDrawn = false;
   4863 
   4864         VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
   4865             super(getNextStackId(), parent.getStack().mActivityContainer.mActivityDisplay,
   4866                     true /* onTop */);
   4867             mParentActivity = parent;
   4868             mCallback = callback;
   4869             mContainerState = CONTAINER_STATE_NO_SURFACE;
   4870             mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
   4871         }
   4872 
   4873         @Override
   4874         public void setSurface(Surface surface, int width, int height, int density) {
   4875             super.setSurface(surface, width, height, density);
   4876 
   4877             synchronized (mService) {
   4878                 final long origId = Binder.clearCallingIdentity();
   4879                 try {
   4880                     setSurfaceLocked(surface, width, height, density);
   4881                 } finally {
   4882                     Binder.restoreCallingIdentity(origId);
   4883                 }
   4884             }
   4885         }
   4886 
   4887         private void setSurfaceLocked(Surface surface, int width, int height, int density) {
   4888             if (mContainerState == CONTAINER_STATE_FINISHING) {
   4889                 return;
   4890             }
   4891             VirtualActivityDisplay virtualActivityDisplay =
   4892                     (VirtualActivityDisplay) mActivityDisplay;
   4893             if (virtualActivityDisplay == null) {
   4894                 virtualActivityDisplay =
   4895                         new VirtualActivityDisplay(width, height, density);
   4896                 mActivityDisplay = virtualActivityDisplay;
   4897                 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
   4898                 addToDisplayLocked(virtualActivityDisplay);
   4899             }
   4900 
   4901             if (mSurface != null) {
   4902                 mSurface.release();
   4903             }
   4904 
   4905             mSurface = surface;
   4906             if (surface != null) {
   4907                 resumeFocusedStackTopActivityLocked();
   4908             } else {
   4909                 mContainerState = CONTAINER_STATE_NO_SURFACE;
   4910                 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
   4911                 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
   4912                     mStack.startPausingLocked(false, true, null, false);
   4913                 }
   4914             }
   4915 
   4916             setSurfaceIfReadyLocked();
   4917 
   4918             if (DEBUG_STACK) Slog.d(TAG_STACK,
   4919                     "setSurface: " + this + " to display=" + virtualActivityDisplay);
   4920         }
   4921 
   4922         @Override
   4923         boolean isAttachedLocked() {
   4924             return mSurface != null && super.isAttachedLocked();
   4925         }
   4926 
   4927         @Override
   4928         void setDrawn() {
   4929             synchronized (mService) {
   4930                 mDrawn = true;
   4931                 setSurfaceIfReadyLocked();
   4932             }
   4933         }
   4934 
   4935         // Never start a new task on an ActivityView if it isn't explicitly specified.
   4936         @Override
   4937         boolean isEligibleForNewTasks() {
   4938             return false;
   4939         }
   4940 
   4941         private void setSurfaceIfReadyLocked() {
   4942             if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
   4943                     " mContainerState=" + mContainerState + " mSurface=" + mSurface);
   4944             if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
   4945                 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
   4946                 mContainerState = CONTAINER_STATE_HAS_SURFACE;
   4947             }
   4948         }
   4949     }
   4950 
   4951     /** Exactly one of these classes per Display in the system. Capable of holding zero or more
   4952      * attached {@link ActivityStack}s */
   4953     class ActivityDisplay extends ConfigurationContainer {
   4954         /** Actual Display this object tracks. */
   4955         int mDisplayId;
   4956         Display mDisplay;
   4957 
   4958         /** All of the stacks on this display. Order matters, topmost stack is in front of all other
   4959          * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
   4960         final ArrayList<ActivityStack> mStacks = new ArrayList<>();
   4961 
   4962         ActivityRecord mVisibleBehindActivity;
   4963 
   4964         /** Array of all UIDs that are present on the display. */
   4965         private IntArray mDisplayAccessUIDs = new IntArray();
   4966 
   4967         ActivityDisplay() {
   4968         }
   4969 
   4970         // After instantiation, check that mDisplay is not null before using this. The alternative
   4971         // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
   4972         ActivityDisplay(int displayId) {
   4973             final Display display = mDisplayManager.getDisplay(displayId);
   4974             if (display == null) {
   4975                 return;
   4976             }
   4977             init(display);
   4978         }
   4979 
   4980         void init(Display display) {
   4981             mDisplay = display;
   4982             mDisplayId = display.getDisplayId();
   4983         }
   4984 
   4985         void attachStack(ActivityStack stack, int position) {
   4986             if (DEBUG_STACK) Slog.v(TAG_STACK, "attachStack: attaching " + stack
   4987                     + " to displayId=" + mDisplayId + " position=" + position);
   4988             mStacks.add(position, stack);
   4989         }
   4990 
   4991         void detachStack(ActivityStack stack) {
   4992             if (DEBUG_STACK) Slog.v(TAG_STACK, "detachStack: detaching " + stack
   4993                     + " from displayId=" + mDisplayId);
   4994             mStacks.remove(stack);
   4995         }
   4996 
   4997         void setVisibleBehindActivity(ActivityRecord r) {
   4998             mVisibleBehindActivity = r;
   4999         }
   5000 
   5001         boolean hasVisibleBehindActivity() {
   5002             return mVisibleBehindActivity != null;
   5003         }
   5004 
   5005         @Override
   5006         public String toString() {
   5007             return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
   5008         }
   5009 
   5010         @Override
   5011         protected int getChildCount() {
   5012             return mStacks.size();
   5013         }
   5014 
   5015         @Override
   5016         protected ConfigurationContainer getChildAt(int index) {
   5017             return mStacks.get(index);
   5018         }
   5019 
   5020         @Override
   5021         protected ConfigurationContainer getParent() {
   5022             return ActivityStackSupervisor.this;
   5023         }
   5024 
   5025         boolean isPrivate() {
   5026             return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
   5027         }
   5028 
   5029         boolean isUidPresent(int uid) {
   5030             for (ActivityStack stack : mStacks) {
   5031                 if (stack.isUidPresent(uid)) {
   5032                     return true;
   5033                 }
   5034             }
   5035             return false;
   5036         }
   5037 
   5038         /** Update and get all UIDs that are present on the display and have access to it. */
   5039         private IntArray getPresentUIDs() {
   5040             mDisplayAccessUIDs.clear();
   5041             for (ActivityStack stack : mStacks) {
   5042                 stack.getPresentUIDs(mDisplayAccessUIDs);
   5043             }
   5044             return mDisplayAccessUIDs;
   5045         }
   5046 
   5047         boolean shouldDestroyContentOnRemove() {
   5048             return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT;
   5049         }
   5050     }
   5051 
   5052     class VirtualActivityDisplay extends ActivityDisplay {
   5053         VirtualDisplay mVirtualDisplay;
   5054 
   5055         VirtualActivityDisplay(int width, int height, int density) {
   5056             DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
   5057             mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null /* projection */,
   5058                     VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null /* surface */,
   5059                     DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
   5060                     DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null /* callback */,
   5061                     null /* handler */, null /* uniqueId */);
   5062 
   5063             init(mVirtualDisplay.getDisplay());
   5064 
   5065             mWindowManager.onDisplayAdded(mDisplayId);
   5066         }
   5067 
   5068         void setSurface(Surface surface) {
   5069             if (mVirtualDisplay != null) {
   5070                 mVirtualDisplay.setSurface(surface);
   5071             }
   5072         }
   5073 
   5074         @Override
   5075         void detachStack(ActivityStack stack) {
   5076             super.detachStack(stack);
   5077             if (mVirtualDisplay != null) {
   5078                 mVirtualDisplay.release();
   5079                 mVirtualDisplay = null;
   5080             }
   5081         }
   5082 
   5083         @Override
   5084         public String toString() {
   5085             return "VirtualActivityDisplay={" + mDisplayId + "}";
   5086         }
   5087     }
   5088 
   5089     ActivityStack findStackBehind(ActivityStack stack) {
   5090         // TODO(multi-display): We are only looking for stacks on the default display.
   5091         final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
   5092         if (display == null) {
   5093             return null;
   5094         }
   5095         final ArrayList<ActivityStack> stacks = display.mStacks;
   5096         for (int i = stacks.size() - 1; i >= 0; i--) {
   5097             if (stacks.get(i) == stack && i > 0) {
   5098                 return stacks.get(i - 1);
   5099             }
   5100         }
   5101         throw new IllegalStateException("Failed to find a stack behind stack=" + stack
   5102                 + " in=" + stacks);
   5103     }
   5104 
   5105     /**
   5106      * Puts a task into resizing mode during the next app transition.
   5107      *
   5108      * @param task The task to put into resizing mode
   5109      */
   5110     private void setResizingDuringAnimation(TaskRecord task) {
   5111         mResizingTasksDuringAnimation.add(task.taskId);
   5112         task.setTaskDockedResizing(true);
   5113     }
   5114 
   5115     final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
   5116         final TaskRecord task;
   5117         final int callingUid;
   5118         final String callingPackage;
   5119         final Intent intent;
   5120         final int userId;
   5121         final ActivityOptions activityOptions = (bOptions != null)
   5122                 ? new ActivityOptions(bOptions) : null;
   5123         final int launchStackId = (activityOptions != null)
   5124                 ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
   5125         if (StackId.isHomeOrRecentsStack(launchStackId)) {
   5126             throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
   5127                     + taskId + " can't be launch in the home/recents stack.");
   5128         }
   5129 
   5130         mWindowManager.deferSurfaceLayout();
   5131         try {
   5132             if (launchStackId == DOCKED_STACK_ID) {
   5133                 mWindowManager.setDockedStackCreateState(
   5134                         activityOptions.getDockCreateMode(), null /* initialBounds */);
   5135 
   5136                 // Defer updating the stack in which recents is until the app transition is done, to
   5137                 // not run into issues where we still need to draw the task in recents but the
   5138                 // docked stack is already created.
   5139                 deferUpdateBounds(RECENTS_STACK_ID);
   5140                 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
   5141             }
   5142 
   5143             task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
   5144                     launchStackId);
   5145             if (task == null) {
   5146                 continueUpdateBounds(RECENTS_STACK_ID);
   5147                 mWindowManager.executeAppTransition();
   5148                 throw new IllegalArgumentException(
   5149                         "startActivityFromRecentsInner: Task " + taskId + " not found.");
   5150             }
   5151 
   5152             // Since we don't have an actual source record here, we assume that the currently
   5153             // focused activity was the source.
   5154             final ActivityStack focusedStack = getFocusedStack();
   5155             final ActivityRecord sourceRecord =
   5156                     focusedStack != null ? focusedStack.topActivity() : null;
   5157 
   5158             if (launchStackId != INVALID_STACK_ID) {
   5159                 if (task.getStackId() != launchStackId) {
   5160                     task.reparent(launchStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
   5161                             DEFER_RESUME, "startActivityFromRecents");
   5162                 }
   5163             }
   5164 
   5165             // If the user must confirm credentials (e.g. when first launching a work app and the
   5166             // Work Challenge is present) let startActivityInPackage handle the intercepting.
   5167             if (!mService.mUserController.shouldConfirmCredentials(task.userId)
   5168                     && task.getRootActivity() != null) {
   5169                 mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
   5170                 mActivityMetricsLogger.notifyActivityLaunching();
   5171                 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions, true /* fromRecents */);
   5172                 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
   5173                         task.getTopActivity());
   5174 
   5175                 // If we are launching the task in the docked stack, put it into resizing mode so
   5176                 // the window renders full-screen with the background filling the void. Also only
   5177                 // call this at the end to make sure that tasks exists on the window manager side.
   5178                 if (launchStackId == DOCKED_STACK_ID) {
   5179                     setResizingDuringAnimation(task);
   5180                 }
   5181 
   5182                 mService.mActivityStarter.postStartActivityProcessing(task.getTopActivity(),
   5183                         ActivityManager.START_TASK_TO_FRONT,
   5184                         sourceRecord != null
   5185                                 ? sourceRecord.getTask().getStackId() : INVALID_STACK_ID,
   5186                         sourceRecord, task.getStack());
   5187                 return ActivityManager.START_TASK_TO_FRONT;
   5188             }
   5189             callingUid = task.mCallingUid;
   5190             callingPackage = task.mCallingPackage;
   5191             intent = task.intent;
   5192             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
   5193             userId = task.userId;
   5194             int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
   5195                     null, null, 0, 0, bOptions, userId, null, task, "startActivityFromRecents");
   5196             if (launchStackId == DOCKED_STACK_ID) {
   5197                 setResizingDuringAnimation(task);
   5198             }
   5199             return result;
   5200         } finally {
   5201             mWindowManager.continueSurfaceLayout();
   5202         }
   5203     }
   5204 
   5205     /**
   5206      * @return a list of activities which are the top ones in each visible stack. The first
   5207      * entry will be the focused activity.
   5208      */
   5209     List<IBinder> getTopVisibleActivities() {
   5210         final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
   5211         // Traverse all displays.
   5212         for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
   5213             final ActivityDisplay display = mActivityDisplays.valueAt(i);
   5214             // Traverse all stacks on a display.
   5215             for (int j = display.mStacks.size() - 1; j >= 0; j--) {
   5216                 final ActivityStack stack = display.mStacks.get(j);
   5217                 // Get top activity from a visible stack and add it to the list.
   5218                 if (stack.shouldBeVisible(null /* starting */)
   5219                         == ActivityStack.STACK_VISIBLE) {
   5220                     final ActivityRecord top = stack.topActivity();
   5221                     if (top != null) {
   5222                         if (stack == mFocusedStack) {
   5223                             topActivityTokens.add(0, top.appToken);
   5224                         } else {
   5225                             topActivityTokens.add(top.appToken);
   5226                         }
   5227                     }
   5228                 }
   5229             }
   5230         }
   5231         return topActivityTokens;
   5232     }
   5233 
   5234     /**
   5235      * Internal container to store a match qualifier alongside a WaitResult.
   5236      */
   5237     static class WaitInfo {
   5238         private final ComponentName mTargetComponent;
   5239         private final WaitResult mResult;
   5240 
   5241         public WaitInfo(ComponentName targetComponent, WaitResult result) {
   5242             this.mTargetComponent = targetComponent;
   5243             this.mResult = result;
   5244         }
   5245 
   5246         public boolean matches(ComponentName targetComponent) {
   5247             return mTargetComponent == null || mTargetComponent.equals(targetComponent);
   5248         }
   5249 
   5250         public WaitResult getResult() {
   5251             return mResult;
   5252         }
   5253 
   5254         public ComponentName getComponent() {
   5255             return mTargetComponent;
   5256         }
   5257 
   5258         public void dump(PrintWriter pw, String prefix) {
   5259             pw.println(prefix + "WaitInfo:");
   5260             pw.println(prefix + "  mTargetComponent=" + mTargetComponent);
   5261             pw.println(prefix + "  mResult=");
   5262             mResult.dump(pw, prefix);
   5263         }
   5264     }
   5265 }
   5266