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