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