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