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