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