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_RESULTS;
     28 import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
     29 import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
     30 import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
     31 import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
     32 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
     33 import static com.android.server.am.ActivityManagerService.TAG;
     34 
     35 import android.app.Activity;
     36 import android.app.ActivityManager;
     37 import android.app.ActivityOptions;
     38 import android.app.AppGlobals;
     39 import android.app.IActivityManager;
     40 import android.app.IApplicationThread;
     41 import android.app.IThumbnailReceiver;
     42 import android.app.PendingIntent;
     43 import android.app.ActivityManager.RunningTaskInfo;
     44 import android.app.IActivityManager.WaitResult;
     45 import android.app.ResultInfo;
     46 import android.content.ComponentName;
     47 import android.content.Context;
     48 import android.content.IIntentSender;
     49 import android.content.Intent;
     50 import android.content.IntentSender;
     51 import android.content.pm.ActivityInfo;
     52 import android.content.pm.ApplicationInfo;
     53 import android.content.pm.PackageManager;
     54 import android.content.pm.ResolveInfo;
     55 import android.content.res.Configuration;
     56 import android.os.Binder;
     57 import android.os.Bundle;
     58 import android.os.Debug;
     59 import android.os.Handler;
     60 import android.os.IBinder;
     61 import android.os.Looper;
     62 import android.os.Message;
     63 import android.os.ParcelFileDescriptor;
     64 import android.os.PowerManager;
     65 import android.os.Process;
     66 import android.os.RemoteException;
     67 import android.os.SystemClock;
     68 import android.os.UserHandle;
     69 import android.util.EventLog;
     70 import android.util.Slog;
     71 import android.util.SparseIntArray;
     72 
     73 import com.android.internal.app.HeavyWeightSwitcherActivity;
     74 import com.android.internal.os.TransferPipe;
     75 import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
     76 import com.android.server.am.ActivityStack.ActivityState;
     77 import com.android.server.wm.StackBox;
     78 import com.android.server.wm.WindowManagerService;
     79 
     80 import java.io.FileDescriptor;
     81 import java.io.IOException;
     82 import java.io.PrintWriter;
     83 import java.util.ArrayList;
     84 import java.util.List;
     85 
     86 public final class ActivityStackSupervisor {
     87     static final boolean DEBUG = ActivityManagerService.DEBUG || false;
     88     static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
     89     static final boolean DEBUG_APP = DEBUG || false;
     90     static final boolean DEBUG_SAVED_STATE = DEBUG || false;
     91     static final boolean DEBUG_STATES = DEBUG || false;
     92     static final boolean DEBUG_IDLE = DEBUG || false;
     93 
     94     public static final int HOME_STACK_ID = 0;
     95 
     96     /** How long we wait until giving up on the last activity telling us it is idle. */
     97     static final int IDLE_TIMEOUT = 10*1000;
     98 
     99     /** How long we can hold the sleep wake lock before giving up. */
    100     static final int SLEEP_TIMEOUT = 5*1000;
    101 
    102     // How long we can hold the launch wake lock before giving up.
    103     static final int LAUNCH_TIMEOUT = 10*1000;
    104 
    105     static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
    106     static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
    107     static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
    108     static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
    109     static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
    110 
    111     // For debugging to make sure the caller when acquiring/releasing our
    112     // wake lock is the system process.
    113     static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
    114 
    115     final ActivityManagerService mService;
    116     final Context mContext;
    117     final Looper mLooper;
    118 
    119     final ActivityStackSupervisorHandler mHandler;
    120 
    121     /** Short cut */
    122     WindowManagerService mWindowManager;
    123 
    124     /** Dismiss the keyguard after the next activity is displayed? */
    125     boolean mDismissKeyguardOnNextActivity = false;
    126 
    127     /** Identifier counter for all ActivityStacks */
    128     private int mLastStackId = HOME_STACK_ID;
    129 
    130     /** Task identifier that activities are currently being started in.  Incremented each time a
    131      * new task is created. */
    132     private int mCurTaskId = 0;
    133 
    134     /** The current user */
    135     private int mCurrentUser;
    136 
    137     /** The stack containing the launcher app */
    138     private ActivityStack mHomeStack;
    139 
    140     /** The non-home stack currently receiving input or launching the next activity. If home is
    141      * in front then mHomeStack overrides mFocusedStack.
    142      * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
    143     private ActivityStack mFocusedStack;
    144 
    145     /** All the non-launcher stacks */
    146     private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
    147 
    148     private static final int STACK_STATE_HOME_IN_FRONT = 0;
    149     private static final int STACK_STATE_HOME_TO_BACK = 1;
    150     private static final int STACK_STATE_HOME_IN_BACK = 2;
    151     private static final int STACK_STATE_HOME_TO_FRONT = 3;
    152     private int mStackState = STACK_STATE_HOME_IN_FRONT;
    153 
    154     /** List of activities that are waiting for a new activity to become visible before completing
    155      * whatever operation they are supposed to do. */
    156     final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
    157 
    158     /** List of processes waiting to find out about the next visible activity. */
    159     final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
    160             new ArrayList<IActivityManager.WaitResult>();
    161 
    162     /** List of processes waiting to find out about the next launched activity. */
    163     final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
    164             new ArrayList<IActivityManager.WaitResult>();
    165 
    166     /** List of activities that are ready to be stopped, but waiting for the next activity to
    167      * settle down before doing so. */
    168     final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
    169 
    170     /** List of activities that are ready to be finished, but waiting for the previous activity to
    171      * settle down before doing so.  It contains ActivityRecord objects. */
    172     final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
    173 
    174     /** List of activities that are in the process of going to sleep. */
    175     final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
    176 
    177     /** List of ActivityRecord objects that have been finished and must still report back to a
    178      * pending thumbnail receiver. */
    179     final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
    180 
    181     /** Used on user changes */
    182     final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
    183 
    184     /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
    185      * is being brought in front of us. */
    186     boolean mUserLeaving = false;
    187 
    188     /** Set when we have taken too long waiting to go to sleep. */
    189     boolean mSleepTimeout = false;
    190 
    191     /**
    192      * We don't want to allow the device to go to sleep while in the process
    193      * of launching an activity.  This is primarily to allow alarm intent
    194      * receivers to launch an activity and get that to run before the device
    195      * goes back to sleep.
    196      */
    197     final PowerManager.WakeLock mLaunchingActivity;
    198 
    199     /**
    200      * Set when the system is going to sleep, until we have
    201      * successfully paused the current activity and released our wake lock.
    202      * At that point the system is allowed to actually sleep.
    203      */
    204     final PowerManager.WakeLock mGoingToSleep;
    205 
    206     /** Stack id of the front stack when user switched, indexed by userId. */
    207     SparseIntArray mUserStackInFront = new SparseIntArray(2);
    208 
    209     public ActivityStackSupervisor(ActivityManagerService service, Context context,
    210             Looper looper) {
    211         mService = service;
    212         mContext = context;
    213         mLooper = looper;
    214         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    215         mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
    216         mHandler = new ActivityStackSupervisorHandler(looper);
    217         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
    218             throw new IllegalStateException("Calling must be system uid");
    219         }
    220         mLaunchingActivity =
    221                 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
    222         mLaunchingActivity.setReferenceCounted(false);
    223     }
    224 
    225     void setWindowManager(WindowManagerService wm) {
    226         mWindowManager = wm;
    227         mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
    228         mStacks.add(mHomeStack);
    229     }
    230 
    231     void dismissKeyguard() {
    232         if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
    233         if (mDismissKeyguardOnNextActivity) {
    234             mDismissKeyguardOnNextActivity = false;
    235             mWindowManager.dismissKeyguard();
    236         }
    237     }
    238 
    239     ActivityStack getFocusedStack() {
    240         if (mFocusedStack == null) {
    241             return mHomeStack;
    242         }
    243         switch (mStackState) {
    244             case STACK_STATE_HOME_IN_FRONT:
    245             case STACK_STATE_HOME_TO_FRONT:
    246                 return mHomeStack;
    247             case STACK_STATE_HOME_IN_BACK:
    248             case STACK_STATE_HOME_TO_BACK:
    249             default:
    250                 return mFocusedStack;
    251         }
    252     }
    253 
    254     ActivityStack getLastStack() {
    255         switch (mStackState) {
    256             case STACK_STATE_HOME_IN_FRONT:
    257             case STACK_STATE_HOME_TO_BACK:
    258                 return mHomeStack;
    259             case STACK_STATE_HOME_TO_FRONT:
    260             case STACK_STATE_HOME_IN_BACK:
    261             default:
    262                 return mFocusedStack;
    263         }
    264     }
    265 
    266     boolean isFrontStack(ActivityStack stack) {
    267         return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
    268     }
    269 
    270     void moveHomeStack(boolean toFront) {
    271         final boolean homeInFront = isFrontStack(mHomeStack);
    272         if (homeInFront ^ toFront) {
    273             if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
    274                     stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
    275                     STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
    276             mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
    277         }
    278     }
    279 
    280     void moveHomeToTop() {
    281         moveHomeStack(true);
    282         mHomeStack.moveHomeTaskToTop();
    283     }
    284 
    285     boolean resumeHomeActivity(ActivityRecord prev) {
    286         moveHomeToTop();
    287         if (prev != null) {
    288             prev.task.mOnTopOfHome = false;
    289         }
    290         ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
    291         if (r != null && r.isHomeActivity()) {
    292             mService.setFocusedActivityLocked(r);
    293             return resumeTopActivitiesLocked(mHomeStack, prev, null);
    294         }
    295         return mService.startHomeActivityLocked(mCurrentUser);
    296     }
    297 
    298     void setDismissKeyguard(boolean dismiss) {
    299         if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
    300         mDismissKeyguardOnNextActivity = dismiss;
    301     }
    302 
    303     TaskRecord anyTaskForIdLocked(int id) {
    304         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    305             ActivityStack stack = mStacks.get(stackNdx);
    306             TaskRecord task = stack.taskForIdLocked(id);
    307             if (task != null) {
    308                 return task;
    309             }
    310         }
    311         return null;
    312     }
    313 
    314     ActivityRecord isInAnyStackLocked(IBinder token) {
    315         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    316             final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
    317             if (r != null) {
    318                 return r;
    319             }
    320         }
    321         return null;
    322     }
    323 
    324     int getNextTaskId() {
    325         do {
    326             mCurTaskId++;
    327             if (mCurTaskId <= 0) {
    328                 mCurTaskId = 1;
    329             }
    330         } while (anyTaskForIdLocked(mCurTaskId) != null);
    331         return mCurTaskId;
    332     }
    333 
    334     void removeTask(TaskRecord task) {
    335         mWindowManager.removeTask(task.taskId);
    336         final ActivityStack stack = task.stack;
    337         final ActivityRecord r = stack.mResumedActivity;
    338         if (r != null && r.task == task) {
    339             stack.mResumedActivity = null;
    340         }
    341         if (stack.removeTask(task) && !stack.isHomeStack()) {
    342             if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
    343             mStacks.remove(stack);
    344             final int stackId = stack.mStackId;
    345             final int nextStackId = mWindowManager.removeStack(stackId);
    346             // TODO: Perhaps we need to let the ActivityManager determine the next focus...
    347             if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {
    348                 // If this is the last app stack, set mFocusedStack to null.
    349                 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
    350             }
    351         }
    352     }
    353 
    354     ActivityRecord resumedAppLocked() {
    355         ActivityStack stack = getFocusedStack();
    356         if (stack == null) {
    357             return null;
    358         }
    359         ActivityRecord resumedActivity = stack.mResumedActivity;
    360         if (resumedActivity == null || resumedActivity.app == null) {
    361             resumedActivity = stack.mPausingActivity;
    362             if (resumedActivity == null || resumedActivity.app == null) {
    363                 resumedActivity = stack.topRunningActivityLocked(null);
    364             }
    365         }
    366         return resumedActivity;
    367     }
    368 
    369     boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
    370         boolean didSomething = false;
    371         final String processName = app.processName;
    372         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    373             final ActivityStack stack = mStacks.get(stackNdx);
    374             if (!isFrontStack(stack)) {
    375                 continue;
    376             }
    377             ActivityRecord hr = stack.topRunningActivityLocked(null);
    378             if (hr != null) {
    379                 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
    380                         && processName.equals(hr.processName)) {
    381                     try {
    382                         if (headless) {
    383                             Slog.e(TAG, "Starting activities not supported on headless device: "
    384                                     + hr);
    385                         } else if (realStartActivityLocked(hr, app, true, true)) {
    386                             didSomething = true;
    387                         }
    388                     } catch (Exception e) {
    389                         Slog.w(TAG, "Exception in new application when starting activity "
    390                               + hr.intent.getComponent().flattenToShortString(), e);
    391                         throw e;
    392                     }
    393                 }
    394             }
    395         }
    396         if (!didSomething) {
    397             ensureActivitiesVisibleLocked(null, 0);
    398         }
    399         return didSomething;
    400     }
    401 
    402     boolean allResumedActivitiesIdle() {
    403         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    404             final ActivityStack stack = mStacks.get(stackNdx);
    405             if (!isFrontStack(stack)) {
    406                 continue;
    407             }
    408             final ActivityRecord resumedActivity = stack.mResumedActivity;
    409             if (resumedActivity == null || !resumedActivity.idle) {
    410                 return false;
    411             }
    412         }
    413         return true;
    414     }
    415 
    416     boolean allResumedActivitiesComplete() {
    417         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    418             final ActivityStack stack = mStacks.get(stackNdx);
    419             if (isFrontStack(stack)) {
    420                 final ActivityRecord r = stack.mResumedActivity;
    421                 if (r != null && r.state != ActivityState.RESUMED) {
    422                     return false;
    423                 }
    424             }
    425         }
    426         // TODO: Not sure if this should check if all Paused are complete too.
    427         switch (mStackState) {
    428             case STACK_STATE_HOME_TO_BACK:
    429                 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
    430                         stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
    431                         stackStateToString(STACK_STATE_HOME_IN_BACK));
    432                 mStackState = STACK_STATE_HOME_IN_BACK;
    433                 break;
    434             case STACK_STATE_HOME_TO_FRONT:
    435                 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
    436                         stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
    437                         stackStateToString(STACK_STATE_HOME_IN_FRONT));
    438                 mStackState = STACK_STATE_HOME_IN_FRONT;
    439                 break;
    440         }
    441         return true;
    442     }
    443 
    444     boolean allResumedActivitiesVisible() {
    445         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    446             final ActivityStack stack = mStacks.get(stackNdx);
    447             final ActivityRecord r = stack.mResumedActivity;
    448             if (r != null && (!r.nowVisible || r.waitingVisible)) {
    449                 return false;
    450             }
    451         }
    452         return true;
    453     }
    454 
    455     /**
    456      * Pause all activities in either all of the stacks or just the back stacks.
    457      * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
    458      * @return true if any activity was paused as a result of this call.
    459      */
    460     boolean pauseBackStacks(boolean userLeaving) {
    461         boolean someActivityPaused = false;
    462         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    463             final ActivityStack stack = mStacks.get(stackNdx);
    464             if (!isFrontStack(stack) && stack.mResumedActivity != null) {
    465                 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
    466                         " mResumedActivity=" + stack.mResumedActivity);
    467                 stack.startPausingLocked(userLeaving, false);
    468                 someActivityPaused = true;
    469             }
    470         }
    471         return someActivityPaused;
    472     }
    473 
    474     boolean allPausedActivitiesComplete() {
    475         boolean pausing = true;
    476         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    477             final ActivityStack stack = mStacks.get(stackNdx);
    478             final ActivityRecord r = stack.mPausingActivity;
    479             if (r != null && r.state != ActivityState.PAUSED
    480                     && r.state != ActivityState.STOPPED
    481                     && r.state != ActivityState.STOPPING) {
    482                 if (DEBUG_STATES) {
    483                     Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
    484                     pausing = false;
    485                 } else {
    486                     return false;
    487                 }
    488             }
    489         }
    490         return pausing;
    491     }
    492 
    493     void reportActivityVisibleLocked(ActivityRecord r) {
    494         for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
    495             WaitResult w = mWaitingActivityVisible.get(i);
    496             w.timeout = false;
    497             if (r != null) {
    498                 w.who = new ComponentName(r.info.packageName, r.info.name);
    499             }
    500             w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
    501             w.thisTime = w.totalTime;
    502         }
    503         mService.notifyAll();
    504         dismissKeyguard();
    505     }
    506 
    507     void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
    508             long thisTime, long totalTime) {
    509         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
    510             WaitResult w = mWaitingActivityLaunched.remove(i);
    511             w.timeout = timeout;
    512             if (r != null) {
    513                 w.who = new ComponentName(r.info.packageName, r.info.name);
    514             }
    515             w.thisTime = thisTime;
    516             w.totalTime = totalTime;
    517         }
    518         mService.notifyAll();
    519     }
    520 
    521     ActivityRecord topRunningActivityLocked() {
    522         final ActivityStack focusedStack = getFocusedStack();
    523         ActivityRecord r = focusedStack.topRunningActivityLocked(null);
    524         if (r != null) {
    525             return r;
    526         }
    527 
    528         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
    529             final ActivityStack stack = mStacks.get(stackNdx);
    530             if (stack != focusedStack && isFrontStack(stack)) {
    531                 r = stack.topRunningActivityLocked(null);
    532                 if (r != null) {
    533                     return r;
    534                 }
    535             }
    536         }
    537         return null;
    538     }
    539 
    540     ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
    541             PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
    542         ActivityRecord r = null;
    543 
    544         // Gather all of the running tasks for each stack into runningTaskLists.
    545         final int numStacks = mStacks.size();
    546         ArrayList<RunningTaskInfo>[] runningTaskLists = new ArrayList[numStacks];
    547         for (int stackNdx = numStacks - 1; stackNdx >= 0; --stackNdx) {
    548             final ActivityStack stack = mStacks.get(stackNdx);
    549             ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
    550             runningTaskLists[stackNdx] = stackTaskList;
    551             final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
    552             if (isFrontStack(stack)) {
    553                 r = ar;
    554             }
    555         }
    556 
    557         // The lists are already sorted from most recent to oldest. Just pull the most recent off
    558         // each list and add it to list. Stop when all lists are empty or maxNum reached.
    559         while (maxNum > 0) {
    560             long mostRecentActiveTime = Long.MIN_VALUE;
    561             ArrayList<RunningTaskInfo> selectedStackList = null;
    562             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
    563                 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists[stackNdx];
    564                 if (!stackTaskList.isEmpty()) {
    565                     final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
    566                     if (lastActiveTime > mostRecentActiveTime) {
    567                         mostRecentActiveTime = lastActiveTime;
    568                         selectedStackList = stackTaskList;
    569                     }
    570                 }
    571             }
    572             if (selectedStackList != null) {
    573                 list.add(selectedStackList.remove(0));
    574                 --maxNum;
    575             } else {
    576                 break;
    577             }
    578         }
    579 
    580         return r;
    581     }
    582 
    583     ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
    584             String profileFile, ParcelFileDescriptor profileFd, int userId) {
    585         // Collect information about the target of the Intent.
    586         ActivityInfo aInfo;
    587         try {
    588             ResolveInfo rInfo =
    589                 AppGlobals.getPackageManager().resolveIntent(
    590                         intent, resolvedType,
    591                         PackageManager.MATCH_DEFAULT_ONLY
    592                                     | ActivityManagerService.STOCK_PM_FLAGS, userId);
    593             aInfo = rInfo != null ? rInfo.activityInfo : null;
    594         } catch (RemoteException e) {
    595             aInfo = null;
    596         }
    597 
    598         if (aInfo != null) {
    599             // Store the found target back into the intent, because now that
    600             // we have it we never want to do this again.  For example, if the
    601             // user navigates back to this point in the history, we should
    602             // always restart the exact same activity.
    603             intent.setComponent(new ComponentName(
    604                     aInfo.applicationInfo.packageName, aInfo.name));
    605 
    606             // Don't debug things in the system process
    607             if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
    608                 if (!aInfo.processName.equals("system")) {
    609                     mService.setDebugApp(aInfo.processName, true, false);
    610                 }
    611             }
    612 
    613             if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
    614                 if (!aInfo.processName.equals("system")) {
    615                     mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
    616                 }
    617             }
    618 
    619             if (profileFile != null) {
    620                 if (!aInfo.processName.equals("system")) {
    621                     mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
    622                             profileFile, profileFd,
    623                             (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
    624                 }
    625             }
    626         }
    627         return aInfo;
    628     }
    629 
    630     void startHomeActivity(Intent intent, ActivityInfo aInfo) {
    631         moveHomeToTop();
    632         startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
    633                 null, false, null);
    634     }
    635 
    636     final int startActivityMayWait(IApplicationThread caller, int callingUid,
    637             String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
    638             String resultWho, int requestCode, int startFlags, String profileFile,
    639             ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
    640             Bundle options, int userId) {
    641         // Refuse possible leaked file descriptors
    642         if (intent != null && intent.hasFileDescriptors()) {
    643             throw new IllegalArgumentException("File descriptors passed in Intent");
    644         }
    645         boolean componentSpecified = intent.getComponent() != null;
    646 
    647         // Don't modify the client's object!
    648         intent = new Intent(intent);
    649 
    650         // Collect information about the target of the Intent.
    651         ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
    652                 profileFile, profileFd, userId);
    653 
    654         synchronized (mService) {
    655             int callingPid;
    656             if (callingUid >= 0) {
    657                 callingPid = -1;
    658             } else if (caller == null) {
    659                 callingPid = Binder.getCallingPid();
    660                 callingUid = Binder.getCallingUid();
    661             } else {
    662                 callingPid = callingUid = -1;
    663             }
    664 
    665             final ActivityStack stack = getFocusedStack();
    666             stack.mConfigWillChange = config != null
    667                     && mService.mConfiguration.diff(config) != 0;
    668             if (DEBUG_CONFIGURATION) Slog.v(TAG,
    669                     "Starting activity when config will change = " + stack.mConfigWillChange);
    670 
    671             final long origId = Binder.clearCallingIdentity();
    672 
    673             if (aInfo != null &&
    674                     (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
    675                 // This may be a heavy-weight process!  Check to see if we already
    676                 // have another, different heavy-weight process running.
    677                 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
    678                     if (mService.mHeavyWeightProcess != null &&
    679                             (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
    680                             !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
    681                         int realCallingUid = callingUid;
    682                         if (caller != null) {
    683                             ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
    684                             if (callerApp != null) {
    685                                 realCallingUid = callerApp.info.uid;
    686                             } else {
    687                                 Slog.w(TAG, "Unable to find app for caller " + caller
    688                                       + " (pid=" + callingPid + ") when starting: "
    689                                       + intent.toString());
    690                                 ActivityOptions.abort(options);
    691                                 return ActivityManager.START_PERMISSION_DENIED;
    692                             }
    693                         }
    694 
    695                         IIntentSender target = mService.getIntentSenderLocked(
    696                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
    697                                 realCallingUid, userId, null, null, 0, new Intent[] { intent },
    698                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
    699                                 | PendingIntent.FLAG_ONE_SHOT, null);
    700 
    701                         Intent newIntent = new Intent();
    702                         if (requestCode >= 0) {
    703                             // Caller is requesting a result.
    704                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
    705                         }
    706                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
    707                                 new IntentSender(target));
    708                         if (mService.mHeavyWeightProcess.activities.size() > 0) {
    709                             ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
    710                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
    711                                     hist.packageName);
    712                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
    713                                     hist.task.taskId);
    714                         }
    715                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
    716                                 aInfo.packageName);
    717                         newIntent.setFlags(intent.getFlags());
    718                         newIntent.setClassName("android",
    719                                 HeavyWeightSwitcherActivity.class.getName());
    720                         intent = newIntent;
    721                         resolvedType = null;
    722                         caller = null;
    723                         callingUid = Binder.getCallingUid();
    724                         callingPid = Binder.getCallingPid();
    725                         componentSpecified = true;
    726                         try {
    727                             ResolveInfo rInfo =
    728                                 AppGlobals.getPackageManager().resolveIntent(
    729                                         intent, null,
    730                                         PackageManager.MATCH_DEFAULT_ONLY
    731                                         | ActivityManagerService.STOCK_PM_FLAGS, userId);
    732                             aInfo = rInfo != null ? rInfo.activityInfo : null;
    733                             aInfo = mService.getActivityInfoForUser(aInfo, userId);
    734                         } catch (RemoteException e) {
    735                             aInfo = null;
    736                         }
    737                     }
    738                 }
    739             }
    740 
    741             int res = startActivityLocked(caller, intent, resolvedType,
    742                     aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
    743                     callingPackage, startFlags, options, componentSpecified, null);
    744 
    745             if (stack.mConfigWillChange) {
    746                 // If the caller also wants to switch to a new configuration,
    747                 // do so now.  This allows a clean switch, as we are waiting
    748                 // for the current activity to pause (so we will not destroy
    749                 // it), and have not yet started the next activity.
    750                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
    751                         "updateConfiguration()");
    752                 stack.mConfigWillChange = false;
    753                 if (DEBUG_CONFIGURATION) Slog.v(TAG,
    754                         "Updating to new configuration after starting activity.");
    755                 mService.updateConfigurationLocked(config, null, false, false);
    756             }
    757 
    758             Binder.restoreCallingIdentity(origId);
    759 
    760             if (outResult != null) {
    761                 outResult.result = res;
    762                 if (res == ActivityManager.START_SUCCESS) {
    763                     mWaitingActivityLaunched.add(outResult);
    764                     do {
    765                         try {
    766                             mService.wait();
    767                         } catch (InterruptedException e) {
    768                         }
    769                     } while (!outResult.timeout && outResult.who == null);
    770                 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
    771                     ActivityRecord r = stack.topRunningActivityLocked(null);
    772                     if (r.nowVisible) {
    773                         outResult.timeout = false;
    774                         outResult.who = new ComponentName(r.info.packageName, r.info.name);
    775                         outResult.totalTime = 0;
    776                         outResult.thisTime = 0;
    777                     } else {
    778                         outResult.thisTime = SystemClock.uptimeMillis();
    779                         mWaitingActivityVisible.add(outResult);
    780                         do {
    781                             try {
    782                                 mService.wait();
    783                             } catch (InterruptedException e) {
    784                             }
    785                         } while (!outResult.timeout && outResult.who == null);
    786                     }
    787                 }
    788             }
    789 
    790             return res;
    791         }
    792     }
    793 
    794     final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
    795             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
    796             Bundle options, int userId) {
    797         if (intents == null) {
    798             throw new NullPointerException("intents is null");
    799         }
    800         if (resolvedTypes == null) {
    801             throw new NullPointerException("resolvedTypes is null");
    802         }
    803         if (intents.length != resolvedTypes.length) {
    804             throw new IllegalArgumentException("intents are length different than resolvedTypes");
    805         }
    806 
    807 
    808         int callingPid;
    809         if (callingUid >= 0) {
    810             callingPid = -1;
    811         } else if (caller == null) {
    812             callingPid = Binder.getCallingPid();
    813             callingUid = Binder.getCallingUid();
    814         } else {
    815             callingPid = callingUid = -1;
    816         }
    817         final long origId = Binder.clearCallingIdentity();
    818         try {
    819             synchronized (mService) {
    820                 ActivityRecord[] outActivity = new ActivityRecord[1];
    821                 for (int i=0; i<intents.length; i++) {
    822                     Intent intent = intents[i];
    823                     if (intent == null) {
    824                         continue;
    825                     }
    826 
    827                     // Refuse possible leaked file descriptors
    828                     if (intent != null && intent.hasFileDescriptors()) {
    829                         throw new IllegalArgumentException("File descriptors passed in Intent");
    830                     }
    831 
    832                     boolean componentSpecified = intent.getComponent() != null;
    833 
    834                     // Don't modify the client's object!
    835                     intent = new Intent(intent);
    836 
    837                     // Collect information about the target of the Intent.
    838                     ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
    839                             0, null, null, userId);
    840                     // TODO: New, check if this is correct
    841                     aInfo = mService.getActivityInfoForUser(aInfo, userId);
    842 
    843                     if (aInfo != null &&
    844                             (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
    845                                     != 0) {
    846                         throw new IllegalArgumentException(
    847                                 "FLAG_CANT_SAVE_STATE not supported here");
    848                     }
    849 
    850                     Bundle theseOptions;
    851                     if (options != null && i == intents.length-1) {
    852                         theseOptions = options;
    853                     } else {
    854                         theseOptions = null;
    855                     }
    856                     int res = startActivityLocked(caller, intent, resolvedTypes[i],
    857                             aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
    858                             0, theseOptions, componentSpecified, outActivity);
    859                     if (res < 0) {
    860                         return res;
    861                     }
    862 
    863                     resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
    864                 }
    865             }
    866         } finally {
    867             Binder.restoreCallingIdentity(origId);
    868         }
    869 
    870         return ActivityManager.START_SUCCESS;
    871     }
    872 
    873     final boolean realStartActivityLocked(ActivityRecord r,
    874             ProcessRecord app, boolean andResume, boolean checkConfig)
    875             throws RemoteException {
    876 
    877         r.startFreezingScreenLocked(app, 0);
    878         if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
    879         mWindowManager.setAppVisibility(r.appToken, true);
    880 
    881         // schedule launch ticks to collect information about slow apps.
    882         r.startLaunchTickingLocked();
    883 
    884         // Have the window manager re-evaluate the orientation of
    885         // the screen based on the new activity order.  Note that
    886         // as a result of this, it can call back into the activity
    887         // manager with a new orientation.  We don't care about that,
    888         // because the activity is not currently running so we are
    889         // just restarting it anyway.
    890         if (checkConfig) {
    891             Configuration config = mWindowManager.updateOrientationFromAppTokens(
    892                     mService.mConfiguration,
    893                     r.mayFreezeScreenLocked(app) ? r.appToken : null);
    894             mService.updateConfigurationLocked(config, r, false, false);
    895         }
    896 
    897         r.app = app;
    898         app.waitingToKill = null;
    899         r.launchCount++;
    900         r.lastLaunchTime = SystemClock.uptimeMillis();
    901 
    902         if (localLOGV) Slog.v(TAG, "Launching: " + r);
    903 
    904         int idx = app.activities.indexOf(r);
    905         if (idx < 0) {
    906             app.activities.add(r);
    907         }
    908         mService.updateLruProcessLocked(app, true, true);
    909 
    910         final ActivityStack stack = r.task.stack;
    911         try {
    912             if (app.thread == null) {
    913                 throw new RemoteException();
    914             }
    915             List<ResultInfo> results = null;
    916             List<Intent> newIntents = null;
    917             if (andResume) {
    918                 results = r.results;
    919                 newIntents = r.newIntents;
    920             }
    921             if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
    922                     + " icicle=" + r.icicle
    923                     + " with results=" + results + " newIntents=" + newIntents
    924                     + " andResume=" + andResume);
    925             if (andResume) {
    926                 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
    927                         r.userId, System.identityHashCode(r),
    928                         r.task.taskId, r.shortComponentName);
    929             }
    930             if (r.isHomeActivity() && r.isNotResolverActivity()) {
    931                 // Home process is the root process of the task.
    932                 mService.mHomeProcess = r.task.mActivities.get(0).app;
    933             }
    934             mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
    935             r.sleeping = false;
    936             r.forceNewConfig = false;
    937             mService.showAskCompatModeDialogLocked(r);
    938             r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
    939             String profileFile = null;
    940             ParcelFileDescriptor profileFd = null;
    941             boolean profileAutoStop = false;
    942             if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
    943                 if (mService.mProfileProc == null || mService.mProfileProc == app) {
    944                     mService.mProfileProc = app;
    945                     profileFile = mService.mProfileFile;
    946                     profileFd = mService.mProfileFd;
    947                     profileAutoStop = mService.mAutoStopProfiler;
    948                 }
    949             }
    950             app.hasShownUi = true;
    951             app.pendingUiClean = true;
    952             if (profileFd != null) {
    953                 try {
    954                     profileFd = profileFd.dup();
    955                 } catch (IOException e) {
    956                     if (profileFd != null) {
    957                         try {
    958                             profileFd.close();
    959                         } catch (IOException o) {
    960                         }
    961                         profileFd = null;
    962                     }
    963                 }
    964             }
    965             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
    966             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
    967                     System.identityHashCode(r), r.info,
    968                     new Configuration(mService.mConfiguration), r.compat,
    969                     app.repProcState, r.icicle, results, newIntents, !andResume,
    970                     mService.isNextTransitionForward(), profileFile, profileFd,
    971                     profileAutoStop);
    972 
    973             if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
    974                 // This may be a heavy-weight process!  Note that the package
    975                 // manager will ensure that only activity can run in the main
    976                 // process of the .apk, which is the only thing that will be
    977                 // considered heavy-weight.
    978                 if (app.processName.equals(app.info.packageName)) {
    979                     if (mService.mHeavyWeightProcess != null
    980                             && mService.mHeavyWeightProcess != app) {
    981                         Slog.w(TAG, "Starting new heavy weight process " + app
    982                                 + " when already running "
    983                                 + mService.mHeavyWeightProcess);
    984                     }
    985                     mService.mHeavyWeightProcess = app;
    986                     Message msg = mService.mHandler.obtainMessage(
    987                             ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
    988                     msg.obj = r;
    989                     mService.mHandler.sendMessage(msg);
    990                 }
    991             }
    992 
    993         } catch (RemoteException e) {
    994             if (r.launchFailed) {
    995                 // This is the second time we failed -- finish activity
    996                 // and give up.
    997                 Slog.e(TAG, "Second failure launching "
    998                       + r.intent.getComponent().flattenToShortString()
    999                       + ", giving up", e);
   1000                 mService.appDiedLocked(app, app.pid, app.thread);
   1001                 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
   1002                         "2nd-crash", false);
   1003                 return false;
   1004             }
   1005 
   1006             // This is the first time we failed -- restart process and
   1007             // retry.
   1008             app.activities.remove(r);
   1009             throw e;
   1010         }
   1011 
   1012         r.launchFailed = false;
   1013         if (stack.updateLRUListLocked(r)) {
   1014             Slog.w(TAG, "Activity " + r
   1015                   + " being launched, but already in LRU list");
   1016         }
   1017 
   1018         if (andResume) {
   1019             // As part of the process of launching, ActivityThread also performs
   1020             // a resume.
   1021             stack.minimalResumeActivityLocked(r);
   1022         } else {
   1023             // This activity is not starting in the resumed state... which
   1024             // should look like we asked it to pause+stop (but remain visible),
   1025             // and it has done so and reported back the current icicle and
   1026             // other state.
   1027             if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
   1028                     + " (starting in stopped state)");
   1029             r.state = ActivityState.STOPPED;
   1030             r.stopped = true;
   1031         }
   1032 
   1033         // Launch the new version setup screen if needed.  We do this -after-
   1034         // launching the initial activity (that is, home), so that it can have
   1035         // a chance to initialize itself while in the background, making the
   1036         // switch back to it faster and look better.
   1037         if (isFrontStack(stack)) {
   1038             mService.startSetupActivityLocked();
   1039         }
   1040 
   1041         return true;
   1042     }
   1043 
   1044     void startSpecificActivityLocked(ActivityRecord r,
   1045             boolean andResume, boolean checkConfig) {
   1046         // Is this activity's application already running?
   1047         ProcessRecord app = mService.getProcessRecordLocked(r.processName,
   1048                 r.info.applicationInfo.uid, true);
   1049 
   1050         r.task.stack.setLaunchTime(r);
   1051 
   1052         if (app != null && app.thread != null) {
   1053             try {
   1054                 app.addPackage(r.info.packageName, mService.mProcessStats);
   1055                 realStartActivityLocked(r, app, andResume, checkConfig);
   1056                 return;
   1057             } catch (RemoteException e) {
   1058                 Slog.w(TAG, "Exception when starting activity "
   1059                         + r.intent.getComponent().flattenToShortString(), e);
   1060             }
   1061 
   1062             // If a dead object exception was thrown -- fall through to
   1063             // restart the application.
   1064         }
   1065 
   1066         mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
   1067                 "activity", r.intent.getComponent(), false, false, true);
   1068     }
   1069 
   1070     final int startActivityLocked(IApplicationThread caller,
   1071             Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
   1072             String resultWho, int requestCode,
   1073             int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
   1074             boolean componentSpecified, ActivityRecord[] outActivity) {
   1075         int err = ActivityManager.START_SUCCESS;
   1076 
   1077         ProcessRecord callerApp = null;
   1078         if (caller != null) {
   1079             callerApp = mService.getRecordForAppLocked(caller);
   1080             if (callerApp != null) {
   1081                 callingPid = callerApp.pid;
   1082                 callingUid = callerApp.info.uid;
   1083             } else {
   1084                 Slog.w(TAG, "Unable to find app for caller " + caller
   1085                       + " (pid=" + callingPid + ") when starting: "
   1086                       + intent.toString());
   1087                 err = ActivityManager.START_PERMISSION_DENIED;
   1088             }
   1089         }
   1090 
   1091         if (err == ActivityManager.START_SUCCESS) {
   1092             final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
   1093             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
   1094                     + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
   1095         }
   1096 
   1097         ActivityRecord sourceRecord = null;
   1098         ActivityRecord resultRecord = null;
   1099         if (resultTo != null) {
   1100             sourceRecord = isInAnyStackLocked(resultTo);
   1101             if (DEBUG_RESULTS) Slog.v(
   1102                 TAG, "Will send result to " + resultTo + " " + sourceRecord);
   1103             if (sourceRecord != null) {
   1104                 if (requestCode >= 0 && !sourceRecord.finishing) {
   1105                     resultRecord = sourceRecord;
   1106                 }
   1107             }
   1108         }
   1109         ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
   1110 
   1111         int launchFlags = intent.getFlags();
   1112 
   1113         if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
   1114                 && sourceRecord != null) {
   1115             // Transfer the result target from the source activity to the new
   1116             // one being started, including any failures.
   1117             if (requestCode >= 0) {
   1118                 ActivityOptions.abort(options);
   1119                 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
   1120             }
   1121             resultRecord = sourceRecord.resultTo;
   1122             resultWho = sourceRecord.resultWho;
   1123             requestCode = sourceRecord.requestCode;
   1124             sourceRecord.resultTo = null;
   1125             if (resultRecord != null) {
   1126                 resultRecord.removeResultsLocked(
   1127                     sourceRecord, resultWho, requestCode);
   1128             }
   1129         }
   1130 
   1131         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
   1132             // We couldn't find a class that can handle the given Intent.
   1133             // That's the end of that!
   1134             err = ActivityManager.START_INTENT_NOT_RESOLVED;
   1135         }
   1136 
   1137         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
   1138             // We couldn't find the specific class specified in the Intent.
   1139             // Also the end of the line.
   1140             err = ActivityManager.START_CLASS_NOT_FOUND;
   1141         }
   1142 
   1143         if (err != ActivityManager.START_SUCCESS) {
   1144             if (resultRecord != null) {
   1145                 resultStack.sendActivityResultLocked(-1,
   1146                     resultRecord, resultWho, requestCode,
   1147                     Activity.RESULT_CANCELED, null);
   1148             }
   1149             setDismissKeyguard(false);
   1150             ActivityOptions.abort(options);
   1151             return err;
   1152         }
   1153 
   1154         final int startAnyPerm = mService.checkPermission(
   1155                 START_ANY_ACTIVITY, callingPid, callingUid);
   1156         final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
   1157                 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
   1158         if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
   1159             if (resultRecord != null) {
   1160                 resultStack.sendActivityResultLocked(-1,
   1161                     resultRecord, resultWho, requestCode,
   1162                     Activity.RESULT_CANCELED, null);
   1163             }
   1164             setDismissKeyguard(false);
   1165             String msg;
   1166             if (!aInfo.exported) {
   1167                 msg = "Permission Denial: starting " + intent.toString()
   1168                         + " from " + callerApp + " (pid=" + callingPid
   1169                         + ", uid=" + callingUid + ")"
   1170                         + " not exported from uid " + aInfo.applicationInfo.uid;
   1171             } else {
   1172                 msg = "Permission Denial: starting " + intent.toString()
   1173                         + " from " + callerApp + " (pid=" + callingPid
   1174                         + ", uid=" + callingUid + ")"
   1175                         + " requires " + aInfo.permission;
   1176             }
   1177             Slog.w(TAG, msg);
   1178             throw new SecurityException(msg);
   1179         }
   1180 
   1181         boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
   1182                 callingPid, resolvedType, aInfo.applicationInfo);
   1183 
   1184         if (mService.mController != null) {
   1185             try {
   1186                 // The Intent we give to the watcher has the extra data
   1187                 // stripped off, since it can contain private information.
   1188                 Intent watchIntent = intent.cloneFilter();
   1189                 abort |= !mService.mController.activityStarting(watchIntent,
   1190                         aInfo.applicationInfo.packageName);
   1191             } catch (RemoteException e) {
   1192                 mService.mController = null;
   1193             }
   1194         }
   1195 
   1196         if (abort) {
   1197             if (resultRecord != null) {
   1198                 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
   1199                         Activity.RESULT_CANCELED, null);
   1200             }
   1201             // We pretend to the caller that it was really started, but
   1202             // they will just get a cancel result.
   1203             setDismissKeyguard(false);
   1204             ActivityOptions.abort(options);
   1205             return ActivityManager.START_SUCCESS;
   1206         }
   1207 
   1208         ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
   1209                 intent, resolvedType, aInfo, mService.mConfiguration,
   1210                 resultRecord, resultWho, requestCode, componentSpecified, this);
   1211         if (outActivity != null) {
   1212             outActivity[0] = r;
   1213         }
   1214 
   1215         final ActivityStack stack = getFocusedStack();
   1216         if (stack.mResumedActivity == null
   1217                 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
   1218             if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
   1219                 PendingActivityLaunch pal =
   1220                         new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
   1221                 mService.mPendingActivityLaunches.add(pal);
   1222                 setDismissKeyguard(false);
   1223                 ActivityOptions.abort(options);
   1224                 return ActivityManager.START_SWITCHES_CANCELED;
   1225             }
   1226         }
   1227 
   1228         if (mService.mDidAppSwitch) {
   1229             // This is the second allowed switch since we stopped switches,
   1230             // so now just generally allow switches.  Use case: user presses
   1231             // home (switches disabled, switch to home, mDidAppSwitch now true);
   1232             // user taps a home icon (coming from home so allowed, we hit here
   1233             // and now allow anyone to switch again).
   1234             mService.mAppSwitchesAllowedTime = 0;
   1235         } else {
   1236             mService.mDidAppSwitch = true;
   1237         }
   1238 
   1239         mService.doPendingActivityLaunchesLocked(false);
   1240 
   1241         err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
   1242 
   1243         if (allPausedActivitiesComplete()) {
   1244             // If someone asked to have the keyguard dismissed on the next
   1245             // activity start, but we are not actually doing an activity
   1246             // switch...  just dismiss the keyguard now, because we
   1247             // probably want to see whatever is behind it.
   1248             dismissKeyguard();
   1249         }
   1250         return err;
   1251     }
   1252 
   1253     ActivityStack adjustStackFocus(ActivityRecord r) {
   1254         final TaskRecord task = r.task;
   1255         if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
   1256             if (task != null) {
   1257                 if (mFocusedStack != task.stack) {
   1258                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1259                             "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
   1260                     mFocusedStack = task.stack;
   1261                 } else {
   1262                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1263                         "adjustStackFocus: Focused stack already=" + mFocusedStack);
   1264                 }
   1265                 return mFocusedStack;
   1266             }
   1267 
   1268             if (mFocusedStack != null) {
   1269                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1270                         "adjustStackFocus: Have a focused stack=" + mFocusedStack);
   1271                 return mFocusedStack;
   1272             }
   1273 
   1274             for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
   1275                 ActivityStack stack = mStacks.get(stackNdx);
   1276                 if (!stack.isHomeStack()) {
   1277                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1278                             "adjustStackFocus: Setting focused stack=" + stack);
   1279                     mFocusedStack = stack;
   1280                     return mFocusedStack;
   1281                 }
   1282             }
   1283 
   1284             // Time to create the first app stack for this user.
   1285             int stackId = mService.createStack(-1, HOME_STACK_ID,
   1286                 StackBox.TASK_STACK_GOES_OVER, 1.0f);
   1287             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
   1288                     " stackId=" + stackId);
   1289             mFocusedStack = getStack(stackId);
   1290             return mFocusedStack;
   1291         }
   1292         return mHomeStack;
   1293     }
   1294 
   1295     void setFocusedStack(ActivityRecord r) {
   1296         if (r == null) {
   1297             return;
   1298         }
   1299         if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
   1300             if (mStackState != STACK_STATE_HOME_IN_FRONT) {
   1301                 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
   1302                         stackStateToString(mStackState) + " new=" +
   1303                         stackStateToString(STACK_STATE_HOME_TO_FRONT) +
   1304                         " Callers=" + Debug.getCallers(3));
   1305                 mStackState = STACK_STATE_HOME_TO_FRONT;
   1306             }
   1307         } else {
   1308             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
   1309                     "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
   1310                     " Callers=" + Debug.getCallers(3));
   1311             mFocusedStack = r.task.stack;
   1312             if (mStackState != STACK_STATE_HOME_IN_BACK) {
   1313                 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
   1314                         stackStateToString(mStackState) + " new=" +
   1315                         stackStateToString(STACK_STATE_HOME_TO_BACK) +
   1316                         " Callers=" + Debug.getCallers(3));
   1317                 mStackState = STACK_STATE_HOME_TO_BACK;
   1318             }
   1319         }
   1320     }
   1321 
   1322     final int startActivityUncheckedLocked(ActivityRecord r,
   1323             ActivityRecord sourceRecord, int startFlags, boolean doResume,
   1324             Bundle options) {
   1325         final Intent intent = r.intent;
   1326         final int callingUid = r.launchedFromUid;
   1327 
   1328         int launchFlags = intent.getFlags();
   1329 
   1330         // We'll invoke onUserLeaving before onPause only if the launching
   1331         // activity did not explicitly state that this is an automated launch.
   1332         mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
   1333         if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
   1334 
   1335         // If the caller has asked not to resume at this point, we make note
   1336         // of this in the record so that we can skip it when trying to find
   1337         // the top running activity.
   1338         if (!doResume) {
   1339             r.delayedResume = true;
   1340         }
   1341 
   1342         ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
   1343 
   1344         // If the onlyIfNeeded flag is set, then we can do this if the activity
   1345         // being launched is the same as the one making the call...  or, as
   1346         // a special case, if we do not know the caller then we count the
   1347         // current top activity as the caller.
   1348         if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
   1349             ActivityRecord checkedCaller = sourceRecord;
   1350             if (checkedCaller == null) {
   1351                 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
   1352             }
   1353             if (!checkedCaller.realActivity.equals(r.realActivity)) {
   1354                 // Caller is not the same as launcher, so always needed.
   1355                 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
   1356             }
   1357         }
   1358 
   1359         if (sourceRecord == null) {
   1360             // This activity is not being started from another...  in this
   1361             // case we -always- start a new task.
   1362             if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
   1363                 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
   1364                         "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
   1365                 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1366             }
   1367         } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   1368             // The original activity who is starting us is running as a single
   1369             // instance...  this new activity it is starting must go on its
   1370             // own task.
   1371             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1372         } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
   1373                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
   1374             // The activity being started is a single instance...  it always
   1375             // gets launched into its own task.
   1376             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1377         }
   1378 
   1379         final ActivityStack sourceStack;
   1380         if (sourceRecord != null) {
   1381             if (sourceRecord.finishing) {
   1382                 // If the source is finishing, we can't further count it as our source.  This
   1383                 // is because the task it is associated with may now be empty and on its way out,
   1384                 // so we don't want to blindly throw it in to that task.  Instead we will take
   1385                 // the NEW_TASK flow and try to find a task for it.
   1386                 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
   1387                     Slog.w(TAG, "startActivity called from finishing " + sourceRecord
   1388                             + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
   1389                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   1390                 }
   1391                 sourceRecord = null;
   1392                 sourceStack = null;
   1393             } else {
   1394                 sourceStack = sourceRecord.task.stack;
   1395             }
   1396         } else {
   1397             sourceStack = null;
   1398         }
   1399 
   1400         if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   1401             // For whatever reason this activity is being launched into a new
   1402             // task...  yet the caller has requested a result back.  Well, that
   1403             // is pretty messed up, so instead immediately send back a cancel
   1404             // and let the new task continue launched as normal without a
   1405             // dependency on its originator.
   1406             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
   1407             r.resultTo.task.stack.sendActivityResultLocked(-1,
   1408                     r.resultTo, r.resultWho, r.requestCode,
   1409                 Activity.RESULT_CANCELED, null);
   1410             r.resultTo = null;
   1411         }
   1412 
   1413         boolean addingToTask = false;
   1414         boolean movedHome = false;
   1415         TaskRecord reuseTask = null;
   1416         ActivityStack targetStack;
   1417         if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
   1418                 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
   1419                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
   1420                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   1421             // If bring to front is requested, and no result is requested, and
   1422             // we can find a task that was started with this same
   1423             // component, then instead of launching bring that one to the front.
   1424             if (r.resultTo == null) {
   1425                 // See if there is a task to bring to the front.  If this is
   1426                 // a SINGLE_INSTANCE activity, there can be one and only one
   1427                 // instance of it in the history, and it is always in its own
   1428                 // unique task, so we do a special search.
   1429                 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
   1430                         ? findTaskLocked(r)
   1431                         : findActivityLocked(intent, r.info);
   1432                 if (intentActivity != null) {
   1433                     if (r.task == null) {
   1434                         r.task = intentActivity.task;
   1435                     }
   1436                     targetStack = intentActivity.task.stack;
   1437                     targetStack.mLastPausedActivity = null;
   1438                     if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
   1439                             + " from " + intentActivity);
   1440                     moveHomeStack(targetStack.isHomeStack());
   1441                     if (intentActivity.task.intent == null) {
   1442                         // This task was started because of movement of
   1443                         // the activity based on affinity...  now that we
   1444                         // are actually launching it, we can assign the
   1445                         // base intent.
   1446                         intentActivity.task.setIntent(intent, r.info);
   1447                     }
   1448                     // If the target task is not in the front, then we need
   1449                     // to bring it to the front...  except...  well, with
   1450                     // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
   1451                     // to have the same behavior as if a new instance was
   1452                     // being started, which means not bringing it to the front
   1453                     // if the caller is not itself in the front.
   1454                     final ActivityStack lastStack = getLastStack();
   1455                     ActivityRecord curTop = lastStack == null?
   1456                             null : lastStack.topRunningNonDelayedActivityLocked(notTop);
   1457                     if (curTop != null && (curTop.task != intentActivity.task ||
   1458                             curTop.task != lastStack.topTask())) {
   1459                         r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
   1460                         if (sourceRecord == null || (sourceStack.topActivity() != null &&
   1461                                 sourceStack.topActivity().task == sourceRecord.task)) {
   1462                             // We really do want to push this one into the
   1463                             // user's face, right now.
   1464                             movedHome = true;
   1465                             if ((launchFlags &
   1466                                     (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
   1467                                     == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
   1468                                 // Caller wants to appear on home activity.
   1469                                 intentActivity.task.mOnTopOfHome = true;
   1470                             }
   1471                             targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
   1472                             options = null;
   1473                         }
   1474                     }
   1475                     // If the caller has requested that the target task be
   1476                     // reset, then do so.
   1477                     if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
   1478                         intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
   1479                     }
   1480                     if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
   1481                         // We don't need to start a new activity, and
   1482                         // the client said not to do anything if that
   1483                         // is the case, so this is it!  And for paranoia, make
   1484                         // sure we have correctly resumed the top activity.
   1485                         if (doResume) {
   1486                             resumeTopActivitiesLocked(targetStack, null, options);
   1487                         } else {
   1488                             ActivityOptions.abort(options);
   1489                         }
   1490                         if (r.task == null)  Slog.v(TAG,
   1491                                 "startActivityUncheckedLocked: task left null",
   1492                                 new RuntimeException("here").fillInStackTrace());
   1493                         return ActivityManager.START_RETURN_INTENT_TO_CALLER;
   1494                     }
   1495                     if ((launchFlags &
   1496                             (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
   1497                             == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
   1498                         // The caller has requested to completely replace any
   1499                         // existing task with its new activity.  Well that should
   1500                         // not be too hard...
   1501                         reuseTask = intentActivity.task;
   1502                         reuseTask.performClearTaskLocked();
   1503                         reuseTask.setIntent(r.intent, r.info);
   1504                     } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
   1505                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
   1506                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   1507                         // In this situation we want to remove all activities
   1508                         // from the task up to the one being started.  In most
   1509                         // cases this means we are resetting the task to its
   1510                         // initial state.
   1511                         ActivityRecord top =
   1512                                 intentActivity.task.performClearTaskLocked(r, launchFlags);
   1513                         if (top != null) {
   1514                             if (top.frontOfTask) {
   1515                                 // Activity aliases may mean we use different
   1516                                 // intents for the top activity, so make sure
   1517                                 // the task now has the identity of the new
   1518                                 // intent.
   1519                                 top.task.setIntent(r.intent, r.info);
   1520                             }
   1521                             ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
   1522                                     r, top.task);
   1523                             top.deliverNewIntentLocked(callingUid, r.intent);
   1524                         } else {
   1525                             // A special case: we need to
   1526                             // start the activity because it is not currently
   1527                             // running, and the caller has asked to clear the
   1528                             // current task to have this activity at the top.
   1529                             addingToTask = true;
   1530                             // Now pretend like this activity is being started
   1531                             // by the top of its task, so it is put in the
   1532                             // right place.
   1533                             sourceRecord = intentActivity;
   1534                         }
   1535                     } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
   1536                         // In this case the top activity on the task is the
   1537                         // same as the one being launched, so we take that
   1538                         // as a request to bring the task to the foreground.
   1539                         // If the top activity in the task is the root
   1540                         // activity, deliver this new intent to it if it
   1541                         // desires.
   1542                         if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
   1543                                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
   1544                                 && intentActivity.realActivity.equals(r.realActivity)) {
   1545                             ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
   1546                                     intentActivity.task);
   1547                             if (intentActivity.frontOfTask) {
   1548                                 intentActivity.task.setIntent(r.intent, r.info);
   1549                             }
   1550                             intentActivity.deliverNewIntentLocked(callingUid, r.intent);
   1551                         } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
   1552                             // In this case we are launching the root activity
   1553                             // of the task, but with a different intent.  We
   1554                             // should start a new instance on top.
   1555                             addingToTask = true;
   1556                             sourceRecord = intentActivity;
   1557                         }
   1558                     } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
   1559                         // In this case an activity is being launched in to an
   1560                         // existing task, without resetting that task.  This
   1561                         // is typically the situation of launching an activity
   1562                         // from a notification or shortcut.  We want to place
   1563                         // the new activity on top of the current task.
   1564                         addingToTask = true;
   1565                         sourceRecord = intentActivity;
   1566                     } else if (!intentActivity.task.rootWasReset) {
   1567                         // In this case we are launching in to an existing task
   1568                         // that has not yet been started from its front door.
   1569                         // The current task has been brought to the front.
   1570                         // Ideally, we'd probably like to place this new task
   1571                         // at the bottom of its stack, but that's a little hard
   1572                         // to do with the current organization of the code so
   1573                         // for now we'll just drop it.
   1574                         intentActivity.task.setIntent(r.intent, r.info);
   1575                     }
   1576                     if (!addingToTask && reuseTask == null) {
   1577                         // We didn't do anything...  but it was needed (a.k.a., client
   1578                         // don't use that intent!)  And for paranoia, make
   1579                         // sure we have correctly resumed the top activity.
   1580                         if (doResume) {
   1581                             targetStack.resumeTopActivityLocked(null, options);
   1582                         } else {
   1583                             ActivityOptions.abort(options);
   1584                         }
   1585                         if (r.task == null)  Slog.v(TAG,
   1586                             "startActivityUncheckedLocked: task left null",
   1587                             new RuntimeException("here").fillInStackTrace());
   1588                         return ActivityManager.START_TASK_TO_FRONT;
   1589                     }
   1590                 }
   1591             }
   1592         }
   1593 
   1594         //String uri = r.intent.toURI();
   1595         //Intent intent2 = new Intent(uri);
   1596         //Slog.i(TAG, "Given intent: " + r.intent);
   1597         //Slog.i(TAG, "URI is: " + uri);
   1598         //Slog.i(TAG, "To intent: " + intent2);
   1599 
   1600         if (r.packageName != null) {
   1601             // If the activity being launched is the same as the one currently
   1602             // at the top, then we need to check if it should only be launched
   1603             // once.
   1604             ActivityStack topStack = getFocusedStack();
   1605             ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
   1606             if (top != null && r.resultTo == null) {
   1607                 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
   1608                     if (top.app != null && top.app.thread != null) {
   1609                         if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
   1610                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
   1611                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
   1612                             ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
   1613                                     top.task);
   1614                             // For paranoia, make sure we have correctly
   1615                             // resumed the top activity.
   1616                             topStack.mLastPausedActivity = null;
   1617                             if (doResume) {
   1618                                 resumeTopActivitiesLocked();
   1619                             }
   1620                             ActivityOptions.abort(options);
   1621                             if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
   1622                                 // We don't need to start a new activity, and
   1623                                 // the client said not to do anything if that
   1624                                 // is the case, so this is it!
   1625                                 if (r.task == null)  Slog.v(TAG,
   1626                                     "startActivityUncheckedLocked: task left null",
   1627                                     new RuntimeException("here").fillInStackTrace());
   1628                                 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
   1629                             }
   1630                             top.deliverNewIntentLocked(callingUid, r.intent);
   1631                             if (r.task == null)  Slog.v(TAG,
   1632                                 "startActivityUncheckedLocked: task left null",
   1633                                 new RuntimeException("here").fillInStackTrace());
   1634                             return ActivityManager.START_DELIVERED_TO_TOP;
   1635                         }
   1636                     }
   1637                 }
   1638             }
   1639 
   1640         } else {
   1641             if (r.resultTo != null) {
   1642                 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
   1643                         r.requestCode, Activity.RESULT_CANCELED, null);
   1644             }
   1645             ActivityOptions.abort(options);
   1646             if (r.task == null)  Slog.v(TAG,
   1647                 "startActivityUncheckedLocked: task left null",
   1648                 new RuntimeException("here").fillInStackTrace());
   1649             return ActivityManager.START_CLASS_NOT_FOUND;
   1650         }
   1651 
   1652         boolean newTask = false;
   1653         boolean keepCurTransition = false;
   1654 
   1655         // Should this be considered a new task?
   1656         if (r.resultTo == null && !addingToTask
   1657                 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   1658             targetStack = adjustStackFocus(r);
   1659             moveHomeStack(targetStack.isHomeStack());
   1660             if (reuseTask == null) {
   1661                 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
   1662                         null, true);
   1663                 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
   1664                         r.task);
   1665             } else {
   1666                 r.setTask(reuseTask, reuseTask, true);
   1667             }
   1668             newTask = true;
   1669             if (!movedHome) {
   1670                 if ((launchFlags &
   1671                         (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
   1672                         == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
   1673                     // Caller wants to appear on home activity, so before starting
   1674                     // their own activity we will bring home to the front.
   1675                     r.task.mOnTopOfHome = true;
   1676                 }
   1677             }
   1678         } else if (sourceRecord != null) {
   1679             TaskRecord sourceTask = sourceRecord.task;
   1680             targetStack = sourceTask.stack;
   1681             moveHomeStack(targetStack.isHomeStack());
   1682             if (!addingToTask &&
   1683                     (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
   1684                 // In this case, we are adding the activity to an existing
   1685                 // task, but the caller has asked to clear that task if the
   1686                 // activity is already running.
   1687                 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
   1688                 keepCurTransition = true;
   1689                 if (top != null) {
   1690                     ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
   1691                     top.deliverNewIntentLocked(callingUid, r.intent);
   1692                     // For paranoia, make sure we have correctly
   1693                     // resumed the top activity.
   1694                     targetStack.mLastPausedActivity = null;
   1695                     if (doResume) {
   1696                         targetStack.resumeTopActivityLocked(null);
   1697                     }
   1698                     ActivityOptions.abort(options);
   1699                     if (r.task == null)  Slog.w(TAG,
   1700                         "startActivityUncheckedLocked: task left null",
   1701                         new RuntimeException("here").fillInStackTrace());
   1702                     return ActivityManager.START_DELIVERED_TO_TOP;
   1703                 }
   1704             } else if (!addingToTask &&
   1705                     (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
   1706                 // In this case, we are launching an activity in our own task
   1707                 // that may already be running somewhere in the history, and
   1708                 // we want to shuffle it to the front of the stack if so.
   1709                 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
   1710                 if (top != null) {
   1711                     final TaskRecord task = top.task;
   1712                     task.moveActivityToFrontLocked(top);
   1713                     ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
   1714                     top.updateOptionsLocked(options);
   1715                     top.deliverNewIntentLocked(callingUid, r.intent);
   1716                     targetStack.mLastPausedActivity = null;
   1717                     if (doResume) {
   1718                         targetStack.resumeTopActivityLocked(null);
   1719                     }
   1720                     return ActivityManager.START_DELIVERED_TO_TOP;
   1721                 }
   1722             }
   1723             // An existing activity is starting this new activity, so we want
   1724             // to keep the new one in the same task as the one that is starting
   1725             // it.
   1726             r.setTask(sourceTask, sourceRecord.thumbHolder, false);
   1727             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   1728                     + " in existing task " + r.task + " from source " + sourceRecord);
   1729 
   1730         } else {
   1731             // This not being started from an existing activity, and not part
   1732             // of a new task...  just put it in the top task, though these days
   1733             // this case should never happen.
   1734             targetStack = adjustStackFocus(r);
   1735             moveHomeStack(targetStack.isHomeStack());
   1736             ActivityRecord prev = targetStack.topActivity();
   1737             r.setTask(prev != null ? prev.task
   1738                     : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
   1739                     null, true);
   1740             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   1741                     + " in new guessed " + r.task);
   1742         }
   1743 
   1744         mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
   1745                 intent, r.getUriPermissionsLocked());
   1746 
   1747         if (newTask) {
   1748             EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
   1749         }
   1750         ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
   1751         targetStack.mLastPausedActivity = null;
   1752         targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
   1753         mService.setFocusedActivityLocked(r);
   1754         return ActivityManager.START_SUCCESS;
   1755     }
   1756 
   1757     void acquireLaunchWakelock() {
   1758         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
   1759             throw new IllegalStateException("Calling must be system uid");
   1760         }
   1761         mLaunchingActivity.acquire();
   1762         if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
   1763             // To be safe, don't allow the wake lock to be held for too long.
   1764             mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
   1765         }
   1766     }
   1767 
   1768     // Checked.
   1769     final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
   1770             Configuration config) {
   1771         if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
   1772 
   1773         ArrayList<ActivityRecord> stops = null;
   1774         ArrayList<ActivityRecord> finishes = null;
   1775         ArrayList<UserStartedState> startingUsers = null;
   1776         int NS = 0;
   1777         int NF = 0;
   1778         IApplicationThread sendThumbnail = null;
   1779         boolean booting = false;
   1780         boolean enableScreen = false;
   1781         boolean activityRemoved = false;
   1782 
   1783         ActivityRecord r = ActivityRecord.forToken(token);
   1784         if (r != null) {
   1785             if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
   1786                     Debug.getCallers(4));
   1787             mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
   1788             r.finishLaunchTickingLocked();
   1789             if (fromTimeout) {
   1790                 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
   1791             }
   1792 
   1793             // This is a hack to semi-deal with a race condition
   1794             // in the client where it can be constructed with a
   1795             // newer configuration from when we asked it to launch.
   1796             // We'll update with whatever configuration it now says
   1797             // it used to launch.
   1798             if (config != null) {
   1799                 r.configuration = config;
   1800             }
   1801 
   1802             // We are now idle.  If someone is waiting for a thumbnail from
   1803             // us, we can now deliver.
   1804             r.idle = true;
   1805 
   1806             if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
   1807                 sendThumbnail = r.app.thread;
   1808                 r.thumbnailNeeded = false;
   1809             }
   1810 
   1811             //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
   1812             if (!mService.mBooted && isFrontStack(r.task.stack)) {
   1813                 mService.mBooted = true;
   1814                 enableScreen = true;
   1815             }
   1816         }
   1817 
   1818         if (allResumedActivitiesIdle()) {
   1819             if (r != null) {
   1820                 mService.scheduleAppGcsLocked();
   1821             }
   1822 
   1823             if (mLaunchingActivity.isHeld()) {
   1824                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   1825                 if (VALIDATE_WAKE_LOCK_CALLER &&
   1826                         Binder.getCallingUid() != Process.myUid()) {
   1827                     throw new IllegalStateException("Calling must be system uid");
   1828                 }
   1829                 mLaunchingActivity.release();
   1830             }
   1831             ensureActivitiesVisibleLocked(null, 0);
   1832         }
   1833 
   1834         // Atomically retrieve all of the other things to do.
   1835         stops = processStoppingActivitiesLocked(true);
   1836         NS = stops != null ? stops.size() : 0;
   1837         if ((NF=mFinishingActivities.size()) > 0) {
   1838             finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
   1839             mFinishingActivities.clear();
   1840         }
   1841 
   1842         final ArrayList<ActivityRecord> thumbnails;
   1843         final int NT = mCancelledThumbnails.size();
   1844         if (NT > 0) {
   1845             thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
   1846             mCancelledThumbnails.clear();
   1847         } else {
   1848             thumbnails = null;
   1849         }
   1850 
   1851         if (isFrontStack(mHomeStack)) {
   1852             booting = mService.mBooting;
   1853             mService.mBooting = false;
   1854         }
   1855 
   1856         if (mStartingUsers.size() > 0) {
   1857             startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
   1858             mStartingUsers.clear();
   1859         }
   1860 
   1861         // Perform the following actions from unsynchronized state.
   1862         final IApplicationThread thumbnailThread = sendThumbnail;
   1863         mHandler.post(new Runnable() {
   1864             @Override
   1865             public void run() {
   1866                 if (thumbnailThread != null) {
   1867                     try {
   1868                         thumbnailThread.requestThumbnail(token);
   1869                     } catch (Exception e) {
   1870                         Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   1871                         mService.sendPendingThumbnail(null, token, null, null, true);
   1872                     }
   1873                 }
   1874 
   1875                 // Report back to any thumbnail receivers.
   1876                 for (int i = 0; i < NT; i++) {
   1877                     ActivityRecord r = thumbnails.get(i);
   1878                     mService.sendPendingThumbnail(r, null, null, null, true);
   1879                 }
   1880             }
   1881         });
   1882 
   1883         // Stop any activities that are scheduled to do so but have been
   1884         // waiting for the next one to start.
   1885         for (int i = 0; i < NS; i++) {
   1886             r = stops.get(i);
   1887             final ActivityStack stack = r.task.stack;
   1888             if (r.finishing) {
   1889                 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
   1890             } else {
   1891                 stack.stopActivityLocked(r);
   1892             }
   1893         }
   1894 
   1895         // Finish any activities that are scheduled to do so but have been
   1896         // waiting for the next one to start.
   1897         for (int i = 0; i < NF; i++) {
   1898             r = finishes.get(i);
   1899             activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
   1900         }
   1901 
   1902         if (booting) {
   1903             mService.finishBooting();
   1904         } else if (startingUsers != null) {
   1905             for (int i = 0; i < startingUsers.size(); i++) {
   1906                 mService.finishUserSwitch(startingUsers.get(i));
   1907             }
   1908         }
   1909 
   1910         mService.trimApplications();
   1911         //dump();
   1912         //mWindowManager.dump();
   1913 
   1914         if (enableScreen) {
   1915             mService.enableScreenAfterBoot();
   1916         }
   1917 
   1918         if (activityRemoved) {
   1919             resumeTopActivitiesLocked();
   1920         }
   1921 
   1922         return r;
   1923     }
   1924 
   1925     boolean handleAppDiedLocked(ProcessRecord app) {
   1926         boolean hasVisibleActivities = false;
   1927         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1928             hasVisibleActivities |= mStacks.get(stackNdx).handleAppDiedLocked(app);
   1929         }
   1930         return hasVisibleActivities;
   1931     }
   1932 
   1933     void closeSystemDialogsLocked() {
   1934         final int numStacks = mStacks.size();
   1935         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   1936             final ActivityStack stack = mStacks.get(stackNdx);
   1937             stack.closeSystemDialogsLocked();
   1938         }
   1939     }
   1940 
   1941     void removeUserLocked(int userId) {
   1942         mUserStackInFront.delete(userId);
   1943     }
   1944 
   1945     /**
   1946      * @return true if some activity was finished (or would have finished if doit were true).
   1947      */
   1948     boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
   1949         boolean didSomething = false;
   1950         final int numStacks = mStacks.size();
   1951         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   1952             final ActivityStack stack = mStacks.get(stackNdx);
   1953             if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
   1954                 didSomething = true;
   1955             }
   1956         }
   1957         return didSomething;
   1958     }
   1959 
   1960     void updatePreviousProcessLocked(ActivityRecord r) {
   1961         // Now that this process has stopped, we may want to consider
   1962         // it to be the previous app to try to keep around in case
   1963         // the user wants to return to it.
   1964 
   1965         // First, found out what is currently the foreground app, so that
   1966         // we don't blow away the previous app if this activity is being
   1967         // hosted by the process that is actually still the foreground.
   1968         ProcessRecord fgApp = null;
   1969         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   1970             final ActivityStack stack = mStacks.get(stackNdx);
   1971             if (isFrontStack(stack)) {
   1972                 if (stack.mResumedActivity != null) {
   1973                     fgApp = stack.mResumedActivity.app;
   1974                 } else if (stack.mPausingActivity != null) {
   1975                     fgApp = stack.mPausingActivity.app;
   1976                 }
   1977                 break;
   1978             }
   1979         }
   1980 
   1981         // Now set this one as the previous process, only if that really
   1982         // makes sense to.
   1983         if (r.app != null && fgApp != null && r.app != fgApp
   1984                 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
   1985                 && r.app != mService.mHomeProcess) {
   1986             mService.mPreviousProcess = r.app;
   1987             mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
   1988         }
   1989     }
   1990 
   1991     boolean resumeTopActivitiesLocked() {
   1992         return resumeTopActivitiesLocked(null, null, null);
   1993     }
   1994 
   1995     boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
   1996             Bundle targetOptions) {
   1997         if (targetStack == null) {
   1998             targetStack = getFocusedStack();
   1999         }
   2000         boolean result = false;
   2001         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2002             final ActivityStack stack = mStacks.get(stackNdx);
   2003             if (isFrontStack(stack)) {
   2004                 if (stack == targetStack) {
   2005                     result = stack.resumeTopActivityLocked(target, targetOptions);
   2006                 } else {
   2007                     stack.resumeTopActivityLocked(null);
   2008                 }
   2009             }
   2010         }
   2011         return result;
   2012     }
   2013 
   2014     void finishTopRunningActivityLocked(ProcessRecord app) {
   2015         final int numStacks = mStacks.size();
   2016         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2017             final ActivityStack stack = mStacks.get(stackNdx);
   2018             stack.finishTopRunningActivityLocked(app);
   2019         }
   2020     }
   2021 
   2022     void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
   2023         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2024             if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
   2025                 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
   2026                         mStacks.get(stackNdx));
   2027                 return;
   2028             }
   2029         }
   2030     }
   2031 
   2032     ActivityStack getStack(int stackId) {
   2033         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2034             final ActivityStack stack = mStacks.get(stackNdx);
   2035             if (stack.getStackId() == stackId) {
   2036                 return stack;
   2037             }
   2038         }
   2039         return null;
   2040     }
   2041 
   2042     ArrayList<ActivityStack> getStacks() {
   2043         return new ArrayList<ActivityStack>(mStacks);
   2044     }
   2045 
   2046     int createStack() {
   2047         while (true) {
   2048             if (++mLastStackId <= HOME_STACK_ID) {
   2049                 mLastStackId = HOME_STACK_ID + 1;
   2050             }
   2051             if (getStack(mLastStackId) == null) {
   2052                 break;
   2053             }
   2054         }
   2055         mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
   2056         return mLastStackId;
   2057     }
   2058 
   2059     void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   2060         final TaskRecord task = anyTaskForIdLocked(taskId);
   2061         if (task == null) {
   2062             return;
   2063         }
   2064         final ActivityStack stack = getStack(stackId);
   2065         if (stack == null) {
   2066             Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
   2067             return;
   2068         }
   2069         removeTask(task);
   2070         stack.addTask(task, toTop);
   2071         mWindowManager.addTask(taskId, stackId, toTop);
   2072         resumeTopActivitiesLocked();
   2073     }
   2074 
   2075     ActivityRecord findTaskLocked(ActivityRecord r) {
   2076         if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
   2077         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2078             final ActivityStack stack = mStacks.get(stackNdx);
   2079             if (!r.isApplicationActivity() && !stack.isHomeStack()) {
   2080                 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
   2081                 continue;
   2082             }
   2083             final ActivityRecord ar = stack.findTaskLocked(r);
   2084             if (ar != null) {
   2085                 return ar;
   2086             }
   2087         }
   2088         if (DEBUG_TASKS) Slog.d(TAG, "No task found");
   2089         return null;
   2090     }
   2091 
   2092     ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
   2093         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2094             final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
   2095             if (ar != null) {
   2096                 return ar;
   2097             }
   2098         }
   2099         return null;
   2100     }
   2101 
   2102     void goingToSleepLocked() {
   2103         scheduleSleepTimeout();
   2104         if (!mGoingToSleep.isHeld()) {
   2105             mGoingToSleep.acquire();
   2106             if (mLaunchingActivity.isHeld()) {
   2107                 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
   2108                     throw new IllegalStateException("Calling must be system uid");
   2109                 }
   2110                 mLaunchingActivity.release();
   2111                 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   2112             }
   2113         }
   2114         checkReadyForSleepLocked();
   2115     }
   2116 
   2117     boolean shutdownLocked(int timeout) {
   2118         boolean timedout = false;
   2119         goingToSleepLocked();
   2120 
   2121         final long endTime = System.currentTimeMillis() + timeout;
   2122         while (true) {
   2123             boolean cantShutdown = false;
   2124             for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2125                 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
   2126             }
   2127             if (cantShutdown) {
   2128                 long timeRemaining = endTime - System.currentTimeMillis();
   2129                 if (timeRemaining > 0) {
   2130                     try {
   2131                         mService.wait(timeRemaining);
   2132                     } catch (InterruptedException e) {
   2133                     }
   2134                 } else {
   2135                     Slog.w(TAG, "Activity manager shutdown timed out");
   2136                     timedout = true;
   2137                     break;
   2138                 }
   2139             } else {
   2140                 break;
   2141             }
   2142         }
   2143 
   2144         // Force checkReadyForSleep to complete.
   2145         mSleepTimeout = true;
   2146         checkReadyForSleepLocked();
   2147 
   2148         return timedout;
   2149     }
   2150 
   2151     void comeOutOfSleepIfNeededLocked() {
   2152         removeSleepTimeouts();
   2153         if (mGoingToSleep.isHeld()) {
   2154             mGoingToSleep.release();
   2155         }
   2156         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2157             final ActivityStack stack = mStacks.get(stackNdx);
   2158             stack.awakeFromSleepingLocked();
   2159             if (isFrontStack(stack)) {
   2160                 resumeTopActivitiesLocked();
   2161             }
   2162         }
   2163         mGoingToSleepActivities.clear();
   2164     }
   2165 
   2166     void activitySleptLocked(ActivityRecord r) {
   2167         mGoingToSleepActivities.remove(r);
   2168         checkReadyForSleepLocked();
   2169     }
   2170 
   2171     void checkReadyForSleepLocked() {
   2172         if (!mService.isSleepingOrShuttingDown()) {
   2173             // Do not care.
   2174             return;
   2175         }
   2176 
   2177         if (!mSleepTimeout) {
   2178             boolean dontSleep = false;
   2179             for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2180                 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
   2181             }
   2182 
   2183             if (mStoppingActivities.size() > 0) {
   2184                 // Still need to tell some activities to stop; can't sleep yet.
   2185                 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
   2186                         + mStoppingActivities.size() + " activities");
   2187                 scheduleIdleLocked();
   2188                 dontSleep = true;
   2189             }
   2190 
   2191             if (mGoingToSleepActivities.size() > 0) {
   2192                 // Still need to tell some activities to sleep; can't sleep yet.
   2193                 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
   2194                         + mGoingToSleepActivities.size() + " activities");
   2195                 dontSleep = true;
   2196             }
   2197 
   2198             if (dontSleep) {
   2199                 return;
   2200             }
   2201         }
   2202 
   2203         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2204             mStacks.get(stackNdx).goToSleep();
   2205         }
   2206 
   2207         removeSleepTimeouts();
   2208 
   2209         if (mGoingToSleep.isHeld()) {
   2210             mGoingToSleep.release();
   2211         }
   2212         if (mService.mShuttingDown) {
   2213             mService.notifyAll();
   2214         }
   2215     }
   2216 
   2217     boolean reportResumedActivityLocked(ActivityRecord r) {
   2218         final ActivityStack stack = r.task.stack;
   2219         if (isFrontStack(stack)) {
   2220             mService.updateUsageStats(r, true);
   2221         }
   2222         if (allResumedActivitiesComplete()) {
   2223             ensureActivitiesVisibleLocked(null, 0);
   2224             mWindowManager.executeAppTransition();
   2225             return true;
   2226         }
   2227         return false;
   2228     }
   2229 
   2230     void handleAppCrashLocked(ProcessRecord app) {
   2231         final int numStacks = mStacks.size();
   2232         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2233             final ActivityStack stack = mStacks.get(stackNdx);
   2234             stack.handleAppCrashLocked(app);
   2235         }
   2236     }
   2237 
   2238     void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
   2239         // First the front stacks. In case any are not fullscreen and are in front of home.
   2240         boolean showHomeBehindStack = false;
   2241         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2242             final ActivityStack stack = mStacks.get(stackNdx);
   2243             if (isFrontStack(stack)) {
   2244                 showHomeBehindStack =
   2245                         stack.ensureActivitiesVisibleLocked(starting, configChanges);
   2246             }
   2247         }
   2248         // Now do back stacks.
   2249         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2250             final ActivityStack stack = mStacks.get(stackNdx);
   2251             if (!isFrontStack(stack)) {
   2252                 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
   2253             }
   2254         }
   2255     }
   2256 
   2257     void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
   2258         final int numStacks = mStacks.size();
   2259         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2260             final ActivityStack stack = mStacks.get(stackNdx);
   2261             stack.scheduleDestroyActivities(app, false, reason);
   2262         }
   2263     }
   2264 
   2265     boolean switchUserLocked(int userId, UserStartedState uss) {
   2266         mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
   2267         final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
   2268         mCurrentUser = userId;
   2269 
   2270         mStartingUsers.add(uss);
   2271         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2272             mStacks.get(stackNdx).switchUserLocked(userId);
   2273         }
   2274 
   2275         ActivityStack stack = getStack(restoreStackId);
   2276         if (stack == null) {
   2277             stack = mHomeStack;
   2278         }
   2279         final boolean homeInFront = stack.isHomeStack();
   2280         moveHomeStack(homeInFront);
   2281         mWindowManager.moveTaskToTop(stack.topTask().taskId);
   2282         return homeInFront;
   2283     }
   2284 
   2285     final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
   2286         int N = mStoppingActivities.size();
   2287         if (N <= 0) return null;
   2288 
   2289         ArrayList<ActivityRecord> stops = null;
   2290 
   2291         final boolean nowVisible = allResumedActivitiesVisible();
   2292         for (int i=0; i<N; i++) {
   2293             ActivityRecord s = mStoppingActivities.get(i);
   2294             if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
   2295                     + nowVisible + " waitingVisible=" + s.waitingVisible
   2296                     + " finishing=" + s.finishing);
   2297             if (s.waitingVisible && nowVisible) {
   2298                 mWaitingVisibleActivities.remove(s);
   2299                 s.waitingVisible = false;
   2300                 if (s.finishing) {
   2301                     // If this activity is finishing, it is sitting on top of
   2302                     // everyone else but we now know it is no longer needed...
   2303                     // so get rid of it.  Otherwise, we need to go through the
   2304                     // normal flow and hide it once we determine that it is
   2305                     // hidden by the activities in front of it.
   2306                     if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
   2307                     mWindowManager.setAppVisibility(s.appToken, false);
   2308                 }
   2309             }
   2310             if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
   2311                 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
   2312                 if (stops == null) {
   2313                     stops = new ArrayList<ActivityRecord>();
   2314                 }
   2315                 stops.add(s);
   2316                 mStoppingActivities.remove(i);
   2317                 N--;
   2318                 i--;
   2319             }
   2320         }
   2321 
   2322         return stops;
   2323     }
   2324 
   2325     void validateTopActivitiesLocked() {
   2326         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
   2327             final ActivityStack stack = mStacks.get(stackNdx);
   2328             final ActivityRecord r = stack.topRunningActivityLocked(null);
   2329             final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
   2330             if (isFrontStack(stack)) {
   2331                 if (r == null) {
   2332                     Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
   2333                 } else {
   2334                     final ActivityRecord pausing = stack.mPausingActivity;
   2335                     if (pausing != null && pausing == r) {
   2336                         Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
   2337                             " state=" + state);
   2338                     }
   2339                     if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
   2340                         Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
   2341                                 " state=" + state);
   2342                     }
   2343                 }
   2344             } else {
   2345                 final ActivityRecord resumed = stack.mResumedActivity;
   2346                 if (resumed != null && resumed == r) {
   2347                     Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
   2348                         " state=" + state);
   2349                 }
   2350                 if (r != null && (state == ActivityState.INITIALIZING
   2351                         || state == ActivityState.RESUMED)) {
   2352                     Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
   2353                             " state=" + state);
   2354                 }
   2355             }
   2356         }
   2357     }
   2358 
   2359     private static String stackStateToString(int stackState) {
   2360         switch (stackState) {
   2361             case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
   2362             case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
   2363             case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
   2364             case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
   2365             default: return "Unknown stackState=" + stackState;
   2366         }
   2367     }
   2368 
   2369     public void dump(PrintWriter pw, String prefix) {
   2370         pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
   2371                 pw.println(mDismissKeyguardOnNextActivity);
   2372         pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
   2373         pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
   2374         pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
   2375         pw.print(prefix); pw.println("mUserStackInFront: " + mUserStackInFront);
   2376     }
   2377 
   2378     ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
   2379         return getFocusedStack().getDumpActivitiesLocked(name);
   2380     }
   2381 
   2382     static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
   2383             boolean needSep, String prefix) {
   2384         if (activity != null) {
   2385             if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
   2386                 if (needSep) {
   2387                     pw.println();
   2388                 }
   2389                 pw.print(prefix);
   2390                 pw.println(activity);
   2391                 return true;
   2392             }
   2393         }
   2394         return false;
   2395     }
   2396 
   2397     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
   2398             boolean dumpClient, String dumpPackage) {
   2399         boolean printed = false;
   2400         boolean needSep = false;
   2401         final int numStacks = mStacks.size();
   2402         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
   2403             final ActivityStack stack = mStacks.get(stackNdx);
   2404             StringBuilder stackHeader = new StringBuilder(128);
   2405             stackHeader.append("  Stack #");
   2406             stackHeader.append(mStacks.indexOf(stack));
   2407             stackHeader.append(":");
   2408             printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
   2409                     stackHeader.toString());
   2410             printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false, !dumpAll,
   2411                     false, dumpPackage, true, "    Running activities (most recent first):", null);
   2412 
   2413             needSep = printed;
   2414             boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
   2415                     "    mPausingActivity: ");
   2416             if (pr) {
   2417                 printed = true;
   2418                 needSep = false;
   2419             }
   2420             pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
   2421                     "    mResumedActivity: ");
   2422             if (pr) {
   2423                 printed = true;
   2424                 needSep = false;
   2425             }
   2426             if (dumpAll) {
   2427                 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
   2428                         "    mLastPausedActivity: ");
   2429                 if (pr) {
   2430                     printed = true;
   2431                     needSep = true;
   2432                 }
   2433                 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
   2434                         needSep, "    mLastNoHistoryActivity: ");
   2435             }
   2436             needSep = printed;
   2437         }
   2438 
   2439         printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
   2440                 false, dumpPackage, true, "  Activities waiting to finish:", null);
   2441         printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
   2442                 false, dumpPackage, true, "  Activities waiting to stop:", null);
   2443         printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
   2444                 false, dumpPackage, true, "  Activities waiting for another to become visible:",
   2445                 null);
   2446         printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
   2447                 false, dumpPackage, true, "  Activities waiting to sleep:", null);
   2448         printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
   2449                 false, dumpPackage, true, "  Activities waiting to sleep:", null);
   2450 
   2451         return printed;
   2452     }
   2453 
   2454     static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
   2455             String prefix, String label, boolean complete, boolean brief, boolean client,
   2456             String dumpPackage, boolean needNL, String header1, String header2) {
   2457         TaskRecord lastTask = null;
   2458         String innerPrefix = null;
   2459         String[] args = null;
   2460         boolean printed = false;
   2461         for (int i=list.size()-1; i>=0; i--) {
   2462             final ActivityRecord r = list.get(i);
   2463             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   2464                 continue;
   2465             }
   2466             if (innerPrefix == null) {
   2467                 innerPrefix = prefix + "      ";
   2468                 args = new String[0];
   2469             }
   2470             printed = true;
   2471             final boolean full = !brief && (complete || !r.isInHistory());
   2472             if (needNL) {
   2473                 pw.println("");
   2474                 needNL = false;
   2475             }
   2476             if (header1 != null) {
   2477                 pw.println(header1);
   2478                 header1 = null;
   2479             }
   2480             if (header2 != null) {
   2481                 pw.println(header2);
   2482                 header2 = null;
   2483             }
   2484             if (lastTask != r.task) {
   2485                 lastTask = r.task;
   2486                 pw.print(prefix);
   2487                 pw.print(full ? "* " : "  ");
   2488                 pw.println(lastTask);
   2489                 if (full) {
   2490                     lastTask.dump(pw, prefix + "  ");
   2491                 } else if (complete) {
   2492                     // Complete + brief == give a summary.  Isn't that obvious?!?
   2493                     if (lastTask.intent != null) {
   2494                         pw.print(prefix); pw.print("  ");
   2495                                 pw.println(lastTask.intent.toInsecureStringWithClip());
   2496                     }
   2497                 }
   2498             }
   2499             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   2500             pw.print(" #"); pw.print(i); pw.print(": ");
   2501             pw.println(r);
   2502             if (full) {
   2503                 r.dump(pw, innerPrefix);
   2504             } else if (complete) {
   2505                 // Complete + brief == give a summary.  Isn't that obvious?!?
   2506                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   2507                 if (r.app != null) {
   2508                     pw.print(innerPrefix); pw.println(r.app);
   2509                 }
   2510             }
   2511             if (client && r.app != null && r.app.thread != null) {
   2512                 // flush anything that is already in the PrintWriter since the thread is going
   2513                 // to write to the file descriptor directly
   2514                 pw.flush();
   2515                 try {
   2516                     TransferPipe tp = new TransferPipe();
   2517                     try {
   2518                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   2519                                 r.appToken, innerPrefix, args);
   2520                         // Short timeout, since blocking here can
   2521                         // deadlock with the application.
   2522                         tp.go(fd, 2000);
   2523                     } finally {
   2524                         tp.kill();
   2525                     }
   2526                 } catch (IOException e) {
   2527                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   2528                 } catch (RemoteException e) {
   2529                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   2530                 }
   2531                 needNL = true;
   2532             }
   2533         }
   2534         return printed;
   2535     }
   2536 
   2537     void scheduleIdleTimeoutLocked(ActivityRecord next) {
   2538         if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
   2539         Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
   2540         mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
   2541     }
   2542 
   2543     final void scheduleIdleLocked() {
   2544         mHandler.sendEmptyMessage(IDLE_NOW_MSG);
   2545     }
   2546 
   2547     void removeTimeoutsForActivityLocked(ActivityRecord r) {
   2548         if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
   2549         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
   2550     }
   2551 
   2552     final void scheduleResumeTopActivities() {
   2553         mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
   2554     }
   2555 
   2556     void removeSleepTimeouts() {
   2557         mSleepTimeout = false;
   2558         mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
   2559     }
   2560 
   2561     final void scheduleSleepTimeout() {
   2562         removeSleepTimeouts();
   2563         mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
   2564     }
   2565 
   2566     private final class ActivityStackSupervisorHandler extends Handler {
   2567 
   2568         public ActivityStackSupervisorHandler(Looper looper) {
   2569             super(looper);
   2570         }
   2571 
   2572         void activityIdleInternal(ActivityRecord r) {
   2573             synchronized (mService) {
   2574                 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
   2575             }
   2576         }
   2577 
   2578         @Override
   2579         public void handleMessage(Message msg) {
   2580             switch (msg.what) {
   2581                 case IDLE_TIMEOUT_MSG: {
   2582                     if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
   2583                     if (mService.mDidDexOpt) {
   2584                         mService.mDidDexOpt = false;
   2585                         Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
   2586                         nmsg.obj = msg.obj;
   2587                         mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
   2588                         return;
   2589                     }
   2590                     // We don't at this point know if the activity is fullscreen,
   2591                     // so we need to be conservative and assume it isn't.
   2592                     activityIdleInternal((ActivityRecord)msg.obj);
   2593                 } break;
   2594                 case IDLE_NOW_MSG: {
   2595                     if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
   2596                     activityIdleInternal((ActivityRecord)msg.obj);
   2597                 } break;
   2598                 case RESUME_TOP_ACTIVITY_MSG: {
   2599                     synchronized (mService) {
   2600                         resumeTopActivitiesLocked();
   2601                     }
   2602                 } break;
   2603                 case SLEEP_TIMEOUT_MSG: {
   2604                     synchronized (mService) {
   2605                         if (mService.isSleepingOrShuttingDown()) {
   2606                             Slog.w(TAG, "Sleep timeout!  Sleeping now.");
   2607                             mSleepTimeout = true;
   2608                             checkReadyForSleepLocked();
   2609                         }
   2610                     }
   2611                 } break;
   2612                 case LAUNCH_TIMEOUT_MSG: {
   2613                     if (mService.mDidDexOpt) {
   2614                         mService.mDidDexOpt = false;
   2615                         mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
   2616                         return;
   2617                     }
   2618                     synchronized (mService) {
   2619                         if (mLaunchingActivity.isHeld()) {
   2620                             Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
   2621                             if (VALIDATE_WAKE_LOCK_CALLER
   2622                                     && Binder.getCallingUid() != Process.myUid()) {
   2623                                 throw new IllegalStateException("Calling must be system uid");
   2624                             }
   2625                             mLaunchingActivity.release();
   2626                         }
   2627                     }
   2628                 } break;
   2629             }
   2630         }
   2631     }
   2632 }
   2633