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