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