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