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