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