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