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