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