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