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