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