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