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