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