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