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