ActivityStackSupervisor.java revision 740c3ac782675d190941b2ab1905e56f246c1b11
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.content.ReferrerIntent;
101import com.android.internal.os.TransferPipe;
102import com.android.internal.statusbar.IStatusBarService;
103import com.android.internal.widget.LockPatternUtils;
104import com.android.server.LocalServices;
105import com.android.server.am.ActivityStack.ActivityState;
106import com.android.server.wm.WindowManagerService;
107
108
109import java.io.FileDescriptor;
110import java.io.IOException;
111import java.io.PrintWriter;
112import java.util.ArrayList;
113import java.util.List;
114
115public final class ActivityStackSupervisor implements DisplayListener {
116    static final boolean DEBUG = ActivityManagerService.DEBUG || false;
117    static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
118    static final boolean DEBUG_APP = DEBUG || false;
119    static final boolean DEBUG_CONTAINERS = DEBUG || false;
120    static final boolean DEBUG_IDLE = DEBUG || false;
121    static final boolean DEBUG_RELEASE = DEBUG || false;
122    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
123    static final boolean DEBUG_SCREENSHOTS = DEBUG || false;
124    static final boolean DEBUG_STATES = DEBUG || false;
125    static final boolean DEBUG_VISIBLE_BEHIND = DEBUG || false;
126
127    public static final int HOME_STACK_ID = 0;
128
129    /** How long we wait until giving up on the last activity telling us it is idle. */
130    static final int IDLE_TIMEOUT = 10*1000;
131
132    /** How long we can hold the sleep wake lock before giving up. */
133    static final int SLEEP_TIMEOUT = 5*1000;
134
135    // How long we can hold the launch wake lock before giving up.
136    static final int LAUNCH_TIMEOUT = 10*1000;
137
138    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
139    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
140    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
141    static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
142    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
143    static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
144    static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
145    static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
146    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
147    static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
148    static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
149    static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
150    static final int CONTAINER_TASK_LIST_EMPTY_TIMEOUT = FIRST_SUPERVISOR_STACK_MSG + 12;
151    static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 13;
152
153    private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
154
155    private static final String LOCK_TASK_TAG = "Lock-to-App";
156
157    /** Status Bar Service **/
158    private IBinder mToken = new Binder();
159    private IStatusBarService mStatusBarService;
160    private IDevicePolicyManager mDevicePolicyManager;
161
162    // For debugging to make sure the caller when acquiring/releasing our
163    // wake lock is the system process.
164    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
165
166    final ActivityManagerService mService;
167
168    final ActivityStackSupervisorHandler mHandler;
169
170    /** Short cut */
171    WindowManagerService mWindowManager;
172    DisplayManager mDisplayManager;
173
174    /** Identifier counter for all ActivityStacks */
175    private int mLastStackId = HOME_STACK_ID;
176
177    /** Task identifier that activities are currently being started in.  Incremented each time a
178     * new task is created. */
179    private int mCurTaskId = 0;
180
181    /** The current user */
182    private int mCurrentUser;
183
184    /** The stack containing the launcher app. Assumed to always be attached to
185     * Display.DEFAULT_DISPLAY. */
186    private ActivityStack mHomeStack;
187
188    /** The stack currently receiving input or launching the next activity. */
189    private ActivityStack mFocusedStack;
190
191    /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
192     * been resumed. If stacks are changing position this will hold the old stack until the new
193     * stack becomes resumed after which it will be set to mFocusedStack. */
194    private ActivityStack mLastFocusedStack;
195
196    /** List of activities that are waiting for a new activity to become visible before completing
197     * whatever operation they are supposed to do. */
198    final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
199
200    /** List of processes waiting to find out about the next visible activity. */
201    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
202            new ArrayList<IActivityManager.WaitResult>();
203
204    /** List of processes waiting to find out about the next launched activity. */
205    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
206            new ArrayList<IActivityManager.WaitResult>();
207
208    /** List of activities that are ready to be stopped, but waiting for the next activity to
209     * settle down before doing so. */
210    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
211
212    /** List of activities that are ready to be finished, but waiting for the previous activity to
213     * settle down before doing so.  It contains ActivityRecord objects. */
214    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
215
216    /** List of activities that are in the process of going to sleep. */
217    final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
218
219    /** Used on user changes */
220    final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
221
222    /** Used to queue up any background users being started */
223    final ArrayList<UserStartedState> mStartingBackgroundUsers = new ArrayList<UserStartedState>();
224
225    /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
226     * is being brought in front of us. */
227    boolean mUserLeaving = false;
228
229    /** Set when we have taken too long waiting to go to sleep. */
230    boolean mSleepTimeout = false;
231
232    /** Indicates if we are running on a Leanback-only (TV) device. Only initialized after
233     * setWindowManager is called. **/
234    private boolean mLeanbackOnlyDevice;
235
236    /**
237     * We don't want to allow the device to go to sleep while in the process
238     * of launching an activity.  This is primarily to allow alarm intent
239     * receivers to launch an activity and get that to run before the device
240     * goes back to sleep.
241     */
242    PowerManager.WakeLock mLaunchingActivity;
243
244    /**
245     * Set when the system is going to sleep, until we have
246     * successfully paused the current activity and released our wake lock.
247     * At that point the system is allowed to actually sleep.
248     */
249    PowerManager.WakeLock mGoingToSleep;
250
251    /** Stack id of the front stack when user switched, indexed by userId. */
252    SparseIntArray mUserStackInFront = new SparseIntArray(2);
253
254    // TODO: Add listener for removal of references.
255    /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
256    private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
257
258    /** Mapping from displayId to display current state */
259    private final SparseArray<ActivityDisplay> mActivityDisplays =
260            new SparseArray<ActivityDisplay>();
261
262    InputManagerInternal mInputManagerInternal;
263
264    /** If non-null then the task specified remains in front and no other tasks may be started
265     * until the task exits or #stopLockTaskMode() is called. */
266    TaskRecord mLockTaskModeTask;
267    /** Whether lock task has been entered by an authorized app and cannot
268     * be exited. */
269    private boolean mLockTaskIsLocked;
270    /**
271     * Notifies the user when entering/exiting lock-task.
272     */
273    private LockTaskNotify mLockTaskNotify;
274
275    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
276            = new ArrayList<PendingActivityLaunch>();
277
278    /** Used to keep resumeTopActivityLocked() from being entered recursively */
279    boolean inResumeTopActivity;
280
281    /**
282     * Description of a request to start a new activity, which has been held
283     * due to app switches being disabled.
284     */
285    static class PendingActivityLaunch {
286        final ActivityRecord r;
287        final ActivityRecord sourceRecord;
288        final int startFlags;
289        final ActivityStack stack;
290
291        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
292                int _startFlags, ActivityStack _stack) {
293            r = _r;
294            sourceRecord = _sourceRecord;
295            startFlags = _startFlags;
296            stack = _stack;
297        }
298    }
299
300    public ActivityStackSupervisor(ActivityManagerService service) {
301        mService = service;
302        mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
303    }
304
305    /**
306     * At the time when the constructor runs, the power manager has not yet been
307     * initialized.  So we initialize our wakelocks afterwards.
308     */
309    void initPowerManagement() {
310        PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
311        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
312        mLaunchingActivity =
313                pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
314        mLaunchingActivity.setReferenceCounted(false);
315    }
316
317    // This function returns a IStatusBarService. The value is from ServiceManager.
318    // getService and is cached.
319    private IStatusBarService getStatusBarService() {
320        synchronized (mService) {
321            if (mStatusBarService == null) {
322                mStatusBarService = IStatusBarService.Stub.asInterface(
323                    ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
324                if (mStatusBarService == null) {
325                    Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
326                }
327            }
328            return mStatusBarService;
329        }
330    }
331
332    private IDevicePolicyManager getDevicePolicyManager() {
333        synchronized (mService) {
334            if (mDevicePolicyManager == null) {
335                mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
336                    ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE));
337                if (mDevicePolicyManager == null) {
338                    Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
339                }
340            }
341            return mDevicePolicyManager;
342        }
343    }
344
345    void setWindowManager(WindowManagerService wm) {
346        synchronized (mService) {
347            mWindowManager = wm;
348
349            mDisplayManager =
350                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
351            mDisplayManager.registerDisplayListener(this, null);
352
353            Display[] displays = mDisplayManager.getDisplays();
354            for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
355                final int displayId = displays[displayNdx].getDisplayId();
356                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
357                if (activityDisplay.mDisplay == null) {
358                    throw new IllegalStateException("Default Display does not exist");
359                }
360                mActivityDisplays.put(displayId, activityDisplay);
361            }
362
363            createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
364            mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
365
366            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
367
368            // Initialize this here, now that we can get a valid reference to PackageManager.
369            mLeanbackOnlyDevice = isLeanbackOnlyDevice();
370        }
371    }
372
373    void notifyActivityDrawnForKeyguard() {
374        if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
375        mWindowManager.notifyActivityDrawnForKeyguard();
376    }
377
378    ActivityStack getFocusedStack() {
379        return mFocusedStack;
380    }
381
382    ActivityStack getLastStack() {
383        return mLastFocusedStack;
384    }
385
386    // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
387    // top of all visible stacks.
388    boolean isFrontStack(ActivityStack stack) {
389        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
390        if (parent != null) {
391            stack = parent.task.stack;
392        }
393        ArrayList<ActivityStack> stacks = stack.mStacks;
394        if (stacks != null && !stacks.isEmpty()) {
395            return stack == stacks.get(stacks.size() - 1);
396        }
397        return false;
398    }
399
400    void moveHomeStack(boolean toFront) {
401        ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
402        int topNdx = stacks.size() - 1;
403        if (topNdx <= 0) {
404            return;
405        }
406        ActivityStack topStack = stacks.get(topNdx);
407        final boolean homeInFront = topStack == mHomeStack;
408        if (homeInFront != toFront) {
409            mLastFocusedStack = topStack;
410            stacks.remove(mHomeStack);
411            stacks.add(toFront ? topNdx : 0, mHomeStack);
412            mFocusedStack = stacks.get(topNdx);
413            if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
414                    + mFocusedStack);
415        }
416    }
417
418    void moveHomeStackTaskToTop(int homeStackTaskType) {
419        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
420            mWindowManager.showRecentApps();
421            return;
422        }
423        moveHomeStack(true);
424        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
425    }
426
427    boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) {
428        if (!mService.mBooting && !mService.mBooted) {
429            // Not ready yet!
430            return false;
431        }
432
433        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
434            mWindowManager.showRecentApps();
435            return false;
436        }
437        moveHomeStackTaskToTop(homeStackTaskType);
438        if (prev != null) {
439            prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
440        }
441
442        ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
443        // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
444        if (r != null && r.isHomeActivity()) {
445            mService.setFocusedActivityLocked(r);
446            return resumeTopActivitiesLocked(mHomeStack, prev, null);
447        }
448        return mService.startHomeActivityLocked(mCurrentUser);
449    }
450
451    TaskRecord anyTaskForIdLocked(int id) {
452        int numDisplays = mActivityDisplays.size();
453        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
454            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
455            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
456                ActivityStack stack = stacks.get(stackNdx);
457                TaskRecord task = stack.taskForIdLocked(id);
458                if (task != null) {
459                    return task;
460                }
461            }
462        }
463        return null;
464    }
465
466    ActivityRecord isInAnyStackLocked(IBinder token) {
467        int numDisplays = mActivityDisplays.size();
468        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
469            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
470            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
471                final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
472                if (r != null) {
473                    return r;
474                }
475            }
476        }
477        return null;
478    }
479
480    void setNextTaskId(int taskId) {
481        if (taskId > mCurTaskId) {
482            mCurTaskId = taskId;
483        }
484    }
485
486    int getNextTaskId() {
487        do {
488            mCurTaskId++;
489            if (mCurTaskId <= 0) {
490                mCurTaskId = 1;
491            }
492        } while (anyTaskForIdLocked(mCurTaskId) != null);
493        return mCurTaskId;
494    }
495
496    ActivityRecord resumedAppLocked() {
497        ActivityStack stack = getFocusedStack();
498        if (stack == null) {
499            return null;
500        }
501        ActivityRecord resumedActivity = stack.mResumedActivity;
502        if (resumedActivity == null || resumedActivity.app == null) {
503            resumedActivity = stack.mPausingActivity;
504            if (resumedActivity == null || resumedActivity.app == null) {
505                resumedActivity = stack.topRunningActivityLocked(null);
506            }
507        }
508        return resumedActivity;
509    }
510
511    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
512        final String processName = app.processName;
513        boolean didSomething = false;
514        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
515            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
516            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
517                final ActivityStack stack = stacks.get(stackNdx);
518                if (!isFrontStack(stack)) {
519                    continue;
520                }
521                ActivityRecord hr = stack.topRunningActivityLocked(null);
522                if (hr != null) {
523                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
524                            && processName.equals(hr.processName)) {
525                        try {
526                            if (realStartActivityLocked(hr, app, true, true)) {
527                                didSomething = true;
528                            }
529                        } catch (RemoteException e) {
530                            Slog.w(TAG, "Exception in new application when starting activity "
531                                  + hr.intent.getComponent().flattenToShortString(), e);
532                            throw e;
533                        }
534                    }
535                }
536            }
537        }
538        if (!didSomething) {
539            ensureActivitiesVisibleLocked(null, 0);
540        }
541        return didSomething;
542    }
543
544    boolean allResumedActivitiesIdle() {
545        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
546            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
547            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
548                final ActivityStack stack = stacks.get(stackNdx);
549                if (!isFrontStack(stack) || stack.numActivities() == 0) {
550                    continue;
551                }
552                final ActivityRecord resumedActivity = stack.mResumedActivity;
553                if (resumedActivity == null || !resumedActivity.idle) {
554                    if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
555                             + stack.mStackId + " " + resumedActivity + " not idle");
556                    return false;
557                }
558            }
559        }
560        return true;
561    }
562
563    boolean allResumedActivitiesComplete() {
564        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
565            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
566            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
567                final ActivityStack stack = stacks.get(stackNdx);
568                if (isFrontStack(stack)) {
569                    final ActivityRecord r = stack.mResumedActivity;
570                    if (r != null && r.state != ActivityState.RESUMED) {
571                        return false;
572                    }
573                }
574            }
575        }
576        // TODO: Not sure if this should check if all Paused are complete too.
577        if (DEBUG_STACK) Slog.d(TAG,
578                "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
579                mLastFocusedStack + " to=" + mFocusedStack);
580        mLastFocusedStack = mFocusedStack;
581        return true;
582    }
583
584    boolean allResumedActivitiesVisible() {
585        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
586            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
587            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
588                final ActivityStack stack = stacks.get(stackNdx);
589                final ActivityRecord r = stack.mResumedActivity;
590                if (r != null && (!r.nowVisible || r.waitingVisible)) {
591                    return false;
592                }
593            }
594        }
595        return true;
596    }
597
598    /**
599     * Pause all activities in either all of the stacks or just the back stacks.
600     * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
601     * @return true if any activity was paused as a result of this call.
602     */
603    boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
604        boolean someActivityPaused = false;
605        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
606            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
607            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
608                final ActivityStack stack = stacks.get(stackNdx);
609                if (!isFrontStack(stack) && stack.mResumedActivity != null) {
610                    if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
611                            " mResumedActivity=" + stack.mResumedActivity);
612                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
613                            dontWait);
614                }
615            }
616        }
617        return someActivityPaused;
618    }
619
620    boolean allPausedActivitiesComplete() {
621        boolean pausing = true;
622        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
623            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
624            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
625                final ActivityStack stack = stacks.get(stackNdx);
626                final ActivityRecord r = stack.mPausingActivity;
627                if (r != null && r.state != ActivityState.PAUSED
628                        && r.state != ActivityState.STOPPED
629                        && r.state != ActivityState.STOPPING) {
630                    if (DEBUG_STATES) {
631                        Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
632                        pausing = false;
633                    } else {
634                        return false;
635                    }
636                }
637            }
638        }
639        return pausing;
640    }
641
642    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
643            boolean resuming, boolean dontWait) {
644        // TODO: Put all stacks in supervisor and iterate through them instead.
645        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
646            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
647            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
648                final ActivityStack stack = stacks.get(stackNdx);
649                if (stack.mResumedActivity != null &&
650                        stack.mActivityContainer.mParentActivity == parent) {
651                    stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
652                }
653            }
654        }
655    }
656
657    void reportActivityVisibleLocked(ActivityRecord r) {
658        sendWaitingVisibleReportLocked(r);
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<ReferrerIntent> 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.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
1159                    r.icicle, r.persistentState, results, newIntents, !andResume,
1160                    mService.isNextTransitionForward(), 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                    boolean movedToFront = false;
1835                    if (curTop != null && (curTop.task != intentActivity.task ||
1836                            curTop.task != lastStack.topTask())) {
1837                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1838                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1839                                sourceStack.topActivity().task == sourceRecord.task)) {
1840                            // We really do want to push this one into the
1841                            // user's face, right now.
1842                            if (launchTaskBehind && sourceRecord != null) {
1843                                intentActivity.setTaskToAffiliateWith(sourceRecord.task);
1844                            }
1845                            movedHome = true;
1846                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1847                            if ((launchFlags &
1848                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1849                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1850                                // Caller wants to appear on home activity.
1851                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1852                            }
1853                            options = null;
1854                            movedToFront = true;
1855                        }
1856                    }
1857                    // If the caller has requested that the target task be
1858                    // reset, then do so.
1859                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1860                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1861                    }
1862                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1863                        // We don't need to start a new activity, and
1864                        // the client said not to do anything if that
1865                        // is the case, so this is it!  And for paranoia, make
1866                        // sure we have correctly resumed the top activity.
1867                        if (doResume) {
1868                            resumeTopActivitiesLocked(targetStack, null, options);
1869
1870                            // Make sure to notify Keyguard as well if we are not running an app
1871                            // transition later.
1872                            if (!movedToFront) {
1873                                notifyActivityDrawnForKeyguard();
1874                            }
1875                        } else {
1876                            ActivityOptions.abort(options);
1877                        }
1878                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1879                    }
1880                    if ((launchFlags &
1881                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1882                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1883                        // The caller has requested to completely replace any
1884                        // existing task with its new activity.  Well that should
1885                        // not be too hard...
1886                        reuseTask = intentActivity.task;
1887                        reuseTask.performClearTaskLocked();
1888                        reuseTask.setIntent(r);
1889                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1890                            || launchSingleInstance || launchSingleTask) {
1891                        // In this situation we want to remove all activities
1892                        // from the task up to the one being started.  In most
1893                        // cases this means we are resetting the task to its
1894                        // initial state.
1895                        ActivityRecord top =
1896                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1897                        if (top != null) {
1898                            if (top.frontOfTask) {
1899                                // Activity aliases may mean we use different
1900                                // intents for the top activity, so make sure
1901                                // the task now has the identity of the new
1902                                // intent.
1903                                top.task.setIntent(r);
1904                            }
1905                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1906                                    r, top.task);
1907                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
1908                        } else {
1909                            // A special case: we need to
1910                            // start the activity because it is not currently
1911                            // running, and the caller has asked to clear the
1912                            // current task to have this activity at the top.
1913                            addingToTask = true;
1914                            // Now pretend like this activity is being started
1915                            // by the top of its task, so it is put in the
1916                            // right place.
1917                            sourceRecord = intentActivity;
1918                        }
1919                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1920                        // In this case the top activity on the task is the
1921                        // same as the one being launched, so we take that
1922                        // as a request to bring the task to the foreground.
1923                        // If the top activity in the task is the root
1924                        // activity, deliver this new intent to it if it
1925                        // desires.
1926                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
1927                                && intentActivity.realActivity.equals(r.realActivity)) {
1928                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1929                                    intentActivity.task);
1930                            if (intentActivity.frontOfTask) {
1931                                intentActivity.task.setIntent(r);
1932                            }
1933                            intentActivity.deliverNewIntentLocked(callingUid, r.intent,
1934                                    r.launchedFromPackage);
1935                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1936                            // In this case we are launching the root activity
1937                            // of the task, but with a different intent.  We
1938                            // should start a new instance on top.
1939                            addingToTask = true;
1940                            sourceRecord = intentActivity;
1941                        }
1942                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1943                        // In this case an activity is being launched in to an
1944                        // existing task, without resetting that task.  This
1945                        // is typically the situation of launching an activity
1946                        // from a notification or shortcut.  We want to place
1947                        // the new activity on top of the current task.
1948                        addingToTask = true;
1949                        sourceRecord = intentActivity;
1950                    } else if (!intentActivity.task.rootWasReset) {
1951                        // In this case we are launching in to an existing task
1952                        // that has not yet been started from its front door.
1953                        // The current task has been brought to the front.
1954                        // Ideally, we'd probably like to place this new task
1955                        // at the bottom of its stack, but that's a little hard
1956                        // to do with the current organization of the code so
1957                        // for now we'll just drop it.
1958                        intentActivity.task.setIntent(r);
1959                    }
1960                    if (!addingToTask && reuseTask == null) {
1961                        // We didn't do anything...  but it was needed (a.k.a., client
1962                        // don't use that intent!)  And for paranoia, make
1963                        // sure we have correctly resumed the top activity.
1964                        if (doResume) {
1965                            targetStack.resumeTopActivityLocked(null, options);
1966                            if (!movedToFront) {
1967                                // Make sure to notify Keyguard as well if we are not running an app
1968                                // transition later.
1969                                notifyActivityDrawnForKeyguard();
1970                            }
1971                        } else {
1972                            ActivityOptions.abort(options);
1973                        }
1974                        return ActivityManager.START_TASK_TO_FRONT;
1975                    }
1976                }
1977            }
1978        }
1979
1980        //String uri = r.intent.toURI();
1981        //Intent intent2 = new Intent(uri);
1982        //Slog.i(TAG, "Given intent: " + r.intent);
1983        //Slog.i(TAG, "URI is: " + uri);
1984        //Slog.i(TAG, "To intent: " + intent2);
1985
1986        if (r.packageName != null) {
1987            // If the activity being launched is the same as the one currently
1988            // at the top, then we need to check if it should only be launched
1989            // once.
1990            ActivityStack topStack = getFocusedStack();
1991            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1992            if (top != null && r.resultTo == null) {
1993                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1994                    if (top.app != null && top.app.thread != null) {
1995                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1996                            || launchSingleTop || launchSingleTask) {
1997                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1998                                    top.task);
1999                            // For paranoia, make sure we have correctly
2000                            // resumed the top activity.
2001                            topStack.mLastPausedActivity = null;
2002                            if (doResume) {
2003                                resumeTopActivitiesLocked();
2004                            }
2005                            ActivityOptions.abort(options);
2006                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2007                                // We don't need to start a new activity, and
2008                                // the client said not to do anything if that
2009                                // is the case, so this is it!
2010                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2011                            }
2012                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2013                            return ActivityManager.START_DELIVERED_TO_TOP;
2014                        }
2015                    }
2016                }
2017            }
2018
2019        } else {
2020            if (r.resultTo != null) {
2021                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
2022                        r.requestCode, Activity.RESULT_CANCELED, null);
2023            }
2024            ActivityOptions.abort(options);
2025            return ActivityManager.START_CLASS_NOT_FOUND;
2026        }
2027
2028        boolean newTask = false;
2029        boolean keepCurTransition = false;
2030
2031        TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
2032                sourceRecord.task : null;
2033
2034        // Should this be considered a new task?
2035        if (r.resultTo == null && inTask == null && !addingToTask
2036                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
2037            if (isLockTaskModeViolation(reuseTask)) {
2038                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2039                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2040            }
2041            newTask = true;
2042            targetStack = adjustStackFocus(r, newTask);
2043            if (!launchTaskBehind) {
2044                targetStack.moveToFront();
2045            }
2046            if (reuseTask == null) {
2047                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
2048                        newTaskInfo != null ? newTaskInfo : r.info,
2049                        newTaskIntent != null ? newTaskIntent : intent,
2050                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
2051                        taskToAffiliate);
2052                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
2053                        r.task);
2054            } else {
2055                r.setTask(reuseTask, taskToAffiliate);
2056            }
2057            if (!movedHome) {
2058                if ((launchFlags &
2059                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
2060                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
2061                    // Caller wants to appear on home activity, so before starting
2062                    // their own activity we will bring home to the front.
2063                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2064                }
2065            }
2066        } else if (sourceRecord != null) {
2067            final TaskRecord sourceTask = sourceRecord.task;
2068            if (isLockTaskModeViolation(sourceTask)) {
2069                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2070                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2071            }
2072            targetStack = sourceTask.stack;
2073            targetStack.moveToFront();
2074            final TaskRecord topTask = targetStack.topTask();
2075            if (topTask != sourceTask) {
2076                targetStack.moveTaskToFrontLocked(sourceTask, r, options);
2077            } else {
2078                mWindowManager.moveTaskToTop(topTask.taskId);
2079            }
2080            if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2081                // In this case, we are adding the activity to an existing
2082                // task, but the caller has asked to clear that task if the
2083                // activity is already running.
2084                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
2085                keepCurTransition = true;
2086                if (top != null) {
2087                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
2088                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2089                    // For paranoia, make sure we have correctly
2090                    // resumed the top activity.
2091                    targetStack.mLastPausedActivity = null;
2092                    if (doResume) {
2093                        targetStack.resumeTopActivityLocked(null);
2094                    }
2095                    ActivityOptions.abort(options);
2096                    return ActivityManager.START_DELIVERED_TO_TOP;
2097                }
2098            } else if (!addingToTask &&
2099                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2100                // In this case, we are launching an activity in our own task
2101                // that may already be running somewhere in the history, and
2102                // we want to shuffle it to the front of the stack if so.
2103                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
2104                if (top != null) {
2105                    final TaskRecord task = top.task;
2106                    task.moveActivityToFrontLocked(top);
2107                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
2108                    top.updateOptionsLocked(options);
2109                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2110                    targetStack.mLastPausedActivity = null;
2111                    if (doResume) {
2112                        targetStack.resumeTopActivityLocked(null);
2113                    }
2114                    return ActivityManager.START_DELIVERED_TO_TOP;
2115                }
2116            }
2117            // An existing activity is starting this new activity, so we want
2118            // to keep the new one in the same task as the one that is starting
2119            // it.
2120            r.setTask(sourceTask, null);
2121            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
2122                    + " in existing task " + r.task + " from source " + sourceRecord);
2123
2124        } else if (inTask != null) {
2125            // The calling is asking that the new activity be started in an explicit
2126            // task it has provided to us.
2127            if (isLockTaskModeViolation(inTask)) {
2128                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2129                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2130            }
2131            targetStack = inTask.stack;
2132            targetStack.moveTaskToFrontLocked(inTask, r, options);
2133            targetStack.moveToFront();
2134            mWindowManager.moveTaskToTop(inTask.taskId);
2135
2136            // Check whether we should actually launch the new activity in to the task,
2137            // or just reuse the current activity on top.
2138            ActivityRecord top = inTask.getTopActivity();
2139            if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2140                if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2141                        || launchSingleTop || launchSingleTask) {
2142                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
2143                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2144                        // We don't need to start a new activity, and
2145                        // the client said not to do anything if that
2146                        // is the case, so this is it!
2147                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2148                    }
2149                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2150                    return ActivityManager.START_DELIVERED_TO_TOP;
2151                }
2152            }
2153
2154            if (!addingToTask) {
2155                // We don't actually want to have this activity added to the task, so just
2156                // stop here but still tell the caller that we consumed the intent.
2157                ActivityOptions.abort(options);
2158                return ActivityManager.START_TASK_TO_FRONT;
2159            }
2160
2161            r.setTask(inTask, null);
2162            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
2163                    + " in explicit task " + r.task);
2164
2165        } else {
2166            // This not being started from an existing activity, and not part
2167            // of a new task...  just put it in the top task, though these days
2168            // this case should never happen.
2169            targetStack = adjustStackFocus(r, newTask);
2170            targetStack.moveToFront();
2171            ActivityRecord prev = targetStack.topActivity();
2172            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
2173                            r.info, intent, null, null, true), null);
2174            mWindowManager.moveTaskToTop(r.task.taskId);
2175            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
2176                    + " in new guessed " + r.task);
2177        }
2178
2179        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2180                intent, r.getUriPermissionsLocked(), r.userId);
2181
2182        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
2183            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
2184        }
2185        if (newTask) {
2186            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
2187        }
2188        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
2189        targetStack.mLastPausedActivity = null;
2190        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
2191        if (!launchTaskBehind) {
2192            // Don't set focus on an activity that's going to the back.
2193            mService.setFocusedActivityLocked(r);
2194        }
2195        return ActivityManager.START_SUCCESS;
2196    }
2197
2198    final void doPendingActivityLaunchesLocked(boolean doResume) {
2199        while (!mPendingActivityLaunches.isEmpty()) {
2200            PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
2201            startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
2202                    doResume && mPendingActivityLaunches.isEmpty(), null, null);
2203        }
2204    }
2205
2206    void removePendingActivityLaunchesLocked(ActivityStack stack) {
2207        for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
2208            PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
2209            if (pal.stack == stack) {
2210                mPendingActivityLaunches.remove(palNdx);
2211            }
2212        }
2213    }
2214
2215    void acquireLaunchWakelock() {
2216        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2217            throw new IllegalStateException("Calling must be system uid");
2218        }
2219        mLaunchingActivity.acquire();
2220        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2221            // To be safe, don't allow the wake lock to be held for too long.
2222            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2223        }
2224    }
2225
2226    // Checked.
2227    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2228            Configuration config) {
2229        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
2230
2231        ArrayList<ActivityRecord> stops = null;
2232        ArrayList<ActivityRecord> finishes = null;
2233        ArrayList<UserStartedState> startingUsers = null;
2234        int NS = 0;
2235        int NF = 0;
2236        boolean booting = false;
2237        boolean enableScreen = false;
2238        boolean activityRemoved = false;
2239
2240        ActivityRecord r = ActivityRecord.forToken(token);
2241        if (r != null) {
2242            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
2243                    Debug.getCallers(4));
2244            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2245            r.finishLaunchTickingLocked();
2246            if (fromTimeout) {
2247                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2248            }
2249
2250            // This is a hack to semi-deal with a race condition
2251            // in the client where it can be constructed with a
2252            // newer configuration from when we asked it to launch.
2253            // We'll update with whatever configuration it now says
2254            // it used to launch.
2255            if (config != null) {
2256                r.configuration = config;
2257            }
2258
2259            // We are now idle.  If someone is waiting for a thumbnail from
2260            // us, we can now deliver.
2261            r.idle = true;
2262
2263            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2264            if (isFrontStack(r.task.stack) || fromTimeout) {
2265                booting = mService.mBooting;
2266                mService.mBooting = false;
2267                if (!mService.mBooted) {
2268                    mService.mBooted = true;
2269                    enableScreen = true;
2270                }
2271            }
2272        }
2273
2274        if (allResumedActivitiesIdle()) {
2275            if (r != null) {
2276                mService.scheduleAppGcsLocked();
2277            }
2278
2279            if (mLaunchingActivity.isHeld()) {
2280                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2281                if (VALIDATE_WAKE_LOCK_CALLER &&
2282                        Binder.getCallingUid() != Process.myUid()) {
2283                    throw new IllegalStateException("Calling must be system uid");
2284                }
2285                mLaunchingActivity.release();
2286            }
2287            ensureActivitiesVisibleLocked(null, 0);
2288        }
2289
2290        // Atomically retrieve all of the other things to do.
2291        stops = processStoppingActivitiesLocked(true);
2292        NS = stops != null ? stops.size() : 0;
2293        if ((NF=mFinishingActivities.size()) > 0) {
2294            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
2295            mFinishingActivities.clear();
2296        }
2297
2298        if (mStartingUsers.size() > 0) {
2299            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
2300            mStartingUsers.clear();
2301        }
2302
2303        // Stop any activities that are scheduled to do so but have been
2304        // waiting for the next one to start.
2305        for (int i = 0; i < NS; i++) {
2306            r = stops.get(i);
2307            final ActivityStack stack = r.task.stack;
2308            if (r.finishing) {
2309                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2310            } else {
2311                stack.stopActivityLocked(r);
2312            }
2313        }
2314
2315        // Finish any activities that are scheduled to do so but have been
2316        // waiting for the next one to start.
2317        for (int i = 0; i < NF; i++) {
2318            r = finishes.get(i);
2319            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle");
2320        }
2321
2322        if (!booting) {
2323            // Complete user switch
2324            if (startingUsers != null) {
2325                for (int i = 0; i < startingUsers.size(); i++) {
2326                    mService.finishUserSwitch(startingUsers.get(i));
2327                }
2328            }
2329            // Complete starting up of background users
2330            if (mStartingBackgroundUsers.size() > 0) {
2331                startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
2332                mStartingBackgroundUsers.clear();
2333                for (int i = 0; i < startingUsers.size(); i++) {
2334                    mService.finishUserBoot(startingUsers.get(i));
2335                }
2336            }
2337        }
2338
2339        mService.trimApplications();
2340        //dump();
2341        //mWindowManager.dump();
2342
2343        if (booting || enableScreen) {
2344            mService.postFinishBooting(booting, enableScreen);
2345        }
2346
2347        if (activityRemoved) {
2348            resumeTopActivitiesLocked();
2349        }
2350
2351        return r;
2352    }
2353
2354    boolean handleAppDiedLocked(ProcessRecord app) {
2355        boolean hasVisibleActivities = false;
2356        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2357            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2358            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2359                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2360            }
2361        }
2362        return hasVisibleActivities;
2363    }
2364
2365    void closeSystemDialogsLocked() {
2366        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2367            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2368            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2369                stacks.get(stackNdx).closeSystemDialogsLocked();
2370            }
2371        }
2372    }
2373
2374    void removeUserLocked(int userId) {
2375        mUserStackInFront.delete(userId);
2376    }
2377
2378    /**
2379     * @return true if some activity was finished (or would have finished if doit were true).
2380     */
2381    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2382        boolean didSomething = false;
2383        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2384            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2385            final int numStacks = stacks.size();
2386            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2387                final ActivityStack stack = stacks.get(stackNdx);
2388                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2389                    didSomething = true;
2390                }
2391            }
2392        }
2393        return didSomething;
2394    }
2395
2396    void updatePreviousProcessLocked(ActivityRecord r) {
2397        // Now that this process has stopped, we may want to consider
2398        // it to be the previous app to try to keep around in case
2399        // the user wants to return to it.
2400
2401        // First, found out what is currently the foreground app, so that
2402        // we don't blow away the previous app if this activity is being
2403        // hosted by the process that is actually still the foreground.
2404        ProcessRecord fgApp = null;
2405        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2406            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2407            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2408                final ActivityStack stack = stacks.get(stackNdx);
2409                if (isFrontStack(stack)) {
2410                    if (stack.mResumedActivity != null) {
2411                        fgApp = stack.mResumedActivity.app;
2412                    } else if (stack.mPausingActivity != null) {
2413                        fgApp = stack.mPausingActivity.app;
2414                    }
2415                    break;
2416                }
2417            }
2418        }
2419
2420        // Now set this one as the previous process, only if that really
2421        // makes sense to.
2422        if (r.app != null && fgApp != null && r.app != fgApp
2423                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2424                && r.app != mService.mHomeProcess) {
2425            mService.mPreviousProcess = r.app;
2426            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2427        }
2428    }
2429
2430    boolean resumeTopActivitiesLocked() {
2431        return resumeTopActivitiesLocked(null, null, null);
2432    }
2433
2434    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2435            Bundle targetOptions) {
2436        if (targetStack == null) {
2437            targetStack = getFocusedStack();
2438        }
2439        // Do targetStack first.
2440        boolean result = false;
2441        if (isFrontStack(targetStack)) {
2442            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2443        }
2444        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2445            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2446            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2447                final ActivityStack stack = stacks.get(stackNdx);
2448                if (stack == targetStack) {
2449                    // Already started above.
2450                    continue;
2451                }
2452                if (isFrontStack(stack)) {
2453                    stack.resumeTopActivityLocked(null);
2454                }
2455            }
2456        }
2457        return result;
2458    }
2459
2460    void finishTopRunningActivityLocked(ProcessRecord app) {
2461        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2462            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2463            final int numStacks = stacks.size();
2464            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2465                final ActivityStack stack = stacks.get(stackNdx);
2466                stack.finishTopRunningActivityLocked(app);
2467            }
2468        }
2469    }
2470
2471    void finishVoiceTask(IVoiceInteractionSession session) {
2472        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2473            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2474            final int numStacks = stacks.size();
2475            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2476                final ActivityStack stack = stacks.get(stackNdx);
2477                stack.finishVoiceTask(session);
2478            }
2479        }
2480    }
2481
2482    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2483        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2484            mUserLeaving = true;
2485        }
2486        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2487            // Caller wants the home activity moved with it.  To accomplish this,
2488            // we'll just indicate that this task returns to the home task.
2489            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2490        }
2491        task.stack.moveTaskToFrontLocked(task, null, options);
2492        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2493                + task.stack);
2494    }
2495
2496    ActivityStack getStack(int stackId) {
2497        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2498        if (activityContainer != null) {
2499            return activityContainer.mStack;
2500        }
2501        return null;
2502    }
2503
2504    ArrayList<ActivityStack> getStacks() {
2505        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2506        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2507            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2508        }
2509        return allStacks;
2510    }
2511
2512    IBinder getHomeActivityToken() {
2513        ActivityRecord homeActivity = getHomeActivity();
2514        if (homeActivity != null) {
2515            return homeActivity.appToken;
2516        }
2517        return null;
2518    }
2519
2520    ActivityRecord getHomeActivity() {
2521        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2522        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2523            final TaskRecord task = tasks.get(taskNdx);
2524            if (task.isHomeTask()) {
2525                final ArrayList<ActivityRecord> activities = task.mActivities;
2526                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2527                    final ActivityRecord r = activities.get(activityNdx);
2528                    if (r.isHomeActivity()) {
2529                        return r;
2530                    }
2531                }
2532            }
2533        }
2534        return null;
2535    }
2536
2537    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2538            IActivityContainerCallback callback) {
2539        ActivityContainer activityContainer =
2540                new VirtualActivityContainer(parentActivity, callback);
2541        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2542        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
2543        parentActivity.mChildContainers.add(activityContainer);
2544        return activityContainer;
2545    }
2546
2547    void removeChildActivityContainers(ActivityRecord parentActivity) {
2548        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2549        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2550            ActivityContainer container = childStacks.remove(containerNdx);
2551            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
2552                    container);
2553            container.release();
2554        }
2555    }
2556
2557    void deleteActivityContainer(IActivityContainer container) {
2558        ActivityContainer activityContainer = (ActivityContainer)container;
2559        if (activityContainer != null) {
2560            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
2561                    new RuntimeException("here").fillInStackTrace());
2562            final int stackId = activityContainer.mStackId;
2563            mActivityContainers.remove(stackId);
2564            mWindowManager.removeStack(stackId);
2565        }
2566    }
2567
2568    private int createStackOnDisplay(int stackId, int displayId) {
2569        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2570        if (activityDisplay == null) {
2571            return -1;
2572        }
2573
2574        ActivityContainer activityContainer = new ActivityContainer(stackId);
2575        mActivityContainers.put(stackId, activityContainer);
2576        activityContainer.attachToDisplayLocked(activityDisplay);
2577        return stackId;
2578    }
2579
2580    int getNextStackId() {
2581        while (true) {
2582            if (++mLastStackId <= HOME_STACK_ID) {
2583                mLastStackId = HOME_STACK_ID + 1;
2584            }
2585            if (getStack(mLastStackId) == null) {
2586                break;
2587            }
2588        }
2589        return mLastStackId;
2590    }
2591
2592    void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) {
2593        int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2594        final ActivityStack stack = getStack(stackId);
2595        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2596            final TaskRecord task = tasks.get(taskNdx);
2597            stack.addTask(task, false, false);
2598            final int taskId = task.taskId;
2599            final ArrayList<ActivityRecord> activities = task.mActivities;
2600            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2601                final ActivityRecord r = activities.get(activityNdx);
2602                mWindowManager.addAppToken(0, r.appToken, taskId, stackId,
2603                        r.info.screenOrientation, r.fullscreen,
2604                        (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
2605                        r.userId, r.info.configChanges, task.voiceSession != null,
2606                        r.mLaunchTaskBehind);
2607            }
2608        }
2609    }
2610
2611    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2612        final TaskRecord task = anyTaskForIdLocked(taskId);
2613        if (task == null) {
2614            return;
2615        }
2616        final ActivityStack stack = getStack(stackId);
2617        if (stack == null) {
2618            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2619            return;
2620        }
2621        task.stack.removeTask(task);
2622        stack.addTask(task, toTop, true);
2623        mWindowManager.addTask(taskId, stackId, toTop);
2624        resumeTopActivitiesLocked();
2625    }
2626
2627    ActivityRecord findTaskLocked(ActivityRecord r) {
2628        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2629        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2630            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2631            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2632                final ActivityStack stack = stacks.get(stackNdx);
2633                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2634                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2635                    continue;
2636                }
2637                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2638                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2639                            stack);
2640                    continue;
2641                }
2642                final ActivityRecord ar = stack.findTaskLocked(r);
2643                if (ar != null) {
2644                    return ar;
2645                }
2646            }
2647        }
2648        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2649        return null;
2650    }
2651
2652    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2653        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2654            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2655            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2656                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2657                if (ar != null) {
2658                    return ar;
2659                }
2660            }
2661        }
2662        return null;
2663    }
2664
2665    void goingToSleepLocked() {
2666        scheduleSleepTimeout();
2667        if (!mGoingToSleep.isHeld()) {
2668            mGoingToSleep.acquire();
2669            if (mLaunchingActivity.isHeld()) {
2670                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2671                    throw new IllegalStateException("Calling must be system uid");
2672                }
2673                mLaunchingActivity.release();
2674                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2675            }
2676        }
2677        checkReadyForSleepLocked();
2678    }
2679
2680    boolean shutdownLocked(int timeout) {
2681        goingToSleepLocked();
2682
2683        boolean timedout = false;
2684        final long endTime = System.currentTimeMillis() + timeout;
2685        while (true) {
2686            boolean cantShutdown = false;
2687            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2688                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2689                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2690                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2691                }
2692            }
2693            if (cantShutdown) {
2694                long timeRemaining = endTime - System.currentTimeMillis();
2695                if (timeRemaining > 0) {
2696                    try {
2697                        mService.wait(timeRemaining);
2698                    } catch (InterruptedException e) {
2699                    }
2700                } else {
2701                    Slog.w(TAG, "Activity manager shutdown timed out");
2702                    timedout = true;
2703                    break;
2704                }
2705            } else {
2706                break;
2707            }
2708        }
2709
2710        // Force checkReadyForSleep to complete.
2711        mSleepTimeout = true;
2712        checkReadyForSleepLocked();
2713
2714        return timedout;
2715    }
2716
2717    void comeOutOfSleepIfNeededLocked() {
2718        removeSleepTimeouts();
2719        if (mGoingToSleep.isHeld()) {
2720            mGoingToSleep.release();
2721        }
2722        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2723            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2724            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2725                final ActivityStack stack = stacks.get(stackNdx);
2726                stack.awakeFromSleepingLocked();
2727                if (isFrontStack(stack)) {
2728                    resumeTopActivitiesLocked();
2729                }
2730            }
2731        }
2732        mGoingToSleepActivities.clear();
2733    }
2734
2735    void activitySleptLocked(ActivityRecord r) {
2736        mGoingToSleepActivities.remove(r);
2737        checkReadyForSleepLocked();
2738    }
2739
2740    void checkReadyForSleepLocked() {
2741        if (!mService.isSleepingOrShuttingDown()) {
2742            // Do not care.
2743            return;
2744        }
2745
2746        if (!mSleepTimeout) {
2747            boolean dontSleep = false;
2748            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2749                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2750                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2751                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2752                }
2753            }
2754
2755            if (mStoppingActivities.size() > 0) {
2756                // Still need to tell some activities to stop; can't sleep yet.
2757                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2758                        + mStoppingActivities.size() + " activities");
2759                scheduleIdleLocked();
2760                dontSleep = true;
2761            }
2762
2763            if (mGoingToSleepActivities.size() > 0) {
2764                // Still need to tell some activities to sleep; can't sleep yet.
2765                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2766                        + mGoingToSleepActivities.size() + " activities");
2767                dontSleep = true;
2768            }
2769
2770            if (dontSleep) {
2771                return;
2772            }
2773        }
2774
2775        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2776            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2777            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2778                stacks.get(stackNdx).goToSleep();
2779            }
2780        }
2781
2782        removeSleepTimeouts();
2783
2784        if (mGoingToSleep.isHeld()) {
2785            mGoingToSleep.release();
2786        }
2787        if (mService.mShuttingDown) {
2788            mService.notifyAll();
2789        }
2790    }
2791
2792    boolean reportResumedActivityLocked(ActivityRecord r) {
2793        final ActivityStack stack = r.task.stack;
2794        if (isFrontStack(stack)) {
2795            mService.updateUsageStats(r, true);
2796        }
2797        if (allResumedActivitiesComplete()) {
2798            ensureActivitiesVisibleLocked(null, 0);
2799            mWindowManager.executeAppTransition();
2800            return true;
2801        }
2802        return false;
2803    }
2804
2805    void handleAppCrashLocked(ProcessRecord app) {
2806        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2807            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2808            final int numStacks = stacks.size();
2809            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2810                final ActivityStack stack = stacks.get(stackNdx);
2811                stack.handleAppCrashLocked(app);
2812            }
2813        }
2814    }
2815
2816    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
2817        final ActivityStack stack = r.task.stack;
2818        if (stack == null) {
2819            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: r=" + r + " visible=" +
2820                    visible + " stack is null");
2821            return false;
2822        }
2823        final boolean isVisible = stack.hasVisibleBehindActivity();
2824        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind r=" + r + " visible=" +
2825                visible + " isVisible=" + isVisible);
2826
2827        final ActivityRecord top = topRunningActivityLocked();
2828        if (top == null || top == r || (visible == isVisible)) {
2829            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: quick return");
2830            stack.setVisibleBehindActivity(visible ? r : null);
2831            return true;
2832        }
2833
2834        // A non-top activity is reporting a visibility change.
2835        if (visible && top.fullscreen) {
2836            // Let the caller know that it can't be seen.
2837            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen="
2838                    + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app +
2839                    " top.app.thread=" + top.app.thread);
2840            return false;
2841        } else if (!visible && stack.getVisibleBehindActivity() != r) {
2842            // Only the activity set as currently visible behind should actively reset its
2843            // visible behind state.
2844            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning visible="
2845                    + visible + " stack.getVisibleBehindActivity()=" +
2846                    stack.getVisibleBehindActivity() + " r=" + r);
2847            return false;
2848        }
2849
2850        stack.setVisibleBehindActivity(visible ? r : null);
2851        if (!visible) {
2852            // Make the activity immediately above r opaque.
2853            final ActivityRecord next = stack.findNextTranslucentActivity(r);
2854            if (next != null) {
2855                mService.convertFromTranslucent(next.appToken);
2856            }
2857        }
2858        if (top.app != null && top.app.thread != null) {
2859            // Notify the top app of the change.
2860            try {
2861                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
2862            } catch (RemoteException e) {
2863            }
2864        }
2865        return true;
2866    }
2867
2868    // Called when WindowManager has finished animating the launchingBehind activity to the back.
2869    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2870        r.mLaunchTaskBehind = false;
2871        final TaskRecord task = r.task;
2872        task.setLastThumbnail(task.stack.screenshotActivities(r));
2873        mService.addRecentTaskLocked(task);
2874        mService.notifyTaskStackChangedLocked();
2875        mWindowManager.setAppVisibility(r.appToken, false);
2876    }
2877
2878    void scheduleLaunchTaskBehindComplete(IBinder token) {
2879        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2880    }
2881
2882    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2883        // First the front stacks. In case any are not fullscreen and are in front of home.
2884        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2885            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2886            final int topStackNdx = stacks.size() - 1;
2887            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2888                final ActivityStack stack = stacks.get(stackNdx);
2889                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2890            }
2891        }
2892    }
2893
2894    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2895        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2896            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2897            final int numStacks = stacks.size();
2898            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2899                final ActivityStack stack = stacks.get(stackNdx);
2900                stack.scheduleDestroyActivities(app, reason);
2901            }
2902        }
2903    }
2904
2905    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
2906        // Examine all activities currently running in the process.
2907        TaskRecord firstTask = null;
2908        // Tasks is non-null only if two or more tasks are found.
2909        ArraySet<TaskRecord> tasks = null;
2910        if (DEBUG_RELEASE) Slog.d(TAG, "Trying to release some activities in " + app);
2911        for (int i=0; i<app.activities.size(); i++) {
2912            ActivityRecord r = app.activities.get(i);
2913            // First, if we find an activity that is in the process of being destroyed,
2914            // then we just aren't going to do anything for now; we want things to settle
2915            // down before we try to prune more activities.
2916            if (r.finishing || r.state == ActivityState.DESTROYING
2917                    || r.state == ActivityState.DESTROYED) {
2918                if (DEBUG_RELEASE) Slog.d(TAG, "Abort release; already destroying: " + r);
2919                return;
2920            }
2921            // Don't consider any activies that are currently not in a state where they
2922            // can be destroyed.
2923            if (r.visible || !r.stopped || !r.haveState
2924                    || r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING
2925                    || r.state == ActivityState.PAUSED || r.state == ActivityState.STOPPING) {
2926                if (DEBUG_RELEASE) Slog.d(TAG, "Not releasing in-use activity: " + r);
2927                continue;
2928            }
2929            if (r.task != null) {
2930                if (DEBUG_RELEASE) Slog.d(TAG, "Collecting release task " + r.task
2931                        + " from " + r);
2932                if (firstTask == null) {
2933                    firstTask = r.task;
2934                } else if (firstTask != r.task) {
2935                    if (tasks == null) {
2936                        tasks = new ArraySet<>();
2937                        tasks.add(firstTask);
2938                    }
2939                    tasks.add(r.task);
2940                }
2941            }
2942        }
2943        if (tasks == null) {
2944            if (DEBUG_RELEASE) Slog.d(TAG, "Didn't find two or more tasks to release");
2945            return;
2946        }
2947        // If we have activities in multiple tasks that are in a position to be destroyed,
2948        // let's iterate through the tasks and release the oldest one.
2949        final int numDisplays = mActivityDisplays.size();
2950        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2951            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2952            // Step through all stacks starting from behind, to hit the oldest things first.
2953            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
2954                final ActivityStack stack = stacks.get(stackNdx);
2955                // Try to release activities in this stack; if we manage to, we are done.
2956                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
2957                    return;
2958                }
2959            }
2960        }
2961    }
2962
2963    boolean switchUserLocked(int userId, UserStartedState uss) {
2964        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2965        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2966        mCurrentUser = userId;
2967
2968        mStartingUsers.add(uss);
2969        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2970            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2971            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2972                final ActivityStack stack = stacks.get(stackNdx);
2973                stack.switchUserLocked(userId);
2974                TaskRecord task = stack.topTask();
2975                if (task != null) {
2976                    mWindowManager.moveTaskToTop(task.taskId);
2977                }
2978            }
2979        }
2980
2981        ActivityStack stack = getStack(restoreStackId);
2982        if (stack == null) {
2983            stack = mHomeStack;
2984        }
2985        final boolean homeInFront = stack.isHomeStack();
2986        if (stack.isOnHomeDisplay()) {
2987            moveHomeStack(homeInFront);
2988            TaskRecord task = stack.topTask();
2989            if (task != null) {
2990                mWindowManager.moveTaskToTop(task.taskId);
2991            }
2992        } else {
2993            // Stack was moved to another display while user was swapped out.
2994            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2995        }
2996        return homeInFront;
2997    }
2998
2999    /**
3000     * Add background users to send boot completed events to.
3001     * @param userId The user being started in the background
3002     * @param uss The state object for the user.
3003     */
3004    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
3005        mStartingBackgroundUsers.add(uss);
3006    }
3007
3008    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
3009        int N = mStoppingActivities.size();
3010        if (N <= 0) return null;
3011
3012        ArrayList<ActivityRecord> stops = null;
3013
3014        final boolean nowVisible = allResumedActivitiesVisible();
3015        for (int i=0; i<N; i++) {
3016            ActivityRecord s = mStoppingActivities.get(i);
3017            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
3018                    + nowVisible + " waitingVisible=" + s.waitingVisible
3019                    + " finishing=" + s.finishing);
3020            if (s.waitingVisible && nowVisible) {
3021                mWaitingVisibleActivities.remove(s);
3022                s.waitingVisible = false;
3023                if (s.finishing) {
3024                    // If this activity is finishing, it is sitting on top of
3025                    // everyone else but we now know it is no longer needed...
3026                    // so get rid of it.  Otherwise, we need to go through the
3027                    // normal flow and hide it once we determine that it is
3028                    // hidden by the activities in front of it.
3029                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
3030                    mWindowManager.setAppVisibility(s.appToken, false);
3031                }
3032            }
3033            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
3034                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
3035                if (stops == null) {
3036                    stops = new ArrayList<ActivityRecord>();
3037                }
3038                stops.add(s);
3039                mStoppingActivities.remove(i);
3040                N--;
3041                i--;
3042            }
3043        }
3044
3045        return stops;
3046    }
3047
3048    void validateTopActivitiesLocked() {
3049        // FIXME
3050/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3051            final ActivityStack stack = stacks.get(stackNdx);
3052            final ActivityRecord r = stack.topRunningActivityLocked(null);
3053            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
3054            if (isFrontStack(stack)) {
3055                if (r == null) {
3056                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
3057                } else {
3058                    final ActivityRecord pausing = stack.mPausingActivity;
3059                    if (pausing != null && pausing == r) {
3060                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
3061                            " state=" + state);
3062                    }
3063                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
3064                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
3065                                " state=" + state);
3066                    }
3067                }
3068            } else {
3069                final ActivityRecord resumed = stack.mResumedActivity;
3070                if (resumed != null && resumed == r) {
3071                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
3072                        " state=" + state);
3073                }
3074                if (r != null && (state == ActivityState.INITIALIZING
3075                        || state == ActivityState.RESUMED)) {
3076                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
3077                            " state=" + state);
3078                }
3079            }
3080        }
3081*/
3082    }
3083
3084    public void dump(PrintWriter pw, String prefix) {
3085        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3086                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3087        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3088        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
3089        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3090        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3091    }
3092
3093    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3094        return getFocusedStack().getDumpActivitiesLocked(name);
3095    }
3096
3097    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3098            boolean needSep, String prefix) {
3099        if (activity != null) {
3100            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3101                if (needSep) {
3102                    pw.println();
3103                }
3104                pw.print(prefix);
3105                pw.println(activity);
3106                return true;
3107            }
3108        }
3109        return false;
3110    }
3111
3112    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3113            boolean dumpClient, String dumpPackage) {
3114        boolean printed = false;
3115        boolean needSep = false;
3116        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3117            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3118            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3119                    pw.println(" (activities from top to bottom):");
3120            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3121            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3122                final ActivityStack stack = stacks.get(stackNdx);
3123                StringBuilder stackHeader = new StringBuilder(128);
3124                stackHeader.append("  Stack #");
3125                stackHeader.append(stack.mStackId);
3126                stackHeader.append(":");
3127                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3128                        needSep, stackHeader.toString());
3129                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3130                        !dumpAll, false, dumpPackage, true,
3131                        "    Running activities (most recent first):", null);
3132
3133                needSep = printed;
3134                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3135                        "    mPausingActivity: ");
3136                if (pr) {
3137                    printed = true;
3138                    needSep = false;
3139                }
3140                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3141                        "    mResumedActivity: ");
3142                if (pr) {
3143                    printed = true;
3144                    needSep = false;
3145                }
3146                if (dumpAll) {
3147                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3148                            "    mLastPausedActivity: ");
3149                    if (pr) {
3150                        printed = true;
3151                        needSep = true;
3152                    }
3153                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3154                            needSep, "    mLastNoHistoryActivity: ");
3155                }
3156                needSep = printed;
3157            }
3158        }
3159
3160        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3161                false, dumpPackage, true, "  Activities waiting to finish:", null);
3162        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3163                false, dumpPackage, true, "  Activities waiting to stop:", null);
3164        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3165                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3166                null);
3167        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3168                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3169        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3170                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3171
3172        return printed;
3173    }
3174
3175    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3176            String prefix, String label, boolean complete, boolean brief, boolean client,
3177            String dumpPackage, boolean needNL, String header1, String header2) {
3178        TaskRecord lastTask = null;
3179        String innerPrefix = null;
3180        String[] args = null;
3181        boolean printed = false;
3182        for (int i=list.size()-1; i>=0; i--) {
3183            final ActivityRecord r = list.get(i);
3184            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3185                continue;
3186            }
3187            if (innerPrefix == null) {
3188                innerPrefix = prefix + "      ";
3189                args = new String[0];
3190            }
3191            printed = true;
3192            final boolean full = !brief && (complete || !r.isInHistory());
3193            if (needNL) {
3194                pw.println("");
3195                needNL = false;
3196            }
3197            if (header1 != null) {
3198                pw.println(header1);
3199                header1 = null;
3200            }
3201            if (header2 != null) {
3202                pw.println(header2);
3203                header2 = null;
3204            }
3205            if (lastTask != r.task) {
3206                lastTask = r.task;
3207                pw.print(prefix);
3208                pw.print(full ? "* " : "  ");
3209                pw.println(lastTask);
3210                if (full) {
3211                    lastTask.dump(pw, prefix + "  ");
3212                } else if (complete) {
3213                    // Complete + brief == give a summary.  Isn't that obvious?!?
3214                    if (lastTask.intent != null) {
3215                        pw.print(prefix); pw.print("  ");
3216                                pw.println(lastTask.intent.toInsecureStringWithClip());
3217                    }
3218                }
3219            }
3220            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3221            pw.print(" #"); pw.print(i); pw.print(": ");
3222            pw.println(r);
3223            if (full) {
3224                r.dump(pw, innerPrefix);
3225            } else if (complete) {
3226                // Complete + brief == give a summary.  Isn't that obvious?!?
3227                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3228                if (r.app != null) {
3229                    pw.print(innerPrefix); pw.println(r.app);
3230                }
3231            }
3232            if (client && r.app != null && r.app.thread != null) {
3233                // flush anything that is already in the PrintWriter since the thread is going
3234                // to write to the file descriptor directly
3235                pw.flush();
3236                try {
3237                    TransferPipe tp = new TransferPipe();
3238                    try {
3239                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3240                                r.appToken, innerPrefix, args);
3241                        // Short timeout, since blocking here can
3242                        // deadlock with the application.
3243                        tp.go(fd, 2000);
3244                    } finally {
3245                        tp.kill();
3246                    }
3247                } catch (IOException e) {
3248                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3249                } catch (RemoteException e) {
3250                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3251                }
3252                needNL = true;
3253            }
3254        }
3255        return printed;
3256    }
3257
3258    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3259        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3260        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3261        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3262    }
3263
3264    final void scheduleIdleLocked() {
3265        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3266    }
3267
3268    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3269        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
3270        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3271    }
3272
3273    final void scheduleResumeTopActivities() {
3274        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3275            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3276        }
3277    }
3278
3279    void removeSleepTimeouts() {
3280        mSleepTimeout = false;
3281        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3282    }
3283
3284    final void scheduleSleepTimeout() {
3285        removeSleepTimeouts();
3286        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3287    }
3288
3289    @Override
3290    public void onDisplayAdded(int displayId) {
3291        Slog.v(TAG, "Display added displayId=" + displayId);
3292        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3293    }
3294
3295    @Override
3296    public void onDisplayRemoved(int displayId) {
3297        Slog.v(TAG, "Display removed displayId=" + displayId);
3298        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3299    }
3300
3301    @Override
3302    public void onDisplayChanged(int displayId) {
3303        Slog.v(TAG, "Display changed displayId=" + displayId);
3304        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3305    }
3306
3307    public void handleDisplayAddedLocked(int displayId) {
3308        boolean newDisplay;
3309        synchronized (mService) {
3310            newDisplay = mActivityDisplays.get(displayId) == null;
3311            if (newDisplay) {
3312                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3313                if (activityDisplay.mDisplay == null) {
3314                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3315                    return;
3316                }
3317                mActivityDisplays.put(displayId, activityDisplay);
3318            }
3319        }
3320        if (newDisplay) {
3321            mWindowManager.onDisplayAdded(displayId);
3322        }
3323    }
3324
3325    public void handleDisplayRemovedLocked(int displayId) {
3326        synchronized (mService) {
3327            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3328            if (activityDisplay != null) {
3329                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3330                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3331                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3332                }
3333                mActivityDisplays.remove(displayId);
3334            }
3335        }
3336        mWindowManager.onDisplayRemoved(displayId);
3337    }
3338
3339    public void handleDisplayChangedLocked(int displayId) {
3340        synchronized (mService) {
3341            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3342            if (activityDisplay != null) {
3343                // TODO: Update the bounds.
3344            }
3345        }
3346        mWindowManager.onDisplayChanged(displayId);
3347    }
3348
3349    StackInfo getStackInfo(ActivityStack stack) {
3350        StackInfo info = new StackInfo();
3351        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3352        info.displayId = Display.DEFAULT_DISPLAY;
3353        info.stackId = stack.mStackId;
3354
3355        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3356        final int numTasks = tasks.size();
3357        int[] taskIds = new int[numTasks];
3358        String[] taskNames = new String[numTasks];
3359        for (int i = 0; i < numTasks; ++i) {
3360            final TaskRecord task = tasks.get(i);
3361            taskIds[i] = task.taskId;
3362            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3363                    : task.realActivity != null ? task.realActivity.flattenToString()
3364                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3365                    : "unknown";
3366        }
3367        info.taskIds = taskIds;
3368        info.taskNames = taskNames;
3369        return info;
3370    }
3371
3372    StackInfo getStackInfoLocked(int stackId) {
3373        ActivityStack stack = getStack(stackId);
3374        if (stack != null) {
3375            return getStackInfo(stack);
3376        }
3377        return null;
3378    }
3379
3380    ArrayList<StackInfo> getAllStackInfosLocked() {
3381        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3382        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3383            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3384            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3385                list.add(getStackInfo(stacks.get(ndx)));
3386            }
3387        }
3388        return list;
3389    }
3390
3391    void showLockTaskToast() {
3392        mLockTaskNotify.showToast(mLockTaskIsLocked);
3393    }
3394
3395    void setLockTaskModeLocked(TaskRecord task, boolean isLocked) {
3396        if (task == null) {
3397            // Take out of lock task mode if necessary
3398            if (mLockTaskModeTask != null) {
3399                final Message lockTaskMsg = Message.obtain();
3400                lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3401                lockTaskMsg.what = LOCK_TASK_END_MSG;
3402                mLockTaskModeTask = null;
3403                mHandler.sendMessage(lockTaskMsg);
3404            }
3405            return;
3406        }
3407        if (isLockTaskModeViolation(task)) {
3408            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
3409            return;
3410        }
3411        mLockTaskModeTask = task;
3412        findTaskToMoveToFrontLocked(task, 0, null);
3413        resumeTopActivitiesLocked();
3414
3415        final Message lockTaskMsg = Message.obtain();
3416        lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
3417        lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3418        lockTaskMsg.what = LOCK_TASK_START_MSG;
3419        lockTaskMsg.arg2 = !isLocked ? 1 : 0;
3420        mHandler.sendMessage(lockTaskMsg);
3421    }
3422
3423    boolean isLockTaskModeViolation(TaskRecord task) {
3424        return mLockTaskModeTask != null && mLockTaskModeTask != task;
3425    }
3426
3427    void endLockTaskModeIfTaskEnding(TaskRecord task) {
3428        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
3429            final Message lockTaskMsg = Message.obtain();
3430            lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3431            lockTaskMsg.what = LOCK_TASK_END_MSG;
3432            mLockTaskModeTask = null;
3433            mHandler.sendMessage(lockTaskMsg);
3434        }
3435    }
3436
3437    boolean isInLockTaskMode() {
3438        return mLockTaskModeTask != null;
3439    }
3440
3441    private final class ActivityStackSupervisorHandler extends Handler {
3442
3443        public ActivityStackSupervisorHandler(Looper looper) {
3444            super(looper);
3445        }
3446
3447        void activityIdleInternal(ActivityRecord r) {
3448            synchronized (mService) {
3449                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3450            }
3451        }
3452
3453        @Override
3454        public void handleMessage(Message msg) {
3455            switch (msg.what) {
3456                case IDLE_TIMEOUT_MSG: {
3457                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3458                    if (mService.mDidDexOpt) {
3459                        mService.mDidDexOpt = false;
3460                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3461                        nmsg.obj = msg.obj;
3462                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3463                        return;
3464                    }
3465                    // We don't at this point know if the activity is fullscreen,
3466                    // so we need to be conservative and assume it isn't.
3467                    activityIdleInternal((ActivityRecord)msg.obj);
3468                } break;
3469                case IDLE_NOW_MSG: {
3470                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3471                    activityIdleInternal((ActivityRecord)msg.obj);
3472                } break;
3473                case RESUME_TOP_ACTIVITY_MSG: {
3474                    synchronized (mService) {
3475                        resumeTopActivitiesLocked();
3476                    }
3477                } break;
3478                case SLEEP_TIMEOUT_MSG: {
3479                    synchronized (mService) {
3480                        if (mService.isSleepingOrShuttingDown()) {
3481                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3482                            mSleepTimeout = true;
3483                            checkReadyForSleepLocked();
3484                        }
3485                    }
3486                } break;
3487                case LAUNCH_TIMEOUT_MSG: {
3488                    if (mService.mDidDexOpt) {
3489                        mService.mDidDexOpt = false;
3490                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3491                        return;
3492                    }
3493                    synchronized (mService) {
3494                        if (mLaunchingActivity.isHeld()) {
3495                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3496                            if (VALIDATE_WAKE_LOCK_CALLER
3497                                    && Binder.getCallingUid() != Process.myUid()) {
3498                                throw new IllegalStateException("Calling must be system uid");
3499                            }
3500                            mLaunchingActivity.release();
3501                        }
3502                    }
3503                } break;
3504                case HANDLE_DISPLAY_ADDED: {
3505                    handleDisplayAddedLocked(msg.arg1);
3506                } break;
3507                case HANDLE_DISPLAY_CHANGED: {
3508                    handleDisplayChangedLocked(msg.arg1);
3509                } break;
3510                case HANDLE_DISPLAY_REMOVED: {
3511                    handleDisplayRemovedLocked(msg.arg1);
3512                } break;
3513                case CONTAINER_CALLBACK_VISIBILITY: {
3514                    final ActivityContainer container = (ActivityContainer) msg.obj;
3515                    final IActivityContainerCallback callback = container.mCallback;
3516                    if (callback != null) {
3517                        try {
3518                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3519                        } catch (RemoteException e) {
3520                        }
3521                    }
3522                } break;
3523                case LOCK_TASK_START_MSG: {
3524                    // When lock task starts, we disable the status bars.
3525                    try {
3526                        if (mLockTaskNotify == null) {
3527                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3528                        }
3529                        mLockTaskNotify.show(true);
3530                        mLockTaskIsLocked = msg.arg2 == 0;
3531                        if (getStatusBarService() != null) {
3532                            int flags =
3533                                    StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
3534                            if (!mLockTaskIsLocked) {
3535                                flags ^= StatusBarManager.DISABLE_HOME
3536                                        | StatusBarManager.DISABLE_RECENT;
3537                            }
3538                            getStatusBarService().disable(flags, mToken,
3539                                    mService.mContext.getPackageName());
3540                        }
3541                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3542                        if (getDevicePolicyManager() != null) {
3543                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3544                                    (String)msg.obj, msg.arg1);
3545                        }
3546                    } catch (RemoteException ex) {
3547                        throw new RuntimeException(ex);
3548                    }
3549                } break;
3550                case LOCK_TASK_END_MSG: {
3551                    // When lock task ends, we enable the status bars.
3552                    try {
3553                        if (getStatusBarService() != null) {
3554                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3555                                    mService.mContext.getPackageName());
3556                        }
3557                        mWindowManager.reenableKeyguard(mToken);
3558                        if (getDevicePolicyManager() != null) {
3559                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3560                                    msg.arg1);
3561                        }
3562                        if (mLockTaskNotify == null) {
3563                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3564                        }
3565                        mLockTaskNotify.show(false);
3566                        try {
3567                            boolean shouldLockKeyguard = Settings.Secure.getInt(
3568                                    mService.mContext.getContentResolver(),
3569                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
3570                            if (!mLockTaskIsLocked && shouldLockKeyguard) {
3571                                mWindowManager.lockNow(null);
3572                                mWindowManager.dismissKeyguard();
3573                                new LockPatternUtils(mService.mContext)
3574                                        .requireCredentialEntry(UserHandle.USER_ALL);
3575                            }
3576                        } catch (SettingNotFoundException e) {
3577                            // No setting, don't lock.
3578                        }
3579                    } catch (RemoteException ex) {
3580                        throw new RuntimeException(ex);
3581                    }
3582                } break;
3583                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3584                    final ActivityContainer container = (ActivityContainer) msg.obj;
3585                    final IActivityContainerCallback callback = container.mCallback;
3586                    if (callback != null) {
3587                        try {
3588                            callback.onAllActivitiesComplete(container.asBinder());
3589                        } catch (RemoteException e) {
3590                        }
3591                    }
3592                } break;
3593                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
3594                    synchronized (mService) {
3595                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
3596                                msg.obj);
3597                        final ActivityContainer container = (ActivityContainer) msg.obj;
3598                        container.mStack.finishAllActivitiesLocked(true);
3599                        container.onTaskListEmptyLocked();
3600                    }
3601                } break;
3602                case LAUNCH_TASK_BEHIND_COMPLETE: {
3603                    synchronized (mService) {
3604                        ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
3605                        if (r != null) {
3606                            handleLaunchTaskBehindCompleteLocked(r);
3607                        }
3608                    }
3609                } break;
3610            }
3611        }
3612    }
3613
3614    class ActivityContainer extends android.app.IActivityContainer.Stub {
3615        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3616                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3617        final int mStackId;
3618        IActivityContainerCallback mCallback = null;
3619        final ActivityStack mStack;
3620        ActivityRecord mParentActivity = null;
3621        String mIdString;
3622
3623        boolean mVisible = true;
3624
3625        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3626        ActivityDisplay mActivityDisplay;
3627
3628        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3629        final static int CONTAINER_STATE_NO_SURFACE = 1;
3630        final static int CONTAINER_STATE_FINISHING = 2;
3631        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3632
3633        ActivityContainer(int stackId) {
3634            synchronized (mService) {
3635                mStackId = stackId;
3636                mStack = new ActivityStack(this);
3637                mIdString = "ActivtyContainer{" + mStackId + "}";
3638                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3639            }
3640        }
3641
3642        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3643            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3644                    + " to display=" + activityDisplay);
3645            mActivityDisplay = activityDisplay;
3646            mStack.mDisplayId = activityDisplay.mDisplayId;
3647            mStack.mStacks = activityDisplay.mStacks;
3648
3649            activityDisplay.attachActivities(mStack);
3650            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3651        }
3652
3653        @Override
3654        public void attachToDisplay(int displayId) {
3655            synchronized (mService) {
3656                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3657                if (activityDisplay == null) {
3658                    return;
3659                }
3660                attachToDisplayLocked(activityDisplay);
3661            }
3662        }
3663
3664        @Override
3665        public int getDisplayId() {
3666            synchronized (mService) {
3667                if (mActivityDisplay != null) {
3668                    return mActivityDisplay.mDisplayId;
3669                }
3670            }
3671            return -1;
3672        }
3673
3674        @Override
3675        public boolean injectEvent(InputEvent event) {
3676            final long origId = Binder.clearCallingIdentity();
3677            try {
3678                synchronized (mService) {
3679                    if (mActivityDisplay != null) {
3680                        return mInputManagerInternal.injectInputEvent(event,
3681                                mActivityDisplay.mDisplayId,
3682                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3683                    }
3684                }
3685                return false;
3686            } finally {
3687                Binder.restoreCallingIdentity(origId);
3688            }
3689        }
3690
3691        @Override
3692        public void release() {
3693            synchronized (mService) {
3694                if (mContainerState == CONTAINER_STATE_FINISHING) {
3695                    return;
3696                }
3697                mContainerState = CONTAINER_STATE_FINISHING;
3698
3699                final Message msg =
3700                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3701                mHandler.sendMessageDelayed(msg, 2000);
3702
3703                long origId = Binder.clearCallingIdentity();
3704                try {
3705                    mStack.finishAllActivitiesLocked(false);
3706                    removePendingActivityLaunchesLocked(mStack);
3707                } finally {
3708                    Binder.restoreCallingIdentity(origId);
3709                }
3710            }
3711        }
3712
3713        protected void detachLocked() {
3714            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3715                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3716            if (mActivityDisplay != null) {
3717                mActivityDisplay.detachActivitiesLocked(mStack);
3718                mActivityDisplay = null;
3719                mStack.mDisplayId = -1;
3720                mStack.mStacks = null;
3721                mWindowManager.detachStack(mStackId);
3722            }
3723        }
3724
3725        @Override
3726        public final int startActivity(Intent intent) {
3727            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3728            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3729                    Binder.getCallingUid(), mCurrentUser, false,
3730                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3731            // TODO: Switch to user app stacks here.
3732            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3733            String mimeType = intent.getType();
3734            if (mimeType == null && intent.getData() != null
3735                    && "content".equals(intent.getData().getScheme())) {
3736                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3737            }
3738            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0,
3739                    0, null, null, null, null, userId, this, null);
3740        }
3741
3742        @Override
3743        public final int startActivityIntentSender(IIntentSender intentSender) {
3744            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3745
3746            if (!(intentSender instanceof PendingIntentRecord)) {
3747                throw new IllegalArgumentException("Bad PendingIntent object");
3748            }
3749
3750            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3751                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3752        }
3753
3754        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3755            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3756                    Binder.getCallingUid(), mCurrentUser, false,
3757                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3758            if (resolvedType == null) {
3759                resolvedType = intent.getType();
3760                if (resolvedType == null && intent.getData() != null
3761                        && "content".equals(intent.getData().getScheme())) {
3762                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3763                }
3764            }
3765            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
3766            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3767                throw new SecurityException(
3768                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3769            }
3770        }
3771
3772        /** Throw a SecurityException if allowEmbedded is not true */
3773        @Override
3774        public final void checkEmbeddedAllowed(Intent intent) {
3775            checkEmbeddedAllowedInner(intent, null);
3776        }
3777
3778        /** Throw a SecurityException if allowEmbedded is not true */
3779        @Override
3780        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3781            if (!(intentSender instanceof PendingIntentRecord)) {
3782                throw new IllegalArgumentException("Bad PendingIntent object");
3783            }
3784            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3785            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3786                    pendingIntent.key.requestResolvedType);
3787        }
3788
3789        @Override
3790        public IBinder asBinder() {
3791            return this;
3792        }
3793
3794        @Override
3795        public void setSurface(Surface surface, int width, int height, int density) {
3796            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3797        }
3798
3799        ActivityStackSupervisor getOuter() {
3800            return ActivityStackSupervisor.this;
3801        }
3802
3803        boolean isAttachedLocked() {
3804            return mActivityDisplay != null;
3805        }
3806
3807        void getBounds(Point outBounds) {
3808            synchronized (mService) {
3809                    if (mActivityDisplay != null) {
3810                    mActivityDisplay.getBounds(outBounds);
3811                } else {
3812                    outBounds.set(0, 0);
3813                }
3814            }
3815        }
3816
3817        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3818        void setVisible(boolean visible) {
3819            if (mVisible != visible) {
3820                mVisible = visible;
3821                if (mCallback != null) {
3822                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3823                            0 /* unused */, this).sendToTarget();
3824                }
3825            }
3826        }
3827
3828        void setDrawn() {
3829        }
3830
3831        // You can always start a new task on a regular ActivityStack.
3832        boolean isEligibleForNewTasks() {
3833            return true;
3834        }
3835
3836        void onTaskListEmptyLocked() {
3837        }
3838
3839        @Override
3840        public String toString() {
3841            return mIdString + (mActivityDisplay == null ? "N" : "A");
3842        }
3843    }
3844
3845    private class VirtualActivityContainer extends ActivityContainer {
3846        Surface mSurface;
3847        boolean mDrawn = false;
3848
3849        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3850            super(getNextStackId());
3851            mParentActivity = parent;
3852            mCallback = callback;
3853            mContainerState = CONTAINER_STATE_NO_SURFACE;
3854            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3855        }
3856
3857        @Override
3858        public void setSurface(Surface surface, int width, int height, int density) {
3859            super.setSurface(surface, width, height, density);
3860
3861            synchronized (mService) {
3862                final long origId = Binder.clearCallingIdentity();
3863                try {
3864                    setSurfaceLocked(surface, width, height, density);
3865                } finally {
3866                    Binder.restoreCallingIdentity(origId);
3867                }
3868            }
3869        }
3870
3871        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3872            if (mContainerState == CONTAINER_STATE_FINISHING) {
3873                return;
3874            }
3875            VirtualActivityDisplay virtualActivityDisplay =
3876                    (VirtualActivityDisplay) mActivityDisplay;
3877            if (virtualActivityDisplay == null) {
3878                virtualActivityDisplay =
3879                        new VirtualActivityDisplay(width, height, density);
3880                mActivityDisplay = virtualActivityDisplay;
3881                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3882                attachToDisplayLocked(virtualActivityDisplay);
3883            }
3884
3885            if (mSurface != null) {
3886                mSurface.release();
3887            }
3888
3889            mSurface = surface;
3890            if (surface != null) {
3891                mStack.resumeTopActivityLocked(null);
3892            } else {
3893                mContainerState = CONTAINER_STATE_NO_SURFACE;
3894                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3895                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3896                    mStack.startPausingLocked(false, true, false, false);
3897                }
3898            }
3899
3900            setSurfaceIfReadyLocked();
3901
3902            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3903                    + virtualActivityDisplay);
3904        }
3905
3906        @Override
3907        boolean isAttachedLocked() {
3908            return mSurface != null && super.isAttachedLocked();
3909        }
3910
3911        @Override
3912        void setDrawn() {
3913            synchronized (mService) {
3914                mDrawn = true;
3915                setSurfaceIfReadyLocked();
3916            }
3917        }
3918
3919        // Never start a new task on an ActivityView if it isn't explicitly specified.
3920        @Override
3921        boolean isEligibleForNewTasks() {
3922            return false;
3923        }
3924
3925        void onTaskListEmptyLocked() {
3926            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3927            detachLocked();
3928            deleteActivityContainer(this);
3929            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3930        }
3931
3932        private void setSurfaceIfReadyLocked() {
3933            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
3934                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3935            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3936                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3937                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3938            }
3939        }
3940    }
3941
3942    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3943     * attached {@link ActivityStack}s */
3944    class ActivityDisplay {
3945        /** Actual Display this object tracks. */
3946        int mDisplayId;
3947        Display mDisplay;
3948        DisplayInfo mDisplayInfo = new DisplayInfo();
3949
3950        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3951         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3952        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3953
3954        ActivityRecord mVisibleBehindActivity;
3955
3956        ActivityDisplay() {
3957        }
3958
3959        // After instantiation, check that mDisplay is not null before using this. The alternative
3960        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
3961        ActivityDisplay(int displayId) {
3962            final Display display = mDisplayManager.getDisplay(displayId);
3963            if (display == null) {
3964                return;
3965            }
3966            init(display);
3967        }
3968
3969        void init(Display display) {
3970            mDisplay = display;
3971            mDisplayId = display.getDisplayId();
3972            mDisplay.getDisplayInfo(mDisplayInfo);
3973        }
3974
3975        void attachActivities(ActivityStack stack) {
3976            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3977                    + mDisplayId);
3978            mStacks.add(stack);
3979        }
3980
3981        void detachActivitiesLocked(ActivityStack stack) {
3982            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3983                    + " from displayId=" + mDisplayId);
3984            mStacks.remove(stack);
3985        }
3986
3987        void getBounds(Point bounds) {
3988            mDisplay.getDisplayInfo(mDisplayInfo);
3989            bounds.x = mDisplayInfo.appWidth;
3990            bounds.y = mDisplayInfo.appHeight;
3991        }
3992
3993        void setVisibleBehindActivity(ActivityRecord r) {
3994            mVisibleBehindActivity = r;
3995        }
3996
3997        boolean hasVisibleBehindActivity() {
3998            return mVisibleBehindActivity != null;
3999        }
4000
4001        @Override
4002        public String toString() {
4003            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4004        }
4005    }
4006
4007    class VirtualActivityDisplay extends ActivityDisplay {
4008        VirtualDisplay mVirtualDisplay;
4009
4010        VirtualActivityDisplay(int width, int height, int density) {
4011            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4012            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4013                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4014                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4015                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4016
4017            init(mVirtualDisplay.getDisplay());
4018
4019            mWindowManager.handleDisplayAdded(mDisplayId);
4020        }
4021
4022        void setSurface(Surface surface) {
4023            if (mVirtualDisplay != null) {
4024                mVirtualDisplay.setSurface(surface);
4025            }
4026        }
4027
4028        @Override
4029        void detachActivitiesLocked(ActivityStack stack) {
4030            super.detachActivitiesLocked(stack);
4031            if (mVirtualDisplay != null) {
4032                mVirtualDisplay.release();
4033                mVirtualDisplay = null;
4034            }
4035        }
4036
4037        @Override
4038        public String toString() {
4039            return "VirtualActivityDisplay={" + mDisplayId + "}";
4040        }
4041    }
4042
4043    private boolean isLeanbackOnlyDevice() {
4044        boolean onLeanbackOnly = false;
4045        try {
4046            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
4047                    PackageManager.FEATURE_LEANBACK_ONLY);
4048        } catch (RemoteException e) {
4049            // noop
4050        }
4051
4052        return onLeanbackOnly;
4053    }
4054}
4055