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