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