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