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