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