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