Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.am;
     18 
     19 import static android.Manifest.permission.START_ANY_ACTIVITY;
     20 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
     21 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
     22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
     23 import static com.android.server.am.ActivityManagerService.localLOGV;
     24 import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
     25 import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
     26 import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
     27 import static com.android.server.am.ActivityManagerService.DEBUG_RECENTS;
     28 import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
     29 import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
     30 import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
     31 import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
     32 import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
     33 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
     34 import static com.android.server.am.ActivityManagerService.TAG;
     35 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
     36 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
     37 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
     38 
     39 import android.app.Activity;
     40 import android.app.ActivityManager;
     41 import android.app.ActivityManager.StackInfo;
     42 import android.app.ActivityOptions;
     43 import android.app.AppGlobals;
     44 import android.app.IActivityContainer;
     45 import android.app.IActivityContainerCallback;
     46 import android.app.IActivityManager;
     47 import android.app.IApplicationThread;
     48 import android.app.PendingIntent;
     49 import android.app.ProfilerInfo;
     50 import android.app.ActivityManager.RunningTaskInfo;
     51 import android.app.IActivityManager.WaitResult;
     52 import android.app.ResultInfo;
     53 import android.app.StatusBarManager;
     54 import android.app.admin.IDevicePolicyManager;
     55 import android.content.ComponentName;
     56 import android.content.Context;
     57 import android.content.IIntentSender;
     58 import android.content.Intent;
     59 import android.content.IntentSender;
     60 import android.content.pm.ActivityInfo;
     61 import android.content.pm.ApplicationInfo;
     62 import android.content.pm.PackageManager;
     63 import android.content.pm.ResolveInfo;
     64 import android.content.res.Configuration;
     65 import android.graphics.Point;
     66 import android.hardware.display.DisplayManager;
     67 import android.hardware.display.DisplayManager.DisplayListener;
     68 import android.hardware.display.DisplayManagerGlobal;
     69 import android.hardware.display.VirtualDisplay;
     70 import android.hardware.input.InputManager;
     71 import android.hardware.input.InputManagerInternal;
     72 import android.os.Binder;
     73 import android.os.Bundle;
     74 import android.os.Debug;
     75 import android.os.Handler;
     76 import android.os.IBinder;
     77 import android.os.Looper;
     78 import android.os.Message;
     79 import android.os.ParcelFileDescriptor;
     80 import android.os.PowerManager;
     81 import android.os.Process;
     82 import android.os.RemoteException;
     83 import android.os.ServiceManager;
     84 import android.os.SystemClock;
     85 import android.os.UserHandle;
     86 import android.provider.Settings;
     87 import android.provider.Settings.SettingNotFoundException;
     88 import android.service.voice.IVoiceInteractionSession;
     89 import android.util.ArraySet;
     90 import android.util.EventLog;
     91 import android.util.Slog;
     92 import android.util.SparseArray;
     93 
     94 import android.util.SparseIntArray;
     95 import android.view.Display;
     96 import android.view.DisplayInfo;
     97 import android.view.InputEvent;
     98 import android.view.Surface;
     99 import com.android.internal.app.HeavyWeightSwitcherActivity;
    100 import com.android.internal.app.IVoiceInteractor;
    101 import com.android.internal.content.ReferrerIntent;
    102 import com.android.internal.os.TransferPipe;
    103 import com.android.internal.statusbar.IStatusBarService;
    104 import com.android.internal.widget.LockPatternUtils;
    105 import com.android.server.LocalServices;
    106 import com.android.server.am.ActivityStack.ActivityState;
    107 import com.android.server.wm.WindowManagerService;
    108 
    109 
    110 import java.io.FileDescriptor;
    111 import java.io.IOException;
    112 import java.io.PrintWriter;
    113 import java.util.ArrayList;
    114 import java.util.List;
    115 
    116 public final class ActivityStackSupervisor implements DisplayListener {
    117     static final boolean DEBUG = ActivityManagerService.DEBUG || false;
    118     static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
    119     static final boolean DEBUG_APP = DEBUG || false;
    120     static final boolean DEBUG_CONTAINERS = DEBUG || false;
    121     static final boolean DEBUG_IDLE = DEBUG || false;
    122     static final boolean DEBUG_RELEASE = DEBUG || false;
    123     static final boolean DEBUG_SAVED_STATE = DEBUG || false;
    124     static final boolean DEBUG_SCREENSHOTS = DEBUG || false;
    125     static final boolean DEBUG_STATES = DEBUG || false;
    126     static final boolean DEBUG_VISIBLE_BEHIND = DEBUG || false;
    127 
    128     public static final int HOME_STACK_ID = 0;
    129 
    130     /** How long we wait until giving up on the last activity telling us it is idle. */
    131     static final int IDLE_TIMEOUT = 10*1000;
    132 
    133     /** How long we can hold the sleep wake lock before giving up. */
    134     static final int SLEEP_TIMEOUT = 5*1000;
    135 
    136     // How long we can hold the launch wake lock before giving up.
    137     static final int LAUNCH_TIMEOUT = 10*1000;
    138 
    139     static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
    140     static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
    141     static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
    142     static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
    143     static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
    144     static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
    145     static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
    146     static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
    147     static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
    148     static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
    149     static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
    150     static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
    151     static final int CONTAINER_TASK_LIST_EMPTY_TIMEOUT = FIRST_SUPERVISOR_STACK_MSG + 12;
    152     static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 13;
    153 
    154     private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
    155 
    156     private static final String LOCK_TASK_TAG = "Lock-to-App";
    157 
    158     /** Status Bar Service **/
    159     private IBinder mToken = new Binder();
    160     private IStatusBarService mStatusBarService;
    161     private IDevicePolicyManager mDevicePolicyManager;
    162 
    163     // For debugging to make sure the caller when acquiring/releasing our
    164     // wake lock is the system process.
    165     static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
    166 
    167     final ActivityManagerService mService;
    168 
    169     final ActivityStackSupervisorHandler mHandler;
    170 
    171     /** Short cut */
    172     WindowManagerService mWindowManager;
    173     DisplayManager mDisplayManager;
    174 
    175     /** Identifier counter for all ActivityStacks */
    176     private int mLastStackId = HOME_STACK_ID;
    177 
    178     /** Task identifier that activities are currently being started in.  Incremented each time a
    179      * new task is created. */
    180     private int mCurTaskId = 0;
    181 
    182     /** The current user */
    183     private int mCurrentUser;
    184 
    185     /** The stack containing the launcher app. Assumed to always be attached to
    186      * Display.DEFAULT_DISPLAY. */
    187     private ActivityStack mHomeStack;
    188 
    189     /** The stack currently receiving input or launching the next activity. */
    190     private ActivityStack mFocusedStack;
    191 
    192     /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
    193      * been resumed. If stacks are changing position this will hold the old stack until the new
    194      * stack becomes resumed after which it will be set to mFocusedStack. */
    195     private ActivityStack mLastFocusedStack;
    196 
    197     /** List of activities that are waiting for a new activity to become visible before completing
    198      * whatever operation they are supposed to do. */
    199     final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
    200 
    201     /** List of processes waiting to find out about the next visible activity. */
    202     final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
    203             new ArrayList<IActivityManager.WaitResult>();
    204 
    205     /** List of processes waiting to find out about the next launched activity. */
    206     final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
    207             new ArrayList<IActivityManager.WaitResult>();
    208 
    209     /** List of activities that are ready to be stopped, but waiting for the next activity to
    210      * settle down before doing so. */
    211     final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
    212 
    213     /** List of activities that are ready to be finished, but waiting for the previous activity to
    214      * settle down before doing so.  It contains ActivityRecord objects. */
    215     final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
    216 
    217     /** List of activities that are in the process of going to sleep. */
    218     final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
    219 
    220     /** Used on user changes */
    221     final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
    222 
    223     /** Used to queue up any background users being started */
    224     final ArrayList<UserStartedState> mStartingBackgroundUsers = new ArrayList<UserStartedState>();
    225 
    226     /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
    227      * is being brought in front of us. */
    228     boolean mUserLeaving = false;
    229 
    230     /** Set when we have taken too long waiting to go to sleep. */
    231     boolean mSleepTimeout = false;
    232 
    233     /** Indicates if we are running on a Leanback-only (TV) device. Only initialized after
    234      * setWindowManager is called. **/
    235     private boolean mLeanbackOnlyDevice;
    236 
    237     /**
    238      * We don't want to allow the device to go to sleep while in the process
    239      * of launching an activity.  This is primarily to allow alarm intent
    240      * receivers to launch an activity and get that to run before the device
    241      * goes back to sleep.
    242      */
    243     PowerManager.WakeLock mLaunchingActivity;
    244 
    245     /**
    246      * Set when the system is going to sleep, until we have
    247      * successfully paused the current activity and released our wake lock.
    248      * At that point the system is allowed to actually sleep.
    249      */
    250     PowerManager.WakeLock mGoingToSleep;
    251 
    252     /** Stack id of the front stack when user switched, indexed by userId. */
    253     SparseIntArray mUserStackInFront = new SparseIntArray(2);
    254 
    255     // TODO: Add listener for removal of references.
    256     /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
    257     private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
    258 
    259     /** Mapping from displayId to display current state */
    260     private final SparseArray<ActivityDisplay> mActivityDisplays =
    261             new SparseArray<ActivityDisplay>();
    262 
    263     InputManagerInternal mInputManagerInternal;
    264 
    265     /** If non-null then the task specified remains in front and no other tasks may be started
    266      * until the task exits or #stopLockTaskMode() is called. */
    267     TaskRecord mLockTaskModeTask;
    268     /** Whether lock task has been entered by an authorized app and cannot
    269      * be exited. */
    270     private boolean mLockTaskIsLocked;
    271     /**
    272      * Notifies the user when entering/exiting lock-task.
    273      */
    274     private LockTaskNotify mLockTaskNotify;
    275 
    276     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    277             = new ArrayList<PendingActivityLaunch>();
    278 
    279     /** Used to keep resumeTopActivityLocked() from being entered recursively */
    280     boolean inResumeTopActivity;
    281 
    282     /**
    283      * Description of a request to start a new activity, which has been held
    284      * due to app switches being disabled.
    285      */
    286     static class PendingActivityLaunch {
    287         final ActivityRecord r;
    288         final ActivityRecord sourceRecord;
    289         final int startFlags;
    290         final ActivityStack stack;
    291 
    292         PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
    293                 int _startFlags, ActivityStack _stack) {
    294             r = _r;
    295             sourceRecord = _sourceRecord;
    296             startFlags = _startFlags;
    297             stack = _stack;
    298         }
    299     }
    300 
    301     public ActivityStackSupervisor(ActivityManagerService service) {
    302         mService = service;
    303         mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
    304     }
    305 
    306     /**
    307      * At the time when the constructor runs, the power manager has not yet been
    308      * initialized.  So we initialize our wakelocks afterwards.
    309      */
    310     void initPowerManagement() {
    311         PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
    312         mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
    313         mLaunchingActivity =
    314                 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
    315         mLaunchingActivity.setReferenceCounted(false);
    316     }
    317 
    318     // This function returns a IStatusBarService. The value is from ServiceManager.
    319     // getService and is cached.
    320     private IStatusBarService getStatusBarService() {
    321         synchronized (mService) {
    322             if (mStatusBarService == null) {
    323                 mStatusBarService = IStatusBarService.Stub.asInterface(
    324                     ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
    325                 if (mStatusBarService == null) {
    326                     Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
    327                 }
    328             }
    329             return mStatusBarService;
    330         }
    331     }
    332 
    333     private IDevicePolicyManager getDevicePolicyManager() {
    334         synchronized (mService) {
    335             if (mDevicePolicyManager == null) {
    336                 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
    337                     ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE));
    338                 if (mDevicePolicyManager == null) {
    339                     Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
    340                 }
    341             }
    342             return mDevicePolicyManager;
    343         }
    344     }
    345 
    346     void setWindowManager(WindowManagerService wm) {
    347         synchronized (mService) {
    348             mWindowManager = wm;
    349 
    350             mDisplayManager =
    351                     (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
    352             mDisplayManager.registerDisplayListener(this, null);
    353 
    354             Display[] displays = mDisplayManager.getDisplays();
    355             for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
    356                 final int displayId = displays[displayNdx].getDisplayId();
    357                 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
    358                 if (activityDisplay.mDisplay == null) {
    359                     throw new IllegalStateException("Default Display does not exist");
    360                 }
    361                 mActivityDisplays.put(displayId, activityDisplay);
    362             }
    363 
    364             createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
    365             mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
    366 
    367             mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
    368 
    369             // Initialize this here, now that we can get a valid reference to PackageManager.
    370             mLeanbackOnlyDevice = isLeanbackOnlyDevice();
    371         }
    372     }
    373 
    374     void notifyActivityDrawnForKeyguard() {
    375         if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
    376         mWindowManager.notifyActivityDrawnForKeyguard();
    377     }
    378 
    379     ActivityStack getFocusedStack() {
    380         return mFocusedStack;
    381     }
    382 
    383     ActivityStack getLastStack() {
    384         return mLastFocusedStack;
    385     }
    386 
    387     // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
    388     // top of all visible stacks.
    389     boolean isFrontStack(ActivityStack stack) {
    390         final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
    391         if (parent != null) {
    392             stack = parent.task.stack;
    393         }
    394         ArrayList<ActivityStack> stacks = stack.mStacks;
    395         if (stacks != null && !stacks.isEmpty()) {
    396             return stack == stacks.get(stacks.size() - 1);
    397         }
    398         return false;
    399     }
    400 
    401     void moveHomeStack(boolean toFront, String reason) {
    402         ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
    403         final int topNdx = stacks.size() - 1;
    404         if (topNdx <= 0) {
    405             return;
    406         }
    407         ActivityStack topStack = stacks.get(topNdx);
    408         final boolean homeInFront = topStack == mHomeStack;
    409         if (homeInFront != toFront) {
    410             mLastFocusedStack = topStack;
    411             stacks.remove(mHomeStack);
    412             stacks.add(toFront ? topNdx : 0, mHomeStack);
    413             mFocusedStack = stacks.get(topNdx);
    414             if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
    415                     + mFocusedStack);
    416         }
    417         EventLog.writeEvent(EventLogTags.AM_HOME_STACK_MOVED,
    418                 mCurrentUser, toFront ? 1 : 0, stacks.get(topNdx).getStackId(),
    419                 mFocusedStack == null ? -1 : mFocusedStack.getStackId(), reason);
    420 
    421         if (mService.mBooting || !mService.mBooted) {
    422             final ActivityRecord r = topRunningActivityLocked();
    423             if (r != null && r.idle) {
    424                 checkFinishBootingLocked();
    425             }
    426         }
    427     }
    428 
    429     void moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
    430         if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
    431             mWindowManager.showRecentApps();
    432             return;
    433         }
    434         moveHomeStack(true, reason);
    435         mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
    436     }
    437 
    438     boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
    439         if (!mService.mBooting && !mService.mBooted) {
    440             // Not ready yet!
    441             return false;
    442         }
    443 
    444         if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
    445             mWindowManager.showRecentApps();
    446             return false;
    447         }
    448         moveHomeStackTaskToTop(homeStackTaskType, reason);
    449         if (prev != null) {
    450             prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
    451         }
    452 
    453         ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
    454         // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
    455         if (r != null && r.isHomeActivity()) {
    456             mService.setFocusedActivityLocked(r, reason);
    457             return resumeTopActivitiesLocked(mHomeStack, prev, null);
    458         }
    459         return mService.startHomeActivityLocked(mCurrentUser, reason);
    460     }
    461 
    462     TaskRecord anyTaskForIdLocked(int id) {
    463         int numDisplays = mActivityDisplays.size();
    464         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
    465             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    466             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    467                 ActivityStack stack = stacks.get(stackNdx);
    468                 TaskRecord task = stack.taskForIdLocked(id);
    469                 if (task != null) {
    470                     return task;
    471                 }
    472             }
    473         }
    474 
    475         // Don't give up! Look in recents.
    476         if (DEBUG_RECENTS) Slog.v(TAG, "Looking for task id=" + id + " in recents");
    477         TaskRecord task = mService.recentTaskForIdLocked(id);
    478         if (task == null) {
    479             if (DEBUG_RECENTS) Slog.d(TAG, "\tDidn't find task id=" + id + " in recents");
    480             return null;
    481         }
    482 
    483         if (!restoreRecentTaskLocked(task)) {
    484             if (DEBUG_RECENTS) Slog.w(TAG, "Couldn't restore task id=" + id + " found in recents");
    485             return null;
    486         }
    487         if (DEBUG_RECENTS) Slog.w(TAG, "Restored task id=" + id + " from in recents");
    488         return task;
    489     }
    490 
    491     ActivityRecord isInAnyStackLocked(IBinder token) {
    492         int numDisplays = mActivityDisplays.size();
    493         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
    494             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    495             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    496                 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
    497                 if (r != null) {
    498                     return r;
    499                 }
    500             }
    501         }
    502         return null;
    503     }
    504 
    505     void setNextTaskId(int taskId) {
    506         if (taskId > mCurTaskId) {
    507             mCurTaskId = taskId;
    508         }
    509     }
    510 
    511     int getNextTaskId() {
    512         do {
    513             mCurTaskId++;
    514             if (mCurTaskId <= 0) {
    515                 mCurTaskId = 1;
    516             }
    517         } while (anyTaskForIdLocked(mCurTaskId) != null);
    518         return mCurTaskId;
    519     }
    520 
    521     ActivityRecord resumedAppLocked() {
    522         ActivityStack stack = getFocusedStack();
    523         if (stack == null) {
    524             return null;
    525         }
    526         ActivityRecord resumedActivity = stack.mResumedActivity;
    527         if (resumedActivity == null || resumedActivity.app == null) {
    528             resumedActivity = stack.mPausingActivity;
    529             if (resumedActivity == null || resumedActivity.app == null) {
    530                 resumedActivity = stack.topRunningActivityLocked(null);
    531             }
    532         }
    533         return resumedActivity;
    534     }
    535 
    536     boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    537         final String processName = app.processName;
    538         boolean didSomething = false;
    539         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    540             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    541             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    542                 final ActivityStack stack = stacks.get(stackNdx);
    543                 if (!isFrontStack(stack)) {
    544                     continue;
    545                 }
    546                 ActivityRecord hr = stack.topRunningActivityLocked(null);
    547                 if (hr != null) {
    548                     if (hr.app == null && app.uid == hr.info.applicationInfo.uid
    549                             && processName.equals(hr.processName)) {
    550                         try {
    551                             if (realStartActivityLocked(hr, app, true, true)) {
    552                                 didSomething = true;
    553                             }
    554                         } catch (RemoteException e) {
    555                             Slog.w(TAG, "Exception in new application when starting activity "
    556                                   + hr.intent.getComponent().flattenToShortString(), e);
    557                             throw e;
    558                         }
    559                     }
    560                 }
    561             }
    562         }
    563         if (!didSomething) {
    564             ensureActivitiesVisibleLocked(null, 0);
    565         }
    566         return didSomething;
    567     }
    568 
    569     boolean allResumedActivitiesIdle() {
    570         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    571             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    572             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    573                 final ActivityStack stack = stacks.get(stackNdx);
    574                 if (!isFrontStack(stack) || stack.numActivities() == 0) {
    575                     continue;
    576                 }
    577                 final ActivityRecord resumedActivity = stack.mResumedActivity;
    578                 if (resumedActivity == null || !resumedActivity.idle) {
    579                     if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
    580                              + stack.mStackId + " " + resumedActivity + " not idle");
    581                     return false;
    582                 }
    583             }
    584         }
    585         return true;
    586     }
    587 
    588     boolean allResumedActivitiesComplete() {
    589         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    590             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    591             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    592                 final ActivityStack stack = stacks.get(stackNdx);
    593                 if (isFrontStack(stack)) {
    594                     final ActivityRecord r = stack.mResumedActivity;
    595                     if (r != null && r.state != ActivityState.RESUMED) {
    596                         return false;
    597                     }
    598                 }
    599             }
    600         }
    601         // TODO: Not sure if this should check if all Paused are complete too.
    602         if (DEBUG_STACK) Slog.d(TAG,
    603                 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
    604                 mLastFocusedStack + " to=" + mFocusedStack);
    605         mLastFocusedStack = mFocusedStack;
    606         return true;
    607     }
    608 
    609     boolean allResumedActivitiesVisible() {
    610         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    611             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    612             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    613                 final ActivityStack stack = stacks.get(stackNdx);
    614                 final ActivityRecord r = stack.mResumedActivity;
    615                 if (r != null && (!r.nowVisible || r.waitingVisible)) {
    616                     return false;
    617                 }
    618             }
    619         }
    620         return true;
    621     }
    622 
    623     /**
    624      * Pause all activities in either all of the stacks or just the back stacks.
    625      * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
    626      * @return true if any activity was paused as a result of this call.
    627      */
    628     boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
    629         boolean someActivityPaused = false;
    630         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    631             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    632             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    633                 final ActivityStack stack = stacks.get(stackNdx);
    634                 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
    635                     if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
    636                             " mResumedActivity=" + stack.mResumedActivity);
    637                     someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
    638                             dontWait);
    639                 }
    640             }
    641         }
    642         return someActivityPaused;
    643     }
    644 
    645     boolean allPausedActivitiesComplete() {
    646         boolean pausing = true;
    647         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    648             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    649             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    650                 final ActivityStack stack = stacks.get(stackNdx);
    651                 final ActivityRecord r = stack.mPausingActivity;
    652                 if (r != null && r.state != ActivityState.PAUSED
    653                         && r.state != ActivityState.STOPPED
    654                         && r.state != ActivityState.STOPPING) {
    655                     if (DEBUG_STATES) {
    656                         Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
    657                         pausing = false;
    658                     } else {
    659                         return false;
    660                     }
    661                 }
    662             }
    663         }
    664         return pausing;
    665     }
    666 
    667     void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
    668             boolean resuming, boolean dontWait) {
    669         // TODO: Put all stacks in supervisor and iterate through them instead.
    670         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    671             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    672             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    673                 final ActivityStack stack = stacks.get(stackNdx);
    674                 if (stack.mResumedActivity != null &&
    675                         stack.mActivityContainer.mParentActivity == parent) {
    676                     stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
    677                 }
    678             }
    679         }
    680     }
    681 
    682     void reportActivityVisibleLocked(ActivityRecord r) {
    683         sendWaitingVisibleReportLocked(r);
    684     }
    685 
    686     void sendWaitingVisibleReportLocked(ActivityRecord r) {
    687         boolean changed = false;
    688         for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
    689             WaitResult w = mWaitingActivityVisible.get(i);
    690             if (w.who == null) {
    691                 changed = true;
    692                 w.timeout = false;
    693                 if (r != null) {
    694                     w.who = new ComponentName(r.info.packageName, r.info.name);
    695                 }
    696                 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
    697                 w.thisTime = w.totalTime;
    698             }
    699         }
    700         if (changed) {
    701             mService.notifyAll();
    702         }
    703     }
    704 
    705     void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
    706             long thisTime, long totalTime) {
    707         boolean changed = false;
    708         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
    709             WaitResult w = mWaitingActivityLaunched.remove(i);
    710             if (w.who == null) {
    711                 changed = true;
    712                 w.timeout = timeout;
    713                 if (r != null) {
    714                     w.who = new ComponentName(r.info.packageName, r.info.name);
    715                 }
    716                 w.thisTime = thisTime;
    717                 w.totalTime = totalTime;
    718             }
    719         }
    720         if (changed) {
    721             mService.notifyAll();
    722         }
    723     }
    724 
    725     ActivityRecord topRunningActivityLocked() {
    726         final ActivityStack focusedStack = getFocusedStack();
    727         ActivityRecord r = focusedStack.topRunningActivityLocked(null);
    728         if (r != null) {
    729             return r;
    730         }
    731 
    732         // Return to the home stack.
    733         final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
    734         for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    735             final ActivityStack stack = stacks.get(stackNdx);
    736             if (stack != focusedStack && isFrontStack(stack)) {
    737                 r = stack.topRunningActivityLocked(null);
    738                 if (r != null) {
    739                     return r;
    740                 }
    741             }
    742         }
    743         return null;
    744     }
    745 
    746     void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) {
    747         // Gather all of the running tasks for each stack into runningTaskLists.
    748         ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
    749                 new ArrayList<ArrayList<RunningTaskInfo>>();
    750         final int numDisplays = mActivityDisplays.size();
    751         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
    752             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
    753             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
    754                 final ActivityStack stack = stacks.get(stackNdx);
    755                 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
    756                 runningTaskLists.add(stackTaskList);
    757                 stack.getTasksLocked(stackTaskList, callingUid, allowed);
    758             }
    759         }
    760 
    761         // The lists are already sorted from most recent to oldest. Just pull the most recent off
    762         // each list and add it to list. Stop when all lists are empty or maxNum reached.
    763         while (maxNum > 0) {
    764             long mostRecentActiveTime = Long.MIN_VALUE;
    765             ArrayList<RunningTaskInfo> selectedStackList = null;
    766             final int numTaskLists = runningTaskLists.size();
    767             for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
    768                 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
    769                 if (!stackTaskList.isEmpty()) {
    770                     final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
    771                     if (lastActiveTime > mostRecentActiveTime) {
    772                         mostRecentActiveTime = lastActiveTime;
    773                         selectedStackList = stackTaskList;
    774                     }
    775                 }
    776             }
    777             if (selectedStackList != null) {
    778                 list.add(selectedStackList.remove(0));
    779                 --maxNum;
    780             } else {
    781                 break;
    782             }
    783         }
    784     }
    785 
    786     ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
    787             ProfilerInfo profilerInfo, int userId) {
    788         // Collect information about the target of the Intent.
    789         ActivityInfo aInfo;
    790         try {
    791             ResolveInfo rInfo =
    792                 AppGlobals.getPackageManager().resolveIntent(
    793                         intent, resolvedType,
    794                         PackageManager.MATCH_DEFAULT_ONLY
    795                                     | ActivityManagerService.STOCK_PM_FLAGS, userId);
    796             aInfo = rInfo != null ? rInfo.activityInfo : null;
    797         } catch (RemoteException e) {
    798             aInfo = null;
    799         }
    800 
    801         if (aInfo != null) {
    802             // Store the found target back into the intent, because now that
    803             // we have it we never want to do this again.  For example, if the
    804             // user navigates back to this point in the history, we should
    805             // always restart the exact same activity.
    806             intent.setComponent(new ComponentName(
    807                     aInfo.applicationInfo.packageName, aInfo.name));
    808 
    809             // Don't debug things in the system process
    810             if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
    811                 if (!aInfo.processName.equals("system")) {
    812                     mService.setDebugApp(aInfo.processName, true, false);
    813                 }
    814             }
    815 
    816             if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
    817                 if (!aInfo.processName.equals("system")) {
    818                     mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
    819                 }
    820             }
    821 
    822             if (profilerInfo != null) {
    823                 if (!aInfo.processName.equals("system")) {
    824                     mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
    825                 }
    826             }
    827         }
    828         return aInfo;
    829     }
    830 
    831     void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
    832         moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
    833         startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null,
    834                 0, 0, 0, null, false, null, null, null);
    835     }
    836 
    837     final int startActivityMayWait(IApplicationThread caller, int callingUid,
    838             String callingPackage, Intent intent, String resolvedType,
    839             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    840             IBinder resultTo, String resultWho, int requestCode, int startFlags,
    841             ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
    842             Bundle options, int userId, IActivityContainer iContainer, TaskRecord inTask) {
    843         // Refuse possible leaked file descriptors
    844         if (intent != null && intent.hasFileDescriptors()) {
    845             throw new IllegalArgumentException("File descriptors passed in Intent");
    846         }
    847         boolean componentSpecified = intent.getComponent() != null;
    848 
    849         // Don't modify the client's object!
    850         intent = new Intent(intent);
    851 
    852         // Collect information about the target of the Intent.
    853         ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
    854                 profilerInfo, userId);
    855 
    856         ActivityContainer container = (ActivityContainer)iContainer;
    857         synchronized (mService) {
    858             final int realCallingPid = Binder.getCallingPid();
    859             final int realCallingUid = Binder.getCallingUid();
    860             int callingPid;
    861             if (callingUid >= 0) {
    862                 callingPid = -1;
    863             } else if (caller == null) {
    864                 callingPid = realCallingPid;
    865                 callingUid = realCallingUid;
    866             } else {
    867                 callingPid = callingUid = -1;
    868             }
    869 
    870             final ActivityStack stack;
    871             if (container == null || container.mStack.isOnHomeDisplay()) {
    872                 stack = getFocusedStack();
    873             } else {
    874                 stack = container.mStack;
    875             }
    876             stack.mConfigWillChange = config != null
    877                     && mService.mConfiguration.diff(config) != 0;
    878             if (DEBUG_CONFIGURATION) Slog.v(TAG,
    879                     "Starting activity when config will change = " + stack.mConfigWillChange);
    880 
    881             final long origId = Binder.clearCallingIdentity();
    882 
    883             if (aInfo != null &&
    884                     (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
    885                 // This may be a heavy-weight process!  Check to see if we already
    886                 // have another, different heavy-weight process running.
    887                 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
    888                     if (mService.mHeavyWeightProcess != null &&
    889                             (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
    890                             !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
    891                         int appCallingUid = callingUid;
    892                         if (caller != null) {
    893                             ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
    894                             if (callerApp != null) {
    895                                 appCallingUid = callerApp.info.uid;
    896                             } else {
    897                                 Slog.w(TAG, "Unable to find app for caller " + caller
    898                                       + " (pid=" + callingPid + ") when starting: "
    899                                       + intent.toString());
    900                                 ActivityOptions.abort(options);
    901                                 return ActivityManager.START_PERMISSION_DENIED;
    902                             }
    903                         }
    904 
    905                         IIntentSender target = mService.getIntentSenderLocked(
    906                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
    907                                 appCallingUid, userId, null, null, 0, new Intent[] { intent },
    908                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
    909                                 | PendingIntent.FLAG_ONE_SHOT, null);
    910 
    911                         Intent newIntent = new Intent();
    912                         if (requestCode >= 0) {
    913                             // Caller is requesting a result.
    914                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
    915                         }
    916                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
    917                                 new IntentSender(target));
    918                         if (mService.mHeavyWeightProcess.activities.size() > 0) {
    919                             ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
    920                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
    921                                     hist.packageName);
    922                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
    923                                     hist.task.taskId);
    924                         }
    925                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
    926                                 aInfo.packageName);
    927                         newIntent.setFlags(intent.getFlags());
    928                         newIntent.setClassName("android",
    929                                 HeavyWeightSwitcherActivity.class.getName());
    930                         intent = newIntent;
    931                         resolvedType = null;
    932                         caller = null;
    933                         callingUid = Binder.getCallingUid();
    934                         callingPid = Binder.getCallingPid();
    935                         componentSpecified = true;
    936                         try {
    937                             ResolveInfo rInfo =
    938                                 AppGlobals.getPackageManager().resolveIntent(
    939                                         intent, null,
    940                                         PackageManager.MATCH_DEFAULT_ONLY
    941                                         | ActivityManagerService.STOCK_PM_FLAGS, userId);
    942                             aInfo = rInfo != null ? rInfo.activityInfo : null;
    943                             aInfo = mService.getActivityInfoForUser(aInfo, userId);
    944                         } catch (RemoteException e) {
    945                             aInfo = null;
    946                         }
    947                     }
    948                 }
    949             }
    950 
    951             int res = startActivityLocked(caller, intent, resolvedType, aInfo,
    952                     voiceSession, voiceInteractor, resultTo, resultWho,
    953                     requestCode, callingPid, callingUid, callingPackage,
    954                     realCallingPid, realCallingUid, startFlags, options,
    955                     componentSpecified, null, container, inTask);
    956 
    957             Binder.restoreCallingIdentity(origId);
    958 
    959             if (stack.mConfigWillChange) {
    960                 // If the caller also wants to switch to a new configuration,
    961                 // do so now.  This allows a clean switch, as we are waiting
    962                 // for the current activity to pause (so we will not destroy
    963                 // it), and have not yet started the next activity.
    964                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
    965                         "updateConfiguration()");
    966                 stack.mConfigWillChange = false;
    967                 if (DEBUG_CONFIGURATION) Slog.v(TAG,
    968                         "Updating to new configuration after starting activity.");
    969                 mService.updateConfigurationLocked(config, null, false, false);
    970             }
    971 
    972             if (outResult != null) {
    973                 outResult.result = res;
    974                 if (res == ActivityManager.START_SUCCESS) {
    975                     mWaitingActivityLaunched.add(outResult);
    976                     do {
    977                         try {
    978                             mService.wait();
    979                         } catch (InterruptedException e) {
    980                         }
    981                     } while (!outResult.timeout && outResult.who == null);
    982                 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
    983                     ActivityRecord r = stack.topRunningActivityLocked(null);
    984                     if (r.nowVisible && r.state == ActivityState.RESUMED) {
    985                         outResult.timeout = false;
    986                         outResult.who = new ComponentName(r.info.packageName, r.info.name);
    987                         outResult.totalTime = 0;
    988                         outResult.thisTime = 0;
    989                     } else {
    990                         outResult.thisTime = SystemClock.uptimeMillis();
    991                         mWaitingActivityVisible.add(outResult);
    992                         do {
    993                             try {
    994                                 mService.wait();
    995                             } catch (InterruptedException e) {
    996                             }
    997                         } while (!outResult.timeout && outResult.who == null);
    998                     }
    999                 }
   1000             }
   1001 
   1002             return res;
   1003         }
   1004     }
   1005 
   1006     final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
   1007             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   1008             Bundle options, int userId) {
   1009         if (intents == null) {
   1010             throw new NullPointerException("intents is null");
   1011         }
   1012         if (resolvedTypes == null) {
   1013             throw new NullPointerException("resolvedTypes is null");
   1014         }
   1015         if (intents.length != resolvedTypes.length) {
   1016             throw new IllegalArgumentException("intents are length different than resolvedTypes");
   1017         }
   1018 
   1019 
   1020         int callingPid;
   1021         if (callingUid >= 0) {
   1022             callingPid = -1;
   1023         } else if (caller == null) {
   1024             callingPid = Binder.getCallingPid();
   1025             callingUid = Binder.getCallingUid();
   1026         } else {
   1027             callingPid = callingUid = -1;
   1028         }
   1029         final long origId = Binder.clearCallingIdentity();
   1030         try {
   1031             synchronized (mService) {
   1032                 ActivityRecord[] outActivity = new ActivityRecord[1];
   1033                 for (int i=0; i<intents.length; i++) {
   1034                     Intent intent = intents[i];
   1035                     if (intent == null) {
   1036                         continue;
   1037                     }
   1038 
   1039                     // Refuse possible leaked file descriptors
   1040                     if (intent != null && intent.hasFileDescriptors()) {
   1041                         throw new IllegalArgumentException("File descriptors passed in Intent");
   1042                     }
   1043 
   1044                     boolean componentSpecified = intent.getComponent() != null;
   1045 
   1046                     // Don't modify the client's object!
   1047                     intent = new Intent(intent);
   1048 
   1049                     // Collect information about the target of the Intent.
   1050                     ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 0, null, userId);
   1051                     // TODO: New, check if this is correct
   1052                     aInfo = mService.getActivityInfoForUser(aInfo, userId);
   1053 
   1054                     if (aInfo != null &&
   1055                             (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
   1056                                     != 0) {
   1057                         throw new IllegalArgumentException(
   1058                                 "FLAG_CANT_SAVE_STATE not supported here");
   1059                     }
   1060 
   1061                     Bundle theseOptions;
   1062                     if (options != null && i == intents.length-1) {
   1063                         theseOptions = options;
   1064                     } else {
   1065                         theseOptions = null;
   1066                     }
   1067                     int res = startActivityLocked(caller, intent, resolvedTypes[i],
   1068                             aInfo, null, null, resultTo, null, -1, callingPid, callingUid,
   1069                             callingPackage, callingPid, callingUid,
   1070                             0, theseOptions, componentSpecified, outActivity, null, null);
   1071                     if (res < 0) {
   1072                         return res;
   1073                     }
   1074 
   1075                     resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
   1076                 }
   1077             }
   1078         } finally {
   1079             Binder.restoreCallingIdentity(origId);
   1080         }
   1081 
   1082         return ActivityManager.START_SUCCESS;
   1083     }
   1084 
   1085     final boolean realStartActivityLocked(ActivityRecord r,
   1086             ProcessRecord app, boolean andResume, boolean checkConfig)
   1087             throws RemoteException {
   1088 
   1089         r.startFreezingScreenLocked(app, 0);
   1090         if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
   1091         mWindowManager.setAppVisibility(r.appToken, true);
   1092 
   1093         // schedule launch ticks to collect information about slow apps.
   1094         r.startLaunchTickingLocked();
   1095 
   1096         // Have the window manager re-evaluate the orientation of
   1097         // the screen based on the new activity order.  Note that
   1098         // as a result of this, it can call back into the activity
   1099         // manager with a new orientation.  We don't care about that,
   1100         // because the activity is not currently running so we are
   1101         // just restarting it anyway.
   1102         if (checkConfig) {
   1103             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   1104                     mService.mConfiguration,
   1105                     r.mayFreezeScreenLocked(app) ? r.appToken : null);
   1106             mService.updateConfigurationLocked(config, r, false, false);
   1107         }
   1108 
   1109         r.app = app;
   1110         app.waitingToKill = null;
   1111         r.launchCount++;
   1112         r.lastLaunchTime = SystemClock.uptimeMillis();
   1113 
   1114         if (localLOGV) Slog.v(TAG, "Launching: " + r);
   1115 
   1116         int idx = app.activities.indexOf(r);
   1117         if (idx < 0) {
   1118             app.activities.add(r);
   1119         }
   1120         mService.updateLruProcessLocked(app, true, null);
   1121         mService.updateOomAdjLocked();
   1122 
   1123         final ActivityStack stack = r.task.stack;
   1124         try {
   1125             if (app.thread == null) {
   1126                 throw new RemoteException();
   1127             }
   1128             List<ResultInfo> results = null;
   1129             List<ReferrerIntent> newIntents = null;
   1130             if (andResume) {
   1131                 results = r.results;
   1132                 newIntents = r.newIntents;
   1133             }
   1134             if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
   1135                     + " icicle=" + r.icicle
   1136                     + " with results=" + results + " newIntents=" + newIntents
   1137                     + " andResume=" + andResume);
   1138             if (andResume) {
   1139                 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
   1140                         r.userId, System.identityHashCode(r),
   1141                         r.task.taskId, r.shortComponentName);
   1142             }
   1143             if (r.isHomeActivity() && r.isNotResolverActivity()) {
   1144                 // Home process is the root process of the task.
   1145                 mService.mHomeProcess = r.task.mActivities.get(0).app;
   1146             }
   1147             mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   1148             r.sleeping = false;
   1149             r.forceNewConfig = false;
   1150             mService.showAskCompatModeDialogLocked(r);
   1151             r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
   1152             String profileFile = null;
   1153             ParcelFileDescriptor profileFd = null;
   1154             if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
   1155                 if (mService.mProfileProc == null || mService.mProfileProc == app) {
   1156                     mService.mProfileProc = app;
   1157                     profileFile = mService.mProfileFile;
   1158                     profileFd = mService.mProfileFd;
   1159                 }
   1160             }
   1161             app.hasShownUi = true;
   1162             app.pendingUiClean = true;
   1163             if (profileFd != null) {
   1164                 try {
   1165                     profileFd = profileFd.dup();
   1166                 } catch (IOException e) {
   1167                     if (profileFd != null) {
   1168                         try {
   1169                             profileFd.close();
   1170                         } catch (IOException o) {
   1171                         }
   1172                         profileFd = null;
   1173                     }
   1174                 }
   1175             }
   1176 
   1177             ProfilerInfo profilerInfo = profileFile != null
   1178                     ? new ProfilerInfo(profileFile, profileFd, mService.mSamplingInterval,
   1179                     mService.mAutoStopProfiler) : null;
   1180             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
   1181             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
   1182                     System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
   1183                     r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
   1184                     r.icicle, r.persistentState, results, newIntents, !andResume,
   1185                     mService.isNextTransitionForward(), profilerInfo);
   1186 
   1187             if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
   1188                 // This may be a heavy-weight process!  Note that the package
   1189                 // manager will ensure that only activity can run in the main
   1190                 // process of the .apk, which is the only thing that will be
   1191                 // considered heavy-weight.
   1192                 if (app.processName.equals(app.info.packageName)) {
   1193                     if (mService.mHeavyWeightProcess != null
   1194                             && mService.mHeavyWeightProcess != app) {
   1195                         Slog.w(TAG, "Starting new heavy weight process " + app
   1196                                 + " when already running "
   1197                                 + mService.mHeavyWeightProcess);
   1198                     }
   1199                     mService.mHeavyWeightProcess = app;
   1200                     Message msg = mService.mHandler.obtainMessage(
   1201                             ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
   1202                     msg.obj = r;
   1203                     mService.mHandler.sendMessage(msg);
   1204                 }
   1205             }
   1206 
   1207         } catch (RemoteException e) {
   1208             if (r.launchFailed) {
   1209                 // This is the second time we failed -- finish activity
   1210                 // and give up.
   1211                 Slog.e(TAG, "Second failure launching "
   1212                       + r.intent.getComponent().flattenToShortString()
   1213                       + ", giving up", e);
   1214                 mService.appDiedLocked(app);
   1215                 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
   1216                         "2nd-crash", false);
   1217                 return false;
   1218             }
   1219 
   1220             // This is the first time we failed -- restart process and
   1221             // retry.
   1222             app.activities.remove(r);
   1223             throw e;
   1224         }
   1225 
   1226         r.launchFailed = false;
   1227         if (stack.updateLRUListLocked(r)) {
   1228             Slog.w(TAG, "Activity " + r
   1229                   + " being launched, but already in LRU list");
   1230         }
   1231 
   1232         if (andResume) {
   1233             // As part of the process of launching, ActivityThread also performs
   1234             // a resume.
   1235             stack.minimalResumeActivityLocked(r);
   1236         } else {
   1237             // This activity is not starting in the resumed state... which
   1238             // should look like we asked it to pause+stop (but remain visible),
   1239             // and it has done so and reported back the current icicle and
   1240             // other state.
   1241             if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
   1242                     + " (starting in stopped state)");
   1243             r.state = ActivityState.STOPPED;
   1244             r.stopped = true;
   1245         }
   1246 
   1247         // Launch the new version setup screen if needed.  We do this -after-
   1248         // launching the initial activity (that is, home), so that it can have
   1249         // a chance to initialize itself while in the background, making the
   1250         // switch back to it faster and look better.
   1251         if (isFrontStack(stack)) {
   1252             mService.startSetupActivityLocked();
   1253         }
   1254 
   1255         // Update any services we are bound to that might care about whether
   1256         // their client may have activities.
   1257         mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
   1258 
   1259         return true;
   1260     }
   1261 
   1262     void startSpecificActivityLocked(ActivityRecord r,
   1263             boolean andResume, boolean checkConfig) {
   1264         // Is this activity's application already running?
   1265         ProcessRecord app = mService.getProcessRecordLocked(r.processName,
   1266                 r.info.applicationInfo.uid, true);
   1267 
   1268         r.task.stack.setLaunchTime(r);
   1269 
   1270         if (app != null && app.thread != null) {
   1271             try {
   1272                 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
   1273                         || !"android".equals(r.info.packageName)) {
   1274                     // Don't add this if it is a platform component that is marked
   1275                     // to run in multiple processes, because this is actually
   1276                     // part of the framework so doesn't make sense to track as a
   1277                     // separate apk in the process.
   1278                     app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
   1279                             mService.mProcessStats);
   1280                 }
   1281                 realStartActivityLocked(r, app, andResume, checkConfig);
   1282                 return;
   1283             } catch (RemoteException e) {
   1284                 Slog.w(TAG, "Exception when starting activity "
   1285                         + r.intent.getComponent().flattenToShortString(), e);
   1286             }
   1287 
   1288             // If a dead object exception was thrown -- fall through to
   1289             // restart the application.
   1290         }
   1291 
   1292         mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
   1293                 "activity", r.intent.getComponent(), false, false, true);
   1294     }
   1295 
   1296     final int startActivityLocked(IApplicationThread caller,
   1297             Intent intent, String resolvedType, ActivityInfo aInfo,
   1298             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
   1299             IBinder resultTo, String resultWho, int requestCode,
   1300             int callingPid, int callingUid, String callingPackage,
   1301             int realCallingPid, int realCallingUid, int startFlags, Bundle options,
   1302             boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
   1303             TaskRecord inTask) {
   1304         int err = ActivityManager.START_SUCCESS;
   1305 
   1306         ProcessRecord callerApp = null;
   1307         if (caller != null) {
   1308             callerApp = mService.getRecordForAppLocked(caller);
   1309             if (callerApp != null) {
   1310                 callingPid = callerApp.pid;
   1311                 callingUid = callerApp.info.uid;
   1312             } else {
   1313                 Slog.w(TAG, "Unable to find app for caller " + caller
   1314                       + " (pid=" + callingPid + ") when starting: "
   1315                       + intent.toString());
   1316                 err = ActivityManager.START_PERMISSION_DENIED;
   1317             }
   1318         }
   1319 
   1320         if (err == ActivityManager.START_SUCCESS) {
   1321             final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
   1322             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
   1323                     + "} from uid " + callingUid
   1324                     + " on display " + (container == null ? (mFocusedStack == null ?
   1325                             Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
   1326                             (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
   1327                                     container.mActivityDisplay.mDisplayId)));
   1328         }
   1329 
   1330         ActivityRecord sourceRecord = null;
   1331         ActivityRecord resultRecord = null;
   1332         if (resultTo != null) {
   1333             sourceRecord = isInAnyStackLocked(resultTo);
   1334             if (DEBUG_RESULTS) Slog.v(
   1335                 TAG, "Will send result to " + resultTo + " " + sourceRecord);
   1336             if (sourceRecord != null) {
   1337                 if (requestCode >= 0 && !sourceRecord.finishing) {
   1338                     resultRecord = sourceRecord;
   1339                 }
   1340             }
   1341         }
   1342 
   1343         final int launchFlags = intent.getFlags();
   1344 
   1345         if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
   1346             // Transfer the result target from the source activity to the new
   1347             // one being started, including any failures.
   1348             if (requestCode >= 0) {
   1349                 ActivityOptions.abort(options);
   1350                 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
   1351             }
   1352             resultRecord = sourceRecord.resultTo;
   1353             resultWho = sourceRecord.resultWho;
   1354             requestCode = sourceRecord.requestCode;
   1355             sourceRecord.resultTo = null;
   1356             if (resultRecord != null) {
   1357                 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
   1358             }
   1359             if (sourceRecord.launchedFromUid == callingUid) {
   1360                 // The new activity is being launched from the same uid as the previous
   1361                 // activity in the flow, and asking to forward its result back to the
   1362                 // previous.  In this case the activity is serving as a trampoline between
   1363                 // the two, so we also want to update its launchedFromPackage to be the
   1364                 // same as the previous activity.  Note that this is safe, since we know
   1365                 // these two packages come from the same uid; the caller could just as
   1366                 // well have supplied that same package name itself.  This specifially
   1367                 // deals with the case of an intent picker/chooser being launched in the app
   1368                 // flow to redirect to an activity picked by the user, where we want the final
   1369                 // activity to consider it to have been launched by the previous app activity.
   1370                 callingPackage = sourceRecord.launchedFromPackage;
   1371             }
   1372         }
   1373 
   1374         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
   1375             // We couldn't find a class that can handle the given Intent.
   1376             // That's the end of that!
   1377             err = ActivityManager.START_INTENT_NOT_RESOLVED;
   1378         }
   1379 
   1380         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
   1381             // We couldn't find the specific class specified in the Intent.
   1382             // Also the end of the line.
   1383             err = ActivityManager.START_CLASS_NOT_FOUND;
   1384         }
   1385 
   1386         if (err == ActivityManager.START_SUCCESS && sourceRecord != null
   1387                 && sourceRecord.task.voiceSession != null) {
   1388             // If this activity is being launched as part of a voice session, we need
   1389             // to ensure that it is safe to do so.  If the upcoming activity will also
   1390             // be part of the voice session, we can only launch it if it has explicitly
   1391             // said it supports the VOICE category, or it is a part of the calling app.
   1392             if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
   1393                     && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
   1394                 try {
   1395                     if (!AppGlobals.getPackageManager().activitySupportsIntent(
   1396                             intent.getComponent(), intent, resolvedType)) {
   1397                         err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
   1398                     }
   1399                 } catch (RemoteException e) {
   1400                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
   1401                 }
   1402             }
   1403         }
   1404 
   1405         if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
   1406             // If the caller is starting a new voice session, just make sure the target
   1407             // is actually allowing it to run this way.
   1408             try {
   1409                 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
   1410                         intent, resolvedType)) {
   1411                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
   1412                 }
   1413             } catch (RemoteException e) {
   1414                 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
   1415             }
   1416         }
   1417 
   1418         final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
   1419 
   1420         if (err != ActivityManager.START_SUCCESS) {
   1421             if (resultRecord != null) {
   1422                 resultStack.sendActivityResultLocked(-1,
   1423                     resultRecord, resultWho, requestCode,
   1424                     Activity.RESULT_CANCELED, null);
   1425             }
   1426             ActivityOptions.abort(options);
   1427             return err;
   1428         }
   1429 
   1430         final int startAnyPerm = mService.checkPermission(
   1431                 START_ANY_ACTIVITY, callingPid, callingUid);
   1432         final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
   1433                 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
   1434         if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
   1435             if (resultRecord != null) {
   1436                 resultStack.sendActivityResultLocked(-1,
   1437                     resultRecord, resultWho, requestCode,
   1438                     Activity.RESULT_CANCELED, null);
   1439             }
   1440             String msg;
   1441             if (!aInfo.exported) {
   1442                 msg = "Permission Denial: starting " + intent.toString()
   1443                         + " from " + callerApp + " (pid=" + callingPid
   1444                         + ", uid=" + callingUid + ")"
   1445                         + " not exported from uid " + aInfo.applicationInfo.uid;
   1446             } else {
   1447                 msg = "Permission Denial: starting " + intent.toString()
   1448                         + " from " + callerApp + " (pid=" + callingPid
   1449                         + ", uid=" + callingUid + ")"
   1450                         + " requires " + aInfo.permission;
   1451             }
   1452             Slog.w(TAG, msg);
   1453             throw new SecurityException(msg);
   1454         }
   1455 
   1456         boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
   1457                 callingPid, resolvedType, aInfo.applicationInfo);
   1458 
   1459         if (mService.mController != null) {
   1460             try {
   1461                 // The Intent we give to the watcher has the extra data
   1462                 // stripped off, since it can contain private information.
   1463                 Intent watchIntent = intent.cloneFilter();
   1464                 abort |= !mService.mController.activityStarting(watchIntent,
   1465                         aInfo.applicationInfo.packageName);
   1466             } catch (RemoteException e) {
   1467                 mService.mController = null;
   1468             }
   1469         }
   1470 
   1471         if (abort) {
   1472             if (resultRecord != null) {
   1473                 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
   1474                         Activity.RESULT_CANCELED, null);
   1475             }
   1476             // We pretend to the caller that it was really started, but
   1477             // they will just get a cancel result.
   1478             ActivityOptions.abort(options);
   1479             return ActivityManager.START_SUCCESS;
   1480         }
   1481 
   1482         ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
   1483                 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
   1484                 requestCode, componentSpecified, this, container, options);
   1485         if (outActivity != null) {
   1486             outActivity[0] = r;
   1487         }
   1488 
   1489         final ActivityStack stack = getFocusedStack();
   1490         if (voiceSession == null && (stack.mResumedActivity == null
   1491                 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
   1492             if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
   1493                     realCallingPid, realCallingUid, "Activity start")) {
   1494                 PendingActivityLaunch pal =
   1495                         new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
   1496                 mPendingActivityLaunches.add(pal);
   1497                 ActivityOptions.abort(options);
   1498                 return ActivityManager.START_SWITCHES_CANCELED;
   1499             }
   1500         }
   1501 
   1502         if (mService.mDidAppSwitch) {
   1503             // This is the second allowed switch since we stopped switches,
   1504             // so now just generally allow switches.  Use case: user presses
   1505             // home (switches disabled, switch to home, mDidAppSwitch now true);
   1506             // user taps a home icon (coming from home so allowed, we hit here
   1507             // and now allow anyone to switch again).
   1508             mService.mAppSwitchesAllowedTime = 0;
   1509         } else {
   1510             mService.mDidAppSwitch = true;
   1511         }
   1512 
   1513         doPendingActivityLaunchesLocked(false);
   1514 
   1515         err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
   1516                 startFlags, true, options, inTask);
   1517 
   1518         if (err < 0) {
   1519             // If someone asked to have the keyguard dismissed on the next
   1520             // activity start, but we are not actually doing an activity
   1521             // switch...  just dismiss the keyguard now, because we
   1522             // probably want to see whatever is behind it.
   1523             notifyActivityDrawnForKeyguard();
   1524         }
   1525         return err;
   1526     }
   1527 
   1528     ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) {
   1529         final TaskRecord task = r.task;
   1530 
   1531         // On leanback only devices we should keep all activities in the same stack.
   1532         if (!mLeanbackOnlyDevice &&
   1533                 (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
   1534             if (task != null) {
   1535                 final ActivityStack taskStack = task.stack;
   1536                 if (taskStack.isOnHomeDisplay()) {
   1537                     if (mFocusedStack != taskStack) {
   1538                         if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
   1539                                 "focused stack to r=" + r + " task=" + task);
   1540                         mFocusedStack = taskStack;
   1541                     } else {
   1542                         if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1543                             "adjustStackFocus: Focused stack already=" + mFocusedStack);
   1544                     }
   1545                 }
   1546                 return taskStack;
   1547             }
   1548 
   1549             final ActivityContainer container = r.mInitialActivityContainer;
   1550             if (container != null) {
   1551                 // The first time put it on the desired stack, after this put on task stack.
   1552                 r.mInitialActivityContainer = null;
   1553                 return container.mStack;
   1554             }
   1555 
   1556             if (mFocusedStack != mHomeStack && (!newTask ||
   1557                     mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
   1558                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1559                         "adjustStackFocus: Have a focused stack=" + mFocusedStack);
   1560                 return mFocusedStack;
   1561             }
   1562 
   1563             final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
   1564             for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1565                 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
   1566                 if (!stack.isHomeStack()) {
   1567                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1568                             "adjustStackFocus: Setting focused stack=" + stack);
   1569                     mFocusedStack = stack;
   1570                     return mFocusedStack;
   1571                 }
   1572             }
   1573 
   1574             // Need to create an app stack for this user.
   1575             int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
   1576             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
   1577                     " stackId=" + stackId);
   1578             mFocusedStack = getStack(stackId);
   1579             return mFocusedStack;
   1580         }
   1581         return mHomeStack;
   1582     }
   1583 
   1584     void setFocusedStack(ActivityRecord r, String reason) {
   1585         if (r != null) {
   1586             final TaskRecord task = r.task;
   1587             boolean isHomeActivity = !r.isApplicationActivity();
   1588             if (!isHomeActivity && task != null) {
   1589                 isHomeActivity = !task.isApplicationTask();
   1590             }
   1591             if (!isHomeActivity && task != null) {
   1592                 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
   1593                 isHomeActivity = parent != null && parent.isHomeActivity();
   1594             }
   1595             moveHomeStack(isHomeActivity, reason);
   1596         }
   1597     }
   1598 
   1599     final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
   1600             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
   1601             boolean doResume, Bundle options, TaskRecord inTask) {
   1602         final Intent intent = r.intent;
   1603         final int callingUid = r.launchedFromUid;
   1604 
   1605         // In some flows in to this function, we retrieve the task record and hold on to it
   1606         // without a lock before calling back in to here...  so the task at this point may
   1607         // not actually be in recents.  Check for that, and if it isn't in recents just
   1608         // consider it invalid.
   1609         if (inTask != null && !inTask.inRecents) {
   1610             Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
   1611             inTask = null;
   1612         }
   1613 
   1614         final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
   1615         final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
   1616         final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
   1617 
   1618         int launchFlags = intent.getFlags();
   1619         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
   1620                 (launchSingleInstance || launchSingleTask)) {
   1621             // We have a conflict between the Intent and the Activity manifest, manifest wins.
   1622             Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
   1623                     "\"singleInstance\" or \"singleTask\"");
   1624             launchFlags &=
   1625                     ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
   1626         } else {
   1627             switch (r.info.documentLaunchMode) {
   1628                 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
   1629                     break;
   1630                 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
   1631                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
   1632                     break;
   1633                 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
   1634                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
   1635                     break;
   1636                 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
   1637                     launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
   1638                     break;
   1639             }
   1640         }
   1641 
   1642         final boolean launchTaskBehind = r.mLaunchTaskBehind
   1643                 && !launchSingleTask && !launchSingleInstance
   1644                 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
   1645 
   1646         if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   1647             // For whatever reason this activity is being launched into a new
   1648             // task...  yet the caller has requested a result back.  Well, that
   1649             // is pretty messed up, so instead immediately send back a cancel
   1650             // and let the new task continue launched as normal without a
   1651             // dependency on its originator.
   1652             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
   1653             r.resultTo.task.stack.sendActivityResultLocked(-1,
   1654                     r.resultTo, r.resultWho, r.requestCode,
   1655                     Activity.RESULT_CANCELED, null);
   1656             r.resultTo = null;
   1657         }
   1658 
   1659         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
   1660             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1661         }
   1662 
   1663         // If we are actually going to launch in to a new task, there are some cases where
   1664         // we further want to do multiple task.
   1665         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   1666             if (launchTaskBehind
   1667                     || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
   1668                 launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
   1669             }
   1670         }
   1671 
   1672         // We'll invoke onUserLeaving before onPause only if the launching
   1673         // activity did not explicitly state that this is an automated launch.
   1674         mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
   1675         if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
   1676 
   1677         // If the caller has asked not to resume at this point, we make note
   1678         // of this in the record so that we can skip it when trying to find
   1679         // the top running activity.
   1680         if (!doResume) {
   1681             r.delayedResume = true;
   1682         }
   1683 
   1684         ActivityRecord notTop =
   1685                 (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
   1686 
   1687         // If the onlyIfNeeded flag is set, then we can do this if the activity
   1688         // being launched is the same as the one making the call...  or, as
   1689         // a special case, if we do not know the caller then we count the
   1690         // current top activity as the caller.
   1691         if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
   1692             ActivityRecord checkedCaller = sourceRecord;
   1693             if (checkedCaller == null) {
   1694                 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
   1695             }
   1696             if (!checkedCaller.realActivity.equals(r.realActivity)) {
   1697                 // Caller is not the same as launcher, so always needed.
   1698                 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
   1699             }
   1700         }
   1701 
   1702         boolean addingToTask = false;
   1703         TaskRecord reuseTask = null;
   1704 
   1705         // If the caller is not coming from another activity, but has given us an
   1706         // explicit task into which they would like us to launch the new activity,
   1707         // then let's see about doing that.
   1708         if (sourceRecord == null && inTask != null && inTask.stack != null) {
   1709             final Intent baseIntent = inTask.getBaseIntent();
   1710             final ActivityRecord root = inTask.getRootActivity();
   1711             if (baseIntent == null) {
   1712                 ActivityOptions.abort(options);
   1713                 throw new IllegalArgumentException("Launching into task without base intent: "
   1714                         + inTask);
   1715             }
   1716 
   1717             // If this task is empty, then we are adding the first activity -- it
   1718             // determines the root, and must be launching as a NEW_TASK.
   1719             if (launchSingleInstance || launchSingleTask) {
   1720                 if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
   1721                     ActivityOptions.abort(options);
   1722                     throw new IllegalArgumentException("Trying to launch singleInstance/Task "
   1723                             + r + " into different task " + inTask);
   1724                 }
   1725                 if (root != null) {
   1726                     ActivityOptions.abort(options);
   1727                     throw new IllegalArgumentException("Caller with inTask " + inTask
   1728                             + " has root " + root + " but target is singleInstance/Task");
   1729                 }
   1730             }
   1731 
   1732             // If task is empty, then adopt the interesting intent launch flags in to the
   1733             // activity being started.
   1734             if (root == null) {
   1735                 final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
   1736                         | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
   1737                         | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
   1738                 launchFlags = (launchFlags&~flagsOfInterest)
   1739                         | (baseIntent.getFlags()&flagsOfInterest);
   1740                 intent.setFlags(launchFlags);
   1741                 inTask.setIntent(r);
   1742                 addingToTask = true;
   1743 
   1744             // If the task is not empty and the caller is asking to start it as the root
   1745             // of a new task, then we don't actually want to start this on the task.  We
   1746             // will bring the task to the front, and possibly give it a new intent.
   1747             } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   1748                 addingToTask = false;
   1749 
   1750             } else {
   1751                 addingToTask = true;
   1752             }
   1753 
   1754             reuseTask = inTask;
   1755         } else {
   1756             inTask = null;
   1757         }
   1758 
   1759         if (inTask == null) {
   1760             if (sourceRecord == null) {
   1761                 // This activity is not being started from another...  in this
   1762                 // case we -always- start a new task.
   1763                 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
   1764                     Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
   1765                             "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
   1766                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1767                 }
   1768             } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   1769                 // The original activity who is starting us is running as a single
   1770                 // instance...  this new activity it is starting must go on its
   1771                 // own task.
   1772                 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1773             } else if (launchSingleInstance || launchSingleTask) {
   1774                 // The activity being started is a single instance...  it always
   1775                 // gets launched into its own task.
   1776                 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1777             }
   1778         }
   1779 
   1780         ActivityInfo newTaskInfo = null;
   1781         Intent newTaskIntent = null;
   1782         ActivityStack sourceStack;
   1783         if (sourceRecord != null) {
   1784             if (sourceRecord.finishing) {
   1785                 // If the source is finishing, we can't further count it as our source.  This
   1786                 // is because the task it is associated with may now be empty and on its way out,
   1787                 // so we don't want to blindly throw it in to that task.  Instead we will take
   1788                 // the NEW_TASK flow and try to find a task for it. But save the task information
   1789                 // so it can be used when creating the new task.
   1790                 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
   1791                     Slog.w(TAG, "startActivity called from finishing " + sourceRecord
   1792                             + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
   1793                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1794                     newTaskInfo = sourceRecord.info;
   1795                     newTaskIntent = sourceRecord.task.intent;
   1796                 }
   1797                 sourceRecord = null;
   1798                 sourceStack = null;
   1799             } else {
   1800                 sourceStack = sourceRecord.task.stack;
   1801             }
   1802         } else {
   1803             sourceStack = null;
   1804         }
   1805 
   1806         boolean movedHome = false;
   1807         ActivityStack targetStack;
   1808 
   1809         intent.setFlags(launchFlags);
   1810 
   1811         // We may want to try to place the new activity in to an existing task.  We always
   1812         // do this if the target activity is singleTask or singleInstance; we will also do
   1813         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
   1814         // us to still place it in a new task: multi task, always doc mode, or being asked to
   1815         // launch this as a new task behind the current one.
   1816         if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
   1817                 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
   1818                 || launchSingleInstance || launchSingleTask) {
   1819             // If bring to front is requested, and no result is requested and we have not
   1820             // been given an explicit task to launch in to, and
   1821             // we can find a task that was started with this same
   1822             // component, then instead of launching bring that one to the front.
   1823             if (inTask == null && r.resultTo == null) {
   1824                 // See if there is a task to bring to the front.  If this is
   1825                 // a SINGLE_INSTANCE activity, there can be one and only one
   1826                 // instance of it in the history, and it is always in its own
   1827                 // unique task, so we do a special search.
   1828                 ActivityRecord intentActivity = !launchSingleInstance ?
   1829                         findTaskLocked(r) : findActivityLocked(intent, r.info);
   1830                 if (intentActivity != null) {
   1831                     if (isLockTaskModeViolation(intentActivity.task)) {
   1832                         showLockTaskToast();
   1833                         Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
   1834                         return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
   1835                     }
   1836                     if (r.task == null) {
   1837                         r.task = intentActivity.task;
   1838                     }
   1839                     targetStack = intentActivity.task.stack;
   1840                     targetStack.mLastPausedActivity = null;
   1841                     if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
   1842                             + " from " + intentActivity);
   1843                     targetStack.moveToFront("intentActivityFound");
   1844                     if (intentActivity.task.intent == null) {
   1845                         // This task was started because of movement of
   1846                         // the activity based on affinity...  now that we
   1847                         // are actually launching it, we can assign the
   1848                         // base intent.
   1849                         intentActivity.task.setIntent(r);
   1850                     }
   1851                     // If the target task is not in the front, then we need
   1852                     // to bring it to the front...  except...  well, with
   1853                     // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
   1854                     // to have the same behavior as if a new instance was
   1855                     // being started, which means not bringing it to the front
   1856                     // if the caller is not itself in the front.
   1857                     final ActivityStack lastStack = getLastStack();
   1858                     ActivityRecord curTop = lastStack == null?
   1859                             null : lastStack.topRunningNonDelayedActivityLocked(notTop);
   1860                     boolean movedToFront = false;
   1861                     if (curTop != null && (curTop.task != intentActivity.task ||
   1862                             curTop.task != lastStack.topTask())) {
   1863                         r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
   1864                         if (sourceRecord == null || (sourceStack.topActivity() != null &&
   1865                                 sourceStack.topActivity().task == sourceRecord.task)) {
   1866                             // We really do want to push this one into the
   1867                             // user's face, right now.
   1868                             if (launchTaskBehind && sourceRecord != null) {
   1869                                 intentActivity.setTaskToAffiliateWith(sourceRecord.task);
   1870                             }
   1871                             movedHome = true;
   1872                             targetStack.moveTaskToFrontLocked(intentActivity.task, r, options,
   1873                                     "bringingFoundTaskToFront");
   1874                             if ((launchFlags &
   1875                                     (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
   1876                                     == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
   1877                                 // Caller wants to appear on home activity.
   1878                                 intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
   1879                             }
   1880                             options = null;
   1881                             movedToFront = true;
   1882                         }
   1883                     }
   1884                     // If the caller has requested that the target task be
   1885                     // reset, then do so.
   1886                     if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
   1887                         intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
   1888                     }
   1889                     if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
   1890                         // We don't need to start a new activity, and
   1891                         // the client said not to do anything if that
   1892                         // is the case, so this is it!  And for paranoia, make
   1893                         // sure we have correctly resumed the top activity.
   1894                         if (doResume) {
   1895                             resumeTopActivitiesLocked(targetStack, null, options);
   1896 
   1897                             // Make sure to notify Keyguard as well if we are not running an app
   1898                             // transition later.
   1899                             if (!movedToFront) {
   1900                                 notifyActivityDrawnForKeyguard();
   1901                             }
   1902                         } else {
   1903                             ActivityOptions.abort(options);
   1904                         }
   1905                         return ActivityManager.START_RETURN_INTENT_TO_CALLER;
   1906                     }
   1907                     if ((launchFlags &
   1908                             (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
   1909                             == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
   1910                         // The caller has requested to completely replace any
   1911                         // existing task with its new activity.  Well that should
   1912                         // not be too hard...
   1913                         reuseTask = intentActivity.task;
   1914                         reuseTask.performClearTaskLocked();
   1915                         reuseTask.setIntent(r);
   1916                     } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
   1917                             || launchSingleInstance || launchSingleTask) {
   1918                         // In this situation we want to remove all activities
   1919                         // from the task up to the one being started.  In most
   1920                         // cases this means we are resetting the task to its
   1921                         // initial state.
   1922                         ActivityRecord top =
   1923                                 intentActivity.task.performClearTaskLocked(r, launchFlags);
   1924                         if (top != null) {
   1925                             if (top.frontOfTask) {
   1926                                 // Activity aliases may mean we use different
   1927                                 // intents for the top activity, so make sure
   1928                                 // the task now has the identity of the new
   1929                                 // intent.
   1930                                 top.task.setIntent(r);
   1931                             }
   1932                             ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
   1933                                     r, top.task);
   1934                             top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
   1935                         } else {
   1936                             // A special case: we need to
   1937                             // start the activity because it is not currently
   1938                             // running, and the caller has asked to clear the
   1939                             // current task to have this activity at the top.
   1940                             addingToTask = true;
   1941                             // Now pretend like this activity is being started
   1942                             // by the top of its task, so it is put in the
   1943                             // right place.
   1944                             sourceRecord = intentActivity;
   1945                         }
   1946                     } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
   1947                         // In this case the top activity on the task is the
   1948                         // same as the one being launched, so we take that
   1949                         // as a request to bring the task to the foreground.
   1950                         // If the top activity in the task is the root
   1951                         // activity, deliver this new intent to it if it
   1952                         // desires.
   1953                         if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
   1954                                 && intentActivity.realActivity.equals(r.realActivity)) {
   1955                             ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
   1956                                     intentActivity.task);
   1957                             if (intentActivity.frontOfTask) {
   1958                                 intentActivity.task.setIntent(r);
   1959                             }
   1960                             intentActivity.deliverNewIntentLocked(callingUid, r.intent,
   1961                                     r.launchedFromPackage);
   1962                         } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
   1963                             // In this case we are launching the root activity
   1964                             // of the task, but with a different intent.  We
   1965                             // should start a new instance on top.
   1966                             addingToTask = true;
   1967                             sourceRecord = intentActivity;
   1968                         }
   1969                     } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
   1970                         // In this case an activity is being launched in to an
   1971                         // existing task, without resetting that task.  This
   1972                         // is typically the situation of launching an activity
   1973                         // from a notification or shortcut.  We want to place
   1974                         // the new activity on top of the current task.
   1975                         addingToTask = true;
   1976                         sourceRecord = intentActivity;
   1977                     } else if (!intentActivity.task.rootWasReset) {
   1978                         // In this case we are launching in to an existing task
   1979                         // that has not yet been started from its front door.
   1980                         // The current task has been brought to the front.
   1981                         // Ideally, we'd probably like to place this new task
   1982                         // at the bottom of its stack, but that's a little hard
   1983                         // to do with the current organization of the code so
   1984                         // for now we'll just drop it.
   1985                         intentActivity.task.setIntent(r);
   1986                     }
   1987                     if (!addingToTask && reuseTask == null) {
   1988                         // We didn't do anything...  but it was needed (a.k.a., client
   1989                         // don't use that intent!)  And for paranoia, make
   1990                         // sure we have correctly resumed the top activity.
   1991                         if (doResume) {
   1992                             targetStack.resumeTopActivityLocked(null, options);
   1993                             if (!movedToFront) {
   1994                                 // Make sure to notify Keyguard as well if we are not running an app
   1995                                 // transition later.
   1996                                 notifyActivityDrawnForKeyguard();
   1997                             }
   1998                         } else {
   1999                             ActivityOptions.abort(options);
   2000                         }
   2001                         return ActivityManager.START_TASK_TO_FRONT;
   2002                     }
   2003                 }
   2004             }
   2005         }
   2006 
   2007         //String uri = r.intent.toURI();
   2008         //Intent intent2 = new Intent(uri);
   2009         //Slog.i(TAG, "Given intent: " + r.intent);
   2010         //Slog.i(TAG, "URI is: " + uri);
   2011         //Slog.i(TAG, "To intent: " + intent2);
   2012 
   2013         if (r.packageName != null) {
   2014             // If the activity being launched is the same as the one currently
   2015             // at the top, then we need to check if it should only be launched
   2016             // once.
   2017             ActivityStack topStack = getFocusedStack();
   2018             ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
   2019             if (top != null && r.resultTo == null) {
   2020                 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
   2021                     if (top.app != null && top.app.thread != null) {
   2022                         if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
   2023                             || launchSingleTop || launchSingleTask) {
   2024                             ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
   2025                                     top.task);
   2026                             // For paranoia, make sure we have correctly
   2027                             // resumed the top activity.
   2028                             topStack.mLastPausedActivity = null;
   2029                             if (doResume) {
   2030                                 resumeTopActivitiesLocked();
   2031                             }
   2032                             ActivityOptions.abort(options);
   2033                             if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
   2034                                 // We don't need to start a new activity, and
   2035                                 // the client said not to do anything if that
   2036                                 // is the case, so this is it!
   2037                                 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
   2038                             }
   2039                             top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
   2040                             return ActivityManager.START_DELIVERED_TO_TOP;
   2041                         }
   2042                     }
   2043                 }
   2044             }
   2045 
   2046         } else {
   2047             if (r.resultTo != null) {
   2048                 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
   2049                         r.requestCode, Activity.RESULT_CANCELED, null);
   2050             }
   2051             ActivityOptions.abort(options);
   2052             return ActivityManager.START_CLASS_NOT_FOUND;
   2053         }
   2054 
   2055         boolean newTask = false;
   2056         boolean keepCurTransition = false;
   2057 
   2058         TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
   2059                 sourceRecord.task : null;
   2060 
   2061         // Should this be considered a new task?
   2062         if (r.resultTo == null && inTask == null && !addingToTask
   2063                 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   2064             if (isLockTaskModeViolation(reuseTask)) {
   2065                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
   2066                 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
   2067             }
   2068             newTask = true;
   2069             targetStack = adjustStackFocus(r, newTask);
   2070             if (!launchTaskBehind) {
   2071                 targetStack.moveToFront("startingNewTask");
   2072             }
   2073             if (reuseTask == null) {
   2074                 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
   2075                         newTaskInfo != null ? newTaskInfo : r.info,
   2076                         newTaskIntent != null ? newTaskIntent : intent,
   2077                         voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
   2078                         taskToAffiliate);
   2079                 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
   2080                         r.task);
   2081             } else {
   2082                 r.setTask(reuseTask, taskToAffiliate);
   2083             }
   2084             if (!movedHome) {
   2085                 if ((launchFlags &
   2086                         (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
   2087                         == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
   2088                     // Caller wants to appear on home activity, so before starting
   2089                     // their own activity we will bring home to the front.
   2090                     r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
   2091                 }
   2092             }
   2093         } else if (sourceRecord != null) {
   2094             final TaskRecord sourceTask = sourceRecord.task;
   2095             if (isLockTaskModeViolation(sourceTask)) {
   2096                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
   2097                 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
   2098             }
   2099             targetStack = sourceTask.stack;
   2100             targetStack.moveToFront("sourceStackToFront");
   2101             final TaskRecord topTask = targetStack.topTask();
   2102             if (topTask != sourceTask) {
   2103                 targetStack.moveTaskToFrontLocked(sourceTask, r, options, "sourceTaskToFront");
   2104             }
   2105             if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
   2106                 // In this case, we are adding the activity to an existing
   2107                 // task, but the caller has asked to clear that task if the
   2108                 // activity is already running.
   2109                 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
   2110                 keepCurTransition = true;
   2111                 if (top != null) {
   2112                     ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
   2113                     top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
   2114                     // For paranoia, make sure we have correctly
   2115                     // resumed the top activity.
   2116                     targetStack.mLastPausedActivity = null;
   2117                     if (doResume) {
   2118                         targetStack.resumeTopActivityLocked(null);
   2119                     }
   2120                     ActivityOptions.abort(options);
   2121                     return ActivityManager.START_DELIVERED_TO_TOP;
   2122                 }
   2123             } else if (!addingToTask &&
   2124                     (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
   2125                 // In this case, we are launching an activity in our own task
   2126                 // that may already be running somewhere in the history, and
   2127                 // we want to shuffle it to the front of the stack if so.
   2128                 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
   2129                 if (top != null) {
   2130                     final TaskRecord task = top.task;
   2131                     task.moveActivityToFrontLocked(top);
   2132                     ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
   2133                     top.updateOptionsLocked(options);
   2134                     top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
   2135                     targetStack.mLastPausedActivity = null;
   2136                     if (doResume) {
   2137                         targetStack.resumeTopActivityLocked(null);
   2138                     }
   2139                     return ActivityManager.START_DELIVERED_TO_TOP;
   2140                 }
   2141             }
   2142             // An existing activity is starting this new activity, so we want
   2143             // to keep the new one in the same task as the one that is starting
   2144             // it.
   2145             r.setTask(sourceTask, null);
   2146             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   2147                     + " in existing task " + r.task + " from source " + sourceRecord);
   2148 
   2149         } else if (inTask != null) {
   2150             // The calling is asking that the new activity be started in an explicit
   2151             // task it has provided to us.
   2152             if (isLockTaskModeViolation(inTask)) {
   2153                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
   2154                 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
   2155             }
   2156             targetStack = inTask.stack;
   2157             targetStack.moveTaskToFrontLocked(inTask, r, options, "inTaskToFront");
   2158 
   2159             // Check whether we should actually launch the new activity in to the task,
   2160             // or just reuse the current activity on top.
   2161             ActivityRecord top = inTask.getTopActivity();
   2162             if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
   2163                 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
   2164                         || launchSingleTop || launchSingleTask) {
   2165                     ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
   2166                     if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
   2167                         // We don't need to start a new activity, and
   2168                         // the client said not to do anything if that
   2169                         // is the case, so this is it!
   2170                         return ActivityManager.START_RETURN_INTENT_TO_CALLER;
   2171                     }
   2172                     top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
   2173                     return ActivityManager.START_DELIVERED_TO_TOP;
   2174                 }
   2175             }
   2176 
   2177             if (!addingToTask) {
   2178                 // We don't actually want to have this activity added to the task, so just
   2179                 // stop here but still tell the caller that we consumed the intent.
   2180                 ActivityOptions.abort(options);
   2181                 return ActivityManager.START_TASK_TO_FRONT;
   2182             }
   2183 
   2184             r.setTask(inTask, null);
   2185             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   2186                     + " in explicit task " + r.task);
   2187 
   2188         } else {
   2189             // This not being started from an existing activity, and not part
   2190             // of a new task...  just put it in the top task, though these days
   2191             // this case should never happen.
   2192             targetStack = adjustStackFocus(r, newTask);
   2193             targetStack.moveToFront("addingToTopTask");
   2194             ActivityRecord prev = targetStack.topActivity();
   2195             r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
   2196                             r.info, intent, null, null, true), null);
   2197             mWindowManager.moveTaskToTop(r.task.taskId);
   2198             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   2199                     + " in new guessed " + r.task);
   2200         }
   2201 
   2202         mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
   2203                 intent, r.getUriPermissionsLocked(), r.userId);
   2204 
   2205         if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
   2206             r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
   2207         }
   2208         if (newTask) {
   2209             EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
   2210         }
   2211         ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
   2212         targetStack.mLastPausedActivity = null;
   2213         targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
   2214         if (!launchTaskBehind) {
   2215             // Don't set focus on an activity that's going to the back.
   2216             mService.setFocusedActivityLocked(r, "startedActivity");
   2217         }
   2218         return ActivityManager.START_SUCCESS;
   2219     }
   2220 
   2221     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2222         while (!mPendingActivityLaunches.isEmpty()) {
   2223             PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
   2224             startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
   2225                     doResume && mPendingActivityLaunches.isEmpty(), null, null);
   2226         }
   2227     }
   2228 
   2229     void removePendingActivityLaunchesLocked(ActivityStack stack) {
   2230         for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
   2231             PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
   2232             if (pal.stack == stack) {
   2233                 mPendingActivityLaunches.remove(palNdx);
   2234             }
   2235         }
   2236     }
   2237 
   2238     void acquireLaunchWakelock() {
   2239         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
   2240             throw new IllegalStateException("Calling must be system uid");
   2241         }
   2242         mLaunchingActivity.acquire();
   2243         if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
   2244             // To be safe, don't allow the wake lock to be held for too long.
   2245             mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
   2246         }
   2247     }
   2248 
   2249     /**
   2250      * Called when the frontmost task is idle.
   2251      * @return the state of mService.mBooting before this was called.
   2252      */
   2253     private boolean checkFinishBootingLocked() {
   2254         final boolean booting = mService.mBooting;
   2255         boolean enableScreen = false;
   2256         mService.mBooting = false;
   2257         if (!mService.mBooted) {
   2258             mService.mBooted = true;
   2259             enableScreen = true;
   2260         }
   2261         if (booting || enableScreen) {
   2262             mService.postFinishBooting(booting, enableScreen);
   2263         }
   2264         return booting;
   2265     }
   2266 
   2267     // Checked.
   2268     final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
   2269             Configuration config) {
   2270         if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
   2271 
   2272         ArrayList<ActivityRecord> stops = null;
   2273         ArrayList<ActivityRecord> finishes = null;
   2274         ArrayList<UserStartedState> startingUsers = null;
   2275         int NS = 0;
   2276         int NF = 0;
   2277         boolean booting = false;
   2278         boolean activityRemoved = false;
   2279 
   2280         ActivityRecord r = ActivityRecord.forToken(token);
   2281         if (r != null) {
   2282             if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
   2283                     Debug.getCallers(4));
   2284             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
   2285             r.finishLaunchTickingLocked();
   2286             if (fromTimeout) {
   2287                 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
   2288             }
   2289 
   2290             // This is a hack to semi-deal with a race condition
   2291             // in the client where it can be constructed with a
   2292             // newer configuration from when we asked it to launch.
   2293             // We'll update with whatever configuration it now says
   2294             // it used to launch.
   2295             if (config != null) {
   2296                 r.configuration = config;
   2297             }
   2298 
   2299             // We are now idle.  If someone is waiting for a thumbnail from
   2300             // us, we can now deliver.
   2301             r.idle = true;
   2302 
   2303             //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
   2304             if (isFrontStack(r.task.stack) || fromTimeout) {
   2305                 booting = checkFinishBootingLocked();
   2306             }
   2307         }
   2308 
   2309         if (allResumedActivitiesIdle()) {
   2310             if (r != null) {
   2311                 mService.scheduleAppGcsLocked();
   2312             }
   2313 
   2314             if (mLaunchingActivity.isHeld()) {
   2315                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   2316                 if (VALIDATE_WAKE_LOCK_CALLER &&
   2317                         Binder.getCallingUid() != Process.myUid()) {
   2318                     throw new IllegalStateException("Calling must be system uid");
   2319                 }
   2320                 mLaunchingActivity.release();
   2321             }
   2322             ensureActivitiesVisibleLocked(null, 0);
   2323         }
   2324 
   2325         // Atomically retrieve all of the other things to do.
   2326         stops = processStoppingActivitiesLocked(true);
   2327         NS = stops != null ? stops.size() : 0;
   2328         if ((NF=mFinishingActivities.size()) > 0) {
   2329             finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
   2330             mFinishingActivities.clear();
   2331         }
   2332 
   2333         if (mStartingUsers.size() > 0) {
   2334             startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
   2335             mStartingUsers.clear();
   2336         }
   2337 
   2338         // Stop any activities that are scheduled to do so but have been
   2339         // waiting for the next one to start.
   2340         for (int i = 0; i < NS; i++) {
   2341             r = stops.get(i);
   2342             final ActivityStack stack = r.task.stack;
   2343             if (r.finishing) {
   2344                 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
   2345             } else {
   2346                 stack.stopActivityLocked(r);
   2347             }
   2348         }
   2349 
   2350         // Finish any activities that are scheduled to do so but have been
   2351         // waiting for the next one to start.
   2352         for (int i = 0; i < NF; i++) {
   2353             r = finishes.get(i);
   2354             activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle");
   2355         }
   2356 
   2357         if (!booting) {
   2358             // Complete user switch
   2359             if (startingUsers != null) {
   2360                 for (int i = 0; i < startingUsers.size(); i++) {
   2361                     mService.finishUserSwitch(startingUsers.get(i));
   2362                 }
   2363             }
   2364             // Complete starting up of background users
   2365             if (mStartingBackgroundUsers.size() > 0) {
   2366                 startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
   2367                 mStartingBackgroundUsers.clear();
   2368                 for (int i = 0; i < startingUsers.size(); i++) {
   2369                     mService.finishUserBoot(startingUsers.get(i));
   2370                 }
   2371             }
   2372         }
   2373 
   2374         mService.trimApplications();
   2375         //dump();
   2376         //mWindowManager.dump();
   2377 
   2378         if (activityRemoved) {
   2379             resumeTopActivitiesLocked();
   2380         }
   2381 
   2382         return r;
   2383     }
   2384 
   2385     boolean handleAppDiedLocked(ProcessRecord app) {
   2386         boolean hasVisibleActivities = false;
   2387         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2388             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2389             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2390                 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
   2391             }
   2392         }
   2393         return hasVisibleActivities;
   2394     }
   2395 
   2396     void closeSystemDialogsLocked() {
   2397         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2398             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2399             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2400                 stacks.get(stackNdx).closeSystemDialogsLocked();
   2401             }
   2402         }
   2403     }
   2404 
   2405     void removeUserLocked(int userId) {
   2406         mUserStackInFront.delete(userId);
   2407     }
   2408 
   2409     /**
   2410      * @return true if some activity was finished (or would have finished if doit were true).
   2411      */
   2412     boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
   2413         boolean didSomething = false;
   2414         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2415             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2416             final int numStacks = stacks.size();
   2417             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2418                 final ActivityStack stack = stacks.get(stackNdx);
   2419                 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
   2420                     didSomething = true;
   2421                 }
   2422             }
   2423         }
   2424         return didSomething;
   2425     }
   2426 
   2427     void updatePreviousProcessLocked(ActivityRecord r) {
   2428         // Now that this process has stopped, we may want to consider
   2429         // it to be the previous app to try to keep around in case
   2430         // the user wants to return to it.
   2431 
   2432         // First, found out what is currently the foreground app, so that
   2433         // we don't blow away the previous app if this activity is being
   2434         // hosted by the process that is actually still the foreground.
   2435         ProcessRecord fgApp = null;
   2436         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2437             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2438             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2439                 final ActivityStack stack = stacks.get(stackNdx);
   2440                 if (isFrontStack(stack)) {
   2441                     if (stack.mResumedActivity != null) {
   2442                         fgApp = stack.mResumedActivity.app;
   2443                     } else if (stack.mPausingActivity != null) {
   2444                         fgApp = stack.mPausingActivity.app;
   2445                     }
   2446                     break;
   2447                 }
   2448             }
   2449         }
   2450 
   2451         // Now set this one as the previous process, only if that really
   2452         // makes sense to.
   2453         if (r.app != null && fgApp != null && r.app != fgApp
   2454                 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
   2455                 && r.app != mService.mHomeProcess) {
   2456             mService.mPreviousProcess = r.app;
   2457             mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
   2458         }
   2459     }
   2460 
   2461     boolean resumeTopActivitiesLocked() {
   2462         return resumeTopActivitiesLocked(null, null, null);
   2463     }
   2464 
   2465     boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
   2466             Bundle targetOptions) {
   2467         if (targetStack == null) {
   2468             targetStack = getFocusedStack();
   2469         }
   2470         // Do targetStack first.
   2471         boolean result = false;
   2472         if (isFrontStack(targetStack)) {
   2473             result = targetStack.resumeTopActivityLocked(target, targetOptions);
   2474         }
   2475         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2476             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2477             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2478                 final ActivityStack stack = stacks.get(stackNdx);
   2479                 if (stack == targetStack) {
   2480                     // Already started above.
   2481                     continue;
   2482                 }
   2483                 if (isFrontStack(stack)) {
   2484                     stack.resumeTopActivityLocked(null);
   2485                 }
   2486             }
   2487         }
   2488         return result;
   2489     }
   2490 
   2491     void finishTopRunningActivityLocked(ProcessRecord app) {
   2492         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2493             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2494             final int numStacks = stacks.size();
   2495             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2496                 final ActivityStack stack = stacks.get(stackNdx);
   2497                 stack.finishTopRunningActivityLocked(app);
   2498             }
   2499         }
   2500     }
   2501 
   2502     void finishVoiceTask(IVoiceInteractionSession session) {
   2503         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2504             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2505             final int numStacks = stacks.size();
   2506             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2507                 final ActivityStack stack = stacks.get(stackNdx);
   2508                 stack.finishVoiceTask(session);
   2509             }
   2510         }
   2511     }
   2512 
   2513     void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options, String reason) {
   2514         if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   2515             mUserLeaving = true;
   2516         }
   2517         if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   2518             // Caller wants the home activity moved with it.  To accomplish this,
   2519             // we'll just indicate that this task returns to the home task.
   2520             task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
   2521         }
   2522         task.stack.moveTaskToFrontLocked(task, null, options, reason);
   2523         if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
   2524                 + task.stack);
   2525     }
   2526 
   2527     ActivityStack getStack(int stackId) {
   2528         ActivityContainer activityContainer = mActivityContainers.get(stackId);
   2529         if (activityContainer != null) {
   2530             return activityContainer.mStack;
   2531         }
   2532         return null;
   2533     }
   2534 
   2535     ArrayList<ActivityStack> getStacks() {
   2536         ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
   2537         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2538             allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
   2539         }
   2540         return allStacks;
   2541     }
   2542 
   2543     IBinder getHomeActivityToken() {
   2544         ActivityRecord homeActivity = getHomeActivity();
   2545         if (homeActivity != null) {
   2546             return homeActivity.appToken;
   2547         }
   2548         return null;
   2549     }
   2550 
   2551     ActivityRecord getHomeActivity() {
   2552         final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
   2553         for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
   2554             final TaskRecord task = tasks.get(taskNdx);
   2555             if (task.isHomeTask()) {
   2556                 final ArrayList<ActivityRecord> activities = task.mActivities;
   2557                 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   2558                     final ActivityRecord r = activities.get(activityNdx);
   2559                     if (r.isHomeActivity()) {
   2560                         return r;
   2561                     }
   2562                 }
   2563             }
   2564         }
   2565         return null;
   2566     }
   2567 
   2568     ActivityContainer createActivityContainer(ActivityRecord parentActivity,
   2569             IActivityContainerCallback callback) {
   2570         ActivityContainer activityContainer =
   2571                 new VirtualActivityContainer(parentActivity, callback);
   2572         mActivityContainers.put(activityContainer.mStackId, activityContainer);
   2573         if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
   2574         parentActivity.mChildContainers.add(activityContainer);
   2575         return activityContainer;
   2576     }
   2577 
   2578     void removeChildActivityContainers(ActivityRecord parentActivity) {
   2579         final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
   2580         for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
   2581             ActivityContainer container = childStacks.remove(containerNdx);
   2582             if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
   2583                     container);
   2584             container.release();
   2585         }
   2586     }
   2587 
   2588     void deleteActivityContainer(IActivityContainer container) {
   2589         ActivityContainer activityContainer = (ActivityContainer)container;
   2590         if (activityContainer != null) {
   2591             if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
   2592                     new RuntimeException("here").fillInStackTrace());
   2593             final int stackId = activityContainer.mStackId;
   2594             mActivityContainers.remove(stackId);
   2595             mWindowManager.removeStack(stackId);
   2596         }
   2597     }
   2598 
   2599     private int createStackOnDisplay(int stackId, int displayId) {
   2600         ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
   2601         if (activityDisplay == null) {
   2602             return -1;
   2603         }
   2604 
   2605         ActivityContainer activityContainer = new ActivityContainer(stackId);
   2606         mActivityContainers.put(stackId, activityContainer);
   2607         activityContainer.attachToDisplayLocked(activityDisplay);
   2608         return stackId;
   2609     }
   2610 
   2611     int getNextStackId() {
   2612         while (true) {
   2613             if (++mLastStackId <= HOME_STACK_ID) {
   2614                 mLastStackId = HOME_STACK_ID + 1;
   2615             }
   2616             if (getStack(mLastStackId) == null) {
   2617                 break;
   2618             }
   2619         }
   2620         return mLastStackId;
   2621     }
   2622 
   2623     private boolean restoreRecentTaskLocked(TaskRecord task) {
   2624         ActivityStack stack = null;
   2625         // Determine stack to restore task to.
   2626         if (mLeanbackOnlyDevice) {
   2627             // There is only one stack for lean back devices.
   2628             stack = mHomeStack;
   2629         } else {
   2630             // Look for the top stack on the home display that isn't the home stack.
   2631             final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
   2632             for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2633                 final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx);
   2634                 if (!tmpStack.isHomeStack()) {
   2635                     stack = tmpStack;
   2636                     break;
   2637                 }
   2638             }
   2639         }
   2640 
   2641         if (stack == null) {
   2642             // We couldn't find a stack to restore the task to. Possible if are restoring recents
   2643             // before an application stack is created...Go ahead and create one on the default
   2644             // display.
   2645             stack = getStack(createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY));
   2646             // Restore home stack to top.
   2647             moveHomeStack(true, "restoreRecentTask");
   2648             if (DEBUG_RECENTS)
   2649                 Slog.v(TAG, "Created stack=" + stack + " for recents restoration.");
   2650         }
   2651 
   2652         if (stack == null) {
   2653             // What does this mean??? Not sure how we would get here...
   2654             if (DEBUG_RECENTS)
   2655                 Slog.v(TAG, "Unable to find/create stack to restore recent task=" + task);
   2656             return false;
   2657         }
   2658 
   2659         stack.addTask(task, false, false);
   2660         if (DEBUG_RECENTS)
   2661             Slog.v(TAG, "Added restored task=" + task + " to stack=" + stack);
   2662         final ArrayList<ActivityRecord> activities = task.mActivities;
   2663         for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   2664             final ActivityRecord r = activities.get(activityNdx);
   2665             mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
   2666                     r.info.screenOrientation, r.fullscreen,
   2667                     (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
   2668                     r.userId, r.info.configChanges, task.voiceSession != null,
   2669                     r.mLaunchTaskBehind);
   2670         }
   2671         return true;
   2672     }
   2673 
   2674     void moveTaskToStackLocked(int taskId, int stackId, boolean toTop) {
   2675         final TaskRecord task = anyTaskForIdLocked(taskId);
   2676         if (task == null) {
   2677             return;
   2678         }
   2679         final ActivityStack stack = getStack(stackId);
   2680         if (stack == null) {
   2681             Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
   2682             return;
   2683         }
   2684         task.stack.removeTask(task, "moveTaskToStack");
   2685         stack.addTask(task, toTop, true);
   2686         mWindowManager.addTask(taskId, stackId, toTop);
   2687         resumeTopActivitiesLocked();
   2688     }
   2689 
   2690     ActivityRecord findTaskLocked(ActivityRecord r) {
   2691         if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
   2692         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2693             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2694             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2695                 final ActivityStack stack = stacks.get(stackNdx);
   2696                 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
   2697                     if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
   2698                     continue;
   2699                 }
   2700                 if (!stack.mActivityContainer.isEligibleForNewTasks()) {
   2701                     if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
   2702                             stack);
   2703                     continue;
   2704                 }
   2705                 final ActivityRecord ar = stack.findTaskLocked(r);
   2706                 if (ar != null) {
   2707                     return ar;
   2708                 }
   2709             }
   2710         }
   2711         if (DEBUG_TASKS) Slog.d(TAG, "No task found");
   2712         return null;
   2713     }
   2714 
   2715     ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
   2716         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2717             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2718             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2719                 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
   2720                 if (ar != null) {
   2721                     return ar;
   2722                 }
   2723             }
   2724         }
   2725         return null;
   2726     }
   2727 
   2728     void goingToSleepLocked() {
   2729         scheduleSleepTimeout();
   2730         if (!mGoingToSleep.isHeld()) {
   2731             mGoingToSleep.acquire();
   2732             if (mLaunchingActivity.isHeld()) {
   2733                 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
   2734                     throw new IllegalStateException("Calling must be system uid");
   2735                 }
   2736                 mLaunchingActivity.release();
   2737                 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   2738             }
   2739         }
   2740         checkReadyForSleepLocked();
   2741     }
   2742 
   2743     boolean shutdownLocked(int timeout) {
   2744         goingToSleepLocked();
   2745 
   2746         boolean timedout = false;
   2747         final long endTime = System.currentTimeMillis() + timeout;
   2748         while (true) {
   2749             boolean cantShutdown = false;
   2750             for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2751                 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2752                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2753                     cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
   2754                 }
   2755             }
   2756             if (cantShutdown) {
   2757                 long timeRemaining = endTime - System.currentTimeMillis();
   2758                 if (timeRemaining > 0) {
   2759                     try {
   2760                         mService.wait(timeRemaining);
   2761                     } catch (InterruptedException e) {
   2762                     }
   2763                 } else {
   2764                     Slog.w(TAG, "Activity manager shutdown timed out");
   2765                     timedout = true;
   2766                     break;
   2767                 }
   2768             } else {
   2769                 break;
   2770             }
   2771         }
   2772 
   2773         // Force checkReadyForSleep to complete.
   2774         mSleepTimeout = true;
   2775         checkReadyForSleepLocked();
   2776 
   2777         return timedout;
   2778     }
   2779 
   2780     void comeOutOfSleepIfNeededLocked() {
   2781         removeSleepTimeouts();
   2782         if (mGoingToSleep.isHeld()) {
   2783             mGoingToSleep.release();
   2784         }
   2785         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2786             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2787             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2788                 final ActivityStack stack = stacks.get(stackNdx);
   2789                 stack.awakeFromSleepingLocked();
   2790                 if (isFrontStack(stack)) {
   2791                     resumeTopActivitiesLocked();
   2792                 }
   2793             }
   2794         }
   2795         mGoingToSleepActivities.clear();
   2796     }
   2797 
   2798     void activitySleptLocked(ActivityRecord r) {
   2799         mGoingToSleepActivities.remove(r);
   2800         checkReadyForSleepLocked();
   2801     }
   2802 
   2803     void checkReadyForSleepLocked() {
   2804         if (!mService.isSleepingOrShuttingDown()) {
   2805             // Do not care.
   2806             return;
   2807         }
   2808 
   2809         if (!mSleepTimeout) {
   2810             boolean dontSleep = false;
   2811             for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2812                 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2813                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2814                     dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
   2815                 }
   2816             }
   2817 
   2818             if (mStoppingActivities.size() > 0) {
   2819                 // Still need to tell some activities to stop; can't sleep yet.
   2820                 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
   2821                         + mStoppingActivities.size() + " activities");
   2822                 scheduleIdleLocked();
   2823                 dontSleep = true;
   2824             }
   2825 
   2826             if (mGoingToSleepActivities.size() > 0) {
   2827                 // Still need to tell some activities to sleep; can't sleep yet.
   2828                 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
   2829                         + mGoingToSleepActivities.size() + " activities");
   2830                 dontSleep = true;
   2831             }
   2832 
   2833             if (dontSleep) {
   2834                 return;
   2835             }
   2836         }
   2837 
   2838         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2839             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2840             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2841                 stacks.get(stackNdx).goToSleep();
   2842             }
   2843         }
   2844 
   2845         removeSleepTimeouts();
   2846 
   2847         if (mGoingToSleep.isHeld()) {
   2848             mGoingToSleep.release();
   2849         }
   2850         if (mService.mShuttingDown) {
   2851             mService.notifyAll();
   2852         }
   2853     }
   2854 
   2855     boolean reportResumedActivityLocked(ActivityRecord r) {
   2856         final ActivityStack stack = r.task.stack;
   2857         if (isFrontStack(stack)) {
   2858             mService.updateUsageStats(r, true);
   2859         }
   2860         if (allResumedActivitiesComplete()) {
   2861             ensureActivitiesVisibleLocked(null, 0);
   2862             mWindowManager.executeAppTransition();
   2863             return true;
   2864         }
   2865         return false;
   2866     }
   2867 
   2868     void handleAppCrashLocked(ProcessRecord app) {
   2869         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2870             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2871             final int numStacks = stacks.size();
   2872             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2873                 final ActivityStack stack = stacks.get(stackNdx);
   2874                 stack.handleAppCrashLocked(app);
   2875             }
   2876         }
   2877     }
   2878 
   2879     boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
   2880         final ActivityStack stack = r.task.stack;
   2881         if (stack == null) {
   2882             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: r=" + r + " visible=" +
   2883                     visible + " stack is null");
   2884             return false;
   2885         }
   2886         final boolean isVisible = stack.hasVisibleBehindActivity();
   2887         if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind r=" + r + " visible=" +
   2888                 visible + " isVisible=" + isVisible);
   2889 
   2890         final ActivityRecord top = topRunningActivityLocked();
   2891         if (top == null || top == r || (visible == isVisible)) {
   2892             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: quick return");
   2893             stack.setVisibleBehindActivity(visible ? r : null);
   2894             return true;
   2895         }
   2896 
   2897         // A non-top activity is reporting a visibility change.
   2898         if (visible && top.fullscreen) {
   2899             // Let the caller know that it can't be seen.
   2900             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen="
   2901                     + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app +
   2902                     " top.app.thread=" + top.app.thread);
   2903             return false;
   2904         } else if (!visible && stack.getVisibleBehindActivity() != r) {
   2905             // Only the activity set as currently visible behind should actively reset its
   2906             // visible behind state.
   2907             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning visible="
   2908                     + visible + " stack.getVisibleBehindActivity()=" +
   2909                     stack.getVisibleBehindActivity() + " r=" + r);
   2910             return false;
   2911         }
   2912 
   2913         stack.setVisibleBehindActivity(visible ? r : null);
   2914         if (!visible) {
   2915             // Make the activity immediately above r opaque.
   2916             final ActivityRecord next = stack.findNextTranslucentActivity(r);
   2917             if (next != null) {
   2918                 mService.convertFromTranslucent(next.appToken);
   2919             }
   2920         }
   2921         if (top.app != null && top.app.thread != null) {
   2922             // Notify the top app of the change.
   2923             try {
   2924                 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
   2925             } catch (RemoteException e) {
   2926             }
   2927         }
   2928         return true;
   2929     }
   2930 
   2931     // Called when WindowManager has finished animating the launchingBehind activity to the back.
   2932     void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
   2933         r.mLaunchTaskBehind = false;
   2934         final TaskRecord task = r.task;
   2935         task.setLastThumbnail(task.stack.screenshotActivities(r));
   2936         mService.addRecentTaskLocked(task);
   2937         mService.notifyTaskStackChangedLocked();
   2938         mWindowManager.setAppVisibility(r.appToken, false);
   2939     }
   2940 
   2941     void scheduleLaunchTaskBehindComplete(IBinder token) {
   2942         mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
   2943     }
   2944 
   2945     void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
   2946         // First the front stacks. In case any are not fullscreen and are in front of home.
   2947         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2948             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2949             final int topStackNdx = stacks.size() - 1;
   2950             for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
   2951                 final ActivityStack stack = stacks.get(stackNdx);
   2952                 stack.ensureActivitiesVisibleLocked(starting, configChanges);
   2953             }
   2954         }
   2955     }
   2956 
   2957     void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
   2958         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   2959             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   2960             final int numStacks = stacks.size();
   2961             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2962                 final ActivityStack stack = stacks.get(stackNdx);
   2963                 stack.scheduleDestroyActivities(app, reason);
   2964             }
   2965         }
   2966     }
   2967 
   2968     void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
   2969         // Examine all activities currently running in the process.
   2970         TaskRecord firstTask = null;
   2971         // Tasks is non-null only if two or more tasks are found.
   2972         ArraySet<TaskRecord> tasks = null;
   2973         if (DEBUG_RELEASE) Slog.d(TAG, "Trying to release some activities in " + app);
   2974         for (int i=0; i<app.activities.size(); i++) {
   2975             ActivityRecord r = app.activities.get(i);
   2976             // First, if we find an activity that is in the process of being destroyed,
   2977             // then we just aren't going to do anything for now; we want things to settle
   2978             // down before we try to prune more activities.
   2979             if (r.finishing || r.state == ActivityState.DESTROYING
   2980                     || r.state == ActivityState.DESTROYED) {
   2981                 if (DEBUG_RELEASE) Slog.d(TAG, "Abort release; already destroying: " + r);
   2982                 return;
   2983             }
   2984             // Don't consider any activies that are currently not in a state where they
   2985             // can be destroyed.
   2986             if (r.visible || !r.stopped || !r.haveState
   2987                     || r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING
   2988                     || r.state == ActivityState.PAUSED || r.state == ActivityState.STOPPING) {
   2989                 if (DEBUG_RELEASE) Slog.d(TAG, "Not releasing in-use activity: " + r);
   2990                 continue;
   2991             }
   2992             if (r.task != null) {
   2993                 if (DEBUG_RELEASE) Slog.d(TAG, "Collecting release task " + r.task
   2994                         + " from " + r);
   2995                 if (firstTask == null) {
   2996                     firstTask = r.task;
   2997                 } else if (firstTask != r.task) {
   2998                     if (tasks == null) {
   2999                         tasks = new ArraySet<>();
   3000                         tasks.add(firstTask);
   3001                     }
   3002                     tasks.add(r.task);
   3003                 }
   3004             }
   3005         }
   3006         if (tasks == null) {
   3007             if (DEBUG_RELEASE) Slog.d(TAG, "Didn't find two or more tasks to release");
   3008             return;
   3009         }
   3010         // If we have activities in multiple tasks that are in a position to be destroyed,
   3011         // let's iterate through the tasks and release the oldest one.
   3012         final int numDisplays = mActivityDisplays.size();
   3013         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
   3014             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3015             // Step through all stacks starting from behind, to hit the oldest things first.
   3016             for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
   3017                 final ActivityStack stack = stacks.get(stackNdx);
   3018                 // Try to release activities in this stack; if we manage to, we are done.
   3019                 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
   3020                     return;
   3021                 }
   3022             }
   3023         }
   3024     }
   3025 
   3026     boolean switchUserLocked(int userId, UserStartedState uss) {
   3027         mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
   3028         final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
   3029         mCurrentUser = userId;
   3030 
   3031         mStartingUsers.add(uss);
   3032         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
   3033             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3034             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3035                 final ActivityStack stack = stacks.get(stackNdx);
   3036                 stack.switchUserLocked(userId);
   3037                 TaskRecord task = stack.topTask();
   3038                 if (task != null) {
   3039                     mWindowManager.moveTaskToTop(task.taskId);
   3040                 }
   3041             }
   3042         }
   3043 
   3044         ActivityStack stack = getStack(restoreStackId);
   3045         if (stack == null) {
   3046             stack = mHomeStack;
   3047         }
   3048         final boolean homeInFront = stack.isHomeStack();
   3049         if (stack.isOnHomeDisplay()) {
   3050             moveHomeStack(homeInFront, "switchUserOnHomeDisplay");
   3051             TaskRecord task = stack.topTask();
   3052             if (task != null) {
   3053                 mWindowManager.moveTaskToTop(task.taskId);
   3054             }
   3055         } else {
   3056             // Stack was moved to another display while user was swapped out.
   3057             resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
   3058         }
   3059         return homeInFront;
   3060     }
   3061 
   3062     /**
   3063      * Add background users to send boot completed events to.
   3064      * @param userId The user being started in the background
   3065      * @param uss The state object for the user.
   3066      */
   3067     public void startBackgroundUserLocked(int userId, UserStartedState uss) {
   3068         mStartingBackgroundUsers.add(uss);
   3069     }
   3070 
   3071     final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
   3072         int N = mStoppingActivities.size();
   3073         if (N <= 0) return null;
   3074 
   3075         ArrayList<ActivityRecord> stops = null;
   3076 
   3077         final boolean nowVisible = allResumedActivitiesVisible();
   3078         for (int i=0; i<N; i++) {
   3079             ActivityRecord s = mStoppingActivities.get(i);
   3080             if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
   3081                     + nowVisible + " waitingVisible=" + s.waitingVisible
   3082                     + " finishing=" + s.finishing);
   3083             if (s.waitingVisible && nowVisible) {
   3084                 mWaitingVisibleActivities.remove(s);
   3085                 s.waitingVisible = false;
   3086                 if (s.finishing) {
   3087                     // If this activity is finishing, it is sitting on top of
   3088                     // everyone else but we now know it is no longer needed...
   3089                     // so get rid of it.  Otherwise, we need to go through the
   3090                     // normal flow and hide it once we determine that it is
   3091                     // hidden by the activities in front of it.
   3092                     if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
   3093                     mWindowManager.setAppVisibility(s.appToken, false);
   3094                 }
   3095             }
   3096             if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
   3097                 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
   3098                 if (stops == null) {
   3099                     stops = new ArrayList<ActivityRecord>();
   3100                 }
   3101                 stops.add(s);
   3102                 mStoppingActivities.remove(i);
   3103                 N--;
   3104                 i--;
   3105             }
   3106         }
   3107 
   3108         return stops;
   3109     }
   3110 
   3111     void validateTopActivitiesLocked() {
   3112         // FIXME
   3113 /*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3114             final ActivityStack stack = stacks.get(stackNdx);
   3115             final ActivityRecord r = stack.topRunningActivityLocked(null);
   3116             final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
   3117             if (isFrontStack(stack)) {
   3118                 if (r == null) {
   3119                     Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
   3120                 } else {
   3121                     final ActivityRecord pausing = stack.mPausingActivity;
   3122                     if (pausing != null && pausing == r) {
   3123                         Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
   3124                             " state=" + state);
   3125                     }
   3126                     if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
   3127                         Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
   3128                                 " state=" + state);
   3129                     }
   3130                 }
   3131             } else {
   3132                 final ActivityRecord resumed = stack.mResumedActivity;
   3133                 if (resumed != null && resumed == r) {
   3134                     Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
   3135                         " state=" + state);
   3136                 }
   3137                 if (r != null && (state == ActivityState.INITIALIZING
   3138                         || state == ActivityState.RESUMED)) {
   3139                     Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
   3140                             " state=" + state);
   3141                 }
   3142             }
   3143         }
   3144 */
   3145     }
   3146 
   3147     public void dump(PrintWriter pw, String prefix) {
   3148         pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
   3149                 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
   3150         pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
   3151         pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
   3152         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
   3153         pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
   3154     }
   3155 
   3156     ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
   3157         return getFocusedStack().getDumpActivitiesLocked(name);
   3158     }
   3159 
   3160     static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
   3161             boolean needSep, String prefix) {
   3162         if (activity != null) {
   3163             if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
   3164                 if (needSep) {
   3165                     pw.println();
   3166                 }
   3167                 pw.print(prefix);
   3168                 pw.println(activity);
   3169                 return true;
   3170             }
   3171         }
   3172         return false;
   3173     }
   3174 
   3175     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
   3176             boolean dumpClient, String dumpPackage) {
   3177         boolean printed = false;
   3178         boolean needSep = false;
   3179         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
   3180             ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
   3181             pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
   3182                     pw.println(" (activities from top to bottom):");
   3183             ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
   3184             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3185                 final ActivityStack stack = stacks.get(stackNdx);
   3186                 StringBuilder stackHeader = new StringBuilder(128);
   3187                 stackHeader.append("  Stack #");
   3188                 stackHeader.append(stack.mStackId);
   3189                 stackHeader.append(":");
   3190                 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
   3191                         needSep, stackHeader.toString());
   3192                 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
   3193                         !dumpAll, false, dumpPackage, true,
   3194                         "    Running activities (most recent first):", null);
   3195 
   3196                 needSep = printed;
   3197                 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
   3198                         "    mPausingActivity: ");
   3199                 if (pr) {
   3200                     printed = true;
   3201                     needSep = false;
   3202                 }
   3203                 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
   3204                         "    mResumedActivity: ");
   3205                 if (pr) {
   3206                     printed = true;
   3207                     needSep = false;
   3208                 }
   3209                 if (dumpAll) {
   3210                     pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
   3211                             "    mLastPausedActivity: ");
   3212                     if (pr) {
   3213                         printed = true;
   3214                         needSep = true;
   3215                     }
   3216                     printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
   3217                             needSep, "    mLastNoHistoryActivity: ");
   3218                 }
   3219                 needSep = printed;
   3220             }
   3221         }
   3222 
   3223         printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
   3224                 false, dumpPackage, true, "  Activities waiting to finish:", null);
   3225         printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
   3226                 false, dumpPackage, true, "  Activities waiting to stop:", null);
   3227         printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
   3228                 false, dumpPackage, true, "  Activities waiting for another to become visible:",
   3229                 null);
   3230         printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
   3231                 false, dumpPackage, true, "  Activities waiting to sleep:", null);
   3232         printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
   3233                 false, dumpPackage, true, "  Activities waiting to sleep:", null);
   3234 
   3235         return printed;
   3236     }
   3237 
   3238     static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
   3239             String prefix, String label, boolean complete, boolean brief, boolean client,
   3240             String dumpPackage, boolean needNL, String header1, String header2) {
   3241         TaskRecord lastTask = null;
   3242         String innerPrefix = null;
   3243         String[] args = null;
   3244         boolean printed = false;
   3245         for (int i=list.size()-1; i>=0; i--) {
   3246             final ActivityRecord r = list.get(i);
   3247             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   3248                 continue;
   3249             }
   3250             if (innerPrefix == null) {
   3251                 innerPrefix = prefix + "      ";
   3252                 args = new String[0];
   3253             }
   3254             printed = true;
   3255             final boolean full = !brief && (complete || !r.isInHistory());
   3256             if (needNL) {
   3257                 pw.println("");
   3258                 needNL = false;
   3259             }
   3260             if (header1 != null) {
   3261                 pw.println(header1);
   3262                 header1 = null;
   3263             }
   3264             if (header2 != null) {
   3265                 pw.println(header2);
   3266                 header2 = null;
   3267             }
   3268             if (lastTask != r.task) {
   3269                 lastTask = r.task;
   3270                 pw.print(prefix);
   3271                 pw.print(full ? "* " : "  ");
   3272                 pw.println(lastTask);
   3273                 if (full) {
   3274                     lastTask.dump(pw, prefix + "  ");
   3275                 } else if (complete) {
   3276                     // Complete + brief == give a summary.  Isn't that obvious?!?
   3277                     if (lastTask.intent != null) {
   3278                         pw.print(prefix); pw.print("  ");
   3279                                 pw.println(lastTask.intent.toInsecureStringWithClip());
   3280                     }
   3281                 }
   3282             }
   3283             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   3284             pw.print(" #"); pw.print(i); pw.print(": ");
   3285             pw.println(r);
   3286             if (full) {
   3287                 r.dump(pw, innerPrefix);
   3288             } else if (complete) {
   3289                 // Complete + brief == give a summary.  Isn't that obvious?!?
   3290                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   3291                 if (r.app != null) {
   3292                     pw.print(innerPrefix); pw.println(r.app);
   3293                 }
   3294             }
   3295             if (client && r.app != null && r.app.thread != null) {
   3296                 // flush anything that is already in the PrintWriter since the thread is going
   3297                 // to write to the file descriptor directly
   3298                 pw.flush();
   3299                 try {
   3300                     TransferPipe tp = new TransferPipe();
   3301                     try {
   3302                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   3303                                 r.appToken, innerPrefix, args);
   3304                         // Short timeout, since blocking here can
   3305                         // deadlock with the application.
   3306                         tp.go(fd, 2000);
   3307                     } finally {
   3308                         tp.kill();
   3309                     }
   3310                 } catch (IOException e) {
   3311                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   3312                 } catch (RemoteException e) {
   3313                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   3314                 }
   3315                 needNL = true;
   3316             }
   3317         }
   3318         return printed;
   3319     }
   3320 
   3321     void scheduleIdleTimeoutLocked(ActivityRecord next) {
   3322         if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
   3323         Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
   3324         mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
   3325     }
   3326 
   3327     final void scheduleIdleLocked() {
   3328         mHandler.sendEmptyMessage(IDLE_NOW_MSG);
   3329     }
   3330 
   3331     void removeTimeoutsForActivityLocked(ActivityRecord r) {
   3332         if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
   3333         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
   3334     }
   3335 
   3336     final void scheduleResumeTopActivities() {
   3337         if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
   3338             mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
   3339         }
   3340     }
   3341 
   3342     void removeSleepTimeouts() {
   3343         mSleepTimeout = false;
   3344         mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
   3345     }
   3346 
   3347     final void scheduleSleepTimeout() {
   3348         removeSleepTimeouts();
   3349         mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
   3350     }
   3351 
   3352     @Override
   3353     public void onDisplayAdded(int displayId) {
   3354         Slog.v(TAG, "Display added displayId=" + displayId);
   3355         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
   3356     }
   3357 
   3358     @Override
   3359     public void onDisplayRemoved(int displayId) {
   3360         Slog.v(TAG, "Display removed displayId=" + displayId);
   3361         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
   3362     }
   3363 
   3364     @Override
   3365     public void onDisplayChanged(int displayId) {
   3366         Slog.v(TAG, "Display changed displayId=" + displayId);
   3367         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
   3368     }
   3369 
   3370     public void handleDisplayAddedLocked(int displayId) {
   3371         boolean newDisplay;
   3372         synchronized (mService) {
   3373             newDisplay = mActivityDisplays.get(displayId) == null;
   3374             if (newDisplay) {
   3375                 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
   3376                 if (activityDisplay.mDisplay == null) {
   3377                     Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
   3378                     return;
   3379                 }
   3380                 mActivityDisplays.put(displayId, activityDisplay);
   3381             }
   3382         }
   3383         if (newDisplay) {
   3384             mWindowManager.onDisplayAdded(displayId);
   3385         }
   3386     }
   3387 
   3388     public void handleDisplayRemovedLocked(int displayId) {
   3389         synchronized (mService) {
   3390             ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
   3391             if (activityDisplay != null) {
   3392                 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
   3393                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
   3394                     stacks.get(stackNdx).mActivityContainer.detachLocked();
   3395                 }
   3396                 mActivityDisplays.remove(displayId);
   3397             }
   3398         }
   3399         mWindowManager.onDisplayRemoved(displayId);
   3400     }
   3401 
   3402     public void handleDisplayChangedLocked(int displayId) {
   3403         synchronized (mService) {
   3404             ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
   3405             if (activityDisplay != null) {
   3406                 // TODO: Update the bounds.
   3407             }
   3408         }
   3409         mWindowManager.onDisplayChanged(displayId);
   3410     }
   3411 
   3412     StackInfo getStackInfo(ActivityStack stack) {
   3413         StackInfo info = new StackInfo();
   3414         mWindowManager.getStackBounds(stack.mStackId, info.bounds);
   3415         info.displayId = Display.DEFAULT_DISPLAY;
   3416         info.stackId = stack.mStackId;
   3417 
   3418         ArrayList<TaskRecord> tasks = stack.getAllTasks();
   3419         final int numTasks = tasks.size();
   3420         int[] taskIds = new int[numTasks];
   3421         String[] taskNames = new String[numTasks];
   3422         for (int i = 0; i < numTasks; ++i) {
   3423             final TaskRecord task = tasks.get(i);
   3424             taskIds[i] = task.taskId;
   3425             taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
   3426                     : task.realActivity != null ? task.realActivity.flattenToString()
   3427                     : task.getTopActivity() != null ? task.getTopActivity().packageName
   3428                     : "unknown";
   3429         }
   3430         info.taskIds = taskIds;
   3431         info.taskNames = taskNames;
   3432         return info;
   3433     }
   3434 
   3435     StackInfo getStackInfoLocked(int stackId) {
   3436         ActivityStack stack = getStack(stackId);
   3437         if (stack != null) {
   3438             return getStackInfo(stack);
   3439         }
   3440         return null;
   3441     }
   3442 
   3443     ArrayList<StackInfo> getAllStackInfosLocked() {
   3444         ArrayList<StackInfo> list = new ArrayList<StackInfo>();
   3445         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
   3446             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
   3447             for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
   3448                 list.add(getStackInfo(stacks.get(ndx)));
   3449             }
   3450         }
   3451         return list;
   3452     }
   3453 
   3454     void showLockTaskToast() {
   3455         mLockTaskNotify.showToast(mLockTaskIsLocked);
   3456     }
   3457 
   3458     void setLockTaskModeLocked(TaskRecord task, boolean isLocked, String reason) {
   3459         if (task == null) {
   3460             // Take out of lock task mode if necessary
   3461             if (mLockTaskModeTask != null) {
   3462                 final Message lockTaskMsg = Message.obtain();
   3463                 lockTaskMsg.arg1 = mLockTaskModeTask.userId;
   3464                 lockTaskMsg.what = LOCK_TASK_END_MSG;
   3465                 mLockTaskModeTask = null;
   3466                 mHandler.sendMessage(lockTaskMsg);
   3467             }
   3468             return;
   3469         }
   3470         if (isLockTaskModeViolation(task)) {
   3471             Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
   3472             return;
   3473         }
   3474         mLockTaskModeTask = task;
   3475         findTaskToMoveToFrontLocked(task, 0, null, reason);
   3476         resumeTopActivitiesLocked();
   3477 
   3478         final Message lockTaskMsg = Message.obtain();
   3479         lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
   3480         lockTaskMsg.arg1 = mLockTaskModeTask.userId;
   3481         lockTaskMsg.what = LOCK_TASK_START_MSG;
   3482         lockTaskMsg.arg2 = !isLocked ? 1 : 0;
   3483         mHandler.sendMessage(lockTaskMsg);
   3484     }
   3485 
   3486     boolean isLockTaskModeViolation(TaskRecord task) {
   3487         return mLockTaskModeTask != null && mLockTaskModeTask != task;
   3488     }
   3489 
   3490     void endLockTaskModeIfTaskEnding(TaskRecord task) {
   3491         if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
   3492             final Message lockTaskMsg = Message.obtain();
   3493             lockTaskMsg.arg1 = mLockTaskModeTask.userId;
   3494             lockTaskMsg.what = LOCK_TASK_END_MSG;
   3495             mLockTaskModeTask = null;
   3496             mHandler.sendMessage(lockTaskMsg);
   3497         }
   3498     }
   3499 
   3500     boolean isInLockTaskMode() {
   3501         return mLockTaskModeTask != null;
   3502     }
   3503 
   3504     private final class ActivityStackSupervisorHandler extends Handler {
   3505 
   3506         public ActivityStackSupervisorHandler(Looper looper) {
   3507             super(looper);
   3508         }
   3509 
   3510         void activityIdleInternal(ActivityRecord r) {
   3511             synchronized (mService) {
   3512                 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
   3513             }
   3514         }
   3515 
   3516         @Override
   3517         public void handleMessage(Message msg) {
   3518             switch (msg.what) {
   3519                 case IDLE_TIMEOUT_MSG: {
   3520                     if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
   3521                     if (mService.mDidDexOpt) {
   3522                         mService.mDidDexOpt = false;
   3523                         Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
   3524                         nmsg.obj = msg.obj;
   3525                         mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
   3526                         return;
   3527                     }
   3528                     // We don't at this point know if the activity is fullscreen,
   3529                     // so we need to be conservative and assume it isn't.
   3530                     activityIdleInternal((ActivityRecord)msg.obj);
   3531                 } break;
   3532                 case IDLE_NOW_MSG: {
   3533                     if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
   3534                     activityIdleInternal((ActivityRecord)msg.obj);
   3535                 } break;
   3536                 case RESUME_TOP_ACTIVITY_MSG: {
   3537                     synchronized (mService) {
   3538                         resumeTopActivitiesLocked();
   3539                     }
   3540                 } break;
   3541                 case SLEEP_TIMEOUT_MSG: {
   3542                     synchronized (mService) {
   3543                         if (mService.isSleepingOrShuttingDown()) {
   3544                             Slog.w(TAG, "Sleep timeout!  Sleeping now.");
   3545                             mSleepTimeout = true;
   3546                             checkReadyForSleepLocked();
   3547                         }
   3548                     }
   3549                 } break;
   3550                 case LAUNCH_TIMEOUT_MSG: {
   3551                     if (mService.mDidDexOpt) {
   3552                         mService.mDidDexOpt = false;
   3553                         mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
   3554                         return;
   3555                     }
   3556                     synchronized (mService) {
   3557                         if (mLaunchingActivity.isHeld()) {
   3558                             Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
   3559                             if (VALIDATE_WAKE_LOCK_CALLER
   3560                                     && Binder.getCallingUid() != Process.myUid()) {
   3561                                 throw new IllegalStateException("Calling must be system uid");
   3562                             }
   3563                             mLaunchingActivity.release();
   3564                         }
   3565                     }
   3566                 } break;
   3567                 case HANDLE_DISPLAY_ADDED: {
   3568                     handleDisplayAddedLocked(msg.arg1);
   3569                 } break;
   3570                 case HANDLE_DISPLAY_CHANGED: {
   3571                     handleDisplayChangedLocked(msg.arg1);
   3572                 } break;
   3573                 case HANDLE_DISPLAY_REMOVED: {
   3574                     handleDisplayRemovedLocked(msg.arg1);
   3575                 } break;
   3576                 case CONTAINER_CALLBACK_VISIBILITY: {
   3577                     final ActivityContainer container = (ActivityContainer) msg.obj;
   3578                     final IActivityContainerCallback callback = container.mCallback;
   3579                     if (callback != null) {
   3580                         try {
   3581                             callback.setVisible(container.asBinder(), msg.arg1 == 1);
   3582                         } catch (RemoteException e) {
   3583                         }
   3584                     }
   3585                 } break;
   3586                 case LOCK_TASK_START_MSG: {
   3587                     // When lock task starts, we disable the status bars.
   3588                     try {
   3589                         if (mLockTaskNotify == null) {
   3590                             mLockTaskNotify = new LockTaskNotify(mService.mContext);
   3591                         }
   3592                         mLockTaskNotify.show(true);
   3593                         mLockTaskIsLocked = msg.arg2 == 0;
   3594                         if (getStatusBarService() != null) {
   3595                             int flags =
   3596                                     StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
   3597                             if (!mLockTaskIsLocked) {
   3598                                 flags ^= StatusBarManager.DISABLE_HOME
   3599                                         | StatusBarManager.DISABLE_RECENT;
   3600                             }
   3601                             getStatusBarService().disable(flags, mToken,
   3602                                     mService.mContext.getPackageName());
   3603                         }
   3604                         mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
   3605                         if (getDevicePolicyManager() != null) {
   3606                             getDevicePolicyManager().notifyLockTaskModeChanged(true,
   3607                                     (String)msg.obj, msg.arg1);
   3608                         }
   3609                     } catch (RemoteException ex) {
   3610                         throw new RuntimeException(ex);
   3611                     }
   3612                 } break;
   3613                 case LOCK_TASK_END_MSG: {
   3614                     // When lock task ends, we enable the status bars.
   3615                     try {
   3616                         if (getStatusBarService() != null) {
   3617                             getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
   3618                                     mService.mContext.getPackageName());
   3619                         }
   3620                         mWindowManager.reenableKeyguard(mToken);
   3621                         if (getDevicePolicyManager() != null) {
   3622                             getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
   3623                                     msg.arg1);
   3624                         }
   3625                         if (mLockTaskNotify == null) {
   3626                             mLockTaskNotify = new LockTaskNotify(mService.mContext);
   3627                         }
   3628                         mLockTaskNotify.show(false);
   3629                         try {
   3630                             boolean shouldLockKeyguard = Settings.Secure.getInt(
   3631                                     mService.mContext.getContentResolver(),
   3632                                     Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
   3633                             if (!mLockTaskIsLocked && shouldLockKeyguard) {
   3634                                 mWindowManager.lockNow(null);
   3635                                 mWindowManager.dismissKeyguard();
   3636                                 new LockPatternUtils(mService.mContext)
   3637                                         .requireCredentialEntry(UserHandle.USER_ALL);
   3638                             }
   3639                         } catch (SettingNotFoundException e) {
   3640                             // No setting, don't lock.
   3641                         }
   3642                     } catch (RemoteException ex) {
   3643                         throw new RuntimeException(ex);
   3644                     }
   3645                 } break;
   3646                 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
   3647                     final ActivityContainer container = (ActivityContainer) msg.obj;
   3648                     final IActivityContainerCallback callback = container.mCallback;
   3649                     if (callback != null) {
   3650                         try {
   3651                             callback.onAllActivitiesComplete(container.asBinder());
   3652                         } catch (RemoteException e) {
   3653                         }
   3654                     }
   3655                 } break;
   3656                 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
   3657                     synchronized (mService) {
   3658                         Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
   3659                                 msg.obj);
   3660                         final ActivityContainer container = (ActivityContainer) msg.obj;
   3661                         container.mStack.finishAllActivitiesLocked(true);
   3662                         container.onTaskListEmptyLocked();
   3663                     }
   3664                 } break;
   3665                 case LAUNCH_TASK_BEHIND_COMPLETE: {
   3666                     synchronized (mService) {
   3667                         ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
   3668                         if (r != null) {
   3669                             handleLaunchTaskBehindCompleteLocked(r);
   3670                         }
   3671                     }
   3672                 } break;
   3673             }
   3674         }
   3675     }
   3676 
   3677     class ActivityContainer extends android.app.IActivityContainer.Stub {
   3678         final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
   3679                 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
   3680         final int mStackId;
   3681         IActivityContainerCallback mCallback = null;
   3682         final ActivityStack mStack;
   3683         ActivityRecord mParentActivity = null;
   3684         String mIdString;
   3685 
   3686         boolean mVisible = true;
   3687 
   3688         /** Display this ActivityStack is currently on. Null if not attached to a Display. */
   3689         ActivityDisplay mActivityDisplay;
   3690 
   3691         final static int CONTAINER_STATE_HAS_SURFACE = 0;
   3692         final static int CONTAINER_STATE_NO_SURFACE = 1;
   3693         final static int CONTAINER_STATE_FINISHING = 2;
   3694         int mContainerState = CONTAINER_STATE_HAS_SURFACE;
   3695 
   3696         ActivityContainer(int stackId) {
   3697             synchronized (mService) {
   3698                 mStackId = stackId;
   3699                 mStack = new ActivityStack(this);
   3700                 mIdString = "ActivtyContainer{" + mStackId + "}";
   3701                 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
   3702             }
   3703         }
   3704 
   3705         void attachToDisplayLocked(ActivityDisplay activityDisplay) {
   3706             if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
   3707                     + " to display=" + activityDisplay);
   3708             mActivityDisplay = activityDisplay;
   3709             mStack.mDisplayId = activityDisplay.mDisplayId;
   3710             mStack.mStacks = activityDisplay.mStacks;
   3711 
   3712             activityDisplay.attachActivities(mStack);
   3713             mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
   3714         }
   3715 
   3716         @Override
   3717         public void attachToDisplay(int displayId) {
   3718             synchronized (mService) {
   3719                 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
   3720                 if (activityDisplay == null) {
   3721                     return;
   3722                 }
   3723                 attachToDisplayLocked(activityDisplay);
   3724             }
   3725         }
   3726 
   3727         @Override
   3728         public int getDisplayId() {
   3729             synchronized (mService) {
   3730                 if (mActivityDisplay != null) {
   3731                     return mActivityDisplay.mDisplayId;
   3732                 }
   3733             }
   3734             return -1;
   3735         }
   3736 
   3737         @Override
   3738         public boolean injectEvent(InputEvent event) {
   3739             final long origId = Binder.clearCallingIdentity();
   3740             try {
   3741                 synchronized (mService) {
   3742                     if (mActivityDisplay != null) {
   3743                         return mInputManagerInternal.injectInputEvent(event,
   3744                                 mActivityDisplay.mDisplayId,
   3745                                 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
   3746                     }
   3747                 }
   3748                 return false;
   3749             } finally {
   3750                 Binder.restoreCallingIdentity(origId);
   3751             }
   3752         }
   3753 
   3754         @Override
   3755         public void release() {
   3756             synchronized (mService) {
   3757                 if (mContainerState == CONTAINER_STATE_FINISHING) {
   3758                     return;
   3759                 }
   3760                 mContainerState = CONTAINER_STATE_FINISHING;
   3761 
   3762                 final Message msg =
   3763                         mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
   3764                 mHandler.sendMessageDelayed(msg, 2000);
   3765 
   3766                 long origId = Binder.clearCallingIdentity();
   3767                 try {
   3768                     mStack.finishAllActivitiesLocked(false);
   3769                     removePendingActivityLaunchesLocked(mStack);
   3770                 } finally {
   3771                     Binder.restoreCallingIdentity(origId);
   3772                 }
   3773             }
   3774         }
   3775 
   3776         protected void detachLocked() {
   3777             if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
   3778                     + mActivityDisplay + " Callers=" + Debug.getCallers(2));
   3779             if (mActivityDisplay != null) {
   3780                 mActivityDisplay.detachActivitiesLocked(mStack);
   3781                 mActivityDisplay = null;
   3782                 mStack.mDisplayId = -1;
   3783                 mStack.mStacks = null;
   3784                 mWindowManager.detachStack(mStackId);
   3785             }
   3786         }
   3787 
   3788         @Override
   3789         public final int startActivity(Intent intent) {
   3790             mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
   3791             int userId = mService.handleIncomingUser(Binder.getCallingPid(),
   3792                     Binder.getCallingUid(), mCurrentUser, false,
   3793                     ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
   3794             // TODO: Switch to user app stacks here.
   3795             intent.addFlags(FORCE_NEW_TASK_FLAGS);
   3796             String mimeType = intent.getType();
   3797             if (mimeType == null && intent.getData() != null
   3798                     && "content".equals(intent.getData().getScheme())) {
   3799                 mimeType = mService.getProviderMimeType(intent.getData(), userId);
   3800             }
   3801             return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0,
   3802                     0, null, null, null, null, userId, this, null);
   3803         }
   3804 
   3805         @Override
   3806         public final int startActivityIntentSender(IIntentSender intentSender) {
   3807             mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
   3808 
   3809             if (!(intentSender instanceof PendingIntentRecord)) {
   3810                 throw new IllegalArgumentException("Bad PendingIntent object");
   3811             }
   3812 
   3813             return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
   3814                     null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
   3815         }
   3816 
   3817         private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
   3818             int userId = mService.handleIncomingUser(Binder.getCallingPid(),
   3819                     Binder.getCallingUid(), mCurrentUser, false,
   3820                     ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
   3821             if (resolvedType == null) {
   3822                 resolvedType = intent.getType();
   3823                 if (resolvedType == null && intent.getData() != null
   3824                         && "content".equals(intent.getData().getScheme())) {
   3825                     resolvedType = mService.getProviderMimeType(intent.getData(), userId);
   3826                 }
   3827             }
   3828             ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
   3829             if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
   3830                 throw new SecurityException(
   3831                         "Attempt to embed activity that has not set allowEmbedded=\"true\"");
   3832             }
   3833         }
   3834 
   3835         /** Throw a SecurityException if allowEmbedded is not true */
   3836         @Override
   3837         public final void checkEmbeddedAllowed(Intent intent) {
   3838             checkEmbeddedAllowedInner(intent, null);
   3839         }
   3840 
   3841         /** Throw a SecurityException if allowEmbedded is not true */
   3842         @Override
   3843         public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
   3844             if (!(intentSender instanceof PendingIntentRecord)) {
   3845                 throw new IllegalArgumentException("Bad PendingIntent object");
   3846             }
   3847             PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
   3848             checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
   3849                     pendingIntent.key.requestResolvedType);
   3850         }
   3851 
   3852         @Override
   3853         public IBinder asBinder() {
   3854             return this;
   3855         }
   3856 
   3857         @Override
   3858         public void setSurface(Surface surface, int width, int height, int density) {
   3859             mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
   3860         }
   3861 
   3862         ActivityStackSupervisor getOuter() {
   3863             return ActivityStackSupervisor.this;
   3864         }
   3865 
   3866         boolean isAttachedLocked() {
   3867             return mActivityDisplay != null;
   3868         }
   3869 
   3870         void getBounds(Point outBounds) {
   3871             synchronized (mService) {
   3872                     if (mActivityDisplay != null) {
   3873                     mActivityDisplay.getBounds(outBounds);
   3874                 } else {
   3875                     outBounds.set(0, 0);
   3876                 }
   3877             }
   3878         }
   3879 
   3880         // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
   3881         void setVisible(boolean visible) {
   3882             if (mVisible != visible) {
   3883                 mVisible = visible;
   3884                 if (mCallback != null) {
   3885                     mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
   3886                             0 /* unused */, this).sendToTarget();
   3887                 }
   3888             }
   3889         }
   3890 
   3891         void setDrawn() {
   3892         }
   3893 
   3894         // You can always start a new task on a regular ActivityStack.
   3895         boolean isEligibleForNewTasks() {
   3896             return true;
   3897         }
   3898 
   3899         void onTaskListEmptyLocked() {
   3900         }
   3901 
   3902         @Override
   3903         public String toString() {
   3904             return mIdString + (mActivityDisplay == null ? "N" : "A");
   3905         }
   3906     }
   3907 
   3908     private class VirtualActivityContainer extends ActivityContainer {
   3909         Surface mSurface;
   3910         boolean mDrawn = false;
   3911 
   3912         VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
   3913             super(getNextStackId());
   3914             mParentActivity = parent;
   3915             mCallback = callback;
   3916             mContainerState = CONTAINER_STATE_NO_SURFACE;
   3917             mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
   3918         }
   3919 
   3920         @Override
   3921         public void setSurface(Surface surface, int width, int height, int density) {
   3922             super.setSurface(surface, width, height, density);
   3923 
   3924             synchronized (mService) {
   3925                 final long origId = Binder.clearCallingIdentity();
   3926                 try {
   3927                     setSurfaceLocked(surface, width, height, density);
   3928                 } finally {
   3929                     Binder.restoreCallingIdentity(origId);
   3930                 }
   3931             }
   3932         }
   3933 
   3934         private void setSurfaceLocked(Surface surface, int width, int height, int density) {
   3935             if (mContainerState == CONTAINER_STATE_FINISHING) {
   3936                 return;
   3937             }
   3938             VirtualActivityDisplay virtualActivityDisplay =
   3939                     (VirtualActivityDisplay) mActivityDisplay;
   3940             if (virtualActivityDisplay == null) {
   3941                 virtualActivityDisplay =
   3942                         new VirtualActivityDisplay(width, height, density);
   3943                 mActivityDisplay = virtualActivityDisplay;
   3944                 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
   3945                 attachToDisplayLocked(virtualActivityDisplay);
   3946             }
   3947 
   3948             if (mSurface != null) {
   3949                 mSurface.release();
   3950             }
   3951 
   3952             mSurface = surface;
   3953             if (surface != null) {
   3954                 mStack.resumeTopActivityLocked(null);
   3955             } else {
   3956                 mContainerState = CONTAINER_STATE_NO_SURFACE;
   3957                 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
   3958                 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
   3959                     mStack.startPausingLocked(false, true, false, false);
   3960                 }
   3961             }
   3962 
   3963             setSurfaceIfReadyLocked();
   3964 
   3965             if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
   3966                     + virtualActivityDisplay);
   3967         }
   3968 
   3969         @Override
   3970         boolean isAttachedLocked() {
   3971             return mSurface != null && super.isAttachedLocked();
   3972         }
   3973 
   3974         @Override
   3975         void setDrawn() {
   3976             synchronized (mService) {
   3977                 mDrawn = true;
   3978                 setSurfaceIfReadyLocked();
   3979             }
   3980         }
   3981 
   3982         // Never start a new task on an ActivityView if it isn't explicitly specified.
   3983         @Override
   3984         boolean isEligibleForNewTasks() {
   3985             return false;
   3986         }
   3987 
   3988         void onTaskListEmptyLocked() {
   3989             mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
   3990             detachLocked();
   3991             deleteActivityContainer(this);
   3992             mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
   3993         }
   3994 
   3995         private void setSurfaceIfReadyLocked() {
   3996             if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
   3997                     " mContainerState=" + mContainerState + " mSurface=" + mSurface);
   3998             if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
   3999                 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
   4000                 mContainerState = CONTAINER_STATE_HAS_SURFACE;
   4001             }
   4002         }
   4003     }
   4004 
   4005     /** Exactly one of these classes per Display in the system. Capable of holding zero or more
   4006      * attached {@link ActivityStack}s */
   4007     class ActivityDisplay {
   4008         /** Actual Display this object tracks. */
   4009         int mDisplayId;
   4010         Display mDisplay;
   4011         DisplayInfo mDisplayInfo = new DisplayInfo();
   4012 
   4013         /** All of the stacks on this display. Order matters, topmost stack is in front of all other
   4014          * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
   4015         final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
   4016 
   4017         ActivityRecord mVisibleBehindActivity;
   4018 
   4019         ActivityDisplay() {
   4020         }
   4021 
   4022         // After instantiation, check that mDisplay is not null before using this. The alternative
   4023         // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
   4024         ActivityDisplay(int displayId) {
   4025             final Display display = mDisplayManager.getDisplay(displayId);
   4026             if (display == null) {
   4027                 return;
   4028             }
   4029             init(display);
   4030         }
   4031 
   4032         void init(Display display) {
   4033             mDisplay = display;
   4034             mDisplayId = display.getDisplayId();
   4035             mDisplay.getDisplayInfo(mDisplayInfo);
   4036         }
   4037 
   4038         void attachActivities(ActivityStack stack) {
   4039             if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
   4040                     + mDisplayId);
   4041             mStacks.add(stack);
   4042         }
   4043 
   4044         void detachActivitiesLocked(ActivityStack stack) {
   4045             if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
   4046                     + " from displayId=" + mDisplayId);
   4047             mStacks.remove(stack);
   4048         }
   4049 
   4050         void getBounds(Point bounds) {
   4051             mDisplay.getDisplayInfo(mDisplayInfo);
   4052             bounds.x = mDisplayInfo.appWidth;
   4053             bounds.y = mDisplayInfo.appHeight;
   4054         }
   4055 
   4056         void setVisibleBehindActivity(ActivityRecord r) {
   4057             mVisibleBehindActivity = r;
   4058         }
   4059 
   4060         boolean hasVisibleBehindActivity() {
   4061             return mVisibleBehindActivity != null;
   4062         }
   4063 
   4064         @Override
   4065         public String toString() {
   4066             return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
   4067         }
   4068     }
   4069 
   4070     class VirtualActivityDisplay extends ActivityDisplay {
   4071         VirtualDisplay mVirtualDisplay;
   4072 
   4073         VirtualActivityDisplay(int width, int height, int density) {
   4074             DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
   4075             mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
   4076                     VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
   4077                     DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
   4078                     DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
   4079 
   4080             init(mVirtualDisplay.getDisplay());
   4081 
   4082             mWindowManager.handleDisplayAdded(mDisplayId);
   4083         }
   4084 
   4085         void setSurface(Surface surface) {
   4086             if (mVirtualDisplay != null) {
   4087                 mVirtualDisplay.setSurface(surface);
   4088             }
   4089         }
   4090 
   4091         @Override
   4092         void detachActivitiesLocked(ActivityStack stack) {
   4093             super.detachActivitiesLocked(stack);
   4094             if (mVirtualDisplay != null) {
   4095                 mVirtualDisplay.release();
   4096                 mVirtualDisplay = null;
   4097             }
   4098         }
   4099 
   4100         @Override
   4101         public String toString() {
   4102             return "VirtualActivityDisplay={" + mDisplayId + "}";
   4103         }
   4104     }
   4105 
   4106     private boolean isLeanbackOnlyDevice() {
   4107         boolean onLeanbackOnly = false;
   4108         try {
   4109             onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
   4110                     PackageManager.FEATURE_LEANBACK_ONLY);
   4111         } catch (RemoteException e) {
   4112             // noop
   4113         }
   4114 
   4115         return onLeanbackOnly;
   4116     }
   4117 }
   4118