ActivityStackSupervisor.java revision 21d24a21ea4aaadd78e73de54168e8a8a8973e4d
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    }
2342
2343    boolean shutdownLocked(int timeout) {
2344        goingToSleepLocked();
2345
2346        boolean timedout = false;
2347        final long endTime = System.currentTimeMillis() + timeout;
2348        while (true) {
2349            boolean cantShutdown = false;
2350            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2351                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2352                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2353                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2354                }
2355            }
2356            if (cantShutdown) {
2357                long timeRemaining = endTime - System.currentTimeMillis();
2358                if (timeRemaining > 0) {
2359                    try {
2360                        mService.wait(timeRemaining);
2361                    } catch (InterruptedException e) {
2362                    }
2363                } else {
2364                    Slog.w(TAG, "Activity manager shutdown timed out");
2365                    timedout = true;
2366                    break;
2367                }
2368            } else {
2369                break;
2370            }
2371        }
2372
2373        // Force checkReadyForSleep to complete.
2374        mSleepTimeout = true;
2375        checkReadyForSleepLocked();
2376
2377        return timedout;
2378    }
2379
2380    void comeOutOfSleepIfNeededLocked() {
2381        removeSleepTimeouts();
2382        if (mGoingToSleep.isHeld()) {
2383            mGoingToSleep.release();
2384        }
2385        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2386            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2387            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2388                final ActivityStack stack = stacks.get(stackNdx);
2389                stack.awakeFromSleepingLocked();
2390                if (isFrontStack(stack)) {
2391                    resumeTopActivitiesLocked();
2392                }
2393            }
2394        }
2395        mGoingToSleepActivities.clear();
2396    }
2397
2398    void activitySleptLocked(ActivityRecord r) {
2399        mGoingToSleepActivities.remove(r);
2400        checkReadyForSleepLocked();
2401    }
2402
2403    void checkReadyForSleepLocked() {
2404        if (!mService.isSleepingOrShuttingDown()) {
2405            // Do not care.
2406            return;
2407        }
2408
2409        if (!mSleepTimeout) {
2410            boolean dontSleep = false;
2411            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2412                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2413                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2414                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2415                }
2416            }
2417
2418            if (mStoppingActivities.size() > 0) {
2419                // Still need to tell some activities to stop; can't sleep yet.
2420                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2421                        + mStoppingActivities.size() + " activities");
2422                scheduleIdleLocked();
2423                dontSleep = true;
2424            }
2425
2426            if (mGoingToSleepActivities.size() > 0) {
2427                // Still need to tell some activities to sleep; can't sleep yet.
2428                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2429                        + mGoingToSleepActivities.size() + " activities");
2430                dontSleep = true;
2431            }
2432
2433            if (dontSleep) {
2434                return;
2435            }
2436        }
2437
2438        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2439            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2440            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2441                stacks.get(stackNdx).goToSleep();
2442            }
2443        }
2444
2445        removeSleepTimeouts();
2446
2447        if (mGoingToSleep.isHeld()) {
2448            mGoingToSleep.release();
2449        }
2450        if (mService.mShuttingDown) {
2451            mService.notifyAll();
2452        }
2453    }
2454
2455    boolean reportResumedActivityLocked(ActivityRecord r) {
2456        final ActivityStack stack = r.task.stack;
2457        if (isFrontStack(stack)) {
2458            mService.updateUsageStats(r, true);
2459        }
2460        if (allResumedActivitiesComplete()) {
2461            ensureActivitiesVisibleLocked(null, 0);
2462            mWindowManager.executeAppTransition();
2463            return true;
2464        }
2465        return false;
2466    }
2467
2468    void handleAppCrashLocked(ProcessRecord app) {
2469        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2470            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2471            final int numStacks = stacks.size();
2472            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2473                final ActivityStack stack = stacks.get(stackNdx);
2474                stack.handleAppCrashLocked(app);
2475            }
2476        }
2477    }
2478
2479    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2480        // First the front stacks. In case any are not fullscreen and are in front of home.
2481        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2482            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2483            final int topStackNdx = stacks.size() - 1;
2484            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2485                final ActivityStack stack = stacks.get(stackNdx);
2486                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2487            }
2488        }
2489    }
2490
2491    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2492        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2493            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2494            final int numStacks = stacks.size();
2495            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2496                final ActivityStack stack = stacks.get(stackNdx);
2497                stack.scheduleDestroyActivities(app, false, reason);
2498            }
2499        }
2500    }
2501
2502    boolean switchUserLocked(int userId, UserStartedState uss) {
2503        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2504        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2505        mCurrentUser = userId;
2506
2507        mStartingUsers.add(uss);
2508        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2509            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2510            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2511                final ActivityStack stack = stacks.get(stackNdx);
2512                stack.switchUserLocked(userId);
2513                TaskRecord task = stack.topTask();
2514                if (task != null) {
2515                    mWindowManager.moveTaskToTop(task.taskId);
2516                }
2517            }
2518        }
2519
2520        ActivityStack stack = getStack(restoreStackId);
2521        if (stack == null) {
2522            stack = mHomeStack;
2523        }
2524        final boolean homeInFront = stack.isHomeStack();
2525        if (stack.isOnHomeDisplay()) {
2526            moveHomeStack(homeInFront);
2527            TaskRecord task = stack.topTask();
2528            if (task != null) {
2529                mWindowManager.moveTaskToTop(task.taskId);
2530            }
2531        } else {
2532            // Stack was moved to another display while user was swapped out.
2533            resumeHomeActivity(null);
2534        }
2535        return homeInFront;
2536    }
2537
2538    /**
2539     * Add background users to send boot completed events to.
2540     * @param userId The user being started in the background
2541     * @param uss The state object for the user.
2542     */
2543    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
2544        mStartingBackgroundUsers.add(uss);
2545    }
2546
2547    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2548        int N = mStoppingActivities.size();
2549        if (N <= 0) return null;
2550
2551        ArrayList<ActivityRecord> stops = null;
2552
2553        final boolean nowVisible = allResumedActivitiesVisible();
2554        for (int i=0; i<N; i++) {
2555            ActivityRecord s = mStoppingActivities.get(i);
2556            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2557                    + nowVisible + " waitingVisible=" + s.waitingVisible
2558                    + " finishing=" + s.finishing);
2559            if (s.waitingVisible && nowVisible) {
2560                mWaitingVisibleActivities.remove(s);
2561                s.waitingVisible = false;
2562                if (s.finishing) {
2563                    // If this activity is finishing, it is sitting on top of
2564                    // everyone else but we now know it is no longer needed...
2565                    // so get rid of it.  Otherwise, we need to go through the
2566                    // normal flow and hide it once we determine that it is
2567                    // hidden by the activities in front of it.
2568                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2569                    mWindowManager.setAppVisibility(s.appToken, false);
2570                }
2571            }
2572            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2573                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2574                if (stops == null) {
2575                    stops = new ArrayList<ActivityRecord>();
2576                }
2577                stops.add(s);
2578                mStoppingActivities.remove(i);
2579                N--;
2580                i--;
2581            }
2582        }
2583
2584        return stops;
2585    }
2586
2587    void validateTopActivitiesLocked() {
2588        // FIXME
2589/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2590            final ActivityStack stack = stacks.get(stackNdx);
2591            final ActivityRecord r = stack.topRunningActivityLocked(null);
2592            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2593            if (isFrontStack(stack)) {
2594                if (r == null) {
2595                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2596                } else {
2597                    final ActivityRecord pausing = stack.mPausingActivity;
2598                    if (pausing != null && pausing == r) {
2599                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2600                            " state=" + state);
2601                    }
2602                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2603                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2604                                " state=" + state);
2605                    }
2606                }
2607            } else {
2608                final ActivityRecord resumed = stack.mResumedActivity;
2609                if (resumed != null && resumed == r) {
2610                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2611                        " state=" + state);
2612                }
2613                if (r != null && (state == ActivityState.INITIALIZING
2614                        || state == ActivityState.RESUMED)) {
2615                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2616                            " state=" + state);
2617                }
2618            }
2619        }
2620*/
2621    }
2622
2623    public void dump(PrintWriter pw, String prefix) {
2624        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2625                pw.println(mDismissKeyguardOnNextActivity);
2626        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2627                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2628        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2629        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2630        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2631        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2632    }
2633
2634    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2635        return getFocusedStack().getDumpActivitiesLocked(name);
2636    }
2637
2638    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2639            boolean needSep, String prefix) {
2640        if (activity != null) {
2641            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2642                if (needSep) {
2643                    pw.println();
2644                }
2645                pw.print(prefix);
2646                pw.println(activity);
2647                return true;
2648            }
2649        }
2650        return false;
2651    }
2652
2653    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2654            boolean dumpClient, String dumpPackage) {
2655        boolean printed = false;
2656        boolean needSep = false;
2657        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2658            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2659            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2660            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2661            final int numStacks = stacks.size();
2662            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2663                final ActivityStack stack = stacks.get(stackNdx);
2664                StringBuilder stackHeader = new StringBuilder(128);
2665                stackHeader.append("  Stack #");
2666                stackHeader.append(stack.mStackId);
2667                stackHeader.append(":");
2668                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2669                        needSep, stackHeader.toString());
2670                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2671                        !dumpAll, false, dumpPackage, true,
2672                        "    Running activities (most recent first):", null);
2673
2674                needSep = printed;
2675                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2676                        "    mPausingActivity: ");
2677                if (pr) {
2678                    printed = true;
2679                    needSep = false;
2680                }
2681                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2682                        "    mResumedActivity: ");
2683                if (pr) {
2684                    printed = true;
2685                    needSep = false;
2686                }
2687                if (dumpAll) {
2688                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2689                            "    mLastPausedActivity: ");
2690                    if (pr) {
2691                        printed = true;
2692                        needSep = true;
2693                    }
2694                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2695                            needSep, "    mLastNoHistoryActivity: ");
2696                }
2697                needSep = printed;
2698            }
2699        }
2700
2701        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2702                false, dumpPackage, true, "  Activities waiting to finish:", null);
2703        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2704                false, dumpPackage, true, "  Activities waiting to stop:", null);
2705        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2706                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2707                null);
2708        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2709                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2710        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2711                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2712
2713        return printed;
2714    }
2715
2716    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2717            String prefix, String label, boolean complete, boolean brief, boolean client,
2718            String dumpPackage, boolean needNL, String header1, String header2) {
2719        TaskRecord lastTask = null;
2720        String innerPrefix = null;
2721        String[] args = null;
2722        boolean printed = false;
2723        for (int i=list.size()-1; i>=0; i--) {
2724            final ActivityRecord r = list.get(i);
2725            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2726                continue;
2727            }
2728            if (innerPrefix == null) {
2729                innerPrefix = prefix + "      ";
2730                args = new String[0];
2731            }
2732            printed = true;
2733            final boolean full = !brief && (complete || !r.isInHistory());
2734            if (needNL) {
2735                pw.println("");
2736                needNL = false;
2737            }
2738            if (header1 != null) {
2739                pw.println(header1);
2740                header1 = null;
2741            }
2742            if (header2 != null) {
2743                pw.println(header2);
2744                header2 = null;
2745            }
2746            if (lastTask != r.task) {
2747                lastTask = r.task;
2748                pw.print(prefix);
2749                pw.print(full ? "* " : "  ");
2750                pw.println(lastTask);
2751                if (full) {
2752                    lastTask.dump(pw, prefix + "  ");
2753                } else if (complete) {
2754                    // Complete + brief == give a summary.  Isn't that obvious?!?
2755                    if (lastTask.intent != null) {
2756                        pw.print(prefix); pw.print("  ");
2757                                pw.println(lastTask.intent.toInsecureStringWithClip());
2758                    }
2759                }
2760            }
2761            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2762            pw.print(" #"); pw.print(i); pw.print(": ");
2763            pw.println(r);
2764            if (full) {
2765                r.dump(pw, innerPrefix);
2766            } else if (complete) {
2767                // Complete + brief == give a summary.  Isn't that obvious?!?
2768                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2769                if (r.app != null) {
2770                    pw.print(innerPrefix); pw.println(r.app);
2771                }
2772            }
2773            if (client && r.app != null && r.app.thread != null) {
2774                // flush anything that is already in the PrintWriter since the thread is going
2775                // to write to the file descriptor directly
2776                pw.flush();
2777                try {
2778                    TransferPipe tp = new TransferPipe();
2779                    try {
2780                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2781                                r.appToken, innerPrefix, args);
2782                        // Short timeout, since blocking here can
2783                        // deadlock with the application.
2784                        tp.go(fd, 2000);
2785                    } finally {
2786                        tp.kill();
2787                    }
2788                } catch (IOException e) {
2789                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2790                } catch (RemoteException e) {
2791                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2792                }
2793                needNL = true;
2794            }
2795        }
2796        return printed;
2797    }
2798
2799    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2800        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2801        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2802        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2803    }
2804
2805    final void scheduleIdleLocked() {
2806        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2807    }
2808
2809    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2810        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2811        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2812    }
2813
2814    final void scheduleResumeTopActivities() {
2815        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2816            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2817        }
2818    }
2819
2820    void removeSleepTimeouts() {
2821        mSleepTimeout = false;
2822        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2823    }
2824
2825    final void scheduleSleepTimeout() {
2826        removeSleepTimeouts();
2827        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2828    }
2829
2830    @Override
2831    public void onDisplayAdded(int displayId) {
2832        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2833    }
2834
2835    @Override
2836    public void onDisplayRemoved(int displayId) {
2837        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2838    }
2839
2840    @Override
2841    public void onDisplayChanged(int displayId) {
2842        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2843    }
2844
2845    public void handleDisplayAddedLocked(int displayId) {
2846        boolean newDisplay;
2847        synchronized (mService) {
2848            newDisplay = mActivityDisplays.get(displayId) == null;
2849            if (newDisplay) {
2850                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2851                mActivityDisplays.put(displayId, activityDisplay);
2852            }
2853        }
2854        if (newDisplay) {
2855            mWindowManager.onDisplayAdded(displayId);
2856        }
2857    }
2858
2859    public void handleDisplayRemovedLocked(int displayId) {
2860        synchronized (mService) {
2861            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2862            if (activityDisplay != null) {
2863                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2864                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2865                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2866                }
2867                mActivityDisplays.remove(displayId);
2868            }
2869        }
2870        mWindowManager.onDisplayRemoved(displayId);
2871    }
2872
2873    public void handleDisplayChangedLocked(int displayId) {
2874        synchronized (mService) {
2875            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2876            if (activityDisplay != null) {
2877                // TODO: Update the bounds.
2878            }
2879        }
2880        mWindowManager.onDisplayChanged(displayId);
2881    }
2882
2883    StackInfo getStackInfo(ActivityStack stack) {
2884        StackInfo info = new StackInfo();
2885        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2886        info.displayId = Display.DEFAULT_DISPLAY;
2887        info.stackId = stack.mStackId;
2888
2889        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2890        final int numTasks = tasks.size();
2891        int[] taskIds = new int[numTasks];
2892        String[] taskNames = new String[numTasks];
2893        for (int i = 0; i < numTasks; ++i) {
2894            final TaskRecord task = tasks.get(i);
2895            taskIds[i] = task.taskId;
2896            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2897                    : task.realActivity != null ? task.realActivity.flattenToString()
2898                    : task.getTopActivity() != null ? task.getTopActivity().packageName
2899                    : "unknown";
2900        }
2901        info.taskIds = taskIds;
2902        info.taskNames = taskNames;
2903        return info;
2904    }
2905
2906    StackInfo getStackInfoLocked(int stackId) {
2907        ActivityStack stack = getStack(stackId);
2908        if (stack != null) {
2909            return getStackInfo(stack);
2910        }
2911        return null;
2912    }
2913
2914    ArrayList<StackInfo> getAllStackInfosLocked() {
2915        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2916        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2917            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2918            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2919                list.add(getStackInfo(stacks.get(ndx)));
2920            }
2921        }
2922        return list;
2923    }
2924
2925    void setLockTaskModeLocked(TaskRecord task) {
2926        if (task == null) {
2927            // Take out of lock task mode.
2928            mLockTaskModeTask = null;
2929            return;
2930        }
2931        if (isLockTaskModeViolation(task)) {
2932            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2933            return;
2934        }
2935        mLockTaskModeTask = task;
2936        findTaskToMoveToFrontLocked(task, 0, null);
2937        resumeTopActivitiesLocked();
2938    }
2939
2940    boolean isLockTaskModeViolation(TaskRecord task) {
2941        return mLockTaskModeTask != null && mLockTaskModeTask != task;
2942    }
2943
2944    void endLockTaskModeIfTaskEnding(TaskRecord task) {
2945        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
2946            mLockTaskModeTask = null;
2947        }
2948    }
2949
2950    boolean isInLockTaskMode() {
2951        return mLockTaskModeTask != null;
2952    }
2953
2954    private final class ActivityStackSupervisorHandler extends Handler {
2955
2956        public ActivityStackSupervisorHandler(Looper looper) {
2957            super(looper);
2958        }
2959
2960        void activityIdleInternal(ActivityRecord r) {
2961            synchronized (mService) {
2962                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2963            }
2964        }
2965
2966        @Override
2967        public void handleMessage(Message msg) {
2968            switch (msg.what) {
2969                case IDLE_TIMEOUT_MSG: {
2970                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2971                    if (mService.mDidDexOpt) {
2972                        mService.mDidDexOpt = false;
2973                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2974                        nmsg.obj = msg.obj;
2975                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2976                        return;
2977                    }
2978                    // We don't at this point know if the activity is fullscreen,
2979                    // so we need to be conservative and assume it isn't.
2980                    activityIdleInternal((ActivityRecord)msg.obj);
2981                } break;
2982                case IDLE_NOW_MSG: {
2983                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2984                    activityIdleInternal((ActivityRecord)msg.obj);
2985                } break;
2986                case RESUME_TOP_ACTIVITY_MSG: {
2987                    synchronized (mService) {
2988                        resumeTopActivitiesLocked();
2989                    }
2990                } break;
2991                case SLEEP_TIMEOUT_MSG: {
2992                    synchronized (mService) {
2993                        if (mService.isSleepingOrShuttingDown()) {
2994                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2995                            mSleepTimeout = true;
2996                            checkReadyForSleepLocked();
2997                        }
2998                    }
2999                } break;
3000                case LAUNCH_TIMEOUT_MSG: {
3001                    if (mService.mDidDexOpt) {
3002                        mService.mDidDexOpt = false;
3003                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3004                        return;
3005                    }
3006                    synchronized (mService) {
3007                        if (mLaunchingActivity.isHeld()) {
3008                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3009                            if (VALIDATE_WAKE_LOCK_CALLER
3010                                    && Binder.getCallingUid() != Process.myUid()) {
3011                                throw new IllegalStateException("Calling must be system uid");
3012                            }
3013                            mLaunchingActivity.release();
3014                        }
3015                    }
3016                } break;
3017                case HANDLE_DISPLAY_ADDED: {
3018                    handleDisplayAddedLocked(msg.arg1);
3019                } break;
3020                case HANDLE_DISPLAY_CHANGED: {
3021                    handleDisplayChangedLocked(msg.arg1);
3022                } break;
3023                case HANDLE_DISPLAY_REMOVED: {
3024                    handleDisplayRemovedLocked(msg.arg1);
3025                } break;
3026                case CONTAINER_CALLBACK_VISIBILITY: {
3027                    final ActivityContainer container = (ActivityContainer) msg.obj;
3028                    try {
3029                        // We only send this message if mCallback is non-null.
3030                        container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1);
3031                    } catch (RemoteException e) {
3032                    }
3033                }
3034            }
3035        }
3036    }
3037
3038    class ActivityContainer extends android.app.IActivityContainer.Stub {
3039        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3040                Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
3041        final int mStackId;
3042        IActivityContainerCallback mCallback = null;
3043        final ActivityStack mStack;
3044        ActivityRecord mParentActivity = null;
3045        String mIdString;
3046
3047        boolean mVisible = true;
3048
3049        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3050        ActivityDisplay mActivityDisplay;
3051
3052        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3053        final static int CONTAINER_STATE_NO_SURFACE = 1;
3054        final static int CONTAINER_STATE_FINISHING = 2;
3055        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3056
3057        ActivityContainer(int stackId) {
3058            synchronized (mService) {
3059                mStackId = stackId;
3060                mStack = new ActivityStack(this);
3061                mIdString = "ActivtyContainer{" + mStackId + "}";
3062                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3063            }
3064        }
3065
3066        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3067            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3068                    + " to display=" + activityDisplay);
3069            mActivityDisplay = activityDisplay;
3070            mStack.mDisplayId = activityDisplay.mDisplayId;
3071            mStack.mStacks = activityDisplay.mStacks;
3072
3073            activityDisplay.attachActivities(mStack);
3074            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3075        }
3076
3077        @Override
3078        public void attachToDisplay(int displayId) {
3079            synchronized (mService) {
3080                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3081                if (activityDisplay == null) {
3082                    return;
3083                }
3084                attachToDisplayLocked(activityDisplay);
3085            }
3086        }
3087
3088        @Override
3089        public int getDisplayId() {
3090            if (mActivityDisplay != null) {
3091                return mActivityDisplay.mDisplayId;
3092            }
3093            return -1;
3094        }
3095
3096        @Override
3097        public boolean injectEvent(InputEvent event) {
3098            final long origId = Binder.clearCallingIdentity();
3099            try {
3100                if (mActivityDisplay != null) {
3101                    return mInputManagerInternal.injectInputEvent(event,
3102                            mActivityDisplay.mDisplayId,
3103                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3104                }
3105                return false;
3106            } finally {
3107                Binder.restoreCallingIdentity(origId);
3108            }
3109        }
3110
3111        @Override
3112        public void release() {
3113            mContainerState = CONTAINER_STATE_FINISHING;
3114            mStack.finishAllActivitiesLocked();
3115            detachLocked();
3116            mWindowManager.removeStack(mStackId);
3117        }
3118
3119        private void detachLocked() {
3120            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3121                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3122            if (mActivityDisplay != null) {
3123                mActivityDisplay.detachActivitiesLocked(mStack);
3124                mActivityDisplay = null;
3125                mStack.mDisplayId = -1;
3126                mStack.mStacks = null;
3127                mWindowManager.detachStack(mStackId);
3128            }
3129        }
3130
3131        @Override
3132        public final int startActivity(Intent intent) {
3133            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3134            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3135                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3136            // TODO: Switch to user app stacks here.
3137            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3138            String mimeType = intent.getType();
3139            if (mimeType == null && intent.getData() != null
3140                    && "content".equals(intent.getData().getScheme())) {
3141                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3142            }
3143            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null,
3144                    null, null, null, null, userId, this);
3145        }
3146
3147        @Override
3148        public final int startActivityIntentSender(IIntentSender intentSender) {
3149            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3150
3151            if (!(intentSender instanceof PendingIntentRecord)) {
3152                throw new IllegalArgumentException("Bad PendingIntent object");
3153            }
3154
3155            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3156                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3157        }
3158
3159        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3160            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3161                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3162            if (resolvedType == null) {
3163                resolvedType = intent.getType();
3164                if (resolvedType == null && intent.getData() != null
3165                        && "content".equals(intent.getData().getScheme())) {
3166                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3167                }
3168            }
3169            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
3170            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3171                throw new SecurityException(
3172                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3173            }
3174        }
3175
3176        /** Throw a SecurityException if allowEmbedded is not true */
3177        @Override
3178        public final void checkEmbeddedAllowed(Intent intent) {
3179            checkEmbeddedAllowedInner(intent, null);
3180        }
3181
3182        /** Throw a SecurityException if allowEmbedded is not true */
3183        @Override
3184        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3185            if (!(intentSender instanceof PendingIntentRecord)) {
3186                throw new IllegalArgumentException("Bad PendingIntent object");
3187            }
3188            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3189            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3190                    pendingIntent.key.requestResolvedType);
3191        }
3192
3193        @Override
3194        public IBinder asBinder() {
3195            return this;
3196        }
3197
3198        @Override
3199        public void setSurface(Surface surface, int width, int height, int density) {
3200            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3201        }
3202
3203        ActivityStackSupervisor getOuter() {
3204            return ActivityStackSupervisor.this;
3205        }
3206
3207        boolean isAttached() {
3208            return mActivityDisplay != null;
3209        }
3210
3211        void getBounds(Point outBounds) {
3212            if (mActivityDisplay != null) {
3213                mActivityDisplay.getBounds(outBounds);
3214            } else {
3215                outBounds.set(0, 0);
3216            }
3217        }
3218
3219        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3220        void setVisible(boolean visible) {
3221            if (mVisible != visible) {
3222                mVisible = visible;
3223                if (mCallback != null) {
3224                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3225                            0 /* unused */, this).sendToTarget();
3226                }
3227            }
3228        }
3229
3230        void setDrawn() {
3231        }
3232
3233        @Override
3234        public String toString() {
3235            return mIdString + (mActivityDisplay == null ? "N" : "A");
3236        }
3237    }
3238
3239    private class VirtualActivityContainer extends ActivityContainer {
3240        Surface mSurface;
3241        boolean mDrawn = false;
3242
3243        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3244            super(getNextStackId());
3245            mParentActivity = parent;
3246            mCallback = callback;
3247            mContainerState = CONTAINER_STATE_NO_SURFACE;
3248            mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3249        }
3250
3251        @Override
3252        public void setSurface(Surface surface, int width, int height, int density) {
3253            super.setSurface(surface, width, height, density);
3254
3255            synchronized (mService) {
3256                final long origId = Binder.clearCallingIdentity();
3257                try {
3258                    setSurfaceLocked(surface, width, height, density);
3259                } finally {
3260                    Binder.restoreCallingIdentity(origId);
3261                }
3262            }
3263        }
3264
3265        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3266            if (mContainerState == CONTAINER_STATE_FINISHING) {
3267                return;
3268            }
3269            VirtualActivityDisplay virtualActivityDisplay =
3270                    (VirtualActivityDisplay) mActivityDisplay;
3271            if (virtualActivityDisplay == null) {
3272                virtualActivityDisplay =
3273                        new VirtualActivityDisplay(width, height, density);
3274                mActivityDisplay = virtualActivityDisplay;
3275                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3276                attachToDisplayLocked(virtualActivityDisplay);
3277            }
3278
3279            if (mSurface != null) {
3280                mSurface.release();
3281            }
3282
3283            mSurface = surface;
3284            if (surface != null) {
3285                mStack.resumeTopActivityLocked(null);
3286            } else {
3287                mContainerState = CONTAINER_STATE_NO_SURFACE;
3288                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3289                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3290                    mStack.startPausingLocked(false, true);
3291                }
3292            }
3293
3294            setSurfaceIfReady();
3295
3296            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3297                    + virtualActivityDisplay);
3298        }
3299
3300        @Override
3301        boolean isAttached() {
3302            return mSurface != null && super.isAttached();
3303        }
3304
3305        @Override
3306        void setDrawn() {
3307            synchronized (mService) {
3308                mDrawn = true;
3309                setSurfaceIfReady();
3310            }
3311        }
3312
3313        private void setSurfaceIfReady() {
3314            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn +
3315                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3316            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3317                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3318                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3319            }
3320        }
3321    }
3322
3323    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3324     * attached {@link ActivityStack}s */
3325    class ActivityDisplay {
3326        /** Actual Display this object tracks. */
3327        int mDisplayId;
3328        Display mDisplay;
3329        DisplayInfo mDisplayInfo = new DisplayInfo();
3330
3331        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3332         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3333        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3334
3335        ActivityDisplay() {
3336        }
3337
3338        ActivityDisplay(int displayId) {
3339            init(mDisplayManager.getDisplay(displayId));
3340        }
3341
3342        void init(Display display) {
3343            mDisplay = display;
3344            mDisplayId = display.getDisplayId();
3345            mDisplay.getDisplayInfo(mDisplayInfo);
3346        }
3347
3348        void attachActivities(ActivityStack stack) {
3349            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3350                    + mDisplayId);
3351            mStacks.add(stack);
3352        }
3353
3354        void detachActivitiesLocked(ActivityStack stack) {
3355            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3356                    + " from displayId=" + mDisplayId);
3357            mStacks.remove(stack);
3358        }
3359
3360        void getBounds(Point bounds) {
3361            mDisplay.getDisplayInfo(mDisplayInfo);
3362            bounds.x = mDisplayInfo.appWidth;
3363            bounds.y = mDisplayInfo.appHeight;
3364        }
3365
3366        @Override
3367        public String toString() {
3368            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3369        }
3370    }
3371
3372    class VirtualActivityDisplay extends ActivityDisplay {
3373        VirtualDisplay mVirtualDisplay;
3374
3375        VirtualActivityDisplay(int width, int height, int density) {
3376            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3377            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
3378                    width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3379                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3380
3381            init(mVirtualDisplay.getDisplay());
3382
3383            mWindowManager.handleDisplayAdded(mDisplayId);
3384        }
3385
3386        void setSurface(Surface surface) {
3387            if (mVirtualDisplay != null) {
3388                mVirtualDisplay.setSurface(surface);
3389            }
3390        }
3391
3392        @Override
3393        void detachActivitiesLocked(ActivityStack stack) {
3394            super.detachActivitiesLocked(stack);
3395            if (mVirtualDisplay != null) {
3396                mVirtualDisplay.release();
3397                mVirtualDisplay = null;
3398            }
3399        }
3400
3401        @Override
3402        public String toString() {
3403            return "VirtualActivityDisplay={" + mDisplayId + "}";
3404        }
3405    }
3406}
3407