ActivityStackSupervisor.java revision ca9bc702df5c14a89c9b8b0109a05894bf74962e
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 boolean isHomeActivity =
1380                    !r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask());
1381            moveHomeStack(isHomeActivity);
1382        }
1383    }
1384
1385    final int startActivityUncheckedLocked(ActivityRecord r,
1386            ActivityRecord sourceRecord, int startFlags, boolean doResume,
1387            Bundle options) {
1388        final Intent intent = r.intent;
1389        final int callingUid = r.launchedFromUid;
1390
1391        int launchFlags = intent.getFlags();
1392
1393        // We'll invoke onUserLeaving before onPause only if the launching
1394        // activity did not explicitly state that this is an automated launch.
1395        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1396        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1397
1398        // If the caller has asked not to resume at this point, we make note
1399        // of this in the record so that we can skip it when trying to find
1400        // the top running activity.
1401        if (!doResume) {
1402            r.delayedResume = true;
1403        }
1404
1405        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1406
1407        // If the onlyIfNeeded flag is set, then we can do this if the activity
1408        // being launched is the same as the one making the call...  or, as
1409        // a special case, if we do not know the caller then we count the
1410        // current top activity as the caller.
1411        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1412            ActivityRecord checkedCaller = sourceRecord;
1413            if (checkedCaller == null) {
1414                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1415            }
1416            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1417                // Caller is not the same as launcher, so always needed.
1418                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1419            }
1420        }
1421
1422        if (sourceRecord == null) {
1423            // This activity is not being started from another...  in this
1424            // case we -always- start a new task.
1425            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1426                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1427                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1428                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1429            }
1430        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1431            // The original activity who is starting us is running as a single
1432            // instance...  this new activity it is starting must go on its
1433            // own task.
1434            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1435        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1436                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1437            // The activity being started is a single instance...  it always
1438            // gets launched into its own task.
1439            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1440        }
1441
1442        ActivityInfo newTaskInfo = null;
1443        Intent newTaskIntent = null;
1444        final ActivityStack sourceStack;
1445        if (sourceRecord != null) {
1446            if (sourceRecord.finishing) {
1447                // If the source is finishing, we can't further count it as our source.  This
1448                // is because the task it is associated with may now be empty and on its way out,
1449                // so we don't want to blindly throw it in to that task.  Instead we will take
1450                // the NEW_TASK flow and try to find a task for it. But save the task information
1451                // so it can be used when creating the new task.
1452                if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1453                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1454                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1455                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1456                    newTaskInfo = sourceRecord.info;
1457                    newTaskIntent = sourceRecord.task.intent;
1458                }
1459                sourceRecord = null;
1460                sourceStack = null;
1461            } else {
1462                sourceStack = sourceRecord.task.stack;
1463            }
1464        } else {
1465            sourceStack = null;
1466        }
1467
1468        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1469            // For whatever reason this activity is being launched into a new
1470            // task...  yet the caller has requested a result back.  Well, that
1471            // is pretty messed up, so instead immediately send back a cancel
1472            // and let the new task continue launched as normal without a
1473            // dependency on its originator.
1474            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1475            r.resultTo.task.stack.sendActivityResultLocked(-1,
1476                    r.resultTo, r.resultWho, r.requestCode,
1477                Activity.RESULT_CANCELED, null);
1478            r.resultTo = null;
1479        }
1480
1481        boolean addingToTask = false;
1482        boolean movedHome = false;
1483        TaskRecord reuseTask = null;
1484        ActivityStack targetStack;
1485        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1486                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1487                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1488                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1489            // If bring to front is requested, and no result is requested, and
1490            // we can find a task that was started with this same
1491            // component, then instead of launching bring that one to the front.
1492            if (r.resultTo == null) {
1493                // See if there is a task to bring to the front.  If this is
1494                // a SINGLE_INSTANCE activity, there can be one and only one
1495                // instance of it in the history, and it is always in its own
1496                // unique task, so we do a special search.
1497                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1498                        ? findTaskLocked(r)
1499                        : findActivityLocked(intent, r.info);
1500                if (intentActivity != null) {
1501                    if (r.task == null) {
1502                        r.task = intentActivity.task;
1503                    }
1504                    targetStack = intentActivity.task.stack;
1505                    targetStack.mLastPausedActivity = null;
1506                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1507                            + " from " + intentActivity);
1508                    targetStack.moveToFront();
1509                    if (intentActivity.task.intent == null) {
1510                        // This task was started because of movement of
1511                        // the activity based on affinity...  now that we
1512                        // are actually launching it, we can assign the
1513                        // base intent.
1514                        intentActivity.task.setIntent(intent, r.info);
1515                    }
1516                    // If the target task is not in the front, then we need
1517                    // to bring it to the front...  except...  well, with
1518                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1519                    // to have the same behavior as if a new instance was
1520                    // being started, which means not bringing it to the front
1521                    // if the caller is not itself in the front.
1522                    final ActivityStack lastStack = getLastStack();
1523                    ActivityRecord curTop = lastStack == null?
1524                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1525                    if (curTop != null && (curTop.task != intentActivity.task ||
1526                            curTop.task != lastStack.topTask())) {
1527                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1528                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1529                                sourceStack.topActivity().task == sourceRecord.task)) {
1530                            // We really do want to push this one into the
1531                            // user's face, right now.
1532                            movedHome = true;
1533                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1534                            if ((launchFlags &
1535                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1536                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1537                                // Caller wants to appear on home activity.
1538                                intentActivity.task.mOnTopOfHome = true;
1539                            }
1540                            options = null;
1541                        }
1542                    }
1543                    // If the caller has requested that the target task be
1544                    // reset, then do so.
1545                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1546                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1547                    }
1548                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1549                        // We don't need to start a new activity, and
1550                        // the client said not to do anything if that
1551                        // is the case, so this is it!  And for paranoia, make
1552                        // sure we have correctly resumed the top activity.
1553                        if (doResume) {
1554                            resumeTopActivitiesLocked(targetStack, null, options);
1555                        } else {
1556                            ActivityOptions.abort(options);
1557                        }
1558                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1559                    }
1560                    if ((launchFlags &
1561                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1562                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1563                        // The caller has requested to completely replace any
1564                        // existing task with its new activity.  Well that should
1565                        // not be too hard...
1566                        reuseTask = intentActivity.task;
1567                        reuseTask.performClearTaskLocked();
1568                        reuseTask.setIntent(r.intent, r.info);
1569                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1570                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1571                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1572                        // In this situation we want to remove all activities
1573                        // from the task up to the one being started.  In most
1574                        // cases this means we are resetting the task to its
1575                        // initial state.
1576                        ActivityRecord top =
1577                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1578                        if (top != null) {
1579                            if (top.frontOfTask) {
1580                                // Activity aliases may mean we use different
1581                                // intents for the top activity, so make sure
1582                                // the task now has the identity of the new
1583                                // intent.
1584                                top.task.setIntent(r.intent, r.info);
1585                            }
1586                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1587                                    r, top.task);
1588                            top.deliverNewIntentLocked(callingUid, r.intent);
1589                        } else {
1590                            // A special case: we need to
1591                            // start the activity because it is not currently
1592                            // running, and the caller has asked to clear the
1593                            // current task to have this activity at the top.
1594                            addingToTask = true;
1595                            // Now pretend like this activity is being started
1596                            // by the top of its task, so it is put in the
1597                            // right place.
1598                            sourceRecord = intentActivity;
1599                        }
1600                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1601                        // In this case the top activity on the task is the
1602                        // same as the one being launched, so we take that
1603                        // as a request to bring the task to the foreground.
1604                        // If the top activity in the task is the root
1605                        // activity, deliver this new intent to it if it
1606                        // desires.
1607                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1608                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1609                                && intentActivity.realActivity.equals(r.realActivity)) {
1610                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1611                                    intentActivity.task);
1612                            if (intentActivity.frontOfTask) {
1613                                intentActivity.task.setIntent(r.intent, r.info);
1614                            }
1615                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1616                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1617                            // In this case we are launching the root activity
1618                            // of the task, but with a different intent.  We
1619                            // should start a new instance on top.
1620                            addingToTask = true;
1621                            sourceRecord = intentActivity;
1622                        }
1623                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1624                        // In this case an activity is being launched in to an
1625                        // existing task, without resetting that task.  This
1626                        // is typically the situation of launching an activity
1627                        // from a notification or shortcut.  We want to place
1628                        // the new activity on top of the current task.
1629                        addingToTask = true;
1630                        sourceRecord = intentActivity;
1631                    } else if (!intentActivity.task.rootWasReset) {
1632                        // In this case we are launching in to an existing task
1633                        // that has not yet been started from its front door.
1634                        // The current task has been brought to the front.
1635                        // Ideally, we'd probably like to place this new task
1636                        // at the bottom of its stack, but that's a little hard
1637                        // to do with the current organization of the code so
1638                        // for now we'll just drop it.
1639                        intentActivity.task.setIntent(r.intent, r.info);
1640                    }
1641                    if (!addingToTask && reuseTask == null) {
1642                        // We didn't do anything...  but it was needed (a.k.a., client
1643                        // don't use that intent!)  And for paranoia, make
1644                        // sure we have correctly resumed the top activity.
1645                        if (doResume) {
1646                            targetStack.resumeTopActivityLocked(null, options);
1647                        } else {
1648                            ActivityOptions.abort(options);
1649                        }
1650                        return ActivityManager.START_TASK_TO_FRONT;
1651                    }
1652                }
1653            }
1654        }
1655
1656        //String uri = r.intent.toURI();
1657        //Intent intent2 = new Intent(uri);
1658        //Slog.i(TAG, "Given intent: " + r.intent);
1659        //Slog.i(TAG, "URI is: " + uri);
1660        //Slog.i(TAG, "To intent: " + intent2);
1661
1662        if (r.packageName != null) {
1663            // If the activity being launched is the same as the one currently
1664            // at the top, then we need to check if it should only be launched
1665            // once.
1666            ActivityStack topStack = getFocusedStack();
1667            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1668            if (top != null && r.resultTo == null) {
1669                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1670                    if (top.app != null && top.app.thread != null) {
1671                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1672                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1673                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1674                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1675                                    top.task);
1676                            // For paranoia, make sure we have correctly
1677                            // resumed the top activity.
1678                            topStack.mLastPausedActivity = null;
1679                            if (doResume) {
1680                                resumeTopActivitiesLocked();
1681                            }
1682                            ActivityOptions.abort(options);
1683                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1684                                // We don't need to start a new activity, and
1685                                // the client said not to do anything if that
1686                                // is the case, so this is it!
1687                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1688                            }
1689                            top.deliverNewIntentLocked(callingUid, r.intent);
1690                            return ActivityManager.START_DELIVERED_TO_TOP;
1691                        }
1692                    }
1693                }
1694            }
1695
1696        } else {
1697            if (r.resultTo != null) {
1698                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1699                        r.requestCode, Activity.RESULT_CANCELED, null);
1700            }
1701            ActivityOptions.abort(options);
1702            return ActivityManager.START_CLASS_NOT_FOUND;
1703        }
1704
1705        boolean newTask = false;
1706        boolean keepCurTransition = false;
1707
1708        // Should this be considered a new task?
1709        if (r.resultTo == null && !addingToTask
1710                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1711            targetStack = adjustStackFocus(r);
1712            targetStack.moveToFront();
1713            if (reuseTask == null) {
1714                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1715                        newTaskInfo != null ? newTaskInfo : r.info,
1716                        newTaskIntent != null ? newTaskIntent : intent,
1717                        true), null, true);
1718                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1719                        r.task);
1720            } else {
1721                r.setTask(reuseTask, reuseTask, true);
1722            }
1723            newTask = true;
1724            if (!movedHome) {
1725                if ((launchFlags &
1726                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1727                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1728                    // Caller wants to appear on home activity, so before starting
1729                    // their own activity we will bring home to the front.
1730                    r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
1731                }
1732            }
1733        } else if (sourceRecord != null) {
1734            TaskRecord sourceTask = sourceRecord.task;
1735            targetStack = sourceTask.stack;
1736            targetStack.moveToFront();
1737            if (!addingToTask &&
1738                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1739                // In this case, we are adding the activity to an existing
1740                // task, but the caller has asked to clear that task if the
1741                // activity is already running.
1742                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1743                keepCurTransition = true;
1744                if (top != null) {
1745                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1746                    top.deliverNewIntentLocked(callingUid, r.intent);
1747                    // For paranoia, make sure we have correctly
1748                    // resumed the top activity.
1749                    targetStack.mLastPausedActivity = null;
1750                    if (doResume) {
1751                        targetStack.resumeTopActivityLocked(null);
1752                    }
1753                    ActivityOptions.abort(options);
1754                    return ActivityManager.START_DELIVERED_TO_TOP;
1755                }
1756            } else if (!addingToTask &&
1757                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1758                // In this case, we are launching an activity in our own task
1759                // that may already be running somewhere in the history, and
1760                // we want to shuffle it to the front of the stack if so.
1761                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1762                if (top != null) {
1763                    final TaskRecord task = top.task;
1764                    task.moveActivityToFrontLocked(top);
1765                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1766                    top.updateOptionsLocked(options);
1767                    top.deliverNewIntentLocked(callingUid, r.intent);
1768                    targetStack.mLastPausedActivity = null;
1769                    if (doResume) {
1770                        targetStack.resumeTopActivityLocked(null);
1771                    }
1772                    return ActivityManager.START_DELIVERED_TO_TOP;
1773                }
1774            }
1775            // An existing activity is starting this new activity, so we want
1776            // to keep the new one in the same task as the one that is starting
1777            // it.
1778            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
1779            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1780                    + " in existing task " + r.task + " from source " + sourceRecord);
1781
1782        } else {
1783            // This not being started from an existing activity, and not part
1784            // of a new task...  just put it in the top task, though these days
1785            // this case should never happen.
1786            targetStack = adjustStackFocus(r);
1787            targetStack.moveToFront();
1788            ActivityRecord prev = targetStack.topActivity();
1789            r.setTask(prev != null ? prev.task
1790                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1791                    null, true);
1792            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1793                    + " in new guessed " + r.task);
1794        }
1795
1796        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1797                intent, r.getUriPermissionsLocked());
1798
1799        if (newTask) {
1800            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1801        }
1802        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1803        targetStack.mLastPausedActivity = null;
1804        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1805        mService.setFocusedActivityLocked(r);
1806        return ActivityManager.START_SUCCESS;
1807    }
1808
1809    void acquireLaunchWakelock() {
1810        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1811            throw new IllegalStateException("Calling must be system uid");
1812        }
1813        mLaunchingActivity.acquire();
1814        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1815            // To be safe, don't allow the wake lock to be held for too long.
1816            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1817        }
1818    }
1819
1820    // Checked.
1821    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1822            Configuration config) {
1823        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1824
1825        ArrayList<ActivityRecord> stops = null;
1826        ArrayList<ActivityRecord> finishes = null;
1827        ArrayList<UserStartedState> startingUsers = null;
1828        int NS = 0;
1829        int NF = 0;
1830        IApplicationThread sendThumbnail = null;
1831        boolean booting = false;
1832        boolean enableScreen = false;
1833        boolean activityRemoved = false;
1834
1835        ActivityRecord r = ActivityRecord.forToken(token);
1836        if (r != null) {
1837            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1838                    Debug.getCallers(4));
1839            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1840            r.finishLaunchTickingLocked();
1841            if (fromTimeout) {
1842                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1843            }
1844
1845            // This is a hack to semi-deal with a race condition
1846            // in the client where it can be constructed with a
1847            // newer configuration from when we asked it to launch.
1848            // We'll update with whatever configuration it now says
1849            // it used to launch.
1850            if (config != null) {
1851                r.configuration = config;
1852            }
1853
1854            // We are now idle.  If someone is waiting for a thumbnail from
1855            // us, we can now deliver.
1856            r.idle = true;
1857
1858            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1859                sendThumbnail = r.app.thread;
1860                r.thumbnailNeeded = false;
1861            }
1862
1863            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1864            if (!mService.mBooted && isFrontStack(r.task.stack)) {
1865                mService.mBooted = true;
1866                enableScreen = true;
1867            }
1868        }
1869
1870        if (allResumedActivitiesIdle()) {
1871            if (r != null) {
1872                mService.scheduleAppGcsLocked();
1873            }
1874
1875            if (mLaunchingActivity.isHeld()) {
1876                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1877                if (VALIDATE_WAKE_LOCK_CALLER &&
1878                        Binder.getCallingUid() != Process.myUid()) {
1879                    throw new IllegalStateException("Calling must be system uid");
1880                }
1881                mLaunchingActivity.release();
1882            }
1883            ensureActivitiesVisibleLocked(null, 0);
1884        }
1885
1886        // Atomically retrieve all of the other things to do.
1887        stops = processStoppingActivitiesLocked(true);
1888        NS = stops != null ? stops.size() : 0;
1889        if ((NF=mFinishingActivities.size()) > 0) {
1890            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1891            mFinishingActivities.clear();
1892        }
1893
1894        final ArrayList<ActivityRecord> thumbnails;
1895        final int NT = mCancelledThumbnails.size();
1896        if (NT > 0) {
1897            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1898            mCancelledThumbnails.clear();
1899        } else {
1900            thumbnails = null;
1901        }
1902
1903        if (isFrontStack(mHomeStack)) {
1904            booting = mService.mBooting;
1905            mService.mBooting = false;
1906        }
1907
1908        if (mStartingUsers.size() > 0) {
1909            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1910            mStartingUsers.clear();
1911        }
1912
1913        // Perform the following actions from unsynchronized state.
1914        final IApplicationThread thumbnailThread = sendThumbnail;
1915        mHandler.post(new Runnable() {
1916            @Override
1917            public void run() {
1918                if (thumbnailThread != null) {
1919                    try {
1920                        thumbnailThread.requestThumbnail(token);
1921                    } catch (Exception e) {
1922                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1923                        mService.sendPendingThumbnail(null, token, null, null, true);
1924                    }
1925                }
1926
1927                // Report back to any thumbnail receivers.
1928                for (int i = 0; i < NT; i++) {
1929                    ActivityRecord r = thumbnails.get(i);
1930                    mService.sendPendingThumbnail(r, null, null, null, true);
1931                }
1932            }
1933        });
1934
1935        // Stop any activities that are scheduled to do so but have been
1936        // waiting for the next one to start.
1937        for (int i = 0; i < NS; i++) {
1938            r = stops.get(i);
1939            final ActivityStack stack = r.task.stack;
1940            if (r.finishing) {
1941                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1942            } else {
1943                stack.stopActivityLocked(r);
1944            }
1945        }
1946
1947        // Finish any activities that are scheduled to do so but have been
1948        // waiting for the next one to start.
1949        for (int i = 0; i < NF; i++) {
1950            r = finishes.get(i);
1951            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1952        }
1953
1954        if (booting) {
1955            mService.finishBooting();
1956        } else if (startingUsers != null) {
1957            for (int i = 0; i < startingUsers.size(); i++) {
1958                mService.finishUserSwitch(startingUsers.get(i));
1959            }
1960        }
1961
1962        mService.trimApplications();
1963        //dump();
1964        //mWindowManager.dump();
1965
1966        if (enableScreen) {
1967            mService.enableScreenAfterBoot();
1968        }
1969
1970        if (activityRemoved) {
1971            resumeTopActivitiesLocked();
1972        }
1973
1974        return r;
1975    }
1976
1977    boolean handleAppDiedLocked(ProcessRecord app) {
1978        boolean hasVisibleActivities = false;
1979        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1980            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1981            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1982                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1983            }
1984        }
1985        return hasVisibleActivities;
1986    }
1987
1988    void closeSystemDialogsLocked() {
1989        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1990            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
1991            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1992                stacks.get(stackNdx).closeSystemDialogsLocked();
1993            }
1994        }
1995    }
1996
1997    void removeUserLocked(int userId) {
1998        mUserStackInFront.delete(userId);
1999    }
2000
2001    /**
2002     * @return true if some activity was finished (or would have finished if doit were true).
2003     */
2004    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2005        boolean didSomething = false;
2006        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2007            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2008            final int numStacks = stacks.size();
2009            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2010                final ActivityStack stack = stacks.get(stackNdx);
2011                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2012                    didSomething = true;
2013                }
2014            }
2015        }
2016        return didSomething;
2017    }
2018
2019    void updatePreviousProcessLocked(ActivityRecord r) {
2020        // Now that this process has stopped, we may want to consider
2021        // it to be the previous app to try to keep around in case
2022        // the user wants to return to it.
2023
2024        // First, found out what is currently the foreground app, so that
2025        // we don't blow away the previous app if this activity is being
2026        // hosted by the process that is actually still the foreground.
2027        ProcessRecord fgApp = null;
2028        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2029            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2030            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2031                final ActivityStack stack = stacks.get(stackNdx);
2032                if (isFrontStack(stack)) {
2033                    if (stack.mResumedActivity != null) {
2034                        fgApp = stack.mResumedActivity.app;
2035                    } else if (stack.mPausingActivity != null) {
2036                        fgApp = stack.mPausingActivity.app;
2037                    }
2038                    break;
2039                }
2040            }
2041        }
2042
2043        // Now set this one as the previous process, only if that really
2044        // makes sense to.
2045        if (r.app != null && fgApp != null && r.app != fgApp
2046                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2047                && r.app != mService.mHomeProcess) {
2048            mService.mPreviousProcess = r.app;
2049            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2050        }
2051    }
2052
2053    boolean resumeTopActivitiesLocked() {
2054        return resumeTopActivitiesLocked(null, null, null);
2055    }
2056
2057    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2058            Bundle targetOptions) {
2059        if (targetStack == null) {
2060            targetStack = getFocusedStack();
2061        }
2062        boolean result = false;
2063        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2064            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2065            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2066                final ActivityStack stack = stacks.get(stackNdx);
2067                if (isFrontStack(stack)) {
2068                    if (stack == targetStack) {
2069                        result = stack.resumeTopActivityLocked(target, targetOptions);
2070                    } else {
2071                        stack.resumeTopActivityLocked(null);
2072                    }
2073                }
2074            }
2075        }
2076        return result;
2077    }
2078
2079    void finishTopRunningActivityLocked(ProcessRecord app) {
2080        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2081            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2082            final int numStacks = stacks.size();
2083            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2084                final ActivityStack stack = stacks.get(stackNdx);
2085                stack.finishTopRunningActivityLocked(app);
2086            }
2087        }
2088    }
2089
2090    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2091        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2092            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2093            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2094                if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2095                    if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2096                            + stacks.get(stackNdx));
2097                    return;
2098                }
2099            }
2100        }
2101    }
2102
2103    ActivityStack getStack(int stackId) {
2104        WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2105        if (weakReference != null) {
2106            ActivityContainer activityContainer = weakReference.get();
2107            if (activityContainer != null) {
2108                return activityContainer.mStack;
2109            } else {
2110                mActivityContainers.remove(stackId);
2111            }
2112        }
2113        return null;
2114    }
2115
2116    ArrayList<ActivityStack> getStacks() {
2117        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2118        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2119            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2120        }
2121        return allStacks;
2122    }
2123
2124    IBinder getHomeActivityToken() {
2125        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2126        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2127            final TaskRecord task = tasks.get(taskNdx);
2128            if (task.isHomeTask()) {
2129                final ArrayList<ActivityRecord> activities = task.mActivities;
2130                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2131                    final ActivityRecord r = activities.get(activityNdx);
2132                    if (r.isHomeActivity()) {
2133                        return r.appToken;
2134                    }
2135                }
2136            }
2137        }
2138        return null;
2139    }
2140
2141    ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2142            IActivityContainerCallback callback) {
2143        ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2144                callback);
2145        mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
2146        if (parentActivity != null) {
2147            parentActivity.mChildContainers.add(activityContainer.mStack);
2148        }
2149        return activityContainer;
2150    }
2151
2152    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2153            IActivityContainerCallback callback) {
2154        return createActivityContainer(parentActivity, getNextStackId(), callback);
2155    }
2156
2157    void removeChildActivityContainers(ActivityRecord parentActivity) {
2158        for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2159            final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2160            if (container == null) {
2161                mActivityContainers.removeAt(ndx);
2162                continue;
2163            }
2164            if (container.mParentActivity != parentActivity) {
2165                continue;
2166            }
2167
2168            ActivityStack stack = container.mStack;
2169            ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2170            if (top != null) {
2171                // TODO: Make sure the next activity doesn't start up when top is destroyed.
2172                stack.destroyActivityLocked(top, true, true, "stack removal");
2173            }
2174            mActivityContainers.removeAt(ndx);
2175            container.detachLocked();
2176        }
2177    }
2178
2179    private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
2180        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2181        if (activityDisplay == null) {
2182            return -1;
2183        }
2184
2185        ActivityContainer activityContainer =
2186                createActivityContainer(parentActivity, stackId, null);
2187        activityContainer.attachToDisplayLocked(activityDisplay);
2188        return stackId;
2189    }
2190
2191    int getNextStackId() {
2192        while (true) {
2193            if (++mLastStackId <= HOME_STACK_ID) {
2194                mLastStackId = HOME_STACK_ID + 1;
2195            }
2196            if (getStack(mLastStackId) == null) {
2197                break;
2198            }
2199        }
2200        return mLastStackId;
2201    }
2202
2203    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2204        final TaskRecord task = anyTaskForIdLocked(taskId);
2205        if (task == null) {
2206            return;
2207        }
2208        final ActivityStack stack = getStack(stackId);
2209        if (stack == null) {
2210            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2211            return;
2212        }
2213        task.stack.removeTask(task);
2214        stack.addTask(task, toTop);
2215        mWindowManager.addTask(taskId, stackId, toTop);
2216        resumeTopActivitiesLocked();
2217    }
2218
2219    ActivityRecord findTaskLocked(ActivityRecord r) {
2220        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2221        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2222            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2223            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2224                final ActivityStack stack = stacks.get(stackNdx);
2225                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2226                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2227                    continue;
2228                }
2229                final ActivityRecord ar = stack.findTaskLocked(r);
2230                if (ar != null) {
2231                    return ar;
2232                }
2233            }
2234        }
2235        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2236        return null;
2237    }
2238
2239    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2240        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2241            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2242            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2243                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2244                if (ar != null) {
2245                    return ar;
2246                }
2247            }
2248        }
2249        return null;
2250    }
2251
2252    void goingToSleepLocked() {
2253        scheduleSleepTimeout();
2254        if (!mGoingToSleep.isHeld()) {
2255            mGoingToSleep.acquire();
2256            if (mLaunchingActivity.isHeld()) {
2257                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2258                    throw new IllegalStateException("Calling must be system uid");
2259                }
2260                mLaunchingActivity.release();
2261                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2262            }
2263        }
2264        checkReadyForSleepLocked();
2265    }
2266
2267    boolean shutdownLocked(int timeout) {
2268        boolean timedout = false;
2269        goingToSleepLocked();
2270
2271        final long endTime = System.currentTimeMillis() + timeout;
2272        while (true) {
2273            boolean cantShutdown = false;
2274            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2275                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2276                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2277                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2278                }
2279            }
2280            if (cantShutdown) {
2281                long timeRemaining = endTime - System.currentTimeMillis();
2282                if (timeRemaining > 0) {
2283                    try {
2284                        mService.wait(timeRemaining);
2285                    } catch (InterruptedException e) {
2286                    }
2287                } else {
2288                    Slog.w(TAG, "Activity manager shutdown timed out");
2289                    timedout = true;
2290                    break;
2291                }
2292            } else {
2293                break;
2294            }
2295        }
2296
2297        // Force checkReadyForSleep to complete.
2298        mSleepTimeout = true;
2299        checkReadyForSleepLocked();
2300
2301        return timedout;
2302    }
2303
2304    void comeOutOfSleepIfNeededLocked() {
2305        removeSleepTimeouts();
2306        if (mGoingToSleep.isHeld()) {
2307            mGoingToSleep.release();
2308        }
2309        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2310            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2311            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2312                final ActivityStack stack = stacks.get(stackNdx);
2313                stack.awakeFromSleepingLocked();
2314                if (isFrontStack(stack)) {
2315                    resumeTopActivitiesLocked();
2316                }
2317            }
2318        }
2319        mGoingToSleepActivities.clear();
2320    }
2321
2322    void activitySleptLocked(ActivityRecord r) {
2323        mGoingToSleepActivities.remove(r);
2324        checkReadyForSleepLocked();
2325    }
2326
2327    void checkReadyForSleepLocked() {
2328        if (!mService.isSleepingOrShuttingDown()) {
2329            // Do not care.
2330            return;
2331        }
2332
2333        if (!mSleepTimeout) {
2334            boolean dontSleep = false;
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                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2339                }
2340            }
2341
2342            if (mStoppingActivities.size() > 0) {
2343                // Still need to tell some activities to stop; can't sleep yet.
2344                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2345                        + mStoppingActivities.size() + " activities");
2346                scheduleIdleLocked();
2347                dontSleep = true;
2348            }
2349
2350            if (mGoingToSleepActivities.size() > 0) {
2351                // Still need to tell some activities to sleep; can't sleep yet.
2352                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2353                        + mGoingToSleepActivities.size() + " activities");
2354                dontSleep = true;
2355            }
2356
2357            if (dontSleep) {
2358                return;
2359            }
2360        }
2361
2362        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2363            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2364            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2365                stacks.get(stackNdx).goToSleep();
2366            }
2367        }
2368
2369        removeSleepTimeouts();
2370
2371        if (mGoingToSleep.isHeld()) {
2372            mGoingToSleep.release();
2373        }
2374        if (mService.mShuttingDown) {
2375            mService.notifyAll();
2376        }
2377    }
2378
2379    boolean reportResumedActivityLocked(ActivityRecord r) {
2380        final ActivityStack stack = r.task.stack;
2381        if (isFrontStack(stack)) {
2382            mService.updateUsageStats(r, true);
2383        }
2384        if (allResumedActivitiesComplete()) {
2385            ensureActivitiesVisibleLocked(null, 0);
2386            mWindowManager.executeAppTransition();
2387            return true;
2388        }
2389        return false;
2390    }
2391
2392    void handleAppCrashLocked(ProcessRecord app) {
2393        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2394            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2395            final int numStacks = stacks.size();
2396            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2397                final ActivityStack stack = stacks.get(stackNdx);
2398                stack.handleAppCrashLocked(app);
2399            }
2400        }
2401    }
2402
2403    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2404        // First the front stacks. In case any are not fullscreen and are in front of home.
2405        boolean showHomeBehindStack = false;
2406        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2407            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2408            final int topStackNdx = stacks.size() - 1;
2409            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2410                final ActivityStack stack = stacks.get(stackNdx);
2411                if (stackNdx == topStackNdx) {
2412                    // Top stack.
2413                    showHomeBehindStack =
2414                            stack.ensureActivitiesVisibleLocked(starting, configChanges);
2415                } else {
2416                    // Back stack.
2417                    stack.ensureActivitiesVisibleLocked(starting, configChanges,
2418                            showHomeBehindStack);
2419                }
2420            }
2421        }
2422    }
2423
2424    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2425        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2426            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2427            final int numStacks = stacks.size();
2428            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2429                final ActivityStack stack = stacks.get(stackNdx);
2430                stack.scheduleDestroyActivities(app, false, reason);
2431            }
2432        }
2433    }
2434
2435    boolean switchUserLocked(int userId, UserStartedState uss) {
2436        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2437        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2438        mCurrentUser = userId;
2439
2440        mStartingUsers.add(uss);
2441        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2442            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2443            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2444                final ActivityStack stack = stacks.get(stackNdx);
2445                stack.switchUserLocked(userId);
2446                mWindowManager.moveTaskToTop(stack.topTask().taskId);
2447            }
2448        }
2449
2450        ActivityStack stack = getStack(restoreStackId);
2451        if (stack == null) {
2452            stack = mHomeStack;
2453        }
2454        final boolean homeInFront = stack.isHomeStack();
2455        if (stack.isOnHomeDisplay()) {
2456            moveHomeStack(homeInFront);
2457            mWindowManager.moveTaskToTop(stack.topTask().taskId);
2458        } else {
2459            // Stack was moved to another display while user was swapped out.
2460            resumeHomeActivity(null);
2461        }
2462        return homeInFront;
2463    }
2464
2465    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2466        int N = mStoppingActivities.size();
2467        if (N <= 0) return null;
2468
2469        ArrayList<ActivityRecord> stops = null;
2470
2471        final boolean nowVisible = allResumedActivitiesVisible();
2472        for (int i=0; i<N; i++) {
2473            ActivityRecord s = mStoppingActivities.get(i);
2474            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2475                    + nowVisible + " waitingVisible=" + s.waitingVisible
2476                    + " finishing=" + s.finishing);
2477            if (s.waitingVisible && nowVisible) {
2478                mWaitingVisibleActivities.remove(s);
2479                s.waitingVisible = false;
2480                if (s.finishing) {
2481                    // If this activity is finishing, it is sitting on top of
2482                    // everyone else but we now know it is no longer needed...
2483                    // so get rid of it.  Otherwise, we need to go through the
2484                    // normal flow and hide it once we determine that it is
2485                    // hidden by the activities in front of it.
2486                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2487                    mWindowManager.setAppVisibility(s.appToken, false);
2488                }
2489            }
2490            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2491                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2492                if (stops == null) {
2493                    stops = new ArrayList<ActivityRecord>();
2494                }
2495                stops.add(s);
2496                mStoppingActivities.remove(i);
2497                N--;
2498                i--;
2499            }
2500        }
2501
2502        return stops;
2503    }
2504
2505    void validateTopActivitiesLocked() {
2506        // FIXME
2507/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2508            final ActivityStack stack = stacks.get(stackNdx);
2509            final ActivityRecord r = stack.topRunningActivityLocked(null);
2510            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2511            if (isFrontStack(stack)) {
2512                if (r == null) {
2513                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2514                } else {
2515                    final ActivityRecord pausing = stack.mPausingActivity;
2516                    if (pausing != null && pausing == r) {
2517                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2518                            " state=" + state);
2519                    }
2520                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2521                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2522                                " state=" + state);
2523                    }
2524                }
2525            } else {
2526                final ActivityRecord resumed = stack.mResumedActivity;
2527                if (resumed != null && resumed == r) {
2528                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2529                        " state=" + state);
2530                }
2531                if (r != null && (state == ActivityState.INITIALIZING
2532                        || state == ActivityState.RESUMED)) {
2533                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2534                            " state=" + state);
2535                }
2536            }
2537        }
2538*/
2539    }
2540
2541    public void dump(PrintWriter pw, String prefix) {
2542        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2543                pw.println(mDismissKeyguardOnNextActivity);
2544        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2545                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2546        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2547        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2548        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2549    }
2550
2551    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2552        return getFocusedStack().getDumpActivitiesLocked(name);
2553    }
2554
2555    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2556            boolean needSep, String prefix) {
2557        if (activity != null) {
2558            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2559                if (needSep) {
2560                    pw.println();
2561                }
2562                pw.print(prefix);
2563                pw.println(activity);
2564                return true;
2565            }
2566        }
2567        return false;
2568    }
2569
2570    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2571            boolean dumpClient, String dumpPackage) {
2572        boolean printed = false;
2573        boolean needSep = false;
2574        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2575            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2576            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2577            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2578            final int numStacks = stacks.size();
2579            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2580                final ActivityStack stack = stacks.get(stackNdx);
2581                StringBuilder stackHeader = new StringBuilder(128);
2582                stackHeader.append("  Stack #");
2583                stackHeader.append(stack.mStackId);
2584                stackHeader.append(":");
2585                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2586                        needSep, stackHeader.toString());
2587                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2588                        !dumpAll, false, dumpPackage, true,
2589                        "    Running activities (most recent first):", null);
2590
2591                needSep = printed;
2592                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2593                        "    mPausingActivity: ");
2594                if (pr) {
2595                    printed = true;
2596                    needSep = false;
2597                }
2598                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2599                        "    mResumedActivity: ");
2600                if (pr) {
2601                    printed = true;
2602                    needSep = false;
2603                }
2604                if (dumpAll) {
2605                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2606                            "    mLastPausedActivity: ");
2607                    if (pr) {
2608                        printed = true;
2609                        needSep = true;
2610                    }
2611                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2612                            needSep, "    mLastNoHistoryActivity: ");
2613                }
2614                needSep = printed;
2615            }
2616        }
2617
2618        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2619                false, dumpPackage, true, "  Activities waiting to finish:", null);
2620        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2621                false, dumpPackage, true, "  Activities waiting to stop:", null);
2622        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2623                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2624                null);
2625        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2626                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2627        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2628                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2629
2630        return printed;
2631    }
2632
2633    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2634            String prefix, String label, boolean complete, boolean brief, boolean client,
2635            String dumpPackage, boolean needNL, String header1, String header2) {
2636        TaskRecord lastTask = null;
2637        String innerPrefix = null;
2638        String[] args = null;
2639        boolean printed = false;
2640        for (int i=list.size()-1; i>=0; i--) {
2641            final ActivityRecord r = list.get(i);
2642            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2643                continue;
2644            }
2645            if (innerPrefix == null) {
2646                innerPrefix = prefix + "      ";
2647                args = new String[0];
2648            }
2649            printed = true;
2650            final boolean full = !brief && (complete || !r.isInHistory());
2651            if (needNL) {
2652                pw.println("");
2653                needNL = false;
2654            }
2655            if (header1 != null) {
2656                pw.println(header1);
2657                header1 = null;
2658            }
2659            if (header2 != null) {
2660                pw.println(header2);
2661                header2 = null;
2662            }
2663            if (lastTask != r.task) {
2664                lastTask = r.task;
2665                pw.print(prefix);
2666                pw.print(full ? "* " : "  ");
2667                pw.println(lastTask);
2668                if (full) {
2669                    lastTask.dump(pw, prefix + "  ");
2670                } else if (complete) {
2671                    // Complete + brief == give a summary.  Isn't that obvious?!?
2672                    if (lastTask.intent != null) {
2673                        pw.print(prefix); pw.print("  ");
2674                                pw.println(lastTask.intent.toInsecureStringWithClip());
2675                    }
2676                }
2677            }
2678            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2679            pw.print(" #"); pw.print(i); pw.print(": ");
2680            pw.println(r);
2681            if (full) {
2682                r.dump(pw, innerPrefix);
2683            } else if (complete) {
2684                // Complete + brief == give a summary.  Isn't that obvious?!?
2685                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2686                if (r.app != null) {
2687                    pw.print(innerPrefix); pw.println(r.app);
2688                }
2689            }
2690            if (client && r.app != null && r.app.thread != null) {
2691                // flush anything that is already in the PrintWriter since the thread is going
2692                // to write to the file descriptor directly
2693                pw.flush();
2694                try {
2695                    TransferPipe tp = new TransferPipe();
2696                    try {
2697                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2698                                r.appToken, innerPrefix, args);
2699                        // Short timeout, since blocking here can
2700                        // deadlock with the application.
2701                        tp.go(fd, 2000);
2702                    } finally {
2703                        tp.kill();
2704                    }
2705                } catch (IOException e) {
2706                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2707                } catch (RemoteException e) {
2708                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2709                }
2710                needNL = true;
2711            }
2712        }
2713        return printed;
2714    }
2715
2716    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2717        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2718        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2719        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2720    }
2721
2722    final void scheduleIdleLocked() {
2723        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2724    }
2725
2726    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2727        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2728        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2729    }
2730
2731    final void scheduleResumeTopActivities() {
2732        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2733            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2734        }
2735    }
2736
2737    void removeSleepTimeouts() {
2738        mSleepTimeout = false;
2739        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2740    }
2741
2742    final void scheduleSleepTimeout() {
2743        removeSleepTimeouts();
2744        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2745    }
2746
2747    @Override
2748    public void onDisplayAdded(int displayId) {
2749        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2750    }
2751
2752    @Override
2753    public void onDisplayRemoved(int displayId) {
2754        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2755    }
2756
2757    @Override
2758    public void onDisplayChanged(int displayId) {
2759        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2760    }
2761
2762    public void handleDisplayAddedLocked(int displayId) {
2763        boolean newDisplay;
2764        synchronized (mService) {
2765            newDisplay = mActivityDisplays.get(displayId) == null;
2766            if (newDisplay) {
2767                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2768                mActivityDisplays.put(displayId, activityDisplay);
2769            }
2770        }
2771        if (newDisplay) {
2772            mWindowManager.onDisplayAdded(displayId);
2773        }
2774    }
2775
2776    public void handleDisplayRemovedLocked(int displayId) {
2777        synchronized (mService) {
2778            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2779            if (activityDisplay != null) {
2780                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2781                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2782                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2783                }
2784                mActivityDisplays.remove(displayId);
2785            }
2786        }
2787        mWindowManager.onDisplayRemoved(displayId);
2788    }
2789
2790    public void handleDisplayChangedLocked(int displayId) {
2791        synchronized (mService) {
2792            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2793            if (activityDisplay != null) {
2794                // TODO: Update the bounds.
2795            }
2796        }
2797        mWindowManager.onDisplayChanged(displayId);
2798    }
2799
2800    StackInfo getStackInfo(ActivityStack stack) {
2801        StackInfo info = new StackInfo();
2802        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2803        info.displayId = Display.DEFAULT_DISPLAY;
2804        info.stackId = stack.mStackId;
2805
2806        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2807        final int numTasks = tasks.size();
2808        int[] taskIds = new int[numTasks];
2809        String[] taskNames = new String[numTasks];
2810        for (int i = 0; i < numTasks; ++i) {
2811            final TaskRecord task = tasks.get(i);
2812            taskIds[i] = task.taskId;
2813            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2814                    : task.realActivity != null ? task.realActivity.flattenToString()
2815                    : task.getTopActivity() != null ? task.getTopActivity().packageName
2816                    : "unknown";
2817        }
2818        info.taskIds = taskIds;
2819        info.taskNames = taskNames;
2820        return info;
2821    }
2822
2823    StackInfo getStackInfoLocked(int stackId) {
2824        ActivityStack stack = getStack(stackId);
2825        if (stack != null) {
2826            return getStackInfo(stack);
2827        }
2828        return null;
2829    }
2830
2831    ArrayList<StackInfo> getAllStackInfosLocked() {
2832        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2833        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2834            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2835            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2836                list.add(getStackInfo(stacks.get(ndx)));
2837            }
2838        }
2839        return list;
2840    }
2841
2842    private final class ActivityStackSupervisorHandler extends Handler {
2843
2844        public ActivityStackSupervisorHandler(Looper looper) {
2845            super(looper);
2846        }
2847
2848        void activityIdleInternal(ActivityRecord r) {
2849            synchronized (mService) {
2850                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2851            }
2852        }
2853
2854        @Override
2855        public void handleMessage(Message msg) {
2856            switch (msg.what) {
2857                case IDLE_TIMEOUT_MSG: {
2858                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2859                    if (mService.mDidDexOpt) {
2860                        mService.mDidDexOpt = false;
2861                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2862                        nmsg.obj = msg.obj;
2863                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2864                        return;
2865                    }
2866                    // We don't at this point know if the activity is fullscreen,
2867                    // so we need to be conservative and assume it isn't.
2868                    activityIdleInternal((ActivityRecord)msg.obj);
2869                } break;
2870                case IDLE_NOW_MSG: {
2871                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2872                    activityIdleInternal((ActivityRecord)msg.obj);
2873                } break;
2874                case RESUME_TOP_ACTIVITY_MSG: {
2875                    synchronized (mService) {
2876                        resumeTopActivitiesLocked();
2877                    }
2878                } break;
2879                case SLEEP_TIMEOUT_MSG: {
2880                    synchronized (mService) {
2881                        if (mService.isSleepingOrShuttingDown()) {
2882                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2883                            mSleepTimeout = true;
2884                            checkReadyForSleepLocked();
2885                        }
2886                    }
2887                } break;
2888                case LAUNCH_TIMEOUT_MSG: {
2889                    if (mService.mDidDexOpt) {
2890                        mService.mDidDexOpt = false;
2891                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2892                        return;
2893                    }
2894                    synchronized (mService) {
2895                        if (mLaunchingActivity.isHeld()) {
2896                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2897                            if (VALIDATE_WAKE_LOCK_CALLER
2898                                    && Binder.getCallingUid() != Process.myUid()) {
2899                                throw new IllegalStateException("Calling must be system uid");
2900                            }
2901                            mLaunchingActivity.release();
2902                        }
2903                    }
2904                } break;
2905                case HANDLE_DISPLAY_ADDED: {
2906                    handleDisplayAddedLocked(msg.arg1);
2907                } break;
2908                case HANDLE_DISPLAY_CHANGED: {
2909                    handleDisplayChangedLocked(msg.arg1);
2910                } break;
2911                case HANDLE_DISPLAY_REMOVED: {
2912                    handleDisplayRemovedLocked(msg.arg1);
2913                } break;
2914            }
2915        }
2916    }
2917
2918    class ActivityContainer extends IActivityContainer.Stub {
2919        final int mStackId;
2920        final IActivityContainerCallback mCallback;
2921        final ActivityStack mStack;
2922        final ActivityRecord mParentActivity;
2923        final String mIdString;
2924
2925        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
2926        ActivityDisplay mActivityDisplay;
2927
2928        ActivityContainer(ActivityRecord parentActivity, int stackId,
2929                IActivityContainerCallback callback) {
2930            synchronized (mService) {
2931                mStackId = stackId;
2932                mStack = new ActivityStack(this);
2933                mParentActivity = parentActivity;
2934                mCallback = callback;
2935                mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2936                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
2937            }
2938        }
2939
2940        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
2941            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2942                    + " to display=" + activityDisplay);
2943            mActivityDisplay = activityDisplay;
2944            mStack.mDisplayId = activityDisplay.mDisplayId;
2945            mStack.mStacks = activityDisplay.mStacks;
2946
2947            activityDisplay.attachActivities(mStack);
2948            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
2949        }
2950
2951        @Override
2952        public void attachToDisplay(int displayId) {
2953            synchronized (mService) {
2954                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2955                if (activityDisplay == null) {
2956                    return;
2957                }
2958                attachToDisplayLocked(activityDisplay);
2959            }
2960        }
2961
2962        @Override
2963        public int getDisplayId() {
2964            if (mActivityDisplay != null) {
2965                return mActivityDisplay.mDisplayId;
2966            }
2967            return -1;
2968        }
2969
2970        @Override
2971        public boolean injectEvent(InputEvent event) {
2972            final long origId = Binder.clearCallingIdentity();
2973            try {
2974                if (mActivityDisplay != null) {
2975                    return mInputManagerInternal.injectInputEvent(event,
2976                            mActivityDisplay.mDisplayId,
2977                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
2978                }
2979                return false;
2980            } finally {
2981                Binder.restoreCallingIdentity(origId);
2982            }
2983        }
2984
2985        private void detachLocked() {
2986            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
2987                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
2988            if (mActivityDisplay != null) {
2989                mActivityDisplay.detachActivitiesLocked(mStack);
2990                mActivityDisplay = null;
2991                mStack.mDisplayId = -1;
2992                mStack.mStacks = null;
2993                mWindowManager.detachStack(mStackId);
2994            }
2995        }
2996
2997        @Override
2998        public void detachFromDisplay() {
2999            synchronized (mService) {
3000                detachLocked();
3001            }
3002        }
3003
3004        @Override
3005        public final int startActivity(Intent intent) {
3006            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3007            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3008                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3009            // TODO: Switch to user app stacks here.
3010            String mimeType = intent.getType();
3011            if (mimeType == null && intent.getData() != null
3012                    && "content".equals(intent.getData().getScheme())) {
3013                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3014            }
3015            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3016                    null, null, null, null, userId, this);
3017        }
3018
3019        @Override
3020        public final int startActivityIntentSender(IIntentSender intentSender) {
3021            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3022
3023            if (!(intentSender instanceof PendingIntentRecord)) {
3024                throw new IllegalArgumentException("Bad PendingIntent object");
3025            }
3026
3027            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3028                    null, 0, 0, 0, null, this);
3029        }
3030
3031        @Override
3032        public IBinder asBinder() {
3033            return this;
3034        }
3035
3036        @Override
3037        public void attachToSurface(Surface surface, int width, int height, int density) {
3038            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3039
3040            final long origId = Binder.clearCallingIdentity();
3041            try {
3042                synchronized (mService) {
3043                    ActivityDisplay activityDisplay =
3044                            new ActivityDisplay(surface, width, height, density);
3045                    mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3046                    attachToDisplayLocked(activityDisplay);
3047                    mStack.resumeTopActivityLocked(null);
3048                }
3049                if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3050                        + mActivityDisplay);
3051            } finally {
3052                Binder.restoreCallingIdentity(origId);
3053            }
3054        }
3055
3056        ActivityStackSupervisor getOuter() {
3057            return ActivityStackSupervisor.this;
3058        }
3059
3060        boolean isAttached() {
3061            return mActivityDisplay != null;
3062        }
3063
3064        void getBounds(Point outBounds) {
3065            if (mActivityDisplay != null) {
3066                mActivityDisplay.getBounds(outBounds);
3067            } else {
3068                outBounds.set(0, 0);
3069            }
3070        }
3071
3072        @Override
3073        public String toString() {
3074            return mIdString + (mActivityDisplay == null ? "N" : "A");
3075        }
3076    }
3077
3078    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3079     * attached {@link ActivityStack}s */
3080    final class ActivityDisplay {
3081        /** Actual Display this object tracks. */
3082        int mDisplayId;
3083        Display mDisplay;
3084        DisplayInfo mDisplayInfo = new DisplayInfo();
3085        Surface mSurface;
3086
3087        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3088         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3089        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3090
3091        /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3092         * here. */
3093        VirtualDisplay mVirtualDisplay;
3094
3095        ActivityDisplay(int displayId) {
3096            init(mDisplayManager.getDisplay(displayId));
3097        }
3098
3099        ActivityDisplay(Surface surface, int width, int height, int density) {
3100            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3101            long ident = Binder.clearCallingIdentity();
3102            try {
3103                mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3104                        VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3105                        DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3106                        DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3107            } finally {
3108                Binder.restoreCallingIdentity(ident);
3109            }
3110
3111            init(mVirtualDisplay.getDisplay());
3112            mSurface = surface;
3113
3114            mWindowManager.handleDisplayAdded(mDisplayId);
3115        }
3116
3117        private void init(Display display) {
3118            mDisplay = display;
3119            mDisplayId = display.getDisplayId();
3120            mDisplay.getDisplayInfo(mDisplayInfo);
3121        }
3122
3123        void attachActivities(ActivityStack stack) {
3124            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3125                    + mDisplayId);
3126            mStacks.add(stack);
3127        }
3128
3129        void detachActivitiesLocked(ActivityStack stack) {
3130            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3131                    + " from displayId=" + mDisplayId);
3132            mStacks.remove(stack);
3133            if (mStacks.isEmpty() && mVirtualDisplay != null) {
3134                mVirtualDisplay.release();
3135                mVirtualDisplay = null;
3136            }
3137            mSurface.release();
3138        }
3139
3140        void getBounds(Point bounds) {
3141            mDisplay.getDisplayInfo(mDisplayInfo);
3142            bounds.x = mDisplayInfo.appWidth;
3143            bounds.y = mDisplayInfo.appHeight;
3144        }
3145
3146        @Override
3147        public String toString() {
3148            return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3149                    + " numStacks=" + mStacks.size() + "}";
3150        }
3151    }
3152}
3153