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