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