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