ActivityStackSupervisor.java revision b53d97c4571f8ed09e92eee64301969b96ff1e4d
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
17package com.android.server.am;
18
19import static android.Manifest.permission.START_ANY_ACTIVITY;
20import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.server.am.ActivityManagerService.localLOGV;
24import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
25import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
26import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
27import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
28import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
29import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
30import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
32import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
33import static com.android.server.am.ActivityManagerService.TAG;
34
35import android.app.Activity;
36import android.app.ActivityManager;
37import android.app.ActivityOptions;
38import android.app.AppGlobals;
39import android.app.IActivityManager;
40import android.app.IApplicationThread;
41import android.app.IThumbnailReceiver;
42import android.app.PendingIntent;
43import android.app.ActivityManager.RunningTaskInfo;
44import android.app.IActivityManager.WaitResult;
45import android.app.ResultInfo;
46import android.content.ComponentName;
47import android.content.Context;
48import android.content.IIntentSender;
49import android.content.Intent;
50import android.content.IntentSender;
51import android.content.pm.ActivityInfo;
52import android.content.pm.ApplicationInfo;
53import android.content.pm.PackageManager;
54import android.content.pm.ResolveInfo;
55import android.content.res.Configuration;
56import android.os.Binder;
57import android.os.Bundle;
58import android.os.Debug;
59import android.os.Handler;
60import android.os.IBinder;
61import android.os.Looper;
62import android.os.Message;
63import android.os.ParcelFileDescriptor;
64import android.os.PowerManager;
65import android.os.Process;
66import android.os.RemoteException;
67import android.os.SystemClock;
68import android.os.UserHandle;
69import android.util.EventLog;
70import android.util.Slog;
71import android.util.SparseIntArray;
72
73import com.android.internal.app.HeavyWeightSwitcherActivity;
74import com.android.internal.os.TransferPipe;
75import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
76import com.android.server.am.ActivityStack.ActivityState;
77import com.android.server.wm.StackBox;
78import com.android.server.wm.WindowManagerService;
79
80import java.io.FileDescriptor;
81import java.io.IOException;
82import java.io.PrintWriter;
83import java.util.ArrayList;
84import java.util.List;
85
86public 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                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1055                        || !"android".equals(r.info.packageName)) {
1056                    // Don't add this if it is a platform component that is marked
1057                    // to run in multiple processes, because this is actually
1058                    // part of the framework so doesn't make sense to track as a
1059                    // separate apk in the process.
1060                    app.addPackage(r.info.packageName, mService.mProcessStats);
1061                }
1062                realStartActivityLocked(r, app, andResume, checkConfig);
1063                return;
1064            } catch (RemoteException e) {
1065                Slog.w(TAG, "Exception when starting activity "
1066                        + r.intent.getComponent().flattenToShortString(), e);
1067            }
1068
1069            // If a dead object exception was thrown -- fall through to
1070            // restart the application.
1071        }
1072
1073        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1074                "activity", r.intent.getComponent(), false, false, true);
1075    }
1076
1077    final int startActivityLocked(IApplicationThread caller,
1078            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1079            String resultWho, int requestCode,
1080            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1081            boolean componentSpecified, ActivityRecord[] outActivity) {
1082        int err = ActivityManager.START_SUCCESS;
1083
1084        ProcessRecord callerApp = null;
1085        if (caller != null) {
1086            callerApp = mService.getRecordForAppLocked(caller);
1087            if (callerApp != null) {
1088                callingPid = callerApp.pid;
1089                callingUid = callerApp.info.uid;
1090            } else {
1091                Slog.w(TAG, "Unable to find app for caller " + caller
1092                      + " (pid=" + callingPid + ") when starting: "
1093                      + intent.toString());
1094                err = ActivityManager.START_PERMISSION_DENIED;
1095            }
1096        }
1097
1098        if (err == ActivityManager.START_SUCCESS) {
1099            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1100            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1101                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1102        }
1103
1104        ActivityRecord sourceRecord = null;
1105        ActivityRecord resultRecord = null;
1106        if (resultTo != null) {
1107            sourceRecord = isInAnyStackLocked(resultTo);
1108            if (DEBUG_RESULTS) Slog.v(
1109                TAG, "Will send result to " + resultTo + " " + sourceRecord);
1110            if (sourceRecord != null) {
1111                if (requestCode >= 0 && !sourceRecord.finishing) {
1112                    resultRecord = sourceRecord;
1113                }
1114            }
1115        }
1116        ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1117
1118        int launchFlags = intent.getFlags();
1119
1120        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1121                && sourceRecord != null) {
1122            // Transfer the result target from the source activity to the new
1123            // one being started, including any failures.
1124            if (requestCode >= 0) {
1125                ActivityOptions.abort(options);
1126                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1127            }
1128            resultRecord = sourceRecord.resultTo;
1129            resultWho = sourceRecord.resultWho;
1130            requestCode = sourceRecord.requestCode;
1131            sourceRecord.resultTo = null;
1132            if (resultRecord != null) {
1133                resultRecord.removeResultsLocked(
1134                    sourceRecord, resultWho, requestCode);
1135            }
1136        }
1137
1138        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1139            // We couldn't find a class that can handle the given Intent.
1140            // That's the end of that!
1141            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1142        }
1143
1144        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1145            // We couldn't find the specific class specified in the Intent.
1146            // Also the end of the line.
1147            err = ActivityManager.START_CLASS_NOT_FOUND;
1148        }
1149
1150        if (err != ActivityManager.START_SUCCESS) {
1151            if (resultRecord != null) {
1152                resultStack.sendActivityResultLocked(-1,
1153                    resultRecord, resultWho, requestCode,
1154                    Activity.RESULT_CANCELED, null);
1155            }
1156            setDismissKeyguard(false);
1157            ActivityOptions.abort(options);
1158            return err;
1159        }
1160
1161        final int startAnyPerm = mService.checkPermission(
1162                START_ANY_ACTIVITY, callingPid, callingUid);
1163        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1164                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1165        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1166            if (resultRecord != null) {
1167                resultStack.sendActivityResultLocked(-1,
1168                    resultRecord, resultWho, requestCode,
1169                    Activity.RESULT_CANCELED, null);
1170            }
1171            setDismissKeyguard(false);
1172            String msg;
1173            if (!aInfo.exported) {
1174                msg = "Permission Denial: starting " + intent.toString()
1175                        + " from " + callerApp + " (pid=" + callingPid
1176                        + ", uid=" + callingUid + ")"
1177                        + " not exported from uid " + aInfo.applicationInfo.uid;
1178            } else {
1179                msg = "Permission Denial: starting " + intent.toString()
1180                        + " from " + callerApp + " (pid=" + callingPid
1181                        + ", uid=" + callingUid + ")"
1182                        + " requires " + aInfo.permission;
1183            }
1184            Slog.w(TAG, msg);
1185            throw new SecurityException(msg);
1186        }
1187
1188        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1189                callingPid, resolvedType, aInfo.applicationInfo);
1190
1191        if (mService.mController != null) {
1192            try {
1193                // The Intent we give to the watcher has the extra data
1194                // stripped off, since it can contain private information.
1195                Intent watchIntent = intent.cloneFilter();
1196                abort |= !mService.mController.activityStarting(watchIntent,
1197                        aInfo.applicationInfo.packageName);
1198            } catch (RemoteException e) {
1199                mService.mController = null;
1200            }
1201        }
1202
1203        if (abort) {
1204            if (resultRecord != null) {
1205                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1206                        Activity.RESULT_CANCELED, null);
1207            }
1208            // We pretend to the caller that it was really started, but
1209            // they will just get a cancel result.
1210            setDismissKeyguard(false);
1211            ActivityOptions.abort(options);
1212            return ActivityManager.START_SUCCESS;
1213        }
1214
1215        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1216                intent, resolvedType, aInfo, mService.mConfiguration,
1217                resultRecord, resultWho, requestCode, componentSpecified, this);
1218        if (outActivity != null) {
1219            outActivity[0] = r;
1220        }
1221
1222        final ActivityStack stack = getFocusedStack();
1223        if (stack.mResumedActivity == null
1224                || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
1225            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1226                PendingActivityLaunch pal =
1227                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1228                mService.mPendingActivityLaunches.add(pal);
1229                setDismissKeyguard(false);
1230                ActivityOptions.abort(options);
1231                return ActivityManager.START_SWITCHES_CANCELED;
1232            }
1233        }
1234
1235        if (mService.mDidAppSwitch) {
1236            // This is the second allowed switch since we stopped switches,
1237            // so now just generally allow switches.  Use case: user presses
1238            // home (switches disabled, switch to home, mDidAppSwitch now true);
1239            // user taps a home icon (coming from home so allowed, we hit here
1240            // and now allow anyone to switch again).
1241            mService.mAppSwitchesAllowedTime = 0;
1242        } else {
1243            mService.mDidAppSwitch = true;
1244        }
1245
1246        mService.doPendingActivityLaunchesLocked(false);
1247
1248        err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
1249
1250        if (allPausedActivitiesComplete()) {
1251            // If someone asked to have the keyguard dismissed on the next
1252            // activity start, but we are not actually doing an activity
1253            // switch...  just dismiss the keyguard now, because we
1254            // probably want to see whatever is behind it.
1255            dismissKeyguard();
1256        }
1257        return err;
1258    }
1259
1260    ActivityStack adjustStackFocus(ActivityRecord r) {
1261        final TaskRecord task = r.task;
1262        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
1263            if (task != null) {
1264                final ActivityStack taskStack = task.stack;
1265                if (mFocusedStack != taskStack) {
1266                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1267                            "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
1268                    mFocusedStack = taskStack.isHomeStack() ? null : taskStack;
1269                } else {
1270                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1271                        "adjustStackFocus: Focused stack already=" + mFocusedStack);
1272                }
1273                return taskStack;
1274            }
1275
1276            if (mFocusedStack != null) {
1277                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1278                        "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1279                return mFocusedStack;
1280            }
1281
1282            for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1283                ActivityStack stack = mStacks.get(stackNdx);
1284                if (!stack.isHomeStack()) {
1285                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1286                            "adjustStackFocus: Setting focused stack=" + stack);
1287                    mFocusedStack = stack;
1288                    return mFocusedStack;
1289                }
1290            }
1291
1292            // Time to create the first app stack for this user.
1293            int stackId =
1294                    mService.createStack(-1, HOME_STACK_ID, StackBox.TASK_STACK_GOES_OVER, 1.0f);
1295            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1296                    " stackId=" + stackId);
1297            mFocusedStack = getStack(stackId);
1298            return mFocusedStack;
1299        }
1300        return mHomeStack;
1301    }
1302
1303    void setFocusedStack(ActivityRecord r) {
1304        if (r == null) {
1305            return;
1306        }
1307        if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
1308            if (mStackState != STACK_STATE_HOME_IN_FRONT) {
1309                if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1310                        stackStateToString(mStackState) + " new=" +
1311                        stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1312                        " Callers=" + Debug.getCallers(3));
1313                mStackState = STACK_STATE_HOME_TO_FRONT;
1314            }
1315        } else {
1316            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1317                    "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
1318                    " Callers=" + Debug.getCallers(3));
1319            final ActivityStack taskStack = r.task.stack;
1320            mFocusedStack = taskStack.isHomeStack() ? null : taskStack;
1321            if (mStackState != STACK_STATE_HOME_IN_BACK) {
1322                if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1323                        stackStateToString(mStackState) + " new=" +
1324                        stackStateToString(STACK_STATE_HOME_TO_BACK) +
1325                        " Callers=" + Debug.getCallers(3));
1326                mStackState = STACK_STATE_HOME_TO_BACK;
1327            }
1328        }
1329    }
1330
1331    final int startActivityUncheckedLocked(ActivityRecord r,
1332            ActivityRecord sourceRecord, int startFlags, boolean doResume,
1333            Bundle options) {
1334        final Intent intent = r.intent;
1335        final int callingUid = r.launchedFromUid;
1336
1337        int launchFlags = intent.getFlags();
1338
1339        // We'll invoke onUserLeaving before onPause only if the launching
1340        // activity did not explicitly state that this is an automated launch.
1341        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1342        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1343
1344        // If the caller has asked not to resume at this point, we make note
1345        // of this in the record so that we can skip it when trying to find
1346        // the top running activity.
1347        if (!doResume) {
1348            r.delayedResume = true;
1349        }
1350
1351        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1352
1353        // If the onlyIfNeeded flag is set, then we can do this if the activity
1354        // being launched is the same as the one making the call...  or, as
1355        // a special case, if we do not know the caller then we count the
1356        // current top activity as the caller.
1357        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1358            ActivityRecord checkedCaller = sourceRecord;
1359            if (checkedCaller == null) {
1360                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1361            }
1362            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1363                // Caller is not the same as launcher, so always needed.
1364                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1365            }
1366        }
1367
1368        if (sourceRecord == null) {
1369            // This activity is not being started from another...  in this
1370            // case we -always- start a new task.
1371            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1372                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1373                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1374                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1375            }
1376        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1377            // The original activity who is starting us is running as a single
1378            // instance...  this new activity it is starting must go on its
1379            // own task.
1380            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1381        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1382                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1383            // The activity being started is a single instance...  it always
1384            // gets launched into its own task.
1385            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1386        }
1387
1388        final ActivityStack sourceStack;
1389        if (sourceRecord != null) {
1390            if (sourceRecord.finishing) {
1391                // If the source is finishing, we can't further count it as our source.  This
1392                // is because the task it is associated with may now be empty and on its way out,
1393                // so we don't want to blindly throw it in to that task.  Instead we will take
1394                // the NEW_TASK flow and try to find a task for it.
1395                if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1396                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1397                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1398                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1399                }
1400                sourceRecord = null;
1401                sourceStack = null;
1402            } else {
1403                sourceStack = sourceRecord.task.stack;
1404            }
1405        } else {
1406            sourceStack = null;
1407        }
1408
1409        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1410            // For whatever reason this activity is being launched into a new
1411            // task...  yet the caller has requested a result back.  Well, that
1412            // is pretty messed up, so instead immediately send back a cancel
1413            // and let the new task continue launched as normal without a
1414            // dependency on its originator.
1415            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1416            r.resultTo.task.stack.sendActivityResultLocked(-1,
1417                    r.resultTo, r.resultWho, r.requestCode,
1418                Activity.RESULT_CANCELED, null);
1419            r.resultTo = null;
1420        }
1421
1422        boolean addingToTask = false;
1423        boolean movedHome = false;
1424        TaskRecord reuseTask = null;
1425        ActivityStack targetStack;
1426        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1427                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1428                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1429                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1430            // If bring to front is requested, and no result is requested, and
1431            // we can find a task that was started with this same
1432            // component, then instead of launching bring that one to the front.
1433            if (r.resultTo == null) {
1434                // See if there is a task to bring to the front.  If this is
1435                // a SINGLE_INSTANCE activity, there can be one and only one
1436                // instance of it in the history, and it is always in its own
1437                // unique task, so we do a special search.
1438                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1439                        ? findTaskLocked(r)
1440                        : findActivityLocked(intent, r.info);
1441                if (intentActivity != null) {
1442                    if (r.task == null) {
1443                        r.task = intentActivity.task;
1444                    }
1445                    targetStack = intentActivity.task.stack;
1446                    targetStack.mLastPausedActivity = null;
1447                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1448                            + " from " + intentActivity);
1449                    moveHomeStack(targetStack.isHomeStack());
1450                    if (intentActivity.task.intent == null) {
1451                        // This task was started because of movement of
1452                        // the activity based on affinity...  now that we
1453                        // are actually launching it, we can assign the
1454                        // base intent.
1455                        intentActivity.task.setIntent(intent, r.info);
1456                    }
1457                    // If the target task is not in the front, then we need
1458                    // to bring it to the front...  except...  well, with
1459                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1460                    // to have the same behavior as if a new instance was
1461                    // being started, which means not bringing it to the front
1462                    // if the caller is not itself in the front.
1463                    final ActivityStack lastStack = getLastStack();
1464                    ActivityRecord curTop = lastStack == null?
1465                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1466                    if (curTop != null && (curTop.task != intentActivity.task ||
1467                            curTop.task != lastStack.topTask())) {
1468                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1469                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1470                                sourceStack.topActivity().task == sourceRecord.task)) {
1471                            // We really do want to push this one into the
1472                            // user's face, right now.
1473                            movedHome = true;
1474                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1475                            if ((launchFlags &
1476                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1477                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1478                                // Caller wants to appear on home activity.
1479                                intentActivity.task.mOnTopOfHome = true;
1480                            }
1481                            options = null;
1482                        }
1483                    }
1484                    // If the caller has requested that the target task be
1485                    // reset, then do so.
1486                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1487                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1488                    }
1489                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1490                        // We don't need to start a new activity, and
1491                        // the client said not to do anything if that
1492                        // is the case, so this is it!  And for paranoia, make
1493                        // sure we have correctly resumed the top activity.
1494                        if (doResume) {
1495                            resumeTopActivitiesLocked(targetStack, null, options);
1496                        } else {
1497                            ActivityOptions.abort(options);
1498                        }
1499                        if (r.task == null)  Slog.v(TAG,
1500                                "startActivityUncheckedLocked: task left null",
1501                                new RuntimeException("here").fillInStackTrace());
1502                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1503                    }
1504                    if ((launchFlags &
1505                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1506                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1507                        // The caller has requested to completely replace any
1508                        // existing task with its new activity.  Well that should
1509                        // not be too hard...
1510                        reuseTask = intentActivity.task;
1511                        reuseTask.performClearTaskLocked();
1512                        reuseTask.setIntent(r.intent, r.info);
1513                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1514                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1515                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1516                        // In this situation we want to remove all activities
1517                        // from the task up to the one being started.  In most
1518                        // cases this means we are resetting the task to its
1519                        // initial state.
1520                        ActivityRecord top =
1521                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1522                        if (top != null) {
1523                            if (top.frontOfTask) {
1524                                // Activity aliases may mean we use different
1525                                // intents for the top activity, so make sure
1526                                // the task now has the identity of the new
1527                                // intent.
1528                                top.task.setIntent(r.intent, r.info);
1529                            }
1530                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1531                                    r, top.task);
1532                            top.deliverNewIntentLocked(callingUid, r.intent);
1533                        } else {
1534                            // A special case: we need to
1535                            // start the activity because it is not currently
1536                            // running, and the caller has asked to clear the
1537                            // current task to have this activity at the top.
1538                            addingToTask = true;
1539                            // Now pretend like this activity is being started
1540                            // by the top of its task, so it is put in the
1541                            // right place.
1542                            sourceRecord = intentActivity;
1543                        }
1544                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1545                        // In this case the top activity on the task is the
1546                        // same as the one being launched, so we take that
1547                        // as a request to bring the task to the foreground.
1548                        // If the top activity in the task is the root
1549                        // activity, deliver this new intent to it if it
1550                        // desires.
1551                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1552                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1553                                && intentActivity.realActivity.equals(r.realActivity)) {
1554                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1555                                    intentActivity.task);
1556                            if (intentActivity.frontOfTask) {
1557                                intentActivity.task.setIntent(r.intent, r.info);
1558                            }
1559                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1560                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1561                            // In this case we are launching the root activity
1562                            // of the task, but with a different intent.  We
1563                            // should start a new instance on top.
1564                            addingToTask = true;
1565                            sourceRecord = intentActivity;
1566                        }
1567                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1568                        // In this case an activity is being launched in to an
1569                        // existing task, without resetting that task.  This
1570                        // is typically the situation of launching an activity
1571                        // from a notification or shortcut.  We want to place
1572                        // the new activity on top of the current task.
1573                        addingToTask = true;
1574                        sourceRecord = intentActivity;
1575                    } else if (!intentActivity.task.rootWasReset) {
1576                        // In this case we are launching in to an existing task
1577                        // that has not yet been started from its front door.
1578                        // The current task has been brought to the front.
1579                        // Ideally, we'd probably like to place this new task
1580                        // at the bottom of its stack, but that's a little hard
1581                        // to do with the current organization of the code so
1582                        // for now we'll just drop it.
1583                        intentActivity.task.setIntent(r.intent, r.info);
1584                    }
1585                    if (!addingToTask && reuseTask == null) {
1586                        // We didn't do anything...  but it was needed (a.k.a., client
1587                        // don't use that intent!)  And for paranoia, make
1588                        // sure we have correctly resumed the top activity.
1589                        if (doResume) {
1590                            targetStack.resumeTopActivityLocked(null, options);
1591                        } else {
1592                            ActivityOptions.abort(options);
1593                        }
1594                        if (r.task == null)  Slog.v(TAG,
1595                            "startActivityUncheckedLocked: task left null",
1596                            new RuntimeException("here").fillInStackTrace());
1597                        return ActivityManager.START_TASK_TO_FRONT;
1598                    }
1599                }
1600            }
1601        }
1602
1603        //String uri = r.intent.toURI();
1604        //Intent intent2 = new Intent(uri);
1605        //Slog.i(TAG, "Given intent: " + r.intent);
1606        //Slog.i(TAG, "URI is: " + uri);
1607        //Slog.i(TAG, "To intent: " + intent2);
1608
1609        if (r.packageName != null) {
1610            // If the activity being launched is the same as the one currently
1611            // at the top, then we need to check if it should only be launched
1612            // once.
1613            ActivityStack topStack = getFocusedStack();
1614            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1615            if (top != null && r.resultTo == null) {
1616                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1617                    if (top.app != null && top.app.thread != null) {
1618                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1619                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1620                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1621                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1622                                    top.task);
1623                            // For paranoia, make sure we have correctly
1624                            // resumed the top activity.
1625                            topStack.mLastPausedActivity = null;
1626                            if (doResume) {
1627                                resumeTopActivitiesLocked();
1628                            }
1629                            ActivityOptions.abort(options);
1630                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1631                                // We don't need to start a new activity, and
1632                                // the client said not to do anything if that
1633                                // is the case, so this is it!
1634                                if (r.task == null)  Slog.v(TAG,
1635                                    "startActivityUncheckedLocked: task left null",
1636                                    new RuntimeException("here").fillInStackTrace());
1637                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1638                            }
1639                            top.deliverNewIntentLocked(callingUid, r.intent);
1640                            if (r.task == null)  Slog.v(TAG,
1641                                "startActivityUncheckedLocked: task left null",
1642                                new RuntimeException("here").fillInStackTrace());
1643                            return ActivityManager.START_DELIVERED_TO_TOP;
1644                        }
1645                    }
1646                }
1647            }
1648
1649        } else {
1650            if (r.resultTo != null) {
1651                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1652                        r.requestCode, Activity.RESULT_CANCELED, null);
1653            }
1654            ActivityOptions.abort(options);
1655            if (r.task == null)  Slog.v(TAG,
1656                "startActivityUncheckedLocked: task left null",
1657                new RuntimeException("here").fillInStackTrace());
1658            return ActivityManager.START_CLASS_NOT_FOUND;
1659        }
1660
1661        boolean newTask = false;
1662        boolean keepCurTransition = false;
1663
1664        // Should this be considered a new task?
1665        if (r.resultTo == null && !addingToTask
1666                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1667            targetStack = adjustStackFocus(r);
1668            moveHomeStack(targetStack.isHomeStack());
1669            if (reuseTask == null) {
1670                r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1671                        null, true);
1672                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1673                        r.task);
1674            } else {
1675                r.setTask(reuseTask, reuseTask, true);
1676            }
1677            newTask = true;
1678            if (!movedHome) {
1679                if ((launchFlags &
1680                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1681                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1682                    // Caller wants to appear on home activity, so before starting
1683                    // their own activity we will bring home to the front.
1684                    r.task.mOnTopOfHome = true;
1685                }
1686            }
1687        } else if (sourceRecord != null) {
1688            TaskRecord sourceTask = sourceRecord.task;
1689            targetStack = sourceTask.stack;
1690            moveHomeStack(targetStack.isHomeStack());
1691            if (!addingToTask &&
1692                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1693                // In this case, we are adding the activity to an existing
1694                // task, but the caller has asked to clear that task if the
1695                // activity is already running.
1696                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1697                keepCurTransition = true;
1698                if (top != null) {
1699                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1700                    top.deliverNewIntentLocked(callingUid, r.intent);
1701                    // For paranoia, make sure we have correctly
1702                    // resumed the top activity.
1703                    targetStack.mLastPausedActivity = null;
1704                    if (doResume) {
1705                        targetStack.resumeTopActivityLocked(null);
1706                    }
1707                    ActivityOptions.abort(options);
1708                    if (r.task == null)  Slog.w(TAG,
1709                        "startActivityUncheckedLocked: task left null",
1710                        new RuntimeException("here").fillInStackTrace());
1711                    return ActivityManager.START_DELIVERED_TO_TOP;
1712                }
1713            } else if (!addingToTask &&
1714                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1715                // In this case, we are launching an activity in our own task
1716                // that may already be running somewhere in the history, and
1717                // we want to shuffle it to the front of the stack if so.
1718                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1719                if (top != null) {
1720                    final TaskRecord task = top.task;
1721                    task.moveActivityToFrontLocked(top);
1722                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1723                    top.updateOptionsLocked(options);
1724                    top.deliverNewIntentLocked(callingUid, r.intent);
1725                    targetStack.mLastPausedActivity = null;
1726                    if (doResume) {
1727                        targetStack.resumeTopActivityLocked(null);
1728                    }
1729                    return ActivityManager.START_DELIVERED_TO_TOP;
1730                }
1731            }
1732            // An existing activity is starting this new activity, so we want
1733            // to keep the new one in the same task as the one that is starting
1734            // it.
1735            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
1736            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1737                    + " in existing task " + r.task + " from source " + sourceRecord);
1738
1739        } else {
1740            // This not being started from an existing activity, and not part
1741            // of a new task...  just put it in the top task, though these days
1742            // this case should never happen.
1743            targetStack = adjustStackFocus(r);
1744            moveHomeStack(targetStack.isHomeStack());
1745            ActivityRecord prev = targetStack.topActivity();
1746            r.setTask(prev != null ? prev.task
1747                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1748                    null, true);
1749            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1750                    + " in new guessed " + r.task);
1751        }
1752
1753        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1754                intent, r.getUriPermissionsLocked());
1755
1756        if (newTask) {
1757            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1758        }
1759        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1760        targetStack.mLastPausedActivity = null;
1761        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1762        mService.setFocusedActivityLocked(r);
1763        return ActivityManager.START_SUCCESS;
1764    }
1765
1766    void acquireLaunchWakelock() {
1767        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1768            throw new IllegalStateException("Calling must be system uid");
1769        }
1770        mLaunchingActivity.acquire();
1771        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1772            // To be safe, don't allow the wake lock to be held for too long.
1773            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1774        }
1775    }
1776
1777    // Checked.
1778    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1779            Configuration config) {
1780        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1781
1782        ArrayList<ActivityRecord> stops = null;
1783        ArrayList<ActivityRecord> finishes = null;
1784        ArrayList<UserStartedState> startingUsers = null;
1785        int NS = 0;
1786        int NF = 0;
1787        IApplicationThread sendThumbnail = null;
1788        boolean booting = false;
1789        boolean enableScreen = false;
1790        boolean activityRemoved = false;
1791
1792        ActivityRecord r = ActivityRecord.forToken(token);
1793        if (r != null) {
1794            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1795                    Debug.getCallers(4));
1796            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1797            r.finishLaunchTickingLocked();
1798            if (fromTimeout) {
1799                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1800            }
1801
1802            // This is a hack to semi-deal with a race condition
1803            // in the client where it can be constructed with a
1804            // newer configuration from when we asked it to launch.
1805            // We'll update with whatever configuration it now says
1806            // it used to launch.
1807            if (config != null) {
1808                r.configuration = config;
1809            }
1810
1811            // We are now idle.  If someone is waiting for a thumbnail from
1812            // us, we can now deliver.
1813            r.idle = true;
1814
1815            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1816                sendThumbnail = r.app.thread;
1817                r.thumbnailNeeded = false;
1818            }
1819
1820            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1821            if (!mService.mBooted && isFrontStack(r.task.stack)) {
1822                mService.mBooted = true;
1823                enableScreen = true;
1824            }
1825        }
1826
1827        if (allResumedActivitiesIdle()) {
1828            if (r != null) {
1829                mService.scheduleAppGcsLocked();
1830            }
1831
1832            if (mLaunchingActivity.isHeld()) {
1833                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1834                if (VALIDATE_WAKE_LOCK_CALLER &&
1835                        Binder.getCallingUid() != Process.myUid()) {
1836                    throw new IllegalStateException("Calling must be system uid");
1837                }
1838                mLaunchingActivity.release();
1839            }
1840            ensureActivitiesVisibleLocked(null, 0);
1841        }
1842
1843        // Atomically retrieve all of the other things to do.
1844        stops = processStoppingActivitiesLocked(true);
1845        NS = stops != null ? stops.size() : 0;
1846        if ((NF=mFinishingActivities.size()) > 0) {
1847            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1848            mFinishingActivities.clear();
1849        }
1850
1851        final ArrayList<ActivityRecord> thumbnails;
1852        final int NT = mCancelledThumbnails.size();
1853        if (NT > 0) {
1854            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1855            mCancelledThumbnails.clear();
1856        } else {
1857            thumbnails = null;
1858        }
1859
1860        if (isFrontStack(mHomeStack)) {
1861            booting = mService.mBooting;
1862            mService.mBooting = false;
1863        }
1864
1865        if (mStartingUsers.size() > 0) {
1866            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1867            mStartingUsers.clear();
1868        }
1869
1870        // Perform the following actions from unsynchronized state.
1871        final IApplicationThread thumbnailThread = sendThumbnail;
1872        mHandler.post(new Runnable() {
1873            @Override
1874            public void run() {
1875                if (thumbnailThread != null) {
1876                    try {
1877                        thumbnailThread.requestThumbnail(token);
1878                    } catch (Exception e) {
1879                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1880                        mService.sendPendingThumbnail(null, token, null, null, true);
1881                    }
1882                }
1883
1884                // Report back to any thumbnail receivers.
1885                for (int i = 0; i < NT; i++) {
1886                    ActivityRecord r = thumbnails.get(i);
1887                    mService.sendPendingThumbnail(r, null, null, null, true);
1888                }
1889            }
1890        });
1891
1892        // Stop any activities that are scheduled to do so but have been
1893        // waiting for the next one to start.
1894        for (int i = 0; i < NS; i++) {
1895            r = stops.get(i);
1896            final ActivityStack stack = r.task.stack;
1897            if (r.finishing) {
1898                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1899            } else {
1900                stack.stopActivityLocked(r);
1901            }
1902        }
1903
1904        // Finish any activities that are scheduled to do so but have been
1905        // waiting for the next one to start.
1906        for (int i = 0; i < NF; i++) {
1907            r = finishes.get(i);
1908            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1909        }
1910
1911        if (booting) {
1912            mService.finishBooting();
1913        } else if (startingUsers != null) {
1914            for (int i = 0; i < startingUsers.size(); i++) {
1915                mService.finishUserSwitch(startingUsers.get(i));
1916            }
1917        }
1918
1919        mService.trimApplications();
1920        //dump();
1921        //mWindowManager.dump();
1922
1923        if (enableScreen) {
1924            mService.enableScreenAfterBoot();
1925        }
1926
1927        if (activityRemoved) {
1928            resumeTopActivitiesLocked();
1929        }
1930
1931        return r;
1932    }
1933
1934    boolean handleAppDiedLocked(ProcessRecord app) {
1935        boolean hasVisibleActivities = false;
1936        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1937            hasVisibleActivities |= mStacks.get(stackNdx).handleAppDiedLocked(app);
1938        }
1939        return hasVisibleActivities;
1940    }
1941
1942    void closeSystemDialogsLocked() {
1943        final int numStacks = mStacks.size();
1944        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1945            final ActivityStack stack = mStacks.get(stackNdx);
1946            stack.closeSystemDialogsLocked();
1947        }
1948    }
1949
1950    void removeUserLocked(int userId) {
1951        mUserStackInFront.delete(userId);
1952    }
1953
1954    /**
1955     * @return true if some activity was finished (or would have finished if doit were true).
1956     */
1957    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1958        boolean didSomething = false;
1959        final int numStacks = mStacks.size();
1960        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1961            final ActivityStack stack = mStacks.get(stackNdx);
1962            if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1963                didSomething = true;
1964            }
1965        }
1966        return didSomething;
1967    }
1968
1969    void updatePreviousProcessLocked(ActivityRecord r) {
1970        // Now that this process has stopped, we may want to consider
1971        // it to be the previous app to try to keep around in case
1972        // the user wants to return to it.
1973
1974        // First, found out what is currently the foreground app, so that
1975        // we don't blow away the previous app if this activity is being
1976        // hosted by the process that is actually still the foreground.
1977        ProcessRecord fgApp = null;
1978        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1979            final ActivityStack stack = mStacks.get(stackNdx);
1980            if (isFrontStack(stack)) {
1981                if (stack.mResumedActivity != null) {
1982                    fgApp = stack.mResumedActivity.app;
1983                } else if (stack.mPausingActivity != null) {
1984                    fgApp = stack.mPausingActivity.app;
1985                }
1986                break;
1987            }
1988        }
1989
1990        // Now set this one as the previous process, only if that really
1991        // makes sense to.
1992        if (r.app != null && fgApp != null && r.app != fgApp
1993                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
1994                && r.app != mService.mHomeProcess) {
1995            mService.mPreviousProcess = r.app;
1996            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1997        }
1998    }
1999
2000    boolean resumeTopActivitiesLocked() {
2001        return resumeTopActivitiesLocked(null, null, null);
2002    }
2003
2004    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2005            Bundle targetOptions) {
2006        if (targetStack == null) {
2007            targetStack = getFocusedStack();
2008        }
2009        boolean result = false;
2010        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2011            final ActivityStack stack = mStacks.get(stackNdx);
2012            if (isFrontStack(stack)) {
2013                if (stack == targetStack) {
2014                    result = stack.resumeTopActivityLocked(target, targetOptions);
2015                } else {
2016                    stack.resumeTopActivityLocked(null);
2017                }
2018            }
2019        }
2020        return result;
2021    }
2022
2023    void finishTopRunningActivityLocked(ProcessRecord app) {
2024        final int numStacks = mStacks.size();
2025        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2026            final ActivityStack stack = mStacks.get(stackNdx);
2027            stack.finishTopRunningActivityLocked(app);
2028        }
2029    }
2030
2031    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2032        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2033            if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2034                if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
2035                        mStacks.get(stackNdx));
2036                return;
2037            }
2038        }
2039    }
2040
2041    ActivityStack getStack(int stackId) {
2042        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2043            final ActivityStack stack = mStacks.get(stackNdx);
2044            if (stack.getStackId() == stackId) {
2045                return stack;
2046            }
2047        }
2048        return null;
2049    }
2050
2051    ArrayList<ActivityStack> getStacks() {
2052        return new ArrayList<ActivityStack>(mStacks);
2053    }
2054
2055    int createStack() {
2056        while (true) {
2057            if (++mLastStackId <= HOME_STACK_ID) {
2058                mLastStackId = HOME_STACK_ID + 1;
2059            }
2060            if (getStack(mLastStackId) == null) {
2061                break;
2062            }
2063        }
2064        mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
2065        return mLastStackId;
2066    }
2067
2068    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2069        final TaskRecord task = anyTaskForIdLocked(taskId);
2070        if (task == null) {
2071            return;
2072        }
2073        final ActivityStack stack = getStack(stackId);
2074        if (stack == null) {
2075            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2076            return;
2077        }
2078        removeTask(task);
2079        stack.addTask(task, toTop);
2080        mWindowManager.addTask(taskId, stackId, toTop);
2081        resumeTopActivitiesLocked();
2082    }
2083
2084    ActivityRecord findTaskLocked(ActivityRecord r) {
2085        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2086        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2087            final ActivityStack stack = mStacks.get(stackNdx);
2088            if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2089                if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2090                continue;
2091            }
2092            final ActivityRecord ar = stack.findTaskLocked(r);
2093            if (ar != null) {
2094                return ar;
2095            }
2096        }
2097        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2098        return null;
2099    }
2100
2101    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2102        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2103            final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
2104            if (ar != null) {
2105                return ar;
2106            }
2107        }
2108        return null;
2109    }
2110
2111    void goingToSleepLocked() {
2112        scheduleSleepTimeout();
2113        if (!mGoingToSleep.isHeld()) {
2114            mGoingToSleep.acquire();
2115            if (mLaunchingActivity.isHeld()) {
2116                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2117                    throw new IllegalStateException("Calling must be system uid");
2118                }
2119                mLaunchingActivity.release();
2120                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2121            }
2122        }
2123        checkReadyForSleepLocked();
2124    }
2125
2126    boolean shutdownLocked(int timeout) {
2127        boolean timedout = false;
2128        goingToSleepLocked();
2129
2130        final long endTime = System.currentTimeMillis() + timeout;
2131        while (true) {
2132            boolean cantShutdown = false;
2133            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2134                cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2135            }
2136            if (cantShutdown) {
2137                long timeRemaining = endTime - System.currentTimeMillis();
2138                if (timeRemaining > 0) {
2139                    try {
2140                        mService.wait(timeRemaining);
2141                    } catch (InterruptedException e) {
2142                    }
2143                } else {
2144                    Slog.w(TAG, "Activity manager shutdown timed out");
2145                    timedout = true;
2146                    break;
2147                }
2148            } else {
2149                break;
2150            }
2151        }
2152
2153        // Force checkReadyForSleep to complete.
2154        mSleepTimeout = true;
2155        checkReadyForSleepLocked();
2156
2157        return timedout;
2158    }
2159
2160    void comeOutOfSleepIfNeededLocked() {
2161        removeSleepTimeouts();
2162        if (mGoingToSleep.isHeld()) {
2163            mGoingToSleep.release();
2164        }
2165        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2166            final ActivityStack stack = mStacks.get(stackNdx);
2167            stack.awakeFromSleepingLocked();
2168            if (isFrontStack(stack)) {
2169                resumeTopActivitiesLocked();
2170            }
2171        }
2172        mGoingToSleepActivities.clear();
2173    }
2174
2175    void activitySleptLocked(ActivityRecord r) {
2176        mGoingToSleepActivities.remove(r);
2177        checkReadyForSleepLocked();
2178    }
2179
2180    void checkReadyForSleepLocked() {
2181        if (!mService.isSleepingOrShuttingDown()) {
2182            // Do not care.
2183            return;
2184        }
2185
2186        if (!mSleepTimeout) {
2187            boolean dontSleep = false;
2188            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2189                dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2190            }
2191
2192            if (mStoppingActivities.size() > 0) {
2193                // Still need to tell some activities to stop; can't sleep yet.
2194                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2195                        + mStoppingActivities.size() + " activities");
2196                scheduleIdleLocked();
2197                dontSleep = true;
2198            }
2199
2200            if (mGoingToSleepActivities.size() > 0) {
2201                // Still need to tell some activities to sleep; can't sleep yet.
2202                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2203                        + mGoingToSleepActivities.size() + " activities");
2204                dontSleep = true;
2205            }
2206
2207            if (dontSleep) {
2208                return;
2209            }
2210        }
2211
2212        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2213            mStacks.get(stackNdx).goToSleep();
2214        }
2215
2216        removeSleepTimeouts();
2217
2218        if (mGoingToSleep.isHeld()) {
2219            mGoingToSleep.release();
2220        }
2221        if (mService.mShuttingDown) {
2222            mService.notifyAll();
2223        }
2224    }
2225
2226    boolean reportResumedActivityLocked(ActivityRecord r) {
2227        final ActivityStack stack = r.task.stack;
2228        if (isFrontStack(stack)) {
2229            mService.updateUsageStats(r, true);
2230        }
2231        if (allResumedActivitiesComplete()) {
2232            ensureActivitiesVisibleLocked(null, 0);
2233            mWindowManager.executeAppTransition();
2234            return true;
2235        }
2236        return false;
2237    }
2238
2239    void handleAppCrashLocked(ProcessRecord app) {
2240        final int numStacks = mStacks.size();
2241        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2242            final ActivityStack stack = mStacks.get(stackNdx);
2243            stack.handleAppCrashLocked(app);
2244        }
2245    }
2246
2247    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2248        // First the front stacks. In case any are not fullscreen and are in front of home.
2249        boolean showHomeBehindStack = false;
2250        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2251            final ActivityStack stack = mStacks.get(stackNdx);
2252            if (isFrontStack(stack)) {
2253                showHomeBehindStack =
2254                        stack.ensureActivitiesVisibleLocked(starting, configChanges);
2255            }
2256        }
2257        // Now do back stacks.
2258        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2259            final ActivityStack stack = mStacks.get(stackNdx);
2260            if (!isFrontStack(stack)) {
2261                stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2262            }
2263        }
2264    }
2265
2266    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2267        final int numStacks = mStacks.size();
2268        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2269            final ActivityStack stack = mStacks.get(stackNdx);
2270            stack.scheduleDestroyActivities(app, false, reason);
2271        }
2272    }
2273
2274    boolean switchUserLocked(int userId, UserStartedState uss) {
2275        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2276        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2277        mCurrentUser = userId;
2278
2279        mStartingUsers.add(uss);
2280        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2281            mStacks.get(stackNdx).switchUserLocked(userId);
2282        }
2283
2284        ActivityStack stack = getStack(restoreStackId);
2285        if (stack == null) {
2286            stack = mHomeStack;
2287        }
2288        final boolean homeInFront = stack.isHomeStack();
2289        moveHomeStack(homeInFront);
2290        mWindowManager.moveTaskToTop(stack.topTask().taskId);
2291        return homeInFront;
2292    }
2293
2294    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2295        int N = mStoppingActivities.size();
2296        if (N <= 0) return null;
2297
2298        ArrayList<ActivityRecord> stops = null;
2299
2300        final boolean nowVisible = allResumedActivitiesVisible();
2301        for (int i=0; i<N; i++) {
2302            ActivityRecord s = mStoppingActivities.get(i);
2303            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2304                    + nowVisible + " waitingVisible=" + s.waitingVisible
2305                    + " finishing=" + s.finishing);
2306            if (s.waitingVisible && nowVisible) {
2307                mWaitingVisibleActivities.remove(s);
2308                s.waitingVisible = false;
2309                if (s.finishing) {
2310                    // If this activity is finishing, it is sitting on top of
2311                    // everyone else but we now know it is no longer needed...
2312                    // so get rid of it.  Otherwise, we need to go through the
2313                    // normal flow and hide it once we determine that it is
2314                    // hidden by the activities in front of it.
2315                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2316                    mWindowManager.setAppVisibility(s.appToken, false);
2317                }
2318            }
2319            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2320                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2321                if (stops == null) {
2322                    stops = new ArrayList<ActivityRecord>();
2323                }
2324                stops.add(s);
2325                mStoppingActivities.remove(i);
2326                N--;
2327                i--;
2328            }
2329        }
2330
2331        return stops;
2332    }
2333
2334    void validateTopActivitiesLocked() {
2335        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2336            final ActivityStack stack = mStacks.get(stackNdx);
2337            final ActivityRecord r = stack.topRunningActivityLocked(null);
2338            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2339            if (isFrontStack(stack)) {
2340                if (r == null) {
2341                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2342                } else {
2343                    final ActivityRecord pausing = stack.mPausingActivity;
2344                    if (pausing != null && pausing == r) {
2345                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2346                            " state=" + state);
2347                    }
2348                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2349                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2350                                " state=" + state);
2351                    }
2352                }
2353            } else {
2354                final ActivityRecord resumed = stack.mResumedActivity;
2355                if (resumed != null && resumed == r) {
2356                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2357                        " state=" + state);
2358                }
2359                if (r != null && (state == ActivityState.INITIALIZING
2360                        || state == ActivityState.RESUMED)) {
2361                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2362                            " state=" + state);
2363                }
2364            }
2365        }
2366    }
2367
2368    private static String stackStateToString(int stackState) {
2369        switch (stackState) {
2370            case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2371            case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2372            case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2373            case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2374            default: return "Unknown stackState=" + stackState;
2375        }
2376    }
2377
2378    public void dump(PrintWriter pw, String prefix) {
2379        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2380                pw.println(mDismissKeyguardOnNextActivity);
2381        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2382                pw.print(" mStackState="); pw.println(stackStateToString(mStackState));
2383        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2384        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2385        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2386    }
2387
2388    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2389        return getFocusedStack().getDumpActivitiesLocked(name);
2390    }
2391
2392    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2393            boolean needSep, String prefix) {
2394        if (activity != null) {
2395            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2396                if (needSep) {
2397                    pw.println();
2398                }
2399                pw.print(prefix);
2400                pw.println(activity);
2401                return true;
2402            }
2403        }
2404        return false;
2405    }
2406
2407    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2408            boolean dumpClient, String dumpPackage) {
2409        boolean printed = false;
2410        boolean needSep = false;
2411        final int numStacks = mStacks.size();
2412        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2413            final ActivityStack stack = mStacks.get(stackNdx);
2414            StringBuilder stackHeader = new StringBuilder(128);
2415            stackHeader.append("  Stack #");
2416            stackHeader.append(mStacks.indexOf(stack));
2417            stackHeader.append(":");
2418            printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2419                    stackHeader.toString());
2420            printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false, !dumpAll,
2421                    false, dumpPackage, true, "    Running activities (most recent first):", null);
2422
2423            needSep = printed;
2424            boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2425                    "    mPausingActivity: ");
2426            if (pr) {
2427                printed = true;
2428                needSep = false;
2429            }
2430            pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2431                    "    mResumedActivity: ");
2432            if (pr) {
2433                printed = true;
2434                needSep = false;
2435            }
2436            if (dumpAll) {
2437                pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2438                        "    mLastPausedActivity: ");
2439                if (pr) {
2440                    printed = true;
2441                    needSep = true;
2442                }
2443                printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2444                        needSep, "    mLastNoHistoryActivity: ");
2445            }
2446            needSep = printed;
2447        }
2448
2449        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2450                false, dumpPackage, true, "  Activities waiting to finish:", null);
2451        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2452                false, dumpPackage, true, "  Activities waiting to stop:", null);
2453        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2454                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2455                null);
2456        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2457                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2458        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2459                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2460
2461        return printed;
2462    }
2463
2464    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2465            String prefix, String label, boolean complete, boolean brief, boolean client,
2466            String dumpPackage, boolean needNL, String header1, String header2) {
2467        TaskRecord lastTask = null;
2468        String innerPrefix = null;
2469        String[] args = null;
2470        boolean printed = false;
2471        for (int i=list.size()-1; i>=0; i--) {
2472            final ActivityRecord r = list.get(i);
2473            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2474                continue;
2475            }
2476            if (innerPrefix == null) {
2477                innerPrefix = prefix + "      ";
2478                args = new String[0];
2479            }
2480            printed = true;
2481            final boolean full = !brief && (complete || !r.isInHistory());
2482            if (needNL) {
2483                pw.println("");
2484                needNL = false;
2485            }
2486            if (header1 != null) {
2487                pw.println(header1);
2488                header1 = null;
2489            }
2490            if (header2 != null) {
2491                pw.println(header2);
2492                header2 = null;
2493            }
2494            if (lastTask != r.task) {
2495                lastTask = r.task;
2496                pw.print(prefix);
2497                pw.print(full ? "* " : "  ");
2498                pw.println(lastTask);
2499                if (full) {
2500                    lastTask.dump(pw, prefix + "  ");
2501                } else if (complete) {
2502                    // Complete + brief == give a summary.  Isn't that obvious?!?
2503                    if (lastTask.intent != null) {
2504                        pw.print(prefix); pw.print("  ");
2505                                pw.println(lastTask.intent.toInsecureStringWithClip());
2506                    }
2507                }
2508            }
2509            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2510            pw.print(" #"); pw.print(i); pw.print(": ");
2511            pw.println(r);
2512            if (full) {
2513                r.dump(pw, innerPrefix);
2514            } else if (complete) {
2515                // Complete + brief == give a summary.  Isn't that obvious?!?
2516                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2517                if (r.app != null) {
2518                    pw.print(innerPrefix); pw.println(r.app);
2519                }
2520            }
2521            if (client && r.app != null && r.app.thread != null) {
2522                // flush anything that is already in the PrintWriter since the thread is going
2523                // to write to the file descriptor directly
2524                pw.flush();
2525                try {
2526                    TransferPipe tp = new TransferPipe();
2527                    try {
2528                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2529                                r.appToken, innerPrefix, args);
2530                        // Short timeout, since blocking here can
2531                        // deadlock with the application.
2532                        tp.go(fd, 2000);
2533                    } finally {
2534                        tp.kill();
2535                    }
2536                } catch (IOException e) {
2537                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2538                } catch (RemoteException e) {
2539                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2540                }
2541                needNL = true;
2542            }
2543        }
2544        return printed;
2545    }
2546
2547    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2548        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2549        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2550        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2551    }
2552
2553    final void scheduleIdleLocked() {
2554        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2555    }
2556
2557    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2558        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2559        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2560    }
2561
2562    final void scheduleResumeTopActivities() {
2563        mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2564    }
2565
2566    void removeSleepTimeouts() {
2567        mSleepTimeout = false;
2568        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2569    }
2570
2571    final void scheduleSleepTimeout() {
2572        removeSleepTimeouts();
2573        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2574    }
2575
2576    private final class ActivityStackSupervisorHandler extends Handler {
2577
2578        public ActivityStackSupervisorHandler(Looper looper) {
2579            super(looper);
2580        }
2581
2582        void activityIdleInternal(ActivityRecord r) {
2583            synchronized (mService) {
2584                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2585            }
2586        }
2587
2588        @Override
2589        public void handleMessage(Message msg) {
2590            switch (msg.what) {
2591                case IDLE_TIMEOUT_MSG: {
2592                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2593                    if (mService.mDidDexOpt) {
2594                        mService.mDidDexOpt = false;
2595                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2596                        nmsg.obj = msg.obj;
2597                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2598                        return;
2599                    }
2600                    // We don't at this point know if the activity is fullscreen,
2601                    // so we need to be conservative and assume it isn't.
2602                    activityIdleInternal((ActivityRecord)msg.obj);
2603                } break;
2604                case IDLE_NOW_MSG: {
2605                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2606                    activityIdleInternal((ActivityRecord)msg.obj);
2607                } break;
2608                case RESUME_TOP_ACTIVITY_MSG: {
2609                    synchronized (mService) {
2610                        resumeTopActivitiesLocked();
2611                    }
2612                } break;
2613                case SLEEP_TIMEOUT_MSG: {
2614                    synchronized (mService) {
2615                        if (mService.isSleepingOrShuttingDown()) {
2616                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2617                            mSleepTimeout = true;
2618                            checkReadyForSleepLocked();
2619                        }
2620                    }
2621                } break;
2622                case LAUNCH_TIMEOUT_MSG: {
2623                    if (mService.mDidDexOpt) {
2624                        mService.mDidDexOpt = false;
2625                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2626                        return;
2627                    }
2628                    synchronized (mService) {
2629                        if (mLaunchingActivity.isHeld()) {
2630                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2631                            if (VALIDATE_WAKE_LOCK_CALLER
2632                                    && Binder.getCallingUid() != Process.myUid()) {
2633                                throw new IllegalStateException("Calling must be system uid");
2634                            }
2635                            mLaunchingActivity.release();
2636                        }
2637                    }
2638                } break;
2639            }
2640        }
2641    }
2642}
2643