ActivityStackSupervisor.java revision 6b904ef4741321dcb01caee9795c2a044018706c
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
1318        final int launchFlags = intent.getFlags();
1319
1320        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
1321            // Transfer the result target from the source activity to the new
1322            // one being started, including any failures.
1323            if (requestCode >= 0) {
1324                ActivityOptions.abort(options);
1325                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1326            }
1327            resultRecord = sourceRecord.resultTo;
1328            resultWho = sourceRecord.resultWho;
1329            requestCode = sourceRecord.requestCode;
1330            sourceRecord.resultTo = null;
1331            if (resultRecord != null) {
1332                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
1333            }
1334            if (sourceRecord.launchedFromUid == callingUid) {
1335                // The new activity is being launched from the same uid as the previous
1336                // activity in the flow, and asking to forward its result back to the
1337                // previous.  In this case the activity is serving as a trampoline between
1338                // the two, so we also want to update its launchedFromPackage to be the
1339                // same as the previous activity.  Note that this is safe, since we know
1340                // these two packages come from the same uid; the caller could just as
1341                // well have supplied that same package name itself.  This specifially
1342                // deals with the case of an intent picker/chooser being launched in the app
1343                // flow to redirect to an activity picked by the user, where we want the final
1344                // activity to consider it to have been launched by the previous app activity.
1345                callingPackage = sourceRecord.launchedFromPackage;
1346            }
1347        }
1348
1349        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1350            // We couldn't find a class that can handle the given Intent.
1351            // That's the end of that!
1352            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1353        }
1354
1355        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1356            // We couldn't find the specific class specified in the Intent.
1357            // Also the end of the line.
1358            err = ActivityManager.START_CLASS_NOT_FOUND;
1359        }
1360
1361        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
1362                && sourceRecord.task.voiceSession != null) {
1363            // If this activity is being launched as part of a voice session, we need
1364            // to ensure that it is safe to do so.  If the upcoming activity will also
1365            // be part of the voice session, we can only launch it if it has explicitly
1366            // said it supports the VOICE category, or it is a part of the calling app.
1367            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
1368                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
1369                try {
1370                    if (!AppGlobals.getPackageManager().activitySupportsIntent(
1371                            intent.getComponent(), intent, resolvedType)) {
1372                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1373                    }
1374                } catch (RemoteException e) {
1375                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1376                }
1377            }
1378        }
1379
1380        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
1381            // If the caller is starting a new voice session, just make sure the target
1382            // is actually allowing it to run this way.
1383            try {
1384                if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1385                        intent, resolvedType)) {
1386                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1387                }
1388            } catch (RemoteException e) {
1389                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1390            }
1391        }
1392
1393        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1394
1395        if (err != ActivityManager.START_SUCCESS) {
1396            if (resultRecord != null) {
1397                resultStack.sendActivityResultLocked(-1,
1398                    resultRecord, resultWho, requestCode,
1399                    Activity.RESULT_CANCELED, null);
1400            }
1401            ActivityOptions.abort(options);
1402            return err;
1403        }
1404
1405        final int startAnyPerm = mService.checkPermission(
1406                START_ANY_ACTIVITY, callingPid, callingUid);
1407        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1408                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1409        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1410            if (resultRecord != null) {
1411                resultStack.sendActivityResultLocked(-1,
1412                    resultRecord, resultWho, requestCode,
1413                    Activity.RESULT_CANCELED, null);
1414            }
1415            String msg;
1416            if (!aInfo.exported) {
1417                msg = "Permission Denial: starting " + intent.toString()
1418                        + " from " + callerApp + " (pid=" + callingPid
1419                        + ", uid=" + callingUid + ")"
1420                        + " not exported from uid " + aInfo.applicationInfo.uid;
1421            } else {
1422                msg = "Permission Denial: starting " + intent.toString()
1423                        + " from " + callerApp + " (pid=" + callingPid
1424                        + ", uid=" + callingUid + ")"
1425                        + " requires " + aInfo.permission;
1426            }
1427            Slog.w(TAG, msg);
1428            throw new SecurityException(msg);
1429        }
1430
1431        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1432                callingPid, resolvedType, aInfo.applicationInfo);
1433
1434        if (mService.mController != null) {
1435            try {
1436                // The Intent we give to the watcher has the extra data
1437                // stripped off, since it can contain private information.
1438                Intent watchIntent = intent.cloneFilter();
1439                abort |= !mService.mController.activityStarting(watchIntent,
1440                        aInfo.applicationInfo.packageName);
1441            } catch (RemoteException e) {
1442                mService.mController = null;
1443            }
1444        }
1445
1446        if (abort) {
1447            if (resultRecord != null) {
1448                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1449                        Activity.RESULT_CANCELED, null);
1450            }
1451            // We pretend to the caller that it was really started, but
1452            // they will just get a cancel result.
1453            ActivityOptions.abort(options);
1454            return ActivityManager.START_SUCCESS;
1455        }
1456
1457        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1458                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1459                requestCode, componentSpecified, this, container, options);
1460        if (outActivity != null) {
1461            outActivity[0] = r;
1462        }
1463
1464        final ActivityStack stack = getFocusedStack();
1465        if (voiceSession == null && (stack.mResumedActivity == null
1466                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
1467            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
1468                    realCallingPid, realCallingUid, "Activity start")) {
1469                PendingActivityLaunch pal =
1470                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1471                mPendingActivityLaunches.add(pal);
1472                ActivityOptions.abort(options);
1473                return ActivityManager.START_SWITCHES_CANCELED;
1474            }
1475        }
1476
1477        if (mService.mDidAppSwitch) {
1478            // This is the second allowed switch since we stopped switches,
1479            // so now just generally allow switches.  Use case: user presses
1480            // home (switches disabled, switch to home, mDidAppSwitch now true);
1481            // user taps a home icon (coming from home so allowed, we hit here
1482            // and now allow anyone to switch again).
1483            mService.mAppSwitchesAllowedTime = 0;
1484        } else {
1485            mService.mDidAppSwitch = true;
1486        }
1487
1488        doPendingActivityLaunchesLocked(false);
1489
1490        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
1491                startFlags, true, options, inTask);
1492
1493        if (err < 0) {
1494            // If someone asked to have the keyguard dismissed on the next
1495            // activity start, but we are not actually doing an activity
1496            // switch...  just dismiss the keyguard now, because we
1497            // probably want to see whatever is behind it.
1498            notifyActivityDrawnForKeyguard();
1499        }
1500        return err;
1501    }
1502
1503    ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) {
1504        final TaskRecord task = r.task;
1505
1506        // On leanback only devices we should keep all activities in the same stack.
1507        if (!mLeanbackOnlyDevice &&
1508                (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
1509            if (task != null) {
1510                final ActivityStack taskStack = task.stack;
1511                if (taskStack.isOnHomeDisplay()) {
1512                    if (mFocusedStack != taskStack) {
1513                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1514                                "focused stack to r=" + r + " task=" + task);
1515                        mFocusedStack = taskStack;
1516                    } else {
1517                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1518                            "adjustStackFocus: Focused stack already=" + mFocusedStack);
1519                    }
1520                }
1521                return taskStack;
1522            }
1523
1524            final ActivityContainer container = r.mInitialActivityContainer;
1525            if (container != null) {
1526                // The first time put it on the desired stack, after this put on task stack.
1527                r.mInitialActivityContainer = null;
1528                return container.mStack;
1529            }
1530
1531            if (mFocusedStack != mHomeStack && (!newTask ||
1532                    mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
1533                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1534                        "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1535                return mFocusedStack;
1536            }
1537
1538            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1539            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1540                final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1541                if (!stack.isHomeStack()) {
1542                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1543                            "adjustStackFocus: Setting focused stack=" + stack);
1544                    mFocusedStack = stack;
1545                    return mFocusedStack;
1546                }
1547            }
1548
1549            // Need to create an app stack for this user.
1550            int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
1551            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1552                    " stackId=" + stackId);
1553            mFocusedStack = getStack(stackId);
1554            return mFocusedStack;
1555        }
1556        return mHomeStack;
1557    }
1558
1559    void setFocusedStack(ActivityRecord r) {
1560        if (r != null) {
1561            final TaskRecord task = r.task;
1562            boolean isHomeActivity = !r.isApplicationActivity();
1563            if (!isHomeActivity && task != null) {
1564                isHomeActivity = !task.isApplicationTask();
1565            }
1566            if (!isHomeActivity && task != null) {
1567                final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1568                isHomeActivity = parent != null && parent.isHomeActivity();
1569            }
1570            moveHomeStack(isHomeActivity);
1571        }
1572    }
1573
1574    final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
1575            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
1576            boolean doResume, Bundle options, TaskRecord inTask) {
1577        final Intent intent = r.intent;
1578        final int callingUid = r.launchedFromUid;
1579
1580        // In some flows in to this function, we retrieve the task record and hold on to it
1581        // without a lock before calling back in to here...  so the task at this point may
1582        // not actually be in recents.  Check for that, and if it isn't in recents just
1583        // consider it invalid.
1584        if (inTask != null && !inTask.inRecents) {
1585            Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1586            inTask = null;
1587        }
1588
1589        final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
1590        final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
1591        final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
1592
1593        int launchFlags = intent.getFlags();
1594        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1595                (launchSingleInstance || launchSingleTask)) {
1596            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1597            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1598                    "\"singleInstance\" or \"singleTask\"");
1599            launchFlags &=
1600                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
1601        } else {
1602            switch (r.info.documentLaunchMode) {
1603                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1604                    break;
1605                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1606                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1607                    break;
1608                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1609                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1610                    break;
1611                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1612                    launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1613                    break;
1614            }
1615        }
1616
1617        final boolean launchTaskBehind = r.mLaunchTaskBehind
1618                && !launchSingleTask && !launchSingleInstance
1619                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1620
1621        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1622            // For whatever reason this activity is being launched into a new
1623            // task...  yet the caller has requested a result back.  Well, that
1624            // is pretty messed up, so instead immediately send back a cancel
1625            // and let the new task continue launched as normal without a
1626            // dependency on its originator.
1627            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1628            r.resultTo.task.stack.sendActivityResultLocked(-1,
1629                    r.resultTo, r.resultWho, r.requestCode,
1630                    Activity.RESULT_CANCELED, null);
1631            r.resultTo = null;
1632        }
1633
1634        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1635            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1636        }
1637
1638        // If we are actually going to launch in to a new task, there are some cases where
1639        // we further want to do multiple task.
1640        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1641            if (launchTaskBehind
1642                    || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
1643                launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1644            }
1645        }
1646
1647        // We'll invoke onUserLeaving before onPause only if the launching
1648        // activity did not explicitly state that this is an automated launch.
1649        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1650        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1651
1652        // If the caller has asked not to resume at this point, we make note
1653        // of this in the record so that we can skip it when trying to find
1654        // the top running activity.
1655        if (!doResume) {
1656            r.delayedResume = true;
1657        }
1658
1659        ActivityRecord notTop =
1660                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1661
1662        // If the onlyIfNeeded flag is set, then we can do this if the activity
1663        // being launched is the same as the one making the call...  or, as
1664        // a special case, if we do not know the caller then we count the
1665        // current top activity as the caller.
1666        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1667            ActivityRecord checkedCaller = sourceRecord;
1668            if (checkedCaller == null) {
1669                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1670            }
1671            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1672                // Caller is not the same as launcher, so always needed.
1673                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1674            }
1675        }
1676
1677        boolean addingToTask = false;
1678        TaskRecord reuseTask = null;
1679
1680        // If the caller is not coming from another activity, but has given us an
1681        // explicit task into which they would like us to launch the new activity,
1682        // then let's see about doing that.
1683        if (sourceRecord == null && inTask != null && inTask.stack != null) {
1684            final Intent baseIntent = inTask.getBaseIntent();
1685            final ActivityRecord root = inTask.getRootActivity();
1686            if (baseIntent == null) {
1687                ActivityOptions.abort(options);
1688                throw new IllegalArgumentException("Launching into task without base intent: "
1689                        + inTask);
1690            }
1691
1692            // If this task is empty, then we are adding the first activity -- it
1693            // determines the root, and must be launching as a NEW_TASK.
1694            if (launchSingleInstance || launchSingleTask) {
1695                if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
1696                    ActivityOptions.abort(options);
1697                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1698                            + r + " into different task " + inTask);
1699                }
1700                if (root != null) {
1701                    ActivityOptions.abort(options);
1702                    throw new IllegalArgumentException("Caller with inTask " + inTask
1703                            + " has root " + root + " but target is singleInstance/Task");
1704                }
1705            }
1706
1707            // If task is empty, then adopt the interesting intent launch flags in to the
1708            // activity being started.
1709            if (root == null) {
1710                final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
1711                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
1712                        | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1713                launchFlags = (launchFlags&~flagsOfInterest)
1714                        | (baseIntent.getFlags()&flagsOfInterest);
1715                intent.setFlags(launchFlags);
1716                inTask.setIntent(r);
1717                addingToTask = true;
1718
1719            // If the task is not empty and the caller is asking to start it as the root
1720            // of a new task, then we don't actually want to start this on the task.  We
1721            // will bring the task to the front, and possibly give it a new intent.
1722            } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1723                addingToTask = false;
1724
1725            } else {
1726                addingToTask = true;
1727            }
1728
1729            reuseTask = inTask;
1730        } else {
1731            inTask = null;
1732        }
1733
1734        if (inTask == null) {
1735            if (sourceRecord == null) {
1736                // This activity is not being started from another...  in this
1737                // case we -always- start a new task.
1738                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
1739                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1740                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1741                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1742                }
1743            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1744                // The original activity who is starting us is running as a single
1745                // instance...  this new activity it is starting must go on its
1746                // own task.
1747                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1748            } else if (launchSingleInstance || launchSingleTask) {
1749                // The activity being started is a single instance...  it always
1750                // gets launched into its own task.
1751                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1752            }
1753        }
1754
1755        ActivityInfo newTaskInfo = null;
1756        Intent newTaskIntent = null;
1757        ActivityStack sourceStack;
1758        if (sourceRecord != null) {
1759            if (sourceRecord.finishing) {
1760                // If the source is finishing, we can't further count it as our source.  This
1761                // is because the task it is associated with may now be empty and on its way out,
1762                // so we don't want to blindly throw it in to that task.  Instead we will take
1763                // the NEW_TASK flow and try to find a task for it. But save the task information
1764                // so it can be used when creating the new task.
1765                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1766                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1767                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1768                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1769                    newTaskInfo = sourceRecord.info;
1770                    newTaskIntent = sourceRecord.task.intent;
1771                }
1772                sourceRecord = null;
1773                sourceStack = null;
1774            } else {
1775                sourceStack = sourceRecord.task.stack;
1776            }
1777        } else {
1778            sourceStack = null;
1779        }
1780
1781        boolean movedHome = false;
1782        ActivityStack targetStack;
1783
1784        intent.setFlags(launchFlags);
1785
1786        // We may want to try to place the new activity in to an existing task.  We always
1787        // do this if the target activity is singleTask or singleInstance; we will also do
1788        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1789        // us to still place it in a new task: multi task, always doc mode, or being asked to
1790        // launch this as a new task behind the current one.
1791        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1792                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1793                || launchSingleInstance || launchSingleTask) {
1794            // If bring to front is requested, and no result is requested and we have not
1795            // been given an explicit task to launch in to, and
1796            // we can find a task that was started with this same
1797            // component, then instead of launching bring that one to the front.
1798            if (inTask == null && r.resultTo == null) {
1799                // See if there is a task to bring to the front.  If this is
1800                // a SINGLE_INSTANCE activity, there can be one and only one
1801                // instance of it in the history, and it is always in its own
1802                // unique task, so we do a special search.
1803                ActivityRecord intentActivity = !launchSingleInstance ?
1804                        findTaskLocked(r) : findActivityLocked(intent, r.info);
1805                if (intentActivity != null) {
1806                    if (isLockTaskModeViolation(intentActivity.task)) {
1807                        showLockTaskToast();
1808                        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1809                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1810                    }
1811                    if (r.task == null) {
1812                        r.task = intentActivity.task;
1813                    }
1814                    targetStack = intentActivity.task.stack;
1815                    targetStack.mLastPausedActivity = null;
1816                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1817                            + " from " + intentActivity);
1818                    targetStack.moveToFront();
1819                    if (intentActivity.task.intent == null) {
1820                        // This task was started because of movement of
1821                        // the activity based on affinity...  now that we
1822                        // are actually launching it, we can assign the
1823                        // base intent.
1824                        intentActivity.task.setIntent(r);
1825                    }
1826                    // If the target task is not in the front, then we need
1827                    // to bring it to the front...  except...  well, with
1828                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1829                    // to have the same behavior as if a new instance was
1830                    // being started, which means not bringing it to the front
1831                    // if the caller is not itself in the front.
1832                    final ActivityStack lastStack = getLastStack();
1833                    ActivityRecord curTop = lastStack == null?
1834                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1835                    boolean movedToFront = false;
1836                    if (curTop != null && (curTop.task != intentActivity.task ||
1837                            curTop.task != lastStack.topTask())) {
1838                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1839                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1840                                sourceStack.topActivity().task == sourceRecord.task)) {
1841                            // We really do want to push this one into the
1842                            // user's face, right now.
1843                            if (launchTaskBehind && sourceRecord != null) {
1844                                intentActivity.setTaskToAffiliateWith(sourceRecord.task);
1845                            }
1846                            movedHome = true;
1847                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1848                            if ((launchFlags &
1849                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1850                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1851                                // Caller wants to appear on home activity.
1852                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1853                            }
1854                            options = null;
1855                            movedToFront = true;
1856                        }
1857                    }
1858                    // If the caller has requested that the target task be
1859                    // reset, then do so.
1860                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1861                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1862                    }
1863                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1864                        // We don't need to start a new activity, and
1865                        // the client said not to do anything if that
1866                        // is the case, so this is it!  And for paranoia, make
1867                        // sure we have correctly resumed the top activity.
1868                        if (doResume) {
1869                            resumeTopActivitiesLocked(targetStack, null, options);
1870
1871                            // Make sure to notify Keyguard as well if we are not running an app
1872                            // transition later.
1873                            if (!movedToFront) {
1874                                notifyActivityDrawnForKeyguard();
1875                            }
1876                        } else {
1877                            ActivityOptions.abort(options);
1878                        }
1879                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1880                    }
1881                    if ((launchFlags &
1882                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1883                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1884                        // The caller has requested to completely replace any
1885                        // existing task with its new activity.  Well that should
1886                        // not be too hard...
1887                        reuseTask = intentActivity.task;
1888                        reuseTask.performClearTaskLocked();
1889                        reuseTask.setIntent(r);
1890                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1891                            || launchSingleInstance || launchSingleTask) {
1892                        // In this situation we want to remove all activities
1893                        // from the task up to the one being started.  In most
1894                        // cases this means we are resetting the task to its
1895                        // initial state.
1896                        ActivityRecord top =
1897                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1898                        if (top != null) {
1899                            if (top.frontOfTask) {
1900                                // Activity aliases may mean we use different
1901                                // intents for the top activity, so make sure
1902                                // the task now has the identity of the new
1903                                // intent.
1904                                top.task.setIntent(r);
1905                            }
1906                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1907                                    r, top.task);
1908                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
1909                        } else {
1910                            // A special case: we need to
1911                            // start the activity because it is not currently
1912                            // running, and the caller has asked to clear the
1913                            // current task to have this activity at the top.
1914                            addingToTask = true;
1915                            // Now pretend like this activity is being started
1916                            // by the top of its task, so it is put in the
1917                            // right place.
1918                            sourceRecord = intentActivity;
1919                        }
1920                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1921                        // In this case the top activity on the task is the
1922                        // same as the one being launched, so we take that
1923                        // as a request to bring the task to the foreground.
1924                        // If the top activity in the task is the root
1925                        // activity, deliver this new intent to it if it
1926                        // desires.
1927                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
1928                                && intentActivity.realActivity.equals(r.realActivity)) {
1929                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1930                                    intentActivity.task);
1931                            if (intentActivity.frontOfTask) {
1932                                intentActivity.task.setIntent(r);
1933                            }
1934                            intentActivity.deliverNewIntentLocked(callingUid, r.intent,
1935                                    r.launchedFromPackage);
1936                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1937                            // In this case we are launching the root activity
1938                            // of the task, but with a different intent.  We
1939                            // should start a new instance on top.
1940                            addingToTask = true;
1941                            sourceRecord = intentActivity;
1942                        }
1943                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1944                        // In this case an activity is being launched in to an
1945                        // existing task, without resetting that task.  This
1946                        // is typically the situation of launching an activity
1947                        // from a notification or shortcut.  We want to place
1948                        // the new activity on top of the current task.
1949                        addingToTask = true;
1950                        sourceRecord = intentActivity;
1951                    } else if (!intentActivity.task.rootWasReset) {
1952                        // In this case we are launching in to an existing task
1953                        // that has not yet been started from its front door.
1954                        // The current task has been brought to the front.
1955                        // Ideally, we'd probably like to place this new task
1956                        // at the bottom of its stack, but that's a little hard
1957                        // to do with the current organization of the code so
1958                        // for now we'll just drop it.
1959                        intentActivity.task.setIntent(r);
1960                    }
1961                    if (!addingToTask && reuseTask == null) {
1962                        // We didn't do anything...  but it was needed (a.k.a., client
1963                        // don't use that intent!)  And for paranoia, make
1964                        // sure we have correctly resumed the top activity.
1965                        if (doResume) {
1966                            targetStack.resumeTopActivityLocked(null, options);
1967                            if (!movedToFront) {
1968                                // Make sure to notify Keyguard as well if we are not running an app
1969                                // transition later.
1970                                notifyActivityDrawnForKeyguard();
1971                            }
1972                        } else {
1973                            ActivityOptions.abort(options);
1974                        }
1975                        return ActivityManager.START_TASK_TO_FRONT;
1976                    }
1977                }
1978            }
1979        }
1980
1981        //String uri = r.intent.toURI();
1982        //Intent intent2 = new Intent(uri);
1983        //Slog.i(TAG, "Given intent: " + r.intent);
1984        //Slog.i(TAG, "URI is: " + uri);
1985        //Slog.i(TAG, "To intent: " + intent2);
1986
1987        if (r.packageName != null) {
1988            // If the activity being launched is the same as the one currently
1989            // at the top, then we need to check if it should only be launched
1990            // once.
1991            ActivityStack topStack = getFocusedStack();
1992            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1993            if (top != null && r.resultTo == null) {
1994                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1995                    if (top.app != null && top.app.thread != null) {
1996                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1997                            || launchSingleTop || launchSingleTask) {
1998                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1999                                    top.task);
2000                            // For paranoia, make sure we have correctly
2001                            // resumed the top activity.
2002                            topStack.mLastPausedActivity = null;
2003                            if (doResume) {
2004                                resumeTopActivitiesLocked();
2005                            }
2006                            ActivityOptions.abort(options);
2007                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2008                                // We don't need to start a new activity, and
2009                                // the client said not to do anything if that
2010                                // is the case, so this is it!
2011                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2012                            }
2013                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2014                            return ActivityManager.START_DELIVERED_TO_TOP;
2015                        }
2016                    }
2017                }
2018            }
2019
2020        } else {
2021            if (r.resultTo != null) {
2022                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
2023                        r.requestCode, Activity.RESULT_CANCELED, null);
2024            }
2025            ActivityOptions.abort(options);
2026            return ActivityManager.START_CLASS_NOT_FOUND;
2027        }
2028
2029        boolean newTask = false;
2030        boolean keepCurTransition = false;
2031
2032        TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
2033                sourceRecord.task : null;
2034
2035        // Should this be considered a new task?
2036        if (r.resultTo == null && inTask == null && !addingToTask
2037                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
2038            if (isLockTaskModeViolation(reuseTask)) {
2039                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2040                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2041            }
2042            newTask = true;
2043            targetStack = adjustStackFocus(r, newTask);
2044            if (!launchTaskBehind) {
2045                targetStack.moveToFront();
2046            }
2047            if (reuseTask == null) {
2048                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
2049                        newTaskInfo != null ? newTaskInfo : r.info,
2050                        newTaskIntent != null ? newTaskIntent : intent,
2051                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
2052                        taskToAffiliate);
2053                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
2054                        r.task);
2055            } else {
2056                r.setTask(reuseTask, taskToAffiliate);
2057            }
2058            if (!movedHome) {
2059                if ((launchFlags &
2060                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
2061                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
2062                    // Caller wants to appear on home activity, so before starting
2063                    // their own activity we will bring home to the front.
2064                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2065                }
2066            }
2067        } else if (sourceRecord != null) {
2068            final TaskRecord sourceTask = sourceRecord.task;
2069            if (isLockTaskModeViolation(sourceTask)) {
2070                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2071                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2072            }
2073            targetStack = sourceTask.stack;
2074            targetStack.moveToFront();
2075            final TaskRecord topTask = targetStack.topTask();
2076            if (topTask != sourceTask) {
2077                targetStack.moveTaskToFrontLocked(sourceTask, r, options);
2078            }
2079            if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2080                // In this case, we are adding the activity to an existing
2081                // task, but the caller has asked to clear that task if the
2082                // activity is already running.
2083                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
2084                keepCurTransition = true;
2085                if (top != null) {
2086                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
2087                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2088                    // For paranoia, make sure we have correctly
2089                    // resumed the top activity.
2090                    targetStack.mLastPausedActivity = null;
2091                    if (doResume) {
2092                        targetStack.resumeTopActivityLocked(null);
2093                    }
2094                    ActivityOptions.abort(options);
2095                    return ActivityManager.START_DELIVERED_TO_TOP;
2096                }
2097            } else if (!addingToTask &&
2098                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2099                // In this case, we are launching an activity in our own task
2100                // that may already be running somewhere in the history, and
2101                // we want to shuffle it to the front of the stack if so.
2102                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
2103                if (top != null) {
2104                    final TaskRecord task = top.task;
2105                    task.moveActivityToFrontLocked(top);
2106                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
2107                    top.updateOptionsLocked(options);
2108                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2109                    targetStack.mLastPausedActivity = null;
2110                    if (doResume) {
2111                        targetStack.resumeTopActivityLocked(null);
2112                    }
2113                    return ActivityManager.START_DELIVERED_TO_TOP;
2114                }
2115            }
2116            // An existing activity is starting this new activity, so we want
2117            // to keep the new one in the same task as the one that is starting
2118            // it.
2119            r.setTask(sourceTask, null);
2120            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
2121                    + " in existing task " + r.task + " from source " + sourceRecord);
2122
2123        } else if (inTask != null) {
2124            // The calling is asking that the new activity be started in an explicit
2125            // task it has provided to us.
2126            if (isLockTaskModeViolation(inTask)) {
2127                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2128                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2129            }
2130            targetStack = inTask.stack;
2131            targetStack.moveTaskToFrontLocked(inTask, r, options);
2132
2133            // Check whether we should actually launch the new activity in to the task,
2134            // or just reuse the current activity on top.
2135            ActivityRecord top = inTask.getTopActivity();
2136            if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2137                if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2138                        || launchSingleTop || launchSingleTask) {
2139                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
2140                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2141                        // We don't need to start a new activity, and
2142                        // the client said not to do anything if that
2143                        // is the case, so this is it!
2144                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2145                    }
2146                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2147                    return ActivityManager.START_DELIVERED_TO_TOP;
2148                }
2149            }
2150
2151            if (!addingToTask) {
2152                // We don't actually want to have this activity added to the task, so just
2153                // stop here but still tell the caller that we consumed the intent.
2154                ActivityOptions.abort(options);
2155                return ActivityManager.START_TASK_TO_FRONT;
2156            }
2157
2158            r.setTask(inTask, null);
2159            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
2160                    + " in explicit task " + r.task);
2161
2162        } else {
2163            // This not being started from an existing activity, and not part
2164            // of a new task...  just put it in the top task, though these days
2165            // this case should never happen.
2166            targetStack = adjustStackFocus(r, newTask);
2167            targetStack.moveToFront();
2168            ActivityRecord prev = targetStack.topActivity();
2169            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
2170                            r.info, intent, null, null, true), null);
2171            mWindowManager.moveTaskToTop(r.task.taskId);
2172            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
2173                    + " in new guessed " + r.task);
2174        }
2175
2176        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2177                intent, r.getUriPermissionsLocked(), r.userId);
2178
2179        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
2180            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
2181        }
2182        if (newTask) {
2183            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
2184        }
2185        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
2186        targetStack.mLastPausedActivity = null;
2187        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
2188        if (!launchTaskBehind) {
2189            // Don't set focus on an activity that's going to the back.
2190            mService.setFocusedActivityLocked(r);
2191        }
2192        return ActivityManager.START_SUCCESS;
2193    }
2194
2195    final void doPendingActivityLaunchesLocked(boolean doResume) {
2196        while (!mPendingActivityLaunches.isEmpty()) {
2197            PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
2198            startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
2199                    doResume && mPendingActivityLaunches.isEmpty(), null, null);
2200        }
2201    }
2202
2203    void removePendingActivityLaunchesLocked(ActivityStack stack) {
2204        for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
2205            PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
2206            if (pal.stack == stack) {
2207                mPendingActivityLaunches.remove(palNdx);
2208            }
2209        }
2210    }
2211
2212    void acquireLaunchWakelock() {
2213        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2214            throw new IllegalStateException("Calling must be system uid");
2215        }
2216        mLaunchingActivity.acquire();
2217        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2218            // To be safe, don't allow the wake lock to be held for too long.
2219            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2220        }
2221    }
2222
2223    // Checked.
2224    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2225            Configuration config) {
2226        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
2227
2228        ArrayList<ActivityRecord> stops = null;
2229        ArrayList<ActivityRecord> finishes = null;
2230        ArrayList<UserStartedState> startingUsers = null;
2231        int NS = 0;
2232        int NF = 0;
2233        boolean booting = false;
2234        boolean enableScreen = false;
2235        boolean activityRemoved = false;
2236
2237        ActivityRecord r = ActivityRecord.forToken(token);
2238        if (r != null) {
2239            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
2240                    Debug.getCallers(4));
2241            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2242            r.finishLaunchTickingLocked();
2243            if (fromTimeout) {
2244                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2245            }
2246
2247            // This is a hack to semi-deal with a race condition
2248            // in the client where it can be constructed with a
2249            // newer configuration from when we asked it to launch.
2250            // We'll update with whatever configuration it now says
2251            // it used to launch.
2252            if (config != null) {
2253                r.configuration = config;
2254            }
2255
2256            // We are now idle.  If someone is waiting for a thumbnail from
2257            // us, we can now deliver.
2258            r.idle = true;
2259
2260            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2261            if (isFrontStack(r.task.stack) || fromTimeout) {
2262                booting = mService.mBooting;
2263                mService.mBooting = false;
2264                if (!mService.mBooted) {
2265                    mService.mBooted = true;
2266                    enableScreen = true;
2267                }
2268            }
2269        }
2270
2271        if (allResumedActivitiesIdle()) {
2272            if (r != null) {
2273                mService.scheduleAppGcsLocked();
2274            }
2275
2276            if (mLaunchingActivity.isHeld()) {
2277                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2278                if (VALIDATE_WAKE_LOCK_CALLER &&
2279                        Binder.getCallingUid() != Process.myUid()) {
2280                    throw new IllegalStateException("Calling must be system uid");
2281                }
2282                mLaunchingActivity.release();
2283            }
2284            ensureActivitiesVisibleLocked(null, 0);
2285        }
2286
2287        // Atomically retrieve all of the other things to do.
2288        stops = processStoppingActivitiesLocked(true);
2289        NS = stops != null ? stops.size() : 0;
2290        if ((NF=mFinishingActivities.size()) > 0) {
2291            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
2292            mFinishingActivities.clear();
2293        }
2294
2295        if (mStartingUsers.size() > 0) {
2296            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
2297            mStartingUsers.clear();
2298        }
2299
2300        // Stop any activities that are scheduled to do so but have been
2301        // waiting for the next one to start.
2302        for (int i = 0; i < NS; i++) {
2303            r = stops.get(i);
2304            final ActivityStack stack = r.task.stack;
2305            if (r.finishing) {
2306                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2307            } else {
2308                stack.stopActivityLocked(r);
2309            }
2310        }
2311
2312        // Finish any activities that are scheduled to do so but have been
2313        // waiting for the next one to start.
2314        for (int i = 0; i < NF; i++) {
2315            r = finishes.get(i);
2316            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle");
2317        }
2318
2319        if (!booting) {
2320            // Complete user switch
2321            if (startingUsers != null) {
2322                for (int i = 0; i < startingUsers.size(); i++) {
2323                    mService.finishUserSwitch(startingUsers.get(i));
2324                }
2325            }
2326            // Complete starting up of background users
2327            if (mStartingBackgroundUsers.size() > 0) {
2328                startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
2329                mStartingBackgroundUsers.clear();
2330                for (int i = 0; i < startingUsers.size(); i++) {
2331                    mService.finishUserBoot(startingUsers.get(i));
2332                }
2333            }
2334        }
2335
2336        mService.trimApplications();
2337        //dump();
2338        //mWindowManager.dump();
2339
2340        if (booting || enableScreen) {
2341            mService.postFinishBooting(booting, enableScreen);
2342        }
2343
2344        if (activityRemoved) {
2345            resumeTopActivitiesLocked();
2346        }
2347
2348        return r;
2349    }
2350
2351    boolean handleAppDiedLocked(ProcessRecord app) {
2352        boolean hasVisibleActivities = false;
2353        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2354            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2355            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2356                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2357            }
2358        }
2359        return hasVisibleActivities;
2360    }
2361
2362    void closeSystemDialogsLocked() {
2363        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2364            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2365            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2366                stacks.get(stackNdx).closeSystemDialogsLocked();
2367            }
2368        }
2369    }
2370
2371    void removeUserLocked(int userId) {
2372        mUserStackInFront.delete(userId);
2373    }
2374
2375    /**
2376     * @return true if some activity was finished (or would have finished if doit were true).
2377     */
2378    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2379        boolean didSomething = false;
2380        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2381            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2382            final int numStacks = stacks.size();
2383            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2384                final ActivityStack stack = stacks.get(stackNdx);
2385                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2386                    didSomething = true;
2387                }
2388            }
2389        }
2390        return didSomething;
2391    }
2392
2393    void updatePreviousProcessLocked(ActivityRecord r) {
2394        // Now that this process has stopped, we may want to consider
2395        // it to be the previous app to try to keep around in case
2396        // the user wants to return to it.
2397
2398        // First, found out what is currently the foreground app, so that
2399        // we don't blow away the previous app if this activity is being
2400        // hosted by the process that is actually still the foreground.
2401        ProcessRecord fgApp = null;
2402        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2403            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2404            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2405                final ActivityStack stack = stacks.get(stackNdx);
2406                if (isFrontStack(stack)) {
2407                    if (stack.mResumedActivity != null) {
2408                        fgApp = stack.mResumedActivity.app;
2409                    } else if (stack.mPausingActivity != null) {
2410                        fgApp = stack.mPausingActivity.app;
2411                    }
2412                    break;
2413                }
2414            }
2415        }
2416
2417        // Now set this one as the previous process, only if that really
2418        // makes sense to.
2419        if (r.app != null && fgApp != null && r.app != fgApp
2420                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2421                && r.app != mService.mHomeProcess) {
2422            mService.mPreviousProcess = r.app;
2423            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2424        }
2425    }
2426
2427    boolean resumeTopActivitiesLocked() {
2428        return resumeTopActivitiesLocked(null, null, null);
2429    }
2430
2431    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2432            Bundle targetOptions) {
2433        if (targetStack == null) {
2434            targetStack = getFocusedStack();
2435        }
2436        // Do targetStack first.
2437        boolean result = false;
2438        if (isFrontStack(targetStack)) {
2439            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2440        }
2441        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2442            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2443            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2444                final ActivityStack stack = stacks.get(stackNdx);
2445                if (stack == targetStack) {
2446                    // Already started above.
2447                    continue;
2448                }
2449                if (isFrontStack(stack)) {
2450                    stack.resumeTopActivityLocked(null);
2451                }
2452            }
2453        }
2454        return result;
2455    }
2456
2457    void finishTopRunningActivityLocked(ProcessRecord app) {
2458        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2459            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2460            final int numStacks = stacks.size();
2461            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2462                final ActivityStack stack = stacks.get(stackNdx);
2463                stack.finishTopRunningActivityLocked(app);
2464            }
2465        }
2466    }
2467
2468    void finishVoiceTask(IVoiceInteractionSession session) {
2469        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2470            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2471            final int numStacks = stacks.size();
2472            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2473                final ActivityStack stack = stacks.get(stackNdx);
2474                stack.finishVoiceTask(session);
2475            }
2476        }
2477    }
2478
2479    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2480        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2481            mUserLeaving = true;
2482        }
2483        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2484            // Caller wants the home activity moved with it.  To accomplish this,
2485            // we'll just indicate that this task returns to the home task.
2486            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2487        }
2488        task.stack.moveTaskToFrontLocked(task, null, options);
2489        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2490                + task.stack);
2491    }
2492
2493    ActivityStack getStack(int stackId) {
2494        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2495        if (activityContainer != null) {
2496            return activityContainer.mStack;
2497        }
2498        return null;
2499    }
2500
2501    ArrayList<ActivityStack> getStacks() {
2502        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2503        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2504            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2505        }
2506        return allStacks;
2507    }
2508
2509    IBinder getHomeActivityToken() {
2510        ActivityRecord homeActivity = getHomeActivity();
2511        if (homeActivity != null) {
2512            return homeActivity.appToken;
2513        }
2514        return null;
2515    }
2516
2517    ActivityRecord getHomeActivity() {
2518        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2519        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2520            final TaskRecord task = tasks.get(taskNdx);
2521            if (task.isHomeTask()) {
2522                final ArrayList<ActivityRecord> activities = task.mActivities;
2523                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2524                    final ActivityRecord r = activities.get(activityNdx);
2525                    if (r.isHomeActivity()) {
2526                        return r;
2527                    }
2528                }
2529            }
2530        }
2531        return null;
2532    }
2533
2534    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2535            IActivityContainerCallback callback) {
2536        ActivityContainer activityContainer =
2537                new VirtualActivityContainer(parentActivity, callback);
2538        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2539        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
2540        parentActivity.mChildContainers.add(activityContainer);
2541        return activityContainer;
2542    }
2543
2544    void removeChildActivityContainers(ActivityRecord parentActivity) {
2545        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2546        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2547            ActivityContainer container = childStacks.remove(containerNdx);
2548            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
2549                    container);
2550            container.release();
2551        }
2552    }
2553
2554    void deleteActivityContainer(IActivityContainer container) {
2555        ActivityContainer activityContainer = (ActivityContainer)container;
2556        if (activityContainer != null) {
2557            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
2558                    new RuntimeException("here").fillInStackTrace());
2559            final int stackId = activityContainer.mStackId;
2560            mActivityContainers.remove(stackId);
2561            mWindowManager.removeStack(stackId);
2562        }
2563    }
2564
2565    private int createStackOnDisplay(int stackId, int displayId) {
2566        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2567        if (activityDisplay == null) {
2568            return -1;
2569        }
2570
2571        ActivityContainer activityContainer = new ActivityContainer(stackId);
2572        mActivityContainers.put(stackId, activityContainer);
2573        activityContainer.attachToDisplayLocked(activityDisplay);
2574        return stackId;
2575    }
2576
2577    int getNextStackId() {
2578        while (true) {
2579            if (++mLastStackId <= HOME_STACK_ID) {
2580                mLastStackId = HOME_STACK_ID + 1;
2581            }
2582            if (getStack(mLastStackId) == null) {
2583                break;
2584            }
2585        }
2586        return mLastStackId;
2587    }
2588
2589    void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) {
2590        int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2591        final ActivityStack stack = getStack(stackId);
2592        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2593            final TaskRecord task = tasks.get(taskNdx);
2594            stack.addTask(task, false, false);
2595            final int taskId = task.taskId;
2596            final ArrayList<ActivityRecord> activities = task.mActivities;
2597            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2598                final ActivityRecord r = activities.get(activityNdx);
2599                mWindowManager.addAppToken(0, r.appToken, taskId, stackId,
2600                        r.info.screenOrientation, r.fullscreen,
2601                        (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
2602                        r.userId, r.info.configChanges, task.voiceSession != null,
2603                        r.mLaunchTaskBehind);
2604            }
2605        }
2606    }
2607
2608    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2609        final TaskRecord task = anyTaskForIdLocked(taskId);
2610        if (task == null) {
2611            return;
2612        }
2613        final ActivityStack stack = getStack(stackId);
2614        if (stack == null) {
2615            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2616            return;
2617        }
2618        task.stack.removeTask(task);
2619        stack.addTask(task, toTop, true);
2620        mWindowManager.addTask(taskId, stackId, toTop);
2621        resumeTopActivitiesLocked();
2622    }
2623
2624    ActivityRecord findTaskLocked(ActivityRecord r) {
2625        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2626        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2627            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2628            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2629                final ActivityStack stack = stacks.get(stackNdx);
2630                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2631                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2632                    continue;
2633                }
2634                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2635                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2636                            stack);
2637                    continue;
2638                }
2639                final ActivityRecord ar = stack.findTaskLocked(r);
2640                if (ar != null) {
2641                    return ar;
2642                }
2643            }
2644        }
2645        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2646        return null;
2647    }
2648
2649    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2650        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2651            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2652            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2653                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2654                if (ar != null) {
2655                    return ar;
2656                }
2657            }
2658        }
2659        return null;
2660    }
2661
2662    void goingToSleepLocked() {
2663        scheduleSleepTimeout();
2664        if (!mGoingToSleep.isHeld()) {
2665            mGoingToSleep.acquire();
2666            if (mLaunchingActivity.isHeld()) {
2667                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2668                    throw new IllegalStateException("Calling must be system uid");
2669                }
2670                mLaunchingActivity.release();
2671                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2672            }
2673        }
2674        checkReadyForSleepLocked();
2675    }
2676
2677    boolean shutdownLocked(int timeout) {
2678        goingToSleepLocked();
2679
2680        boolean timedout = false;
2681        final long endTime = System.currentTimeMillis() + timeout;
2682        while (true) {
2683            boolean cantShutdown = false;
2684            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2685                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2686                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2687                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2688                }
2689            }
2690            if (cantShutdown) {
2691                long timeRemaining = endTime - System.currentTimeMillis();
2692                if (timeRemaining > 0) {
2693                    try {
2694                        mService.wait(timeRemaining);
2695                    } catch (InterruptedException e) {
2696                    }
2697                } else {
2698                    Slog.w(TAG, "Activity manager shutdown timed out");
2699                    timedout = true;
2700                    break;
2701                }
2702            } else {
2703                break;
2704            }
2705        }
2706
2707        // Force checkReadyForSleep to complete.
2708        mSleepTimeout = true;
2709        checkReadyForSleepLocked();
2710
2711        return timedout;
2712    }
2713
2714    void comeOutOfSleepIfNeededLocked() {
2715        removeSleepTimeouts();
2716        if (mGoingToSleep.isHeld()) {
2717            mGoingToSleep.release();
2718        }
2719        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2720            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2721            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2722                final ActivityStack stack = stacks.get(stackNdx);
2723                stack.awakeFromSleepingLocked();
2724                if (isFrontStack(stack)) {
2725                    resumeTopActivitiesLocked();
2726                }
2727            }
2728        }
2729        mGoingToSleepActivities.clear();
2730    }
2731
2732    void activitySleptLocked(ActivityRecord r) {
2733        mGoingToSleepActivities.remove(r);
2734        checkReadyForSleepLocked();
2735    }
2736
2737    void checkReadyForSleepLocked() {
2738        if (!mService.isSleepingOrShuttingDown()) {
2739            // Do not care.
2740            return;
2741        }
2742
2743        if (!mSleepTimeout) {
2744            boolean dontSleep = false;
2745            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2746                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2747                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2748                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2749                }
2750            }
2751
2752            if (mStoppingActivities.size() > 0) {
2753                // Still need to tell some activities to stop; can't sleep yet.
2754                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2755                        + mStoppingActivities.size() + " activities");
2756                scheduleIdleLocked();
2757                dontSleep = true;
2758            }
2759
2760            if (mGoingToSleepActivities.size() > 0) {
2761                // Still need to tell some activities to sleep; can't sleep yet.
2762                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2763                        + mGoingToSleepActivities.size() + " activities");
2764                dontSleep = true;
2765            }
2766
2767            if (dontSleep) {
2768                return;
2769            }
2770        }
2771
2772        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2773            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2774            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2775                stacks.get(stackNdx).goToSleep();
2776            }
2777        }
2778
2779        removeSleepTimeouts();
2780
2781        if (mGoingToSleep.isHeld()) {
2782            mGoingToSleep.release();
2783        }
2784        if (mService.mShuttingDown) {
2785            mService.notifyAll();
2786        }
2787    }
2788
2789    boolean reportResumedActivityLocked(ActivityRecord r) {
2790        final ActivityStack stack = r.task.stack;
2791        if (isFrontStack(stack)) {
2792            mService.updateUsageStats(r, true);
2793        }
2794        if (allResumedActivitiesComplete()) {
2795            ensureActivitiesVisibleLocked(null, 0);
2796            mWindowManager.executeAppTransition();
2797            return true;
2798        }
2799        return false;
2800    }
2801
2802    void handleAppCrashLocked(ProcessRecord app) {
2803        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2804            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2805            final int numStacks = stacks.size();
2806            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2807                final ActivityStack stack = stacks.get(stackNdx);
2808                stack.handleAppCrashLocked(app);
2809            }
2810        }
2811    }
2812
2813    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
2814        final ActivityStack stack = r.task.stack;
2815        if (stack == null) {
2816            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: r=" + r + " visible=" +
2817                    visible + " stack is null");
2818            return false;
2819        }
2820        final boolean isVisible = stack.hasVisibleBehindActivity();
2821        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind r=" + r + " visible=" +
2822                visible + " isVisible=" + isVisible);
2823
2824        final ActivityRecord top = topRunningActivityLocked();
2825        if (top == null || top == r || (visible == isVisible)) {
2826            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: quick return");
2827            stack.setVisibleBehindActivity(visible ? r : null);
2828            return true;
2829        }
2830
2831        // A non-top activity is reporting a visibility change.
2832        if (visible && top.fullscreen) {
2833            // Let the caller know that it can't be seen.
2834            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen="
2835                    + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app +
2836                    " top.app.thread=" + top.app.thread);
2837            return false;
2838        } else if (!visible && stack.getVisibleBehindActivity() != r) {
2839            // Only the activity set as currently visible behind should actively reset its
2840            // visible behind state.
2841            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning visible="
2842                    + visible + " stack.getVisibleBehindActivity()=" +
2843                    stack.getVisibleBehindActivity() + " r=" + r);
2844            return false;
2845        }
2846
2847        stack.setVisibleBehindActivity(visible ? r : null);
2848        if (!visible) {
2849            // Make the activity immediately above r opaque.
2850            final ActivityRecord next = stack.findNextTranslucentActivity(r);
2851            if (next != null) {
2852                mService.convertFromTranslucent(next.appToken);
2853            }
2854        }
2855        if (top.app != null && top.app.thread != null) {
2856            // Notify the top app of the change.
2857            try {
2858                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
2859            } catch (RemoteException e) {
2860            }
2861        }
2862        return true;
2863    }
2864
2865    // Called when WindowManager has finished animating the launchingBehind activity to the back.
2866    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2867        r.mLaunchTaskBehind = false;
2868        final TaskRecord task = r.task;
2869        task.setLastThumbnail(task.stack.screenshotActivities(r));
2870        mService.addRecentTaskLocked(task);
2871        mService.notifyTaskStackChangedLocked();
2872        mWindowManager.setAppVisibility(r.appToken, false);
2873    }
2874
2875    void scheduleLaunchTaskBehindComplete(IBinder token) {
2876        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2877    }
2878
2879    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2880        // First the front stacks. In case any are not fullscreen and are in front of home.
2881        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2882            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2883            final int topStackNdx = stacks.size() - 1;
2884            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2885                final ActivityStack stack = stacks.get(stackNdx);
2886                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2887            }
2888        }
2889    }
2890
2891    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2892        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2893            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2894            final int numStacks = stacks.size();
2895            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2896                final ActivityStack stack = stacks.get(stackNdx);
2897                stack.scheduleDestroyActivities(app, reason);
2898            }
2899        }
2900    }
2901
2902    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
2903        // Examine all activities currently running in the process.
2904        TaskRecord firstTask = null;
2905        // Tasks is non-null only if two or more tasks are found.
2906        ArraySet<TaskRecord> tasks = null;
2907        if (DEBUG_RELEASE) Slog.d(TAG, "Trying to release some activities in " + app);
2908        for (int i=0; i<app.activities.size(); i++) {
2909            ActivityRecord r = app.activities.get(i);
2910            // First, if we find an activity that is in the process of being destroyed,
2911            // then we just aren't going to do anything for now; we want things to settle
2912            // down before we try to prune more activities.
2913            if (r.finishing || r.state == ActivityState.DESTROYING
2914                    || r.state == ActivityState.DESTROYED) {
2915                if (DEBUG_RELEASE) Slog.d(TAG, "Abort release; already destroying: " + r);
2916                return;
2917            }
2918            // Don't consider any activies that are currently not in a state where they
2919            // can be destroyed.
2920            if (r.visible || !r.stopped || !r.haveState
2921                    || r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING
2922                    || r.state == ActivityState.PAUSED || r.state == ActivityState.STOPPING) {
2923                if (DEBUG_RELEASE) Slog.d(TAG, "Not releasing in-use activity: " + r);
2924                continue;
2925            }
2926            if (r.task != null) {
2927                if (DEBUG_RELEASE) Slog.d(TAG, "Collecting release task " + r.task
2928                        + " from " + r);
2929                if (firstTask == null) {
2930                    firstTask = r.task;
2931                } else if (firstTask != r.task) {
2932                    if (tasks == null) {
2933                        tasks = new ArraySet<>();
2934                        tasks.add(firstTask);
2935                    }
2936                    tasks.add(r.task);
2937                }
2938            }
2939        }
2940        if (tasks == null) {
2941            if (DEBUG_RELEASE) Slog.d(TAG, "Didn't find two or more tasks to release");
2942            return;
2943        }
2944        // If we have activities in multiple tasks that are in a position to be destroyed,
2945        // let's iterate through the tasks and release the oldest one.
2946        final int numDisplays = mActivityDisplays.size();
2947        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2948            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2949            // Step through all stacks starting from behind, to hit the oldest things first.
2950            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
2951                final ActivityStack stack = stacks.get(stackNdx);
2952                // Try to release activities in this stack; if we manage to, we are done.
2953                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
2954                    return;
2955                }
2956            }
2957        }
2958    }
2959
2960    boolean switchUserLocked(int userId, UserStartedState uss) {
2961        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2962        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2963        mCurrentUser = userId;
2964
2965        mStartingUsers.add(uss);
2966        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2967            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2968            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2969                final ActivityStack stack = stacks.get(stackNdx);
2970                stack.switchUserLocked(userId);
2971                TaskRecord task = stack.topTask();
2972                if (task != null) {
2973                    mWindowManager.moveTaskToTop(task.taskId);
2974                }
2975            }
2976        }
2977
2978        ActivityStack stack = getStack(restoreStackId);
2979        if (stack == null) {
2980            stack = mHomeStack;
2981        }
2982        final boolean homeInFront = stack.isHomeStack();
2983        if (stack.isOnHomeDisplay()) {
2984            moveHomeStack(homeInFront);
2985            TaskRecord task = stack.topTask();
2986            if (task != null) {
2987                mWindowManager.moveTaskToTop(task.taskId);
2988            }
2989        } else {
2990            // Stack was moved to another display while user was swapped out.
2991            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2992        }
2993        return homeInFront;
2994    }
2995
2996    /**
2997     * Add background users to send boot completed events to.
2998     * @param userId The user being started in the background
2999     * @param uss The state object for the user.
3000     */
3001    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
3002        mStartingBackgroundUsers.add(uss);
3003    }
3004
3005    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
3006        int N = mStoppingActivities.size();
3007        if (N <= 0) return null;
3008
3009        ArrayList<ActivityRecord> stops = null;
3010
3011        final boolean nowVisible = allResumedActivitiesVisible();
3012        for (int i=0; i<N; i++) {
3013            ActivityRecord s = mStoppingActivities.get(i);
3014            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
3015                    + nowVisible + " waitingVisible=" + s.waitingVisible
3016                    + " finishing=" + s.finishing);
3017            if (s.waitingVisible && nowVisible) {
3018                mWaitingVisibleActivities.remove(s);
3019                s.waitingVisible = false;
3020                if (s.finishing) {
3021                    // If this activity is finishing, it is sitting on top of
3022                    // everyone else but we now know it is no longer needed...
3023                    // so get rid of it.  Otherwise, we need to go through the
3024                    // normal flow and hide it once we determine that it is
3025                    // hidden by the activities in front of it.
3026                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
3027                    mWindowManager.setAppVisibility(s.appToken, false);
3028                }
3029            }
3030            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
3031                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
3032                if (stops == null) {
3033                    stops = new ArrayList<ActivityRecord>();
3034                }
3035                stops.add(s);
3036                mStoppingActivities.remove(i);
3037                N--;
3038                i--;
3039            }
3040        }
3041
3042        return stops;
3043    }
3044
3045    void validateTopActivitiesLocked() {
3046        // FIXME
3047/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3048            final ActivityStack stack = stacks.get(stackNdx);
3049            final ActivityRecord r = stack.topRunningActivityLocked(null);
3050            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
3051            if (isFrontStack(stack)) {
3052                if (r == null) {
3053                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
3054                } else {
3055                    final ActivityRecord pausing = stack.mPausingActivity;
3056                    if (pausing != null && pausing == r) {
3057                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
3058                            " state=" + state);
3059                    }
3060                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
3061                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
3062                                " state=" + state);
3063                    }
3064                }
3065            } else {
3066                final ActivityRecord resumed = stack.mResumedActivity;
3067                if (resumed != null && resumed == r) {
3068                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
3069                        " state=" + state);
3070                }
3071                if (r != null && (state == ActivityState.INITIALIZING
3072                        || state == ActivityState.RESUMED)) {
3073                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
3074                            " state=" + state);
3075                }
3076            }
3077        }
3078*/
3079    }
3080
3081    public void dump(PrintWriter pw, String prefix) {
3082        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3083                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3084        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3085        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
3086        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3087        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3088    }
3089
3090    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3091        return getFocusedStack().getDumpActivitiesLocked(name);
3092    }
3093
3094    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3095            boolean needSep, String prefix) {
3096        if (activity != null) {
3097            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3098                if (needSep) {
3099                    pw.println();
3100                }
3101                pw.print(prefix);
3102                pw.println(activity);
3103                return true;
3104            }
3105        }
3106        return false;
3107    }
3108
3109    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3110            boolean dumpClient, String dumpPackage) {
3111        boolean printed = false;
3112        boolean needSep = false;
3113        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3114            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3115            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3116                    pw.println(" (activities from top to bottom):");
3117            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3118            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3119                final ActivityStack stack = stacks.get(stackNdx);
3120                StringBuilder stackHeader = new StringBuilder(128);
3121                stackHeader.append("  Stack #");
3122                stackHeader.append(stack.mStackId);
3123                stackHeader.append(":");
3124                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3125                        needSep, stackHeader.toString());
3126                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3127                        !dumpAll, false, dumpPackage, true,
3128                        "    Running activities (most recent first):", null);
3129
3130                needSep = printed;
3131                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3132                        "    mPausingActivity: ");
3133                if (pr) {
3134                    printed = true;
3135                    needSep = false;
3136                }
3137                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3138                        "    mResumedActivity: ");
3139                if (pr) {
3140                    printed = true;
3141                    needSep = false;
3142                }
3143                if (dumpAll) {
3144                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3145                            "    mLastPausedActivity: ");
3146                    if (pr) {
3147                        printed = true;
3148                        needSep = true;
3149                    }
3150                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3151                            needSep, "    mLastNoHistoryActivity: ");
3152                }
3153                needSep = printed;
3154            }
3155        }
3156
3157        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3158                false, dumpPackage, true, "  Activities waiting to finish:", null);
3159        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3160                false, dumpPackage, true, "  Activities waiting to stop:", null);
3161        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3162                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3163                null);
3164        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3165                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3166        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3167                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3168
3169        return printed;
3170    }
3171
3172    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3173            String prefix, String label, boolean complete, boolean brief, boolean client,
3174            String dumpPackage, boolean needNL, String header1, String header2) {
3175        TaskRecord lastTask = null;
3176        String innerPrefix = null;
3177        String[] args = null;
3178        boolean printed = false;
3179        for (int i=list.size()-1; i>=0; i--) {
3180            final ActivityRecord r = list.get(i);
3181            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3182                continue;
3183            }
3184            if (innerPrefix == null) {
3185                innerPrefix = prefix + "      ";
3186                args = new String[0];
3187            }
3188            printed = true;
3189            final boolean full = !brief && (complete || !r.isInHistory());
3190            if (needNL) {
3191                pw.println("");
3192                needNL = false;
3193            }
3194            if (header1 != null) {
3195                pw.println(header1);
3196                header1 = null;
3197            }
3198            if (header2 != null) {
3199                pw.println(header2);
3200                header2 = null;
3201            }
3202            if (lastTask != r.task) {
3203                lastTask = r.task;
3204                pw.print(prefix);
3205                pw.print(full ? "* " : "  ");
3206                pw.println(lastTask);
3207                if (full) {
3208                    lastTask.dump(pw, prefix + "  ");
3209                } else if (complete) {
3210                    // Complete + brief == give a summary.  Isn't that obvious?!?
3211                    if (lastTask.intent != null) {
3212                        pw.print(prefix); pw.print("  ");
3213                                pw.println(lastTask.intent.toInsecureStringWithClip());
3214                    }
3215                }
3216            }
3217            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3218            pw.print(" #"); pw.print(i); pw.print(": ");
3219            pw.println(r);
3220            if (full) {
3221                r.dump(pw, innerPrefix);
3222            } else if (complete) {
3223                // Complete + brief == give a summary.  Isn't that obvious?!?
3224                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3225                if (r.app != null) {
3226                    pw.print(innerPrefix); pw.println(r.app);
3227                }
3228            }
3229            if (client && r.app != null && r.app.thread != null) {
3230                // flush anything that is already in the PrintWriter since the thread is going
3231                // to write to the file descriptor directly
3232                pw.flush();
3233                try {
3234                    TransferPipe tp = new TransferPipe();
3235                    try {
3236                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3237                                r.appToken, innerPrefix, args);
3238                        // Short timeout, since blocking here can
3239                        // deadlock with the application.
3240                        tp.go(fd, 2000);
3241                    } finally {
3242                        tp.kill();
3243                    }
3244                } catch (IOException e) {
3245                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3246                } catch (RemoteException e) {
3247                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3248                }
3249                needNL = true;
3250            }
3251        }
3252        return printed;
3253    }
3254
3255    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3256        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3257        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3258        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3259    }
3260
3261    final void scheduleIdleLocked() {
3262        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3263    }
3264
3265    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3266        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
3267        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3268    }
3269
3270    final void scheduleResumeTopActivities() {
3271        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3272            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3273        }
3274    }
3275
3276    void removeSleepTimeouts() {
3277        mSleepTimeout = false;
3278        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3279    }
3280
3281    final void scheduleSleepTimeout() {
3282        removeSleepTimeouts();
3283        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3284    }
3285
3286    @Override
3287    public void onDisplayAdded(int displayId) {
3288        Slog.v(TAG, "Display added displayId=" + displayId);
3289        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3290    }
3291
3292    @Override
3293    public void onDisplayRemoved(int displayId) {
3294        Slog.v(TAG, "Display removed displayId=" + displayId);
3295        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3296    }
3297
3298    @Override
3299    public void onDisplayChanged(int displayId) {
3300        Slog.v(TAG, "Display changed displayId=" + displayId);
3301        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3302    }
3303
3304    public void handleDisplayAddedLocked(int displayId) {
3305        boolean newDisplay;
3306        synchronized (mService) {
3307            newDisplay = mActivityDisplays.get(displayId) == null;
3308            if (newDisplay) {
3309                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3310                if (activityDisplay.mDisplay == null) {
3311                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3312                    return;
3313                }
3314                mActivityDisplays.put(displayId, activityDisplay);
3315            }
3316        }
3317        if (newDisplay) {
3318            mWindowManager.onDisplayAdded(displayId);
3319        }
3320    }
3321
3322    public void handleDisplayRemovedLocked(int displayId) {
3323        synchronized (mService) {
3324            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3325            if (activityDisplay != null) {
3326                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3327                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3328                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3329                }
3330                mActivityDisplays.remove(displayId);
3331            }
3332        }
3333        mWindowManager.onDisplayRemoved(displayId);
3334    }
3335
3336    public void handleDisplayChangedLocked(int displayId) {
3337        synchronized (mService) {
3338            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3339            if (activityDisplay != null) {
3340                // TODO: Update the bounds.
3341            }
3342        }
3343        mWindowManager.onDisplayChanged(displayId);
3344    }
3345
3346    StackInfo getStackInfo(ActivityStack stack) {
3347        StackInfo info = new StackInfo();
3348        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3349        info.displayId = Display.DEFAULT_DISPLAY;
3350        info.stackId = stack.mStackId;
3351
3352        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3353        final int numTasks = tasks.size();
3354        int[] taskIds = new int[numTasks];
3355        String[] taskNames = new String[numTasks];
3356        for (int i = 0; i < numTasks; ++i) {
3357            final TaskRecord task = tasks.get(i);
3358            taskIds[i] = task.taskId;
3359            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3360                    : task.realActivity != null ? task.realActivity.flattenToString()
3361                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3362                    : "unknown";
3363        }
3364        info.taskIds = taskIds;
3365        info.taskNames = taskNames;
3366        return info;
3367    }
3368
3369    StackInfo getStackInfoLocked(int stackId) {
3370        ActivityStack stack = getStack(stackId);
3371        if (stack != null) {
3372            return getStackInfo(stack);
3373        }
3374        return null;
3375    }
3376
3377    ArrayList<StackInfo> getAllStackInfosLocked() {
3378        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3379        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3380            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3381            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3382                list.add(getStackInfo(stacks.get(ndx)));
3383            }
3384        }
3385        return list;
3386    }
3387
3388    void showLockTaskToast() {
3389        mLockTaskNotify.showToast(mLockTaskIsLocked);
3390    }
3391
3392    void setLockTaskModeLocked(TaskRecord task, boolean isLocked) {
3393        if (task == null) {
3394            // Take out of lock task mode if necessary
3395            if (mLockTaskModeTask != null) {
3396                final Message lockTaskMsg = Message.obtain();
3397                lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3398                lockTaskMsg.what = LOCK_TASK_END_MSG;
3399                mLockTaskModeTask = null;
3400                mHandler.sendMessage(lockTaskMsg);
3401            }
3402            return;
3403        }
3404        if (isLockTaskModeViolation(task)) {
3405            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
3406            return;
3407        }
3408        mLockTaskModeTask = task;
3409        findTaskToMoveToFrontLocked(task, 0, null);
3410        resumeTopActivitiesLocked();
3411
3412        final Message lockTaskMsg = Message.obtain();
3413        lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
3414        lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3415        lockTaskMsg.what = LOCK_TASK_START_MSG;
3416        lockTaskMsg.arg2 = !isLocked ? 1 : 0;
3417        mHandler.sendMessage(lockTaskMsg);
3418    }
3419
3420    boolean isLockTaskModeViolation(TaskRecord task) {
3421        return mLockTaskModeTask != null && mLockTaskModeTask != task;
3422    }
3423
3424    void endLockTaskModeIfTaskEnding(TaskRecord task) {
3425        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
3426            final Message lockTaskMsg = Message.obtain();
3427            lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3428            lockTaskMsg.what = LOCK_TASK_END_MSG;
3429            mLockTaskModeTask = null;
3430            mHandler.sendMessage(lockTaskMsg);
3431        }
3432    }
3433
3434    boolean isInLockTaskMode() {
3435        return mLockTaskModeTask != null;
3436    }
3437
3438    private final class ActivityStackSupervisorHandler extends Handler {
3439
3440        public ActivityStackSupervisorHandler(Looper looper) {
3441            super(looper);
3442        }
3443
3444        void activityIdleInternal(ActivityRecord r) {
3445            synchronized (mService) {
3446                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3447            }
3448        }
3449
3450        @Override
3451        public void handleMessage(Message msg) {
3452            switch (msg.what) {
3453                case IDLE_TIMEOUT_MSG: {
3454                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3455                    if (mService.mDidDexOpt) {
3456                        mService.mDidDexOpt = false;
3457                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3458                        nmsg.obj = msg.obj;
3459                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3460                        return;
3461                    }
3462                    // We don't at this point know if the activity is fullscreen,
3463                    // so we need to be conservative and assume it isn't.
3464                    activityIdleInternal((ActivityRecord)msg.obj);
3465                } break;
3466                case IDLE_NOW_MSG: {
3467                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3468                    activityIdleInternal((ActivityRecord)msg.obj);
3469                } break;
3470                case RESUME_TOP_ACTIVITY_MSG: {
3471                    synchronized (mService) {
3472                        resumeTopActivitiesLocked();
3473                    }
3474                } break;
3475                case SLEEP_TIMEOUT_MSG: {
3476                    synchronized (mService) {
3477                        if (mService.isSleepingOrShuttingDown()) {
3478                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3479                            mSleepTimeout = true;
3480                            checkReadyForSleepLocked();
3481                        }
3482                    }
3483                } break;
3484                case LAUNCH_TIMEOUT_MSG: {
3485                    if (mService.mDidDexOpt) {
3486                        mService.mDidDexOpt = false;
3487                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3488                        return;
3489                    }
3490                    synchronized (mService) {
3491                        if (mLaunchingActivity.isHeld()) {
3492                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3493                            if (VALIDATE_WAKE_LOCK_CALLER
3494                                    && Binder.getCallingUid() != Process.myUid()) {
3495                                throw new IllegalStateException("Calling must be system uid");
3496                            }
3497                            mLaunchingActivity.release();
3498                        }
3499                    }
3500                } break;
3501                case HANDLE_DISPLAY_ADDED: {
3502                    handleDisplayAddedLocked(msg.arg1);
3503                } break;
3504                case HANDLE_DISPLAY_CHANGED: {
3505                    handleDisplayChangedLocked(msg.arg1);
3506                } break;
3507                case HANDLE_DISPLAY_REMOVED: {
3508                    handleDisplayRemovedLocked(msg.arg1);
3509                } break;
3510                case CONTAINER_CALLBACK_VISIBILITY: {
3511                    final ActivityContainer container = (ActivityContainer) msg.obj;
3512                    final IActivityContainerCallback callback = container.mCallback;
3513                    if (callback != null) {
3514                        try {
3515                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3516                        } catch (RemoteException e) {
3517                        }
3518                    }
3519                } break;
3520                case LOCK_TASK_START_MSG: {
3521                    // When lock task starts, we disable the status bars.
3522                    try {
3523                        if (mLockTaskNotify == null) {
3524                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3525                        }
3526                        mLockTaskNotify.show(true);
3527                        mLockTaskIsLocked = msg.arg2 == 0;
3528                        if (getStatusBarService() != null) {
3529                            int flags =
3530                                    StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
3531                            if (!mLockTaskIsLocked) {
3532                                flags ^= StatusBarManager.DISABLE_HOME
3533                                        | StatusBarManager.DISABLE_RECENT;
3534                            }
3535                            getStatusBarService().disable(flags, mToken,
3536                                    mService.mContext.getPackageName());
3537                        }
3538                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3539                        if (getDevicePolicyManager() != null) {
3540                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3541                                    (String)msg.obj, msg.arg1);
3542                        }
3543                    } catch (RemoteException ex) {
3544                        throw new RuntimeException(ex);
3545                    }
3546                } break;
3547                case LOCK_TASK_END_MSG: {
3548                    // When lock task ends, we enable the status bars.
3549                    try {
3550                        if (getStatusBarService() != null) {
3551                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3552                                    mService.mContext.getPackageName());
3553                        }
3554                        mWindowManager.reenableKeyguard(mToken);
3555                        if (getDevicePolicyManager() != null) {
3556                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3557                                    msg.arg1);
3558                        }
3559                        if (mLockTaskNotify == null) {
3560                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3561                        }
3562                        mLockTaskNotify.show(false);
3563                        try {
3564                            boolean shouldLockKeyguard = Settings.Secure.getInt(
3565                                    mService.mContext.getContentResolver(),
3566                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
3567                            if (!mLockTaskIsLocked && shouldLockKeyguard) {
3568                                mWindowManager.lockNow(null);
3569                                mWindowManager.dismissKeyguard();
3570                                new LockPatternUtils(mService.mContext)
3571                                        .requireCredentialEntry(UserHandle.USER_ALL);
3572                            }
3573                        } catch (SettingNotFoundException e) {
3574                            // No setting, don't lock.
3575                        }
3576                    } catch (RemoteException ex) {
3577                        throw new RuntimeException(ex);
3578                    }
3579                } break;
3580                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3581                    final ActivityContainer container = (ActivityContainer) msg.obj;
3582                    final IActivityContainerCallback callback = container.mCallback;
3583                    if (callback != null) {
3584                        try {
3585                            callback.onAllActivitiesComplete(container.asBinder());
3586                        } catch (RemoteException e) {
3587                        }
3588                    }
3589                } break;
3590                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
3591                    synchronized (mService) {
3592                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
3593                                msg.obj);
3594                        final ActivityContainer container = (ActivityContainer) msg.obj;
3595                        container.mStack.finishAllActivitiesLocked(true);
3596                        container.onTaskListEmptyLocked();
3597                    }
3598                } break;
3599                case LAUNCH_TASK_BEHIND_COMPLETE: {
3600                    synchronized (mService) {
3601                        ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
3602                        if (r != null) {
3603                            handleLaunchTaskBehindCompleteLocked(r);
3604                        }
3605                    }
3606                } break;
3607            }
3608        }
3609    }
3610
3611    class ActivityContainer extends android.app.IActivityContainer.Stub {
3612        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3613                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3614        final int mStackId;
3615        IActivityContainerCallback mCallback = null;
3616        final ActivityStack mStack;
3617        ActivityRecord mParentActivity = null;
3618        String mIdString;
3619
3620        boolean mVisible = true;
3621
3622        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3623        ActivityDisplay mActivityDisplay;
3624
3625        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3626        final static int CONTAINER_STATE_NO_SURFACE = 1;
3627        final static int CONTAINER_STATE_FINISHING = 2;
3628        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3629
3630        ActivityContainer(int stackId) {
3631            synchronized (mService) {
3632                mStackId = stackId;
3633                mStack = new ActivityStack(this);
3634                mIdString = "ActivtyContainer{" + mStackId + "}";
3635                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3636            }
3637        }
3638
3639        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3640            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3641                    + " to display=" + activityDisplay);
3642            mActivityDisplay = activityDisplay;
3643            mStack.mDisplayId = activityDisplay.mDisplayId;
3644            mStack.mStacks = activityDisplay.mStacks;
3645
3646            activityDisplay.attachActivities(mStack);
3647            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3648        }
3649
3650        @Override
3651        public void attachToDisplay(int displayId) {
3652            synchronized (mService) {
3653                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3654                if (activityDisplay == null) {
3655                    return;
3656                }
3657                attachToDisplayLocked(activityDisplay);
3658            }
3659        }
3660
3661        @Override
3662        public int getDisplayId() {
3663            synchronized (mService) {
3664                if (mActivityDisplay != null) {
3665                    return mActivityDisplay.mDisplayId;
3666                }
3667            }
3668            return -1;
3669        }
3670
3671        @Override
3672        public boolean injectEvent(InputEvent event) {
3673            final long origId = Binder.clearCallingIdentity();
3674            try {
3675                synchronized (mService) {
3676                    if (mActivityDisplay != null) {
3677                        return mInputManagerInternal.injectInputEvent(event,
3678                                mActivityDisplay.mDisplayId,
3679                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3680                    }
3681                }
3682                return false;
3683            } finally {
3684                Binder.restoreCallingIdentity(origId);
3685            }
3686        }
3687
3688        @Override
3689        public void release() {
3690            synchronized (mService) {
3691                if (mContainerState == CONTAINER_STATE_FINISHING) {
3692                    return;
3693                }
3694                mContainerState = CONTAINER_STATE_FINISHING;
3695
3696                final Message msg =
3697                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3698                mHandler.sendMessageDelayed(msg, 2000);
3699
3700                long origId = Binder.clearCallingIdentity();
3701                try {
3702                    mStack.finishAllActivitiesLocked(false);
3703                    removePendingActivityLaunchesLocked(mStack);
3704                } finally {
3705                    Binder.restoreCallingIdentity(origId);
3706                }
3707            }
3708        }
3709
3710        protected void detachLocked() {
3711            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3712                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3713            if (mActivityDisplay != null) {
3714                mActivityDisplay.detachActivitiesLocked(mStack);
3715                mActivityDisplay = null;
3716                mStack.mDisplayId = -1;
3717                mStack.mStacks = null;
3718                mWindowManager.detachStack(mStackId);
3719            }
3720        }
3721
3722        @Override
3723        public final int startActivity(Intent intent) {
3724            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3725            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3726                    Binder.getCallingUid(), mCurrentUser, false,
3727                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3728            // TODO: Switch to user app stacks here.
3729            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3730            String mimeType = intent.getType();
3731            if (mimeType == null && intent.getData() != null
3732                    && "content".equals(intent.getData().getScheme())) {
3733                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3734            }
3735            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0,
3736                    0, null, null, null, null, userId, this, null);
3737        }
3738
3739        @Override
3740        public final int startActivityIntentSender(IIntentSender intentSender) {
3741            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3742
3743            if (!(intentSender instanceof PendingIntentRecord)) {
3744                throw new IllegalArgumentException("Bad PendingIntent object");
3745            }
3746
3747            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3748                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3749        }
3750
3751        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3752            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3753                    Binder.getCallingUid(), mCurrentUser, false,
3754                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3755            if (resolvedType == null) {
3756                resolvedType = intent.getType();
3757                if (resolvedType == null && intent.getData() != null
3758                        && "content".equals(intent.getData().getScheme())) {
3759                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3760                }
3761            }
3762            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
3763            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3764                throw new SecurityException(
3765                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3766            }
3767        }
3768
3769        /** Throw a SecurityException if allowEmbedded is not true */
3770        @Override
3771        public final void checkEmbeddedAllowed(Intent intent) {
3772            checkEmbeddedAllowedInner(intent, null);
3773        }
3774
3775        /** Throw a SecurityException if allowEmbedded is not true */
3776        @Override
3777        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3778            if (!(intentSender instanceof PendingIntentRecord)) {
3779                throw new IllegalArgumentException("Bad PendingIntent object");
3780            }
3781            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3782            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3783                    pendingIntent.key.requestResolvedType);
3784        }
3785
3786        @Override
3787        public IBinder asBinder() {
3788            return this;
3789        }
3790
3791        @Override
3792        public void setSurface(Surface surface, int width, int height, int density) {
3793            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3794        }
3795
3796        ActivityStackSupervisor getOuter() {
3797            return ActivityStackSupervisor.this;
3798        }
3799
3800        boolean isAttachedLocked() {
3801            return mActivityDisplay != null;
3802        }
3803
3804        void getBounds(Point outBounds) {
3805            synchronized (mService) {
3806                    if (mActivityDisplay != null) {
3807                    mActivityDisplay.getBounds(outBounds);
3808                } else {
3809                    outBounds.set(0, 0);
3810                }
3811            }
3812        }
3813
3814        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3815        void setVisible(boolean visible) {
3816            if (mVisible != visible) {
3817                mVisible = visible;
3818                if (mCallback != null) {
3819                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3820                            0 /* unused */, this).sendToTarget();
3821                }
3822            }
3823        }
3824
3825        void setDrawn() {
3826        }
3827
3828        // You can always start a new task on a regular ActivityStack.
3829        boolean isEligibleForNewTasks() {
3830            return true;
3831        }
3832
3833        void onTaskListEmptyLocked() {
3834        }
3835
3836        @Override
3837        public String toString() {
3838            return mIdString + (mActivityDisplay == null ? "N" : "A");
3839        }
3840    }
3841
3842    private class VirtualActivityContainer extends ActivityContainer {
3843        Surface mSurface;
3844        boolean mDrawn = false;
3845
3846        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3847            super(getNextStackId());
3848            mParentActivity = parent;
3849            mCallback = callback;
3850            mContainerState = CONTAINER_STATE_NO_SURFACE;
3851            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3852        }
3853
3854        @Override
3855        public void setSurface(Surface surface, int width, int height, int density) {
3856            super.setSurface(surface, width, height, density);
3857
3858            synchronized (mService) {
3859                final long origId = Binder.clearCallingIdentity();
3860                try {
3861                    setSurfaceLocked(surface, width, height, density);
3862                } finally {
3863                    Binder.restoreCallingIdentity(origId);
3864                }
3865            }
3866        }
3867
3868        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3869            if (mContainerState == CONTAINER_STATE_FINISHING) {
3870                return;
3871            }
3872            VirtualActivityDisplay virtualActivityDisplay =
3873                    (VirtualActivityDisplay) mActivityDisplay;
3874            if (virtualActivityDisplay == null) {
3875                virtualActivityDisplay =
3876                        new VirtualActivityDisplay(width, height, density);
3877                mActivityDisplay = virtualActivityDisplay;
3878                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3879                attachToDisplayLocked(virtualActivityDisplay);
3880            }
3881
3882            if (mSurface != null) {
3883                mSurface.release();
3884            }
3885
3886            mSurface = surface;
3887            if (surface != null) {
3888                mStack.resumeTopActivityLocked(null);
3889            } else {
3890                mContainerState = CONTAINER_STATE_NO_SURFACE;
3891                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3892                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3893                    mStack.startPausingLocked(false, true, false, false);
3894                }
3895            }
3896
3897            setSurfaceIfReadyLocked();
3898
3899            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3900                    + virtualActivityDisplay);
3901        }
3902
3903        @Override
3904        boolean isAttachedLocked() {
3905            return mSurface != null && super.isAttachedLocked();
3906        }
3907
3908        @Override
3909        void setDrawn() {
3910            synchronized (mService) {
3911                mDrawn = true;
3912                setSurfaceIfReadyLocked();
3913            }
3914        }
3915
3916        // Never start a new task on an ActivityView if it isn't explicitly specified.
3917        @Override
3918        boolean isEligibleForNewTasks() {
3919            return false;
3920        }
3921
3922        void onTaskListEmptyLocked() {
3923            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3924            detachLocked();
3925            deleteActivityContainer(this);
3926            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3927        }
3928
3929        private void setSurfaceIfReadyLocked() {
3930            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
3931                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3932            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3933                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3934                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3935            }
3936        }
3937    }
3938
3939    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3940     * attached {@link ActivityStack}s */
3941    class ActivityDisplay {
3942        /** Actual Display this object tracks. */
3943        int mDisplayId;
3944        Display mDisplay;
3945        DisplayInfo mDisplayInfo = new DisplayInfo();
3946
3947        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3948         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3949        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3950
3951        ActivityRecord mVisibleBehindActivity;
3952
3953        ActivityDisplay() {
3954        }
3955
3956        // After instantiation, check that mDisplay is not null before using this. The alternative
3957        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
3958        ActivityDisplay(int displayId) {
3959            final Display display = mDisplayManager.getDisplay(displayId);
3960            if (display == null) {
3961                return;
3962            }
3963            init(display);
3964        }
3965
3966        void init(Display display) {
3967            mDisplay = display;
3968            mDisplayId = display.getDisplayId();
3969            mDisplay.getDisplayInfo(mDisplayInfo);
3970        }
3971
3972        void attachActivities(ActivityStack stack) {
3973            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3974                    + mDisplayId);
3975            mStacks.add(stack);
3976        }
3977
3978        void detachActivitiesLocked(ActivityStack stack) {
3979            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3980                    + " from displayId=" + mDisplayId);
3981            mStacks.remove(stack);
3982        }
3983
3984        void getBounds(Point bounds) {
3985            mDisplay.getDisplayInfo(mDisplayInfo);
3986            bounds.x = mDisplayInfo.appWidth;
3987            bounds.y = mDisplayInfo.appHeight;
3988        }
3989
3990        void setVisibleBehindActivity(ActivityRecord r) {
3991            mVisibleBehindActivity = r;
3992        }
3993
3994        boolean hasVisibleBehindActivity() {
3995            return mVisibleBehindActivity != null;
3996        }
3997
3998        @Override
3999        public String toString() {
4000            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4001        }
4002    }
4003
4004    class VirtualActivityDisplay extends ActivityDisplay {
4005        VirtualDisplay mVirtualDisplay;
4006
4007        VirtualActivityDisplay(int width, int height, int density) {
4008            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4009            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4010                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4011                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4012                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4013
4014            init(mVirtualDisplay.getDisplay());
4015
4016            mWindowManager.handleDisplayAdded(mDisplayId);
4017        }
4018
4019        void setSurface(Surface surface) {
4020            if (mVirtualDisplay != null) {
4021                mVirtualDisplay.setSurface(surface);
4022            }
4023        }
4024
4025        @Override
4026        void detachActivitiesLocked(ActivityStack stack) {
4027            super.detachActivitiesLocked(stack);
4028            if (mVirtualDisplay != null) {
4029                mVirtualDisplay.release();
4030                mVirtualDisplay = null;
4031            }
4032        }
4033
4034        @Override
4035        public String toString() {
4036            return "VirtualActivityDisplay={" + mDisplayId + "}";
4037        }
4038    }
4039
4040    private boolean isLeanbackOnlyDevice() {
4041        boolean onLeanbackOnly = false;
4042        try {
4043            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
4044                    PackageManager.FEATURE_LEANBACK_ONLY);
4045        } catch (RemoteException e) {
4046            // noop
4047        }
4048
4049        return onLeanbackOnly;
4050    }
4051}
4052