ActivityStackSupervisor.java revision c6cf95c0f5f7250c65e40c441fe58d8cbfd114c9
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(sourceRecord, resultWho, requestCode);
1242            }
1243            if (sourceRecord.launchedFromUid == callingUid) {
1244                // The new activity is being launched from the same uid as the previous
1245                // activity in the flow, and asking to forward its result back to the
1246                // previous.  In this case the activity is serving as a trampoline between
1247                // the two, so we also want to update its launchedFromPackage to be the
1248                // same as the previous activity.  Note that this is safe, since we know
1249                // these two packages come from the same uid; the caller could just as
1250                // well have supplied that same package name itself.  This specifially
1251                // deals with the case of an intent picker/chooser being launched in the app
1252                // flow to redirect to an activity picked by the user, where we want the final
1253                // activity to consider it to have been launched by the previous app activity.
1254                callingPackage = sourceRecord.launchedFromPackage;
1255            }
1256        }
1257
1258        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1259            // We couldn't find a class that can handle the given Intent.
1260            // That's the end of that!
1261            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1262        }
1263
1264        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1265            // We couldn't find the specific class specified in the Intent.
1266            // Also the end of the line.
1267            err = ActivityManager.START_CLASS_NOT_FOUND;
1268        }
1269
1270        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
1271                && sourceRecord.task.voiceSession != null) {
1272            // If this activity is being launched as part of a voice session, we need
1273            // to ensure that it is safe to do so.  If the upcoming activity will also
1274            // be part of the voice session, we can only launch it if it has explicitly
1275            // said it supports the VOICE category, or it is a part of the calling app.
1276            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
1277                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
1278                try {
1279                    if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1280                            intent, resolvedType)) {
1281                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1282                    }
1283                } catch (RemoteException e) {
1284                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1285                }
1286            }
1287        }
1288
1289        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
1290            // If the caller is starting a new voice session, just make sure the target
1291            // is actually allowing it to run this way.
1292            try {
1293                if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1294                        intent, resolvedType)) {
1295                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1296                }
1297            } catch (RemoteException e) {
1298                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1299            }
1300        }
1301
1302        if (err != ActivityManager.START_SUCCESS) {
1303            if (resultRecord != null) {
1304                resultStack.sendActivityResultLocked(-1,
1305                    resultRecord, resultWho, requestCode,
1306                    Activity.RESULT_CANCELED, null);
1307            }
1308            setDismissKeyguard(false);
1309            ActivityOptions.abort(options);
1310            return err;
1311        }
1312
1313        final int startAnyPerm = mService.checkPermission(
1314                START_ANY_ACTIVITY, callingPid, callingUid);
1315        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1316                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1317        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1318            if (resultRecord != null) {
1319                resultStack.sendActivityResultLocked(-1,
1320                    resultRecord, resultWho, requestCode,
1321                    Activity.RESULT_CANCELED, null);
1322            }
1323            setDismissKeyguard(false);
1324            String msg;
1325            if (!aInfo.exported) {
1326                msg = "Permission Denial: starting " + intent.toString()
1327                        + " from " + callerApp + " (pid=" + callingPid
1328                        + ", uid=" + callingUid + ")"
1329                        + " not exported from uid " + aInfo.applicationInfo.uid;
1330            } else {
1331                msg = "Permission Denial: starting " + intent.toString()
1332                        + " from " + callerApp + " (pid=" + callingPid
1333                        + ", uid=" + callingUid + ")"
1334                        + " requires " + aInfo.permission;
1335            }
1336            Slog.w(TAG, msg);
1337            throw new SecurityException(msg);
1338        }
1339
1340        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1341                callingPid, resolvedType, aInfo.applicationInfo);
1342
1343        if (mService.mController != null) {
1344            try {
1345                // The Intent we give to the watcher has the extra data
1346                // stripped off, since it can contain private information.
1347                Intent watchIntent = intent.cloneFilter();
1348                abort |= !mService.mController.activityStarting(watchIntent,
1349                        aInfo.applicationInfo.packageName);
1350            } catch (RemoteException e) {
1351                mService.mController = null;
1352            }
1353        }
1354
1355        if (abort) {
1356            if (resultRecord != null) {
1357                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1358                        Activity.RESULT_CANCELED, null);
1359            }
1360            // We pretend to the caller that it was really started, but
1361            // they will just get a cancel result.
1362            setDismissKeyguard(false);
1363            ActivityOptions.abort(options);
1364            return ActivityManager.START_SUCCESS;
1365        }
1366
1367        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1368                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1369                requestCode, componentSpecified, this, container, options);
1370        if (outActivity != null) {
1371            outActivity[0] = r;
1372        }
1373
1374        final ActivityStack stack = getFocusedStack();
1375        if (voiceSession == null && (stack.mResumedActivity == null
1376                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
1377            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1378                PendingActivityLaunch pal =
1379                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1380                mService.mPendingActivityLaunches.add(pal);
1381                setDismissKeyguard(false);
1382                ActivityOptions.abort(options);
1383                return ActivityManager.START_SWITCHES_CANCELED;
1384            }
1385        }
1386
1387        if (mService.mDidAppSwitch) {
1388            // This is the second allowed switch since we stopped switches,
1389            // so now just generally allow switches.  Use case: user presses
1390            // home (switches disabled, switch to home, mDidAppSwitch now true);
1391            // user taps a home icon (coming from home so allowed, we hit here
1392            // and now allow anyone to switch again).
1393            mService.mAppSwitchesAllowedTime = 0;
1394        } else {
1395            mService.mDidAppSwitch = true;
1396        }
1397
1398        mService.doPendingActivityLaunchesLocked(false);
1399
1400        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
1401                startFlags, true, options);
1402
1403        if (allPausedActivitiesComplete()) {
1404            // If someone asked to have the keyguard dismissed on the next
1405            // activity start, but we are not actually doing an activity
1406            // switch...  just dismiss the keyguard now, because we
1407            // probably want to see whatever is behind it.
1408            dismissKeyguard();
1409        }
1410        return err;
1411    }
1412
1413    ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) {
1414        final TaskRecord task = r.task;
1415        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
1416            if (task != null) {
1417                final ActivityStack taskStack = task.stack;
1418                if (taskStack.isOnHomeDisplay()) {
1419                    if (mFocusedStack != taskStack) {
1420                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1421                                "focused stack to r=" + r + " task=" + task);
1422                        mFocusedStack = taskStack;
1423                    } else {
1424                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1425                            "adjustStackFocus: Focused stack already=" + mFocusedStack);
1426                    }
1427                }
1428                return taskStack;
1429            }
1430
1431            final ActivityContainer container = r.mInitialActivityContainer;
1432            if (container != null) {
1433                // The first time put it on the desired stack, after this put on task stack.
1434                r.mInitialActivityContainer = null;
1435                return container.mStack;
1436            }
1437
1438            if (mFocusedStack != mHomeStack && (!newTask ||
1439                    mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
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 =
1503                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1504
1505        // If the onlyIfNeeded flag is set, then we can do this if the activity
1506        // being launched is the same as the one making the call...  or, as
1507        // a special case, if we do not know the caller then we count the
1508        // current top activity as the caller.
1509        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1510            ActivityRecord checkedCaller = sourceRecord;
1511            if (checkedCaller == null) {
1512                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1513            }
1514            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1515                // Caller is not the same as launcher, so always needed.
1516                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1517            }
1518        }
1519
1520        switch (r.info.documentLaunchMode) {
1521            case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1522                break;
1523            case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1524                intent.addFlags(
1525                        Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
1526                launchFlags = intent.getFlags();
1527                break;
1528            case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1529                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
1530                launchFlags = intent.getFlags();
1531                break;
1532        }
1533        final boolean newDocument = intent.isDocument();
1534        if (sourceRecord == null) {
1535            // This activity is not being started from another...  in this
1536            // case we -always- start a new task.
1537            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1538                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1539                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1540                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1541            }
1542        } else if (newDocument) {
1543            if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
1544                Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
1545                r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
1546            }
1547        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1548            // The original activity who is starting us is running as a single
1549            // instance...  this new activity it is starting must go on its
1550            // own task.
1551            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1552        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1553                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1554            // The activity being started is a single instance...  it always
1555            // gets launched into its own task.
1556            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1557        }
1558
1559        ActivityInfo newTaskInfo = null;
1560        Intent newTaskIntent = null;
1561        final ActivityStack sourceStack;
1562        if (sourceRecord != null) {
1563            if (sourceRecord.finishing) {
1564                // If the source is finishing, we can't further count it as our source.  This
1565                // is because the task it is associated with may now be empty and on its way out,
1566                // so we don't want to blindly throw it in to that task.  Instead we will take
1567                // the NEW_TASK flow and try to find a task for it. But save the task information
1568                // so it can be used when creating the new task.
1569                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1570                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1571                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1572                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1573                    newTaskInfo = sourceRecord.info;
1574                    newTaskIntent = sourceRecord.task.intent;
1575                }
1576                sourceRecord = null;
1577                sourceStack = null;
1578            } else {
1579                sourceStack = sourceRecord.task.stack;
1580            }
1581        } else {
1582            sourceStack = null;
1583        }
1584
1585        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1586            // For whatever reason this activity is being launched into a new
1587            // task...  yet the caller has requested a result back.  Well, that
1588            // is pretty messed up, so instead immediately send back a cancel
1589            // and let the new task continue launched as normal without a
1590            // dependency on its originator.
1591            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1592            r.resultTo.task.stack.sendActivityResultLocked(-1,
1593                    r.resultTo, r.resultWho, r.requestCode,
1594                Activity.RESULT_CANCELED, null);
1595            r.resultTo = null;
1596        }
1597
1598        boolean addingToTask = false;
1599        boolean movedHome = false;
1600        TaskRecord reuseTask = null;
1601        ActivityStack targetStack;
1602        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1603                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1604                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1605                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1606            // If bring to front is requested, and no result is requested, and
1607            // we can find a task that was started with this same
1608            // component, then instead of launching bring that one to the front.
1609            if (r.resultTo == null) {
1610                // See if there is a task to bring to the front.  If this is
1611                // a SINGLE_INSTANCE activity, there can be one and only one
1612                // instance of it in the history, and it is always in its own
1613                // unique task, so we do a special search.
1614                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1615                        ? findTaskLocked(r)
1616                        : findActivityLocked(intent, r.info);
1617                if (intentActivity != null) {
1618                    if (isLockTaskModeViolation(intentActivity.task)) {
1619                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1620                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1621                    }
1622                    if (r.task == null) {
1623                        r.task = intentActivity.task;
1624                    }
1625                    targetStack = intentActivity.task.stack;
1626                    targetStack.mLastPausedActivity = null;
1627                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1628                            + " from " + intentActivity);
1629                    targetStack.moveToFront();
1630                    if (intentActivity.task.intent == null) {
1631                        // This task was started because of movement of
1632                        // the activity based on affinity...  now that we
1633                        // are actually launching it, we can assign the
1634                        // base intent.
1635                        intentActivity.task.setIntent(intent, r.info);
1636                    }
1637                    // If the target task is not in the front, then we need
1638                    // to bring it to the front...  except...  well, with
1639                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1640                    // to have the same behavior as if a new instance was
1641                    // being started, which means not bringing it to the front
1642                    // if the caller is not itself in the front.
1643                    final ActivityStack lastStack = getLastStack();
1644                    ActivityRecord curTop = lastStack == null?
1645                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1646                    if (curTop != null && (curTop.task != intentActivity.task ||
1647                            curTop.task != lastStack.topTask())) {
1648                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1649                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1650                                sourceStack.topActivity().task == sourceRecord.task)) {
1651                            // We really do want to push this one into the
1652                            // user's face, right now.
1653                            movedHome = true;
1654                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1655                            if ((launchFlags &
1656                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1657                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1658                                // Caller wants to appear on home activity.
1659                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1660                            }
1661                            options = null;
1662                        }
1663                    }
1664                    // If the caller has requested that the target task be
1665                    // reset, then do so.
1666                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1667                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1668                    }
1669                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1670                        // We don't need to start a new activity, and
1671                        // the client said not to do anything if that
1672                        // is the case, so this is it!  And for paranoia, make
1673                        // sure we have correctly resumed the top activity.
1674                        if (doResume) {
1675                            resumeTopActivitiesLocked(targetStack, null, options);
1676                        } else {
1677                            ActivityOptions.abort(options);
1678                        }
1679                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1680                    }
1681                    if ((launchFlags &
1682                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1683                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1684                        // The caller has requested to completely replace any
1685                        // existing task with its new activity.  Well that should
1686                        // not be too hard...
1687                        reuseTask = intentActivity.task;
1688                        reuseTask.performClearTaskLocked();
1689                        reuseTask.setIntent(r.intent, r.info);
1690                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1691                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1692                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1693                        // In this situation we want to remove all activities
1694                        // from the task up to the one being started.  In most
1695                        // cases this means we are resetting the task to its
1696                        // initial state.
1697                        ActivityRecord top =
1698                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1699                        if (top != null) {
1700                            if (top.frontOfTask) {
1701                                // Activity aliases may mean we use different
1702                                // intents for the top activity, so make sure
1703                                // the task now has the identity of the new
1704                                // intent.
1705                                top.task.setIntent(r.intent, r.info);
1706                            }
1707                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1708                                    r, top.task);
1709                            top.deliverNewIntentLocked(callingUid, r.intent);
1710                        } else {
1711                            // A special case: we need to
1712                            // start the activity because it is not currently
1713                            // running, and the caller has asked to clear the
1714                            // current task to have this activity at the top.
1715                            addingToTask = true;
1716                            // Now pretend like this activity is being started
1717                            // by the top of its task, so it is put in the
1718                            // right place.
1719                            sourceRecord = intentActivity;
1720                        }
1721                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1722                        // In this case the top activity on the task is the
1723                        // same as the one being launched, so we take that
1724                        // as a request to bring the task to the foreground.
1725                        // If the top activity in the task is the root
1726                        // activity, deliver this new intent to it if it
1727                        // desires.
1728                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1729                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1730                                && intentActivity.realActivity.equals(r.realActivity)) {
1731                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1732                                    intentActivity.task);
1733                            if (intentActivity.frontOfTask) {
1734                                intentActivity.task.setIntent(r.intent, r.info);
1735                            }
1736                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1737                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1738                            // In this case we are launching the root activity
1739                            // of the task, but with a different intent.  We
1740                            // should start a new instance on top.
1741                            addingToTask = true;
1742                            sourceRecord = intentActivity;
1743                        }
1744                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1745                        // In this case an activity is being launched in to an
1746                        // existing task, without resetting that task.  This
1747                        // is typically the situation of launching an activity
1748                        // from a notification or shortcut.  We want to place
1749                        // the new activity on top of the current task.
1750                        addingToTask = true;
1751                        sourceRecord = intentActivity;
1752                    } else if (!intentActivity.task.rootWasReset) {
1753                        // In this case we are launching in to an existing task
1754                        // that has not yet been started from its front door.
1755                        // The current task has been brought to the front.
1756                        // Ideally, we'd probably like to place this new task
1757                        // at the bottom of its stack, but that's a little hard
1758                        // to do with the current organization of the code so
1759                        // for now we'll just drop it.
1760                        intentActivity.task.setIntent(r.intent, r.info);
1761                    }
1762                    if (!addingToTask && reuseTask == null) {
1763                        // We didn't do anything...  but it was needed (a.k.a., client
1764                        // don't use that intent!)  And for paranoia, make
1765                        // sure we have correctly resumed the top activity.
1766                        if (doResume) {
1767                            targetStack.resumeTopActivityLocked(null, options);
1768                        } else {
1769                            ActivityOptions.abort(options);
1770                        }
1771                        return ActivityManager.START_TASK_TO_FRONT;
1772                    }
1773                }
1774            }
1775        }
1776
1777        //String uri = r.intent.toURI();
1778        //Intent intent2 = new Intent(uri);
1779        //Slog.i(TAG, "Given intent: " + r.intent);
1780        //Slog.i(TAG, "URI is: " + uri);
1781        //Slog.i(TAG, "To intent: " + intent2);
1782
1783        if (r.packageName != null) {
1784            // If the activity being launched is the same as the one currently
1785            // at the top, then we need to check if it should only be launched
1786            // once.
1787            ActivityStack topStack = getFocusedStack();
1788            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1789            if (top != null && r.resultTo == null) {
1790                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1791                    if (top.app != null && top.app.thread != null) {
1792                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1793                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1794                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1795                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1796                                    top.task);
1797                            // For paranoia, make sure we have correctly
1798                            // resumed the top activity.
1799                            topStack.mLastPausedActivity = null;
1800                            if (doResume) {
1801                                resumeTopActivitiesLocked();
1802                            }
1803                            ActivityOptions.abort(options);
1804                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1805                                // We don't need to start a new activity, and
1806                                // the client said not to do anything if that
1807                                // is the case, so this is it!
1808                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1809                            }
1810                            top.deliverNewIntentLocked(callingUid, r.intent);
1811                            return ActivityManager.START_DELIVERED_TO_TOP;
1812                        }
1813                    }
1814                }
1815            }
1816
1817        } else {
1818            if (r.resultTo != null) {
1819                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1820                        r.requestCode, Activity.RESULT_CANCELED, null);
1821            }
1822            ActivityOptions.abort(options);
1823            return ActivityManager.START_CLASS_NOT_FOUND;
1824        }
1825
1826        boolean newTask = false;
1827        boolean keepCurTransition = false;
1828
1829        // Should this be considered a new task?
1830        if (r.resultTo == null && !addingToTask
1831                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1832            if (isLockTaskModeViolation(reuseTask)) {
1833                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1834                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1835            }
1836            newTask = true;
1837            targetStack = adjustStackFocus(r, newTask);
1838            targetStack.moveToFront();
1839            if (reuseTask == null) {
1840                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1841                        newTaskInfo != null ? newTaskInfo : r.info,
1842                        newTaskIntent != null ? newTaskIntent : intent,
1843                        voiceSession, voiceInteractor, true), null, true);
1844                if (sourceRecord == null) {
1845                    // Launched from a service or notification or task that is finishing.
1846                    r.task.setTaskToReturnTo(isFrontStack(mHomeStack) ?
1847                            mHomeStack.topTask().taskType : RECENTS_ACTIVITY_TYPE);
1848                }
1849                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1850                        r.task);
1851            } else {
1852                r.setTask(reuseTask, reuseTask, true);
1853            }
1854            if (!movedHome) {
1855                if ((launchFlags &
1856                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1857                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1858                    // Caller wants to appear on home activity, so before starting
1859                    // their own activity we will bring home to the front.
1860                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1861                }
1862            }
1863        } else if (sourceRecord != null) {
1864            TaskRecord sourceTask = sourceRecord.task;
1865            if (isLockTaskModeViolation(sourceTask)) {
1866                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1867                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1868            }
1869            targetStack = sourceTask.stack;
1870            targetStack.moveToFront();
1871            mWindowManager.moveTaskToTop(targetStack.topTask().taskId);
1872            if (!addingToTask &&
1873                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1874                // In this case, we are adding the activity to an existing
1875                // task, but the caller has asked to clear that task if the
1876                // activity is already running.
1877                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1878                keepCurTransition = true;
1879                if (top != null) {
1880                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1881                    top.deliverNewIntentLocked(callingUid, r.intent);
1882                    // For paranoia, make sure we have correctly
1883                    // resumed the top activity.
1884                    targetStack.mLastPausedActivity = null;
1885                    if (doResume) {
1886                        targetStack.resumeTopActivityLocked(null);
1887                    }
1888                    ActivityOptions.abort(options);
1889                    return ActivityManager.START_DELIVERED_TO_TOP;
1890                }
1891            } else if (!addingToTask &&
1892                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1893                // In this case, we are launching an activity in our own task
1894                // that may already be running somewhere in the history, and
1895                // we want to shuffle it to the front of the stack if so.
1896                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1897                if (top != null) {
1898                    final TaskRecord task = top.task;
1899                    task.moveActivityToFrontLocked(top);
1900                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1901                    top.updateOptionsLocked(options);
1902                    top.deliverNewIntentLocked(callingUid, r.intent);
1903                    targetStack.mLastPausedActivity = null;
1904                    if (doResume) {
1905                        targetStack.resumeTopActivityLocked(null);
1906                    }
1907                    return ActivityManager.START_DELIVERED_TO_TOP;
1908                }
1909            }
1910            // An existing activity is starting this new activity, so we want
1911            // to keep the new one in the same task as the one that is starting
1912            // it.
1913            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
1914            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1915                    + " in existing task " + r.task + " from source " + sourceRecord);
1916
1917        } else {
1918            // This not being started from an existing activity, and not part
1919            // of a new task...  just put it in the top task, though these days
1920            // this case should never happen.
1921            targetStack = adjustStackFocus(r, newTask);
1922            targetStack.moveToFront();
1923            ActivityRecord prev = targetStack.topActivity();
1924            r.setTask(prev != null ? prev.task
1925                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, null, null, true),
1926                    null, true);
1927            mWindowManager.moveTaskToTop(r.task.taskId);
1928            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1929                    + " in new guessed " + r.task);
1930        }
1931
1932        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1933                intent, r.getUriPermissionsLocked(), r.userId);
1934
1935        if (newTask) {
1936            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1937        }
1938        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1939        targetStack.mLastPausedActivity = null;
1940        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1941        mService.setFocusedActivityLocked(r);
1942        return ActivityManager.START_SUCCESS;
1943    }
1944
1945    void acquireLaunchWakelock() {
1946        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1947            throw new IllegalStateException("Calling must be system uid");
1948        }
1949        mLaunchingActivity.acquire();
1950        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1951            // To be safe, don't allow the wake lock to be held for too long.
1952            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1953        }
1954    }
1955
1956    // Checked.
1957    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1958            Configuration config) {
1959        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1960
1961        ArrayList<ActivityRecord> stops = null;
1962        ArrayList<ActivityRecord> finishes = null;
1963        ArrayList<UserStartedState> startingUsers = null;
1964        int NS = 0;
1965        int NF = 0;
1966        boolean booting = false;
1967        boolean enableScreen = false;
1968        boolean activityRemoved = false;
1969
1970        ActivityRecord r = ActivityRecord.forToken(token);
1971        if (r != null) {
1972            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1973                    Debug.getCallers(4));
1974            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1975            r.finishLaunchTickingLocked();
1976            if (fromTimeout) {
1977                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1978            }
1979
1980            // This is a hack to semi-deal with a race condition
1981            // in the client where it can be constructed with a
1982            // newer configuration from when we asked it to launch.
1983            // We'll update with whatever configuration it now says
1984            // it used to launch.
1985            if (config != null) {
1986                r.configuration = config;
1987            }
1988
1989            // We are now idle.  If someone is waiting for a thumbnail from
1990            // us, we can now deliver.
1991            r.idle = true;
1992
1993            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1994            if (!mService.mBooted && isFrontStack(r.task.stack)) {
1995                mService.mBooted = true;
1996                enableScreen = true;
1997            }
1998        }
1999
2000        if (allResumedActivitiesIdle()) {
2001            if (r != null) {
2002                mService.scheduleAppGcsLocked();
2003            }
2004
2005            if (mLaunchingActivity.isHeld()) {
2006                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2007                if (VALIDATE_WAKE_LOCK_CALLER &&
2008                        Binder.getCallingUid() != Process.myUid()) {
2009                    throw new IllegalStateException("Calling must be system uid");
2010                }
2011                mLaunchingActivity.release();
2012            }
2013            ensureActivitiesVisibleLocked(null, 0);
2014        }
2015
2016        // Atomically retrieve all of the other things to do.
2017        stops = processStoppingActivitiesLocked(true);
2018        NS = stops != null ? stops.size() : 0;
2019        if ((NF=mFinishingActivities.size()) > 0) {
2020            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
2021            mFinishingActivities.clear();
2022        }
2023
2024        if (isFrontStack(mHomeStack)) {
2025            booting = mService.mBooting;
2026            mService.mBooting = false;
2027        }
2028
2029        if (mStartingUsers.size() > 0) {
2030            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
2031            mStartingUsers.clear();
2032        }
2033
2034        // Stop any activities that are scheduled to do so but have been
2035        // waiting for the next one to start.
2036        for (int i = 0; i < NS; i++) {
2037            r = stops.get(i);
2038            final ActivityStack stack = r.task.stack;
2039            if (r.finishing) {
2040                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2041            } else {
2042                stack.stopActivityLocked(r);
2043            }
2044        }
2045
2046        // Finish any activities that are scheduled to do so but have been
2047        // waiting for the next one to start.
2048        for (int i = 0; i < NF; i++) {
2049            r = finishes.get(i);
2050            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
2051        }
2052
2053        if (booting) {
2054            mService.finishBooting();
2055        } else {
2056            // Complete user switch
2057            if (startingUsers != null) {
2058                for (int i = 0; i < startingUsers.size(); i++) {
2059                    mService.finishUserSwitch(startingUsers.get(i));
2060                }
2061            }
2062            // Complete starting up of background users
2063            if (mStartingBackgroundUsers.size() > 0) {
2064                startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
2065                mStartingBackgroundUsers.clear();
2066                for (int i = 0; i < startingUsers.size(); i++) {
2067                    mService.finishUserBoot(startingUsers.get(i));
2068                }
2069            }
2070        }
2071
2072        mService.trimApplications();
2073        //dump();
2074        //mWindowManager.dump();
2075
2076        if (enableScreen) {
2077            mService.enableScreenAfterBoot();
2078        }
2079
2080        if (activityRemoved) {
2081            resumeTopActivitiesLocked();
2082        }
2083
2084        return r;
2085    }
2086
2087    boolean handleAppDiedLocked(ProcessRecord app) {
2088        boolean hasVisibleActivities = false;
2089        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2090            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2091            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2092                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2093            }
2094        }
2095        return hasVisibleActivities;
2096    }
2097
2098    void closeSystemDialogsLocked() {
2099        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2100            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2101            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2102                stacks.get(stackNdx).closeSystemDialogsLocked();
2103            }
2104        }
2105    }
2106
2107    void removeUserLocked(int userId) {
2108        mUserStackInFront.delete(userId);
2109    }
2110
2111    /**
2112     * @return true if some activity was finished (or would have finished if doit were true).
2113     */
2114    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2115        boolean didSomething = false;
2116        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2117            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2118            final int numStacks = stacks.size();
2119            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2120                final ActivityStack stack = stacks.get(stackNdx);
2121                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2122                    didSomething = true;
2123                }
2124            }
2125        }
2126        return didSomething;
2127    }
2128
2129    void updatePreviousProcessLocked(ActivityRecord r) {
2130        // Now that this process has stopped, we may want to consider
2131        // it to be the previous app to try to keep around in case
2132        // the user wants to return to it.
2133
2134        // First, found out what is currently the foreground app, so that
2135        // we don't blow away the previous app if this activity is being
2136        // hosted by the process that is actually still the foreground.
2137        ProcessRecord fgApp = null;
2138        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2139            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2140            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2141                final ActivityStack stack = stacks.get(stackNdx);
2142                if (isFrontStack(stack)) {
2143                    if (stack.mResumedActivity != null) {
2144                        fgApp = stack.mResumedActivity.app;
2145                    } else if (stack.mPausingActivity != null) {
2146                        fgApp = stack.mPausingActivity.app;
2147                    }
2148                    break;
2149                }
2150            }
2151        }
2152
2153        // Now set this one as the previous process, only if that really
2154        // makes sense to.
2155        if (r.app != null && fgApp != null && r.app != fgApp
2156                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2157                && r.app != mService.mHomeProcess) {
2158            mService.mPreviousProcess = r.app;
2159            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2160        }
2161    }
2162
2163    boolean resumeTopActivitiesLocked() {
2164        return resumeTopActivitiesLocked(null, null, null);
2165    }
2166
2167    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2168            Bundle targetOptions) {
2169        if (targetStack == null) {
2170            targetStack = getFocusedStack();
2171        }
2172        // Do targetStack first.
2173        boolean result = false;
2174        if (isFrontStack(targetStack)) {
2175            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2176        }
2177        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2178            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2179            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2180                final ActivityStack stack = stacks.get(stackNdx);
2181                if (stack == targetStack) {
2182                    // Already started above.
2183                    continue;
2184                }
2185                if (isFrontStack(stack)) {
2186                    stack.resumeTopActivityLocked(null);
2187                }
2188            }
2189        }
2190        return result;
2191    }
2192
2193    void finishTopRunningActivityLocked(ProcessRecord app) {
2194        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2195            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2196            final int numStacks = stacks.size();
2197            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2198                final ActivityStack stack = stacks.get(stackNdx);
2199                stack.finishTopRunningActivityLocked(app);
2200            }
2201        }
2202    }
2203
2204    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2205        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2206            mUserLeaving = true;
2207        }
2208        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2209            // Caller wants the home activity moved with it.  To accomplish this,
2210            // we'll just indicate that this task returns to the home task.
2211            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2212        }
2213        task.stack.moveTaskToFrontLocked(task, null, options);
2214        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2215                + task.stack);
2216    }
2217
2218    ActivityStack getStack(int stackId) {
2219        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2220        if (activityContainer != null) {
2221            return activityContainer.mStack;
2222        }
2223        return null;
2224    }
2225
2226    ArrayList<ActivityStack> getStacks() {
2227        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2228        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2229            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2230        }
2231        return allStacks;
2232    }
2233
2234    IBinder getHomeActivityToken() {
2235        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2236        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2237            final TaskRecord task = tasks.get(taskNdx);
2238            if (task.isHomeTask()) {
2239                final ArrayList<ActivityRecord> activities = task.mActivities;
2240                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2241                    final ActivityRecord r = activities.get(activityNdx);
2242                    if (r.isHomeActivity()) {
2243                        return r.appToken;
2244                    }
2245                }
2246            }
2247        }
2248        return null;
2249    }
2250
2251    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2252            IActivityContainerCallback callback) {
2253        ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback);
2254        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2255        parentActivity.mChildContainers.add(activityContainer);
2256        return activityContainer;
2257    }
2258
2259    void removeChildActivityContainers(ActivityRecord parentActivity) {
2260        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2261        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2262            ActivityContainer container = childStacks.remove(containerNdx);
2263            container.release();
2264        }
2265    }
2266
2267    void deleteActivityContainer(IActivityContainer container) {
2268        ActivityContainer activityContainer = (ActivityContainer)container;
2269        if (activityContainer != null) {
2270            activityContainer.mStack.finishAllActivitiesLocked();
2271            final ActivityRecord parent = activityContainer.mParentActivity;
2272            if (parent != null) {
2273                parent.mChildContainers.remove(activityContainer);
2274            }
2275            final int stackId = activityContainer.mStackId;
2276            mActivityContainers.remove(stackId);
2277            mWindowManager.removeStack(stackId);
2278        }
2279    }
2280
2281    private int createStackOnDisplay(int stackId, int displayId) {
2282        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2283        if (activityDisplay == null) {
2284            return -1;
2285        }
2286
2287        ActivityContainer activityContainer = new ActivityContainer(stackId);
2288        mActivityContainers.put(stackId, activityContainer);
2289        activityContainer.attachToDisplayLocked(activityDisplay);
2290        return stackId;
2291    }
2292
2293    int getNextStackId() {
2294        while (true) {
2295            if (++mLastStackId <= HOME_STACK_ID) {
2296                mLastStackId = HOME_STACK_ID + 1;
2297            }
2298            if (getStack(mLastStackId) == null) {
2299                break;
2300            }
2301        }
2302        return mLastStackId;
2303    }
2304
2305    void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) {
2306        int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2307        final ActivityStack stack = getStack(stackId);
2308        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2309            final TaskRecord task = tasks.get(taskNdx);
2310            stack.addTask(task, false, false);
2311            final int taskId = task.taskId;
2312            final ArrayList<ActivityRecord> activities = task.mActivities;
2313            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2314                final ActivityRecord r = activities.get(activityNdx);
2315                mWindowManager.addAppToken(0, r.appToken, taskId, stackId,
2316                        r.info.screenOrientation, r.fullscreen,
2317                        (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
2318                        r.userId, r.info.configChanges);
2319            }
2320            mWindowManager.addTask(taskId, stackId, false);
2321        }
2322        resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2323    }
2324
2325    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2326        final TaskRecord task = anyTaskForIdLocked(taskId);
2327        if (task == null) {
2328            return;
2329        }
2330        final ActivityStack stack = getStack(stackId);
2331        if (stack == null) {
2332            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2333            return;
2334        }
2335        task.stack.removeTask(task);
2336        stack.addTask(task, toTop, true);
2337        mWindowManager.addTask(taskId, stackId, toTop);
2338        resumeTopActivitiesLocked();
2339    }
2340
2341    ActivityRecord findTaskLocked(ActivityRecord r) {
2342        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2343        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2344            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2345            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2346                final ActivityStack stack = stacks.get(stackNdx);
2347                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2348                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2349                    continue;
2350                }
2351                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2352                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2353                            stack);
2354                    continue;
2355                }
2356                final ActivityRecord ar = stack.findTaskLocked(r);
2357                if (ar != null) {
2358                    return ar;
2359                }
2360            }
2361        }
2362        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2363        return null;
2364    }
2365
2366    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2367        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2368            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2369            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2370                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2371                if (ar != null) {
2372                    return ar;
2373                }
2374            }
2375        }
2376        return null;
2377    }
2378
2379    void goingToSleepLocked() {
2380        scheduleSleepTimeout();
2381        if (!mGoingToSleep.isHeld()) {
2382            mGoingToSleep.acquire();
2383            if (mLaunchingActivity.isHeld()) {
2384                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2385                    throw new IllegalStateException("Calling must be system uid");
2386                }
2387                mLaunchingActivity.release();
2388                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2389            }
2390        }
2391        checkReadyForSleepLocked();
2392    }
2393
2394    boolean shutdownLocked(int timeout) {
2395        goingToSleepLocked();
2396
2397        boolean timedout = false;
2398        final long endTime = System.currentTimeMillis() + timeout;
2399        while (true) {
2400            boolean cantShutdown = false;
2401            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2402                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2403                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2404                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2405                }
2406            }
2407            if (cantShutdown) {
2408                long timeRemaining = endTime - System.currentTimeMillis();
2409                if (timeRemaining > 0) {
2410                    try {
2411                        mService.wait(timeRemaining);
2412                    } catch (InterruptedException e) {
2413                    }
2414                } else {
2415                    Slog.w(TAG, "Activity manager shutdown timed out");
2416                    timedout = true;
2417                    break;
2418                }
2419            } else {
2420                break;
2421            }
2422        }
2423
2424        // Force checkReadyForSleep to complete.
2425        mSleepTimeout = true;
2426        checkReadyForSleepLocked();
2427
2428        return timedout;
2429    }
2430
2431    void comeOutOfSleepIfNeededLocked() {
2432        removeSleepTimeouts();
2433        if (mGoingToSleep.isHeld()) {
2434            mGoingToSleep.release();
2435        }
2436        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2437            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2438            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2439                final ActivityStack stack = stacks.get(stackNdx);
2440                stack.awakeFromSleepingLocked();
2441                if (isFrontStack(stack)) {
2442                    resumeTopActivitiesLocked();
2443                }
2444            }
2445        }
2446        mGoingToSleepActivities.clear();
2447    }
2448
2449    void activitySleptLocked(ActivityRecord r) {
2450        mGoingToSleepActivities.remove(r);
2451        checkReadyForSleepLocked();
2452    }
2453
2454    void checkReadyForSleepLocked() {
2455        if (!mService.isSleepingOrShuttingDown()) {
2456            // Do not care.
2457            return;
2458        }
2459
2460        if (!mSleepTimeout) {
2461            boolean dontSleep = false;
2462            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2463                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2464                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2465                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2466                }
2467            }
2468
2469            if (mStoppingActivities.size() > 0) {
2470                // Still need to tell some activities to stop; can't sleep yet.
2471                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2472                        + mStoppingActivities.size() + " activities");
2473                scheduleIdleLocked();
2474                dontSleep = true;
2475            }
2476
2477            if (mGoingToSleepActivities.size() > 0) {
2478                // Still need to tell some activities to sleep; can't sleep yet.
2479                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2480                        + mGoingToSleepActivities.size() + " activities");
2481                dontSleep = true;
2482            }
2483
2484            if (dontSleep) {
2485                return;
2486            }
2487        }
2488
2489        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2490            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2491            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2492                stacks.get(stackNdx).goToSleep();
2493            }
2494        }
2495
2496        removeSleepTimeouts();
2497
2498        if (mGoingToSleep.isHeld()) {
2499            mGoingToSleep.release();
2500        }
2501        if (mService.mShuttingDown) {
2502            mService.notifyAll();
2503        }
2504    }
2505
2506    boolean reportResumedActivityLocked(ActivityRecord r) {
2507        final ActivityStack stack = r.task.stack;
2508        if (isFrontStack(stack)) {
2509            mService.updateUsageStats(r, true);
2510        }
2511        if (allResumedActivitiesComplete()) {
2512            ensureActivitiesVisibleLocked(null, 0);
2513            mWindowManager.executeAppTransition();
2514            return true;
2515        }
2516        return false;
2517    }
2518
2519    void handleAppCrashLocked(ProcessRecord app) {
2520        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2521            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2522            final int numStacks = stacks.size();
2523            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2524                final ActivityStack stack = stacks.get(stackNdx);
2525                stack.handleAppCrashLocked(app);
2526            }
2527        }
2528    }
2529
2530    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2531        // First the front stacks. In case any are not fullscreen and are in front of home.
2532        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2533            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2534            final int topStackNdx = stacks.size() - 1;
2535            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2536                final ActivityStack stack = stacks.get(stackNdx);
2537                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2538            }
2539        }
2540    }
2541
2542    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2543        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2544            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2545            final int numStacks = stacks.size();
2546            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2547                final ActivityStack stack = stacks.get(stackNdx);
2548                stack.scheduleDestroyActivities(app, false, reason);
2549            }
2550        }
2551    }
2552
2553    boolean switchUserLocked(int userId, UserStartedState uss) {
2554        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2555        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2556        mCurrentUser = userId;
2557
2558        mStartingUsers.add(uss);
2559        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2560            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2561            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2562                final ActivityStack stack = stacks.get(stackNdx);
2563                stack.switchUserLocked(userId);
2564                TaskRecord task = stack.topTask();
2565                if (task != null) {
2566                    mWindowManager.moveTaskToTop(task.taskId);
2567                }
2568            }
2569        }
2570
2571        ActivityStack stack = getStack(restoreStackId);
2572        if (stack == null) {
2573            stack = mHomeStack;
2574        }
2575        final boolean homeInFront = stack.isHomeStack();
2576        if (stack.isOnHomeDisplay()) {
2577            moveHomeStack(homeInFront);
2578            TaskRecord task = stack.topTask();
2579            if (task != null) {
2580                mWindowManager.moveTaskToTop(task.taskId);
2581            }
2582        } else {
2583            // Stack was moved to another display while user was swapped out.
2584            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2585        }
2586        return homeInFront;
2587    }
2588
2589    /**
2590     * Add background users to send boot completed events to.
2591     * @param userId The user being started in the background
2592     * @param uss The state object for the user.
2593     */
2594    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
2595        mStartingBackgroundUsers.add(uss);
2596    }
2597
2598    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2599        int N = mStoppingActivities.size();
2600        if (N <= 0) return null;
2601
2602        ArrayList<ActivityRecord> stops = null;
2603
2604        final boolean nowVisible = allResumedActivitiesVisible();
2605        for (int i=0; i<N; i++) {
2606            ActivityRecord s = mStoppingActivities.get(i);
2607            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2608                    + nowVisible + " waitingVisible=" + s.waitingVisible
2609                    + " finishing=" + s.finishing);
2610            if (s.waitingVisible && nowVisible) {
2611                mWaitingVisibleActivities.remove(s);
2612                s.waitingVisible = false;
2613                if (s.finishing) {
2614                    // If this activity is finishing, it is sitting on top of
2615                    // everyone else but we now know it is no longer needed...
2616                    // so get rid of it.  Otherwise, we need to go through the
2617                    // normal flow and hide it once we determine that it is
2618                    // hidden by the activities in front of it.
2619                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2620                    mWindowManager.setAppVisibility(s.appToken, false);
2621                }
2622            }
2623            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2624                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2625                if (stops == null) {
2626                    stops = new ArrayList<ActivityRecord>();
2627                }
2628                stops.add(s);
2629                mStoppingActivities.remove(i);
2630                N--;
2631                i--;
2632            }
2633        }
2634
2635        return stops;
2636    }
2637
2638    void validateTopActivitiesLocked() {
2639        // FIXME
2640/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2641            final ActivityStack stack = stacks.get(stackNdx);
2642            final ActivityRecord r = stack.topRunningActivityLocked(null);
2643            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2644            if (isFrontStack(stack)) {
2645                if (r == null) {
2646                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2647                } else {
2648                    final ActivityRecord pausing = stack.mPausingActivity;
2649                    if (pausing != null && pausing == r) {
2650                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2651                            " state=" + state);
2652                    }
2653                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2654                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2655                                " state=" + state);
2656                    }
2657                }
2658            } else {
2659                final ActivityRecord resumed = stack.mResumedActivity;
2660                if (resumed != null && resumed == r) {
2661                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2662                        " state=" + state);
2663                }
2664                if (r != null && (state == ActivityState.INITIALIZING
2665                        || state == ActivityState.RESUMED)) {
2666                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2667                            " state=" + state);
2668                }
2669            }
2670        }
2671*/
2672    }
2673
2674    public void dump(PrintWriter pw, String prefix) {
2675        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2676                pw.println(mDismissKeyguardOnNextActivity);
2677        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2678                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2679        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2680        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2681        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2682        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2683    }
2684
2685    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2686        return getFocusedStack().getDumpActivitiesLocked(name);
2687    }
2688
2689    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2690            boolean needSep, String prefix) {
2691        if (activity != null) {
2692            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2693                if (needSep) {
2694                    pw.println();
2695                }
2696                pw.print(prefix);
2697                pw.println(activity);
2698                return true;
2699            }
2700        }
2701        return false;
2702    }
2703
2704    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2705            boolean dumpClient, String dumpPackage) {
2706        boolean printed = false;
2707        boolean needSep = false;
2708        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2709            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2710            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2711            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2712            final int numStacks = stacks.size();
2713            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2714                final ActivityStack stack = stacks.get(stackNdx);
2715                StringBuilder stackHeader = new StringBuilder(128);
2716                stackHeader.append("  Stack #");
2717                stackHeader.append(stack.mStackId);
2718                stackHeader.append(":");
2719                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2720                        needSep, stackHeader.toString());
2721                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2722                        !dumpAll, false, dumpPackage, true,
2723                        "    Running activities (most recent first):", null);
2724
2725                needSep = printed;
2726                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2727                        "    mPausingActivity: ");
2728                if (pr) {
2729                    printed = true;
2730                    needSep = false;
2731                }
2732                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2733                        "    mResumedActivity: ");
2734                if (pr) {
2735                    printed = true;
2736                    needSep = false;
2737                }
2738                if (dumpAll) {
2739                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2740                            "    mLastPausedActivity: ");
2741                    if (pr) {
2742                        printed = true;
2743                        needSep = true;
2744                    }
2745                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2746                            needSep, "    mLastNoHistoryActivity: ");
2747                }
2748                needSep = printed;
2749            }
2750        }
2751
2752        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2753                false, dumpPackage, true, "  Activities waiting to finish:", null);
2754        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2755                false, dumpPackage, true, "  Activities waiting to stop:", null);
2756        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2757                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2758                null);
2759        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2760                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2761        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2762                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2763
2764        return printed;
2765    }
2766
2767    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2768            String prefix, String label, boolean complete, boolean brief, boolean client,
2769            String dumpPackage, boolean needNL, String header1, String header2) {
2770        TaskRecord lastTask = null;
2771        String innerPrefix = null;
2772        String[] args = null;
2773        boolean printed = false;
2774        for (int i=list.size()-1; i>=0; i--) {
2775            final ActivityRecord r = list.get(i);
2776            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2777                continue;
2778            }
2779            if (innerPrefix == null) {
2780                innerPrefix = prefix + "      ";
2781                args = new String[0];
2782            }
2783            printed = true;
2784            final boolean full = !brief && (complete || !r.isInHistory());
2785            if (needNL) {
2786                pw.println("");
2787                needNL = false;
2788            }
2789            if (header1 != null) {
2790                pw.println(header1);
2791                header1 = null;
2792            }
2793            if (header2 != null) {
2794                pw.println(header2);
2795                header2 = null;
2796            }
2797            if (lastTask != r.task) {
2798                lastTask = r.task;
2799                pw.print(prefix);
2800                pw.print(full ? "* " : "  ");
2801                pw.println(lastTask);
2802                if (full) {
2803                    lastTask.dump(pw, prefix + "  ");
2804                } else if (complete) {
2805                    // Complete + brief == give a summary.  Isn't that obvious?!?
2806                    if (lastTask.intent != null) {
2807                        pw.print(prefix); pw.print("  ");
2808                                pw.println(lastTask.intent.toInsecureStringWithClip());
2809                    }
2810                }
2811            }
2812            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2813            pw.print(" #"); pw.print(i); pw.print(": ");
2814            pw.println(r);
2815            if (full) {
2816                r.dump(pw, innerPrefix);
2817            } else if (complete) {
2818                // Complete + brief == give a summary.  Isn't that obvious?!?
2819                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2820                if (r.app != null) {
2821                    pw.print(innerPrefix); pw.println(r.app);
2822                }
2823            }
2824            if (client && r.app != null && r.app.thread != null) {
2825                // flush anything that is already in the PrintWriter since the thread is going
2826                // to write to the file descriptor directly
2827                pw.flush();
2828                try {
2829                    TransferPipe tp = new TransferPipe();
2830                    try {
2831                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2832                                r.appToken, innerPrefix, args);
2833                        // Short timeout, since blocking here can
2834                        // deadlock with the application.
2835                        tp.go(fd, 2000);
2836                    } finally {
2837                        tp.kill();
2838                    }
2839                } catch (IOException e) {
2840                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2841                } catch (RemoteException e) {
2842                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2843                }
2844                needNL = true;
2845            }
2846        }
2847        return printed;
2848    }
2849
2850    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2851        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2852        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2853        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2854    }
2855
2856    final void scheduleIdleLocked() {
2857        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2858    }
2859
2860    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2861        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2862        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2863    }
2864
2865    final void scheduleResumeTopActivities() {
2866        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2867            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2868        }
2869    }
2870
2871    void removeSleepTimeouts() {
2872        mSleepTimeout = false;
2873        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2874    }
2875
2876    final void scheduleSleepTimeout() {
2877        removeSleepTimeouts();
2878        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2879    }
2880
2881    @Override
2882    public void onDisplayAdded(int displayId) {
2883        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2884    }
2885
2886    @Override
2887    public void onDisplayRemoved(int displayId) {
2888        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2889    }
2890
2891    @Override
2892    public void onDisplayChanged(int displayId) {
2893        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2894    }
2895
2896    public void handleDisplayAddedLocked(int displayId) {
2897        boolean newDisplay;
2898        synchronized (mService) {
2899            newDisplay = mActivityDisplays.get(displayId) == null;
2900            if (newDisplay) {
2901                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2902                mActivityDisplays.put(displayId, activityDisplay);
2903            }
2904        }
2905        if (newDisplay) {
2906            mWindowManager.onDisplayAdded(displayId);
2907        }
2908    }
2909
2910    public void handleDisplayRemovedLocked(int displayId) {
2911        synchronized (mService) {
2912            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2913            if (activityDisplay != null) {
2914                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2915                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2916                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2917                }
2918                mActivityDisplays.remove(displayId);
2919            }
2920        }
2921        mWindowManager.onDisplayRemoved(displayId);
2922    }
2923
2924    public void handleDisplayChangedLocked(int displayId) {
2925        synchronized (mService) {
2926            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2927            if (activityDisplay != null) {
2928                // TODO: Update the bounds.
2929            }
2930        }
2931        mWindowManager.onDisplayChanged(displayId);
2932    }
2933
2934    StackInfo getStackInfo(ActivityStack stack) {
2935        StackInfo info = new StackInfo();
2936        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2937        info.displayId = Display.DEFAULT_DISPLAY;
2938        info.stackId = stack.mStackId;
2939
2940        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2941        final int numTasks = tasks.size();
2942        int[] taskIds = new int[numTasks];
2943        String[] taskNames = new String[numTasks];
2944        for (int i = 0; i < numTasks; ++i) {
2945            final TaskRecord task = tasks.get(i);
2946            taskIds[i] = task.taskId;
2947            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2948                    : task.realActivity != null ? task.realActivity.flattenToString()
2949                    : task.getTopActivity() != null ? task.getTopActivity().packageName
2950                    : "unknown";
2951        }
2952        info.taskIds = taskIds;
2953        info.taskNames = taskNames;
2954        return info;
2955    }
2956
2957    StackInfo getStackInfoLocked(int stackId) {
2958        ActivityStack stack = getStack(stackId);
2959        if (stack != null) {
2960            return getStackInfo(stack);
2961        }
2962        return null;
2963    }
2964
2965    ArrayList<StackInfo> getAllStackInfosLocked() {
2966        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2967        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2968            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2969            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2970                list.add(getStackInfo(stacks.get(ndx)));
2971            }
2972        }
2973        return list;
2974    }
2975
2976    void setLockTaskModeLocked(TaskRecord task) {
2977        final Message lockTaskMsg = Message.obtain();
2978        if (task == null) {
2979            // Take out of lock task mode.
2980            mLockTaskModeTask = null;
2981            lockTaskMsg.what = LOCK_TASK_END_MSG;
2982            mHandler.sendMessage(lockTaskMsg);
2983            return;
2984        }
2985        if (isLockTaskModeViolation(task)) {
2986            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2987            return;
2988        }
2989        mLockTaskModeTask = task;
2990        findTaskToMoveToFrontLocked(task, 0, null);
2991        resumeTopActivitiesLocked();
2992        lockTaskMsg.what = LOCK_TASK_START_MSG;
2993        mHandler.sendMessage(lockTaskMsg);
2994    }
2995
2996    boolean isLockTaskModeViolation(TaskRecord task) {
2997        return mLockTaskModeTask != null && mLockTaskModeTask != task;
2998    }
2999
3000    void endLockTaskModeIfTaskEnding(TaskRecord task) {
3001        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
3002            mLockTaskModeTask = null;
3003        }
3004    }
3005
3006    boolean isInLockTaskMode() {
3007        return mLockTaskModeTask != null;
3008    }
3009
3010    private final class ActivityStackSupervisorHandler extends Handler {
3011
3012        public ActivityStackSupervisorHandler(Looper looper) {
3013            super(looper);
3014        }
3015
3016        void activityIdleInternal(ActivityRecord r) {
3017            synchronized (mService) {
3018                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3019            }
3020        }
3021
3022        @Override
3023        public void handleMessage(Message msg) {
3024            switch (msg.what) {
3025                case IDLE_TIMEOUT_MSG: {
3026                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3027                    if (mService.mDidDexOpt) {
3028                        mService.mDidDexOpt = false;
3029                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3030                        nmsg.obj = msg.obj;
3031                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3032                        return;
3033                    }
3034                    // We don't at this point know if the activity is fullscreen,
3035                    // so we need to be conservative and assume it isn't.
3036                    activityIdleInternal((ActivityRecord)msg.obj);
3037                } break;
3038                case IDLE_NOW_MSG: {
3039                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3040                    activityIdleInternal((ActivityRecord)msg.obj);
3041                } break;
3042                case RESUME_TOP_ACTIVITY_MSG: {
3043                    synchronized (mService) {
3044                        resumeTopActivitiesLocked();
3045                    }
3046                } break;
3047                case SLEEP_TIMEOUT_MSG: {
3048                    synchronized (mService) {
3049                        if (mService.isSleepingOrShuttingDown()) {
3050                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3051                            mSleepTimeout = true;
3052                            checkReadyForSleepLocked();
3053                        }
3054                    }
3055                } break;
3056                case LAUNCH_TIMEOUT_MSG: {
3057                    if (mService.mDidDexOpt) {
3058                        mService.mDidDexOpt = false;
3059                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3060                        return;
3061                    }
3062                    synchronized (mService) {
3063                        if (mLaunchingActivity.isHeld()) {
3064                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3065                            if (VALIDATE_WAKE_LOCK_CALLER
3066                                    && Binder.getCallingUid() != Process.myUid()) {
3067                                throw new IllegalStateException("Calling must be system uid");
3068                            }
3069                            mLaunchingActivity.release();
3070                        }
3071                    }
3072                } break;
3073                case HANDLE_DISPLAY_ADDED: {
3074                    handleDisplayAddedLocked(msg.arg1);
3075                } break;
3076                case HANDLE_DISPLAY_CHANGED: {
3077                    handleDisplayChangedLocked(msg.arg1);
3078                } break;
3079                case HANDLE_DISPLAY_REMOVED: {
3080                    handleDisplayRemovedLocked(msg.arg1);
3081                } break;
3082                case CONTAINER_CALLBACK_VISIBILITY: {
3083                    final ActivityContainer container = (ActivityContainer) msg.obj;
3084                    try {
3085                        // We only send this message if mCallback is non-null.
3086                        container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1);
3087                    } catch (RemoteException e) {
3088                    }
3089                }
3090                case LOCK_TASK_START_MSG: {
3091                    // When lock task starts, we disable the status bars.
3092                    try {
3093                        if (getStatusBarService() != null) {
3094                            getStatusBarService().disable
3095                                (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK,
3096                                mToken, mService.mContext.getPackageName());
3097                        }
3098                    } catch (RemoteException ex) {
3099                        throw new RuntimeException(ex);
3100                    }
3101                    break;
3102                }
3103                case LOCK_TASK_END_MSG: {
3104                    // When lock task ends, we enable the status bars.
3105                    try {
3106                       if (getStatusBarService() != null) {
3107                           getStatusBarService().disable
3108                               (StatusBarManager.DISABLE_NONE,
3109                               mToken, mService.mContext.getPackageName());
3110                       }
3111                    } catch (RemoteException ex) {
3112                        throw new RuntimeException(ex);
3113                    }
3114                    break;
3115                }
3116            }
3117        }
3118    }
3119
3120    class ActivityContainer extends android.app.IActivityContainer.Stub {
3121        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3122                Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
3123        final int mStackId;
3124        IActivityContainerCallback mCallback = null;
3125        final ActivityStack mStack;
3126        ActivityRecord mParentActivity = null;
3127        String mIdString;
3128
3129        boolean mVisible = true;
3130
3131        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3132        ActivityDisplay mActivityDisplay;
3133
3134        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3135        final static int CONTAINER_STATE_NO_SURFACE = 1;
3136        final static int CONTAINER_STATE_FINISHING = 2;
3137        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3138
3139        ActivityContainer(int stackId) {
3140            synchronized (mService) {
3141                mStackId = stackId;
3142                mStack = new ActivityStack(this);
3143                mIdString = "ActivtyContainer{" + mStackId + "}";
3144                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3145            }
3146        }
3147
3148        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3149            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3150                    + " to display=" + activityDisplay);
3151            mActivityDisplay = activityDisplay;
3152            mStack.mDisplayId = activityDisplay.mDisplayId;
3153            mStack.mStacks = activityDisplay.mStacks;
3154
3155            activityDisplay.attachActivities(mStack);
3156            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3157        }
3158
3159        @Override
3160        public void attachToDisplay(int displayId) {
3161            synchronized (mService) {
3162                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3163                if (activityDisplay == null) {
3164                    return;
3165                }
3166                attachToDisplayLocked(activityDisplay);
3167            }
3168        }
3169
3170        @Override
3171        public int getDisplayId() {
3172            if (mActivityDisplay != null) {
3173                return mActivityDisplay.mDisplayId;
3174            }
3175            return -1;
3176        }
3177
3178        @Override
3179        public boolean injectEvent(InputEvent event) {
3180            final long origId = Binder.clearCallingIdentity();
3181            try {
3182                if (mActivityDisplay != null) {
3183                    return mInputManagerInternal.injectInputEvent(event,
3184                            mActivityDisplay.mDisplayId,
3185                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3186                }
3187                return false;
3188            } finally {
3189                Binder.restoreCallingIdentity(origId);
3190            }
3191        }
3192
3193        @Override
3194        public void release() {
3195            mContainerState = CONTAINER_STATE_FINISHING;
3196            mStack.finishAllActivitiesLocked();
3197            detachLocked();
3198            mWindowManager.removeStack(mStackId);
3199        }
3200
3201        private void detachLocked() {
3202            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3203                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3204            if (mActivityDisplay != null) {
3205                mActivityDisplay.detachActivitiesLocked(mStack);
3206                mActivityDisplay = null;
3207                mStack.mDisplayId = -1;
3208                mStack.mStacks = null;
3209                mWindowManager.detachStack(mStackId);
3210            }
3211        }
3212
3213        @Override
3214        public final int startActivity(Intent intent) {
3215            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3216            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3217                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3218            // TODO: Switch to user app stacks here.
3219            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3220            String mimeType = intent.getType();
3221            if (mimeType == null && intent.getData() != null
3222                    && "content".equals(intent.getData().getScheme())) {
3223                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3224            }
3225            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null,
3226                    null, null, null, null, userId, this);
3227        }
3228
3229        @Override
3230        public final int startActivityIntentSender(IIntentSender intentSender) {
3231            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3232
3233            if (!(intentSender instanceof PendingIntentRecord)) {
3234                throw new IllegalArgumentException("Bad PendingIntent object");
3235            }
3236
3237            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3238                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3239        }
3240
3241        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3242            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3243                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3244            if (resolvedType == null) {
3245                resolvedType = intent.getType();
3246                if (resolvedType == null && intent.getData() != null
3247                        && "content".equals(intent.getData().getScheme())) {
3248                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3249                }
3250            }
3251            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
3252            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3253                throw new SecurityException(
3254                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3255            }
3256        }
3257
3258        /** Throw a SecurityException if allowEmbedded is not true */
3259        @Override
3260        public final void checkEmbeddedAllowed(Intent intent) {
3261            checkEmbeddedAllowedInner(intent, null);
3262        }
3263
3264        /** Throw a SecurityException if allowEmbedded is not true */
3265        @Override
3266        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3267            if (!(intentSender instanceof PendingIntentRecord)) {
3268                throw new IllegalArgumentException("Bad PendingIntent object");
3269            }
3270            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3271            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3272                    pendingIntent.key.requestResolvedType);
3273        }
3274
3275        @Override
3276        public IBinder asBinder() {
3277            return this;
3278        }
3279
3280        @Override
3281        public void setSurface(Surface surface, int width, int height, int density) {
3282            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3283        }
3284
3285        ActivityStackSupervisor getOuter() {
3286            return ActivityStackSupervisor.this;
3287        }
3288
3289        boolean isAttached() {
3290            return mActivityDisplay != null;
3291        }
3292
3293        void getBounds(Point outBounds) {
3294            if (mActivityDisplay != null) {
3295                mActivityDisplay.getBounds(outBounds);
3296            } else {
3297                outBounds.set(0, 0);
3298            }
3299        }
3300
3301        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3302        void setVisible(boolean visible) {
3303            if (mVisible != visible) {
3304                mVisible = visible;
3305                if (mCallback != null) {
3306                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3307                            0 /* unused */, this).sendToTarget();
3308                }
3309            }
3310        }
3311
3312        void setDrawn() {
3313        }
3314
3315        // You can always start a new task on a regular ActivityStack.
3316        boolean isEligibleForNewTasks() {
3317            return true;
3318        }
3319
3320        @Override
3321        public String toString() {
3322            return mIdString + (mActivityDisplay == null ? "N" : "A");
3323        }
3324    }
3325
3326    private class VirtualActivityContainer extends ActivityContainer {
3327        Surface mSurface;
3328        boolean mDrawn = false;
3329
3330        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3331            super(getNextStackId());
3332            mParentActivity = parent;
3333            mCallback = callback;
3334            mContainerState = CONTAINER_STATE_NO_SURFACE;
3335            mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3336        }
3337
3338        @Override
3339        public void setSurface(Surface surface, int width, int height, int density) {
3340            super.setSurface(surface, width, height, density);
3341
3342            synchronized (mService) {
3343                final long origId = Binder.clearCallingIdentity();
3344                try {
3345                    setSurfaceLocked(surface, width, height, density);
3346                } finally {
3347                    Binder.restoreCallingIdentity(origId);
3348                }
3349            }
3350        }
3351
3352        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3353            if (mContainerState == CONTAINER_STATE_FINISHING) {
3354                return;
3355            }
3356            VirtualActivityDisplay virtualActivityDisplay =
3357                    (VirtualActivityDisplay) mActivityDisplay;
3358            if (virtualActivityDisplay == null) {
3359                virtualActivityDisplay =
3360                        new VirtualActivityDisplay(width, height, density);
3361                mActivityDisplay = virtualActivityDisplay;
3362                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3363                attachToDisplayLocked(virtualActivityDisplay);
3364            }
3365
3366            if (mSurface != null) {
3367                mSurface.release();
3368            }
3369
3370            mSurface = surface;
3371            if (surface != null) {
3372                mStack.resumeTopActivityLocked(null);
3373            } else {
3374                mContainerState = CONTAINER_STATE_NO_SURFACE;
3375                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3376                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3377                    mStack.startPausingLocked(false, true);
3378                }
3379            }
3380
3381            setSurfaceIfReady();
3382
3383            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3384                    + virtualActivityDisplay);
3385        }
3386
3387        @Override
3388        boolean isAttached() {
3389            return mSurface != null && super.isAttached();
3390        }
3391
3392        @Override
3393        void setDrawn() {
3394            synchronized (mService) {
3395                mDrawn = true;
3396                setSurfaceIfReady();
3397            }
3398        }
3399
3400        // Never start a new task on an ActivityView if it isn't explicitly specified.
3401        @Override
3402        boolean isEligibleForNewTasks() {
3403            return false;
3404        }
3405
3406        private void setSurfaceIfReady() {
3407            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn +
3408                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3409            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3410                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3411                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3412            }
3413        }
3414    }
3415
3416    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3417     * attached {@link ActivityStack}s */
3418    class ActivityDisplay {
3419        /** Actual Display this object tracks. */
3420        int mDisplayId;
3421        Display mDisplay;
3422        DisplayInfo mDisplayInfo = new DisplayInfo();
3423
3424        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3425         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3426        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3427
3428        ActivityDisplay() {
3429        }
3430
3431        ActivityDisplay(int displayId) {
3432            init(mDisplayManager.getDisplay(displayId));
3433        }
3434
3435        void init(Display display) {
3436            mDisplay = display;
3437            mDisplayId = display.getDisplayId();
3438            mDisplay.getDisplayInfo(mDisplayInfo);
3439        }
3440
3441        void attachActivities(ActivityStack stack) {
3442            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3443                    + mDisplayId);
3444            mStacks.add(stack);
3445        }
3446
3447        void detachActivitiesLocked(ActivityStack stack) {
3448            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3449                    + " from displayId=" + mDisplayId);
3450            mStacks.remove(stack);
3451        }
3452
3453        void getBounds(Point bounds) {
3454            mDisplay.getDisplayInfo(mDisplayInfo);
3455            bounds.x = mDisplayInfo.appWidth;
3456            bounds.y = mDisplayInfo.appHeight;
3457        }
3458
3459        @Override
3460        public String toString() {
3461            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3462        }
3463    }
3464
3465    class VirtualActivityDisplay extends ActivityDisplay {
3466        VirtualDisplay mVirtualDisplay;
3467
3468        VirtualActivityDisplay(int width, int height, int density) {
3469            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3470            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
3471                    width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3472                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3473
3474            init(mVirtualDisplay.getDisplay());
3475
3476            mWindowManager.handleDisplayAdded(mDisplayId);
3477        }
3478
3479        void setSurface(Surface surface) {
3480            if (mVirtualDisplay != null) {
3481                mVirtualDisplay.setSurface(surface);
3482            }
3483        }
3484
3485        @Override
3486        void detachActivitiesLocked(ActivityStack stack) {
3487            super.detachActivitiesLocked(stack);
3488            if (mVirtualDisplay != null) {
3489                mVirtualDisplay.release();
3490                mVirtualDisplay = null;
3491            }
3492        }
3493
3494        @Override
3495        public String toString() {
3496            return "VirtualActivityDisplay={" + mDisplayId + "}";
3497        }
3498    }
3499}
3500