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