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