ActivityStackSupervisor.java revision fee26771cfed736d207a8ee9c97134c848be1a52
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(r);
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);
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);
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);
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);
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        if (!playing) {
2684            // Make the activity immediately above r opaque.
2685            final ActivityRecord next = stack.findNextTranslucentActivity(r);
2686            if (next != null) {
2687                mService.convertFromTranslucent(next.appToken);
2688            }
2689        }
2690        try {
2691            top.app.thread.scheduleBackgroundMediaPlayingChanged(top.appToken, playing);
2692        } catch (RemoteException e) {
2693        }
2694        return true;
2695    }
2696
2697    // Called when WindowManager has finished animating the launchingBehind activity to the back.
2698    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
2699        r.mLaunchTaskBehind = false;
2700        final TaskRecord task = r.task;
2701        task.setLastThumbnail(task.stack.screenshotActivities(r));
2702        mService.addRecentTaskLocked(task);
2703        mWindowManager.setAppVisibility(r.appToken, false);
2704    }
2705
2706    void scheduleLaunchTaskBehindComplete(IBinder token) {
2707        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
2708    }
2709
2710    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2711        // First the front stacks. In case any are not fullscreen and are in front of home.
2712        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2713            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2714            final int topStackNdx = stacks.size() - 1;
2715            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2716                final ActivityStack stack = stacks.get(stackNdx);
2717                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2718            }
2719        }
2720    }
2721
2722    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2723        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2724            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2725            final int numStacks = stacks.size();
2726            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2727                final ActivityStack stack = stacks.get(stackNdx);
2728                stack.scheduleDestroyActivities(app, reason);
2729            }
2730        }
2731    }
2732
2733    boolean switchUserLocked(int userId, UserStartedState uss) {
2734        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2735        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2736        mCurrentUser = userId;
2737
2738        mStartingUsers.add(uss);
2739        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2740            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2741            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2742                final ActivityStack stack = stacks.get(stackNdx);
2743                stack.switchUserLocked(userId);
2744                TaskRecord task = stack.topTask();
2745                if (task != null) {
2746                    mWindowManager.moveTaskToTop(task.taskId);
2747                }
2748            }
2749        }
2750
2751        ActivityStack stack = getStack(restoreStackId);
2752        if (stack == null) {
2753            stack = mHomeStack;
2754        }
2755        final boolean homeInFront = stack.isHomeStack();
2756        if (stack.isOnHomeDisplay()) {
2757            moveHomeStack(homeInFront);
2758            TaskRecord task = stack.topTask();
2759            if (task != null) {
2760                mWindowManager.moveTaskToTop(task.taskId);
2761            }
2762        } else {
2763            // Stack was moved to another display while user was swapped out.
2764            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2765        }
2766        return homeInFront;
2767    }
2768
2769    /**
2770     * Add background users to send boot completed events to.
2771     * @param userId The user being started in the background
2772     * @param uss The state object for the user.
2773     */
2774    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
2775        mStartingBackgroundUsers.add(uss);
2776    }
2777
2778    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2779        int N = mStoppingActivities.size();
2780        if (N <= 0) return null;
2781
2782        ArrayList<ActivityRecord> stops = null;
2783
2784        final boolean nowVisible = allResumedActivitiesVisible();
2785        for (int i=0; i<N; i++) {
2786            ActivityRecord s = mStoppingActivities.get(i);
2787            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2788                    + nowVisible + " waitingVisible=" + s.waitingVisible
2789                    + " finishing=" + s.finishing);
2790            if (s.waitingVisible && nowVisible) {
2791                mWaitingVisibleActivities.remove(s);
2792                s.waitingVisible = false;
2793                if (s.finishing) {
2794                    // If this activity is finishing, it is sitting on top of
2795                    // everyone else but we now know it is no longer needed...
2796                    // so get rid of it.  Otherwise, we need to go through the
2797                    // normal flow and hide it once we determine that it is
2798                    // hidden by the activities in front of it.
2799                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2800                    mWindowManager.setAppVisibility(s.appToken, false);
2801                }
2802            }
2803            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2804                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2805                if (stops == null) {
2806                    stops = new ArrayList<ActivityRecord>();
2807                }
2808                stops.add(s);
2809                mStoppingActivities.remove(i);
2810                N--;
2811                i--;
2812            }
2813        }
2814
2815        return stops;
2816    }
2817
2818    void validateTopActivitiesLocked() {
2819        // FIXME
2820/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2821            final ActivityStack stack = stacks.get(stackNdx);
2822            final ActivityRecord r = stack.topRunningActivityLocked(null);
2823            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2824            if (isFrontStack(stack)) {
2825                if (r == null) {
2826                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2827                } else {
2828                    final ActivityRecord pausing = stack.mPausingActivity;
2829                    if (pausing != null && pausing == r) {
2830                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2831                            " state=" + state);
2832                    }
2833                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2834                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2835                                " state=" + state);
2836                    }
2837                }
2838            } else {
2839                final ActivityRecord resumed = stack.mResumedActivity;
2840                if (resumed != null && resumed == r) {
2841                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2842                        " state=" + state);
2843                }
2844                if (r != null && (state == ActivityState.INITIALIZING
2845                        || state == ActivityState.RESUMED)) {
2846                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2847                            " state=" + state);
2848                }
2849            }
2850        }
2851*/
2852    }
2853
2854    public void dump(PrintWriter pw, String prefix) {
2855        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2856                pw.println(mDismissKeyguardOnNextActivity);
2857        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2858                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2859        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2860        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2861        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2862        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2863    }
2864
2865    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2866        return getFocusedStack().getDumpActivitiesLocked(name);
2867    }
2868
2869    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2870            boolean needSep, String prefix) {
2871        if (activity != null) {
2872            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2873                if (needSep) {
2874                    pw.println();
2875                }
2876                pw.print(prefix);
2877                pw.println(activity);
2878                return true;
2879            }
2880        }
2881        return false;
2882    }
2883
2884    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2885            boolean dumpClient, String dumpPackage) {
2886        boolean printed = false;
2887        boolean needSep = false;
2888        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2889            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2890            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
2891                    pw.println(" (activities from bottom to top):");
2892            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2893            final int numStacks = stacks.size();
2894            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2895                final ActivityStack stack = stacks.get(stackNdx);
2896                StringBuilder stackHeader = new StringBuilder(128);
2897                stackHeader.append("  Stack #");
2898                stackHeader.append(stack.mStackId);
2899                stackHeader.append(":");
2900                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2901                        needSep, stackHeader.toString());
2902                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2903                        !dumpAll, false, dumpPackage, true,
2904                        "    Running activities (most recent first):", null);
2905
2906                needSep = printed;
2907                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2908                        "    mPausingActivity: ");
2909                if (pr) {
2910                    printed = true;
2911                    needSep = false;
2912                }
2913                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2914                        "    mResumedActivity: ");
2915                if (pr) {
2916                    printed = true;
2917                    needSep = false;
2918                }
2919                if (dumpAll) {
2920                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2921                            "    mLastPausedActivity: ");
2922                    if (pr) {
2923                        printed = true;
2924                        needSep = true;
2925                    }
2926                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2927                            needSep, "    mLastNoHistoryActivity: ");
2928                }
2929                needSep = printed;
2930            }
2931        }
2932
2933        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2934                false, dumpPackage, true, "  Activities waiting to finish:", null);
2935        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2936                false, dumpPackage, true, "  Activities waiting to stop:", null);
2937        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2938                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2939                null);
2940        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2941                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2942        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2943                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2944
2945        return printed;
2946    }
2947
2948    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2949            String prefix, String label, boolean complete, boolean brief, boolean client,
2950            String dumpPackage, boolean needNL, String header1, String header2) {
2951        TaskRecord lastTask = null;
2952        String innerPrefix = null;
2953        String[] args = null;
2954        boolean printed = false;
2955        for (int i=list.size()-1; i>=0; i--) {
2956            final ActivityRecord r = list.get(i);
2957            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2958                continue;
2959            }
2960            if (innerPrefix == null) {
2961                innerPrefix = prefix + "      ";
2962                args = new String[0];
2963            }
2964            printed = true;
2965            final boolean full = !brief && (complete || !r.isInHistory());
2966            if (needNL) {
2967                pw.println("");
2968                needNL = false;
2969            }
2970            if (header1 != null) {
2971                pw.println(header1);
2972                header1 = null;
2973            }
2974            if (header2 != null) {
2975                pw.println(header2);
2976                header2 = null;
2977            }
2978            if (lastTask != r.task) {
2979                lastTask = r.task;
2980                pw.print(prefix);
2981                pw.print(full ? "* " : "  ");
2982                pw.println(lastTask);
2983                if (full) {
2984                    lastTask.dump(pw, prefix + "  ");
2985                } else if (complete) {
2986                    // Complete + brief == give a summary.  Isn't that obvious?!?
2987                    if (lastTask.intent != null) {
2988                        pw.print(prefix); pw.print("  ");
2989                                pw.println(lastTask.intent.toInsecureStringWithClip());
2990                    }
2991                }
2992            }
2993            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2994            pw.print(" #"); pw.print(i); pw.print(": ");
2995            pw.println(r);
2996            if (full) {
2997                r.dump(pw, innerPrefix);
2998            } else if (complete) {
2999                // Complete + brief == give a summary.  Isn't that obvious?!?
3000                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3001                if (r.app != null) {
3002                    pw.print(innerPrefix); pw.println(r.app);
3003                }
3004            }
3005            if (client && r.app != null && r.app.thread != null) {
3006                // flush anything that is already in the PrintWriter since the thread is going
3007                // to write to the file descriptor directly
3008                pw.flush();
3009                try {
3010                    TransferPipe tp = new TransferPipe();
3011                    try {
3012                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3013                                r.appToken, innerPrefix, args);
3014                        // Short timeout, since blocking here can
3015                        // deadlock with the application.
3016                        tp.go(fd, 2000);
3017                    } finally {
3018                        tp.kill();
3019                    }
3020                } catch (IOException e) {
3021                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3022                } catch (RemoteException e) {
3023                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3024                }
3025                needNL = true;
3026            }
3027        }
3028        return printed;
3029    }
3030
3031    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3032        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3033        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3034        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3035    }
3036
3037    final void scheduleIdleLocked() {
3038        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3039    }
3040
3041    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3042        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
3043        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3044    }
3045
3046    final void scheduleResumeTopActivities() {
3047        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3048            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3049        }
3050    }
3051
3052    void removeSleepTimeouts() {
3053        mSleepTimeout = false;
3054        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3055    }
3056
3057    final void scheduleSleepTimeout() {
3058        removeSleepTimeouts();
3059        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3060    }
3061
3062    @Override
3063    public void onDisplayAdded(int displayId) {
3064        Slog.v(TAG, "Display added displayId=" + displayId);
3065        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3066    }
3067
3068    @Override
3069    public void onDisplayRemoved(int displayId) {
3070        Slog.v(TAG, "Display removed displayId=" + displayId);
3071        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3072    }
3073
3074    @Override
3075    public void onDisplayChanged(int displayId) {
3076        Slog.v(TAG, "Display changed displayId=" + displayId);
3077        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3078    }
3079
3080    public void handleDisplayAddedLocked(int displayId) {
3081        boolean newDisplay;
3082        synchronized (mService) {
3083            newDisplay = mActivityDisplays.get(displayId) == null;
3084            if (newDisplay) {
3085                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3086                mActivityDisplays.put(displayId, activityDisplay);
3087            }
3088        }
3089        if (newDisplay) {
3090            mWindowManager.onDisplayAdded(displayId);
3091        }
3092    }
3093
3094    public void handleDisplayRemovedLocked(int displayId) {
3095        synchronized (mService) {
3096            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3097            if (activityDisplay != null) {
3098                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3099                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3100                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3101                }
3102                mActivityDisplays.remove(displayId);
3103            }
3104        }
3105        mWindowManager.onDisplayRemoved(displayId);
3106    }
3107
3108    public void handleDisplayChangedLocked(int displayId) {
3109        synchronized (mService) {
3110            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3111            if (activityDisplay != null) {
3112                // TODO: Update the bounds.
3113            }
3114        }
3115        mWindowManager.onDisplayChanged(displayId);
3116    }
3117
3118    StackInfo getStackInfo(ActivityStack stack) {
3119        StackInfo info = new StackInfo();
3120        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3121        info.displayId = Display.DEFAULT_DISPLAY;
3122        info.stackId = stack.mStackId;
3123
3124        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3125        final int numTasks = tasks.size();
3126        int[] taskIds = new int[numTasks];
3127        String[] taskNames = new String[numTasks];
3128        for (int i = 0; i < numTasks; ++i) {
3129            final TaskRecord task = tasks.get(i);
3130            taskIds[i] = task.taskId;
3131            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3132                    : task.realActivity != null ? task.realActivity.flattenToString()
3133                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3134                    : "unknown";
3135        }
3136        info.taskIds = taskIds;
3137        info.taskNames = taskNames;
3138        return info;
3139    }
3140
3141    StackInfo getStackInfoLocked(int stackId) {
3142        ActivityStack stack = getStack(stackId);
3143        if (stack != null) {
3144            return getStackInfo(stack);
3145        }
3146        return null;
3147    }
3148
3149    ArrayList<StackInfo> getAllStackInfosLocked() {
3150        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3151        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3152            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3153            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3154                list.add(getStackInfo(stacks.get(ndx)));
3155            }
3156        }
3157        return list;
3158    }
3159
3160    void showLockTaskToast() {
3161        mLockTaskNotify.showToast(mLockTaskIsLocked);
3162    }
3163
3164    void setLockTaskModeLocked(TaskRecord task, boolean isLocked) {
3165        if (task == null) {
3166            // Take out of lock task mode if necessary
3167            if (mLockTaskModeTask != null) {
3168                final Message lockTaskMsg = Message.obtain();
3169                lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3170                lockTaskMsg.what = LOCK_TASK_END_MSG;
3171                mLockTaskModeTask = null;
3172                mHandler.sendMessage(lockTaskMsg);
3173            }
3174            return;
3175        }
3176        if (isLockTaskModeViolation(task)) {
3177            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
3178            return;
3179        }
3180        mLockTaskModeTask = task;
3181        findTaskToMoveToFrontLocked(task, 0, null);
3182        resumeTopActivitiesLocked();
3183
3184        final Message lockTaskMsg = Message.obtain();
3185        lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
3186        lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3187        lockTaskMsg.what = LOCK_TASK_START_MSG;
3188        lockTaskMsg.arg2 = !isLocked ? 1 : 0;
3189        mHandler.sendMessage(lockTaskMsg);
3190    }
3191
3192    boolean isLockTaskModeViolation(TaskRecord task) {
3193        return mLockTaskModeTask != null && mLockTaskModeTask != task;
3194    }
3195
3196    void endLockTaskModeIfTaskEnding(TaskRecord task) {
3197        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
3198            mLockTaskModeTask = null;
3199        }
3200    }
3201
3202    boolean isInLockTaskMode() {
3203        return mLockTaskModeTask != null;
3204    }
3205
3206    private final class ActivityStackSupervisorHandler extends Handler {
3207
3208        public ActivityStackSupervisorHandler(Looper looper) {
3209            super(looper);
3210        }
3211
3212        void activityIdleInternal(ActivityRecord r) {
3213            synchronized (mService) {
3214                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3215            }
3216        }
3217
3218        @Override
3219        public void handleMessage(Message msg) {
3220            switch (msg.what) {
3221                case IDLE_TIMEOUT_MSG: {
3222                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3223                    if (mService.mDidDexOpt) {
3224                        mService.mDidDexOpt = false;
3225                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3226                        nmsg.obj = msg.obj;
3227                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3228                        return;
3229                    }
3230                    // We don't at this point know if the activity is fullscreen,
3231                    // so we need to be conservative and assume it isn't.
3232                    activityIdleInternal((ActivityRecord)msg.obj);
3233                } break;
3234                case IDLE_NOW_MSG: {
3235                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3236                    activityIdleInternal((ActivityRecord)msg.obj);
3237                } break;
3238                case RESUME_TOP_ACTIVITY_MSG: {
3239                    synchronized (mService) {
3240                        resumeTopActivitiesLocked();
3241                    }
3242                } break;
3243                case SLEEP_TIMEOUT_MSG: {
3244                    synchronized (mService) {
3245                        if (mService.isSleepingOrShuttingDown()) {
3246                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3247                            mSleepTimeout = true;
3248                            checkReadyForSleepLocked();
3249                        }
3250                    }
3251                } break;
3252                case LAUNCH_TIMEOUT_MSG: {
3253                    if (mService.mDidDexOpt) {
3254                        mService.mDidDexOpt = false;
3255                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3256                        return;
3257                    }
3258                    synchronized (mService) {
3259                        if (mLaunchingActivity.isHeld()) {
3260                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3261                            if (VALIDATE_WAKE_LOCK_CALLER
3262                                    && Binder.getCallingUid() != Process.myUid()) {
3263                                throw new IllegalStateException("Calling must be system uid");
3264                            }
3265                            mLaunchingActivity.release();
3266                        }
3267                    }
3268                } break;
3269                case HANDLE_DISPLAY_ADDED: {
3270                    handleDisplayAddedLocked(msg.arg1);
3271                } break;
3272                case HANDLE_DISPLAY_CHANGED: {
3273                    handleDisplayChangedLocked(msg.arg1);
3274                } break;
3275                case HANDLE_DISPLAY_REMOVED: {
3276                    handleDisplayRemovedLocked(msg.arg1);
3277                } break;
3278                case CONTAINER_CALLBACK_VISIBILITY: {
3279                    final ActivityContainer container = (ActivityContainer) msg.obj;
3280                    final IActivityContainerCallback callback = container.mCallback;
3281                    if (callback != null) {
3282                        try {
3283                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3284                        } catch (RemoteException e) {
3285                        }
3286                    }
3287                } break;
3288                case LOCK_TASK_START_MSG: {
3289                    // When lock task starts, we disable the status bars.
3290                    try {
3291                        if (mLockTaskNotify == null) {
3292                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3293                        }
3294                        mLockTaskNotify.show(true);
3295                        mLockTaskIsLocked = msg.arg2 == 0;
3296                        if (getStatusBarService() != null) {
3297                            int flags =
3298                                    StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
3299                            if (!mLockTaskIsLocked) {
3300                                flags ^= StatusBarManager.DISABLE_HOME
3301                                        | StatusBarManager.DISABLE_RECENT;
3302                            }
3303                            getStatusBarService().disable(flags, mToken,
3304                                    mService.mContext.getPackageName());
3305                        }
3306                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3307                        if (getDevicePolicyManager() != null) {
3308                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3309                                    (String)msg.obj, msg.arg1);
3310                        }
3311                    } catch (RemoteException ex) {
3312                        throw new RuntimeException(ex);
3313                    }
3314                } break;
3315                case LOCK_TASK_END_MSG: {
3316                    // When lock task ends, we enable the status bars.
3317                    try {
3318                        if (getStatusBarService() != null) {
3319                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3320                                    mService.mContext.getPackageName());
3321                        }
3322                        mWindowManager.reenableKeyguard(mToken);
3323                        if (getDevicePolicyManager() != null) {
3324                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3325                                    msg.arg1);
3326                        }
3327                        if (mLockTaskNotify == null) {
3328                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3329                        }
3330                        mLockTaskNotify.show(false);
3331                        try {
3332                            boolean shouldLockKeyguard = Settings.System.getInt(
3333                                    mService.mContext.getContentResolver(),
3334                                    Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
3335                            if (!mLockTaskIsLocked && shouldLockKeyguard) {
3336                                mWindowManager.lockNow(null);
3337                                mWindowManager.dismissKeyguard();
3338                                new LockPatternUtils(mService.mContext)
3339                                        .requireCredentialEntry(UserHandle.USER_ALL);
3340                            }
3341                        } catch (SettingNotFoundException e) {
3342                            // No setting, don't lock.
3343                        }
3344                    } catch (RemoteException ex) {
3345                        throw new RuntimeException(ex);
3346                    }
3347                } break;
3348                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3349                    final ActivityContainer container = (ActivityContainer) msg.obj;
3350                    final IActivityContainerCallback callback = container.mCallback;
3351                    if (callback != null) {
3352                        try {
3353                            callback.onAllActivitiesComplete(container.asBinder());
3354                        } catch (RemoteException e) {
3355                        }
3356                    }
3357                } break;
3358                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
3359                    synchronized (mService) {
3360                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
3361                                msg.obj);
3362                        final ActivityContainer container = (ActivityContainer) msg.obj;
3363                        container.mStack.finishAllActivitiesLocked(true);
3364                        container.onTaskListEmptyLocked();
3365                    }
3366                } break;
3367                case LAUNCH_TASK_BEHIND_COMPLETE: {
3368                    synchronized (mService) {
3369                        ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
3370                        if (r != null) {
3371                            handleLaunchTaskBehindCompleteLocked(r);
3372                        }
3373                    }
3374                } break;
3375            }
3376        }
3377    }
3378
3379    class ActivityContainer extends android.app.IActivityContainer.Stub {
3380        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3381                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3382        final int mStackId;
3383        IActivityContainerCallback mCallback = null;
3384        final ActivityStack mStack;
3385        ActivityRecord mParentActivity = null;
3386        String mIdString;
3387
3388        boolean mVisible = true;
3389
3390        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3391        ActivityDisplay mActivityDisplay;
3392
3393        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3394        final static int CONTAINER_STATE_NO_SURFACE = 1;
3395        final static int CONTAINER_STATE_FINISHING = 2;
3396        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3397
3398        ActivityContainer(int stackId) {
3399            synchronized (mService) {
3400                mStackId = stackId;
3401                mStack = new ActivityStack(this);
3402                mIdString = "ActivtyContainer{" + mStackId + "}";
3403                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3404            }
3405        }
3406
3407        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3408            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3409                    + " to display=" + activityDisplay);
3410            mActivityDisplay = activityDisplay;
3411            mStack.mDisplayId = activityDisplay.mDisplayId;
3412            mStack.mStacks = activityDisplay.mStacks;
3413
3414            activityDisplay.attachActivities(mStack);
3415            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3416        }
3417
3418        @Override
3419        public void attachToDisplay(int displayId) {
3420            synchronized (mService) {
3421                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3422                if (activityDisplay == null) {
3423                    return;
3424                }
3425                attachToDisplayLocked(activityDisplay);
3426            }
3427        }
3428
3429        @Override
3430        public int getDisplayId() {
3431            synchronized (mService) {
3432                if (mActivityDisplay != null) {
3433                    return mActivityDisplay.mDisplayId;
3434                }
3435            }
3436            return -1;
3437        }
3438
3439        @Override
3440        public boolean injectEvent(InputEvent event) {
3441            final long origId = Binder.clearCallingIdentity();
3442            try {
3443                synchronized (mService) {
3444                    if (mActivityDisplay != null) {
3445                        return mInputManagerInternal.injectInputEvent(event,
3446                                mActivityDisplay.mDisplayId,
3447                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3448                    }
3449                }
3450                return false;
3451            } finally {
3452                Binder.restoreCallingIdentity(origId);
3453            }
3454        }
3455
3456        @Override
3457        public void release() {
3458            synchronized (mService) {
3459                if (mContainerState == CONTAINER_STATE_FINISHING) {
3460                    return;
3461                }
3462                mContainerState = CONTAINER_STATE_FINISHING;
3463
3464                final Message msg =
3465                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3466                mHandler.sendMessageDelayed(msg, 2000);
3467
3468                long origId = Binder.clearCallingIdentity();
3469                try {
3470                    mStack.finishAllActivitiesLocked(false);
3471                    removePendingActivityLaunchesLocked(mStack);
3472                } finally {
3473                    Binder.restoreCallingIdentity(origId);
3474                }
3475            }
3476        }
3477
3478        private void detachLocked() {
3479            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3480                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3481            if (mActivityDisplay != null) {
3482                mActivityDisplay.detachActivitiesLocked(mStack);
3483                mActivityDisplay = null;
3484                mStack.mDisplayId = -1;
3485                mStack.mStacks = null;
3486                mWindowManager.detachStack(mStackId);
3487            }
3488        }
3489
3490        @Override
3491        public final int startActivity(Intent intent) {
3492            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3493            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3494                    Binder.getCallingUid(), mCurrentUser, false,
3495                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3496            // TODO: Switch to user app stacks here.
3497            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3498            String mimeType = intent.getType();
3499            if (mimeType == null && intent.getData() != null
3500                    && "content".equals(intent.getData().getScheme())) {
3501                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3502            }
3503            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null,
3504                    null, null, null, null, userId, this);
3505        }
3506
3507        @Override
3508        public final int startActivityIntentSender(IIntentSender intentSender) {
3509            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3510
3511            if (!(intentSender instanceof PendingIntentRecord)) {
3512                throw new IllegalArgumentException("Bad PendingIntent object");
3513            }
3514
3515            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3516                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3517        }
3518
3519        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3520            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3521                    Binder.getCallingUid(), mCurrentUser, false,
3522                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3523            if (resolvedType == null) {
3524                resolvedType = intent.getType();
3525                if (resolvedType == null && intent.getData() != null
3526                        && "content".equals(intent.getData().getScheme())) {
3527                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3528                }
3529            }
3530            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
3531            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3532                throw new SecurityException(
3533                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3534            }
3535        }
3536
3537        /** Throw a SecurityException if allowEmbedded is not true */
3538        @Override
3539        public final void checkEmbeddedAllowed(Intent intent) {
3540            checkEmbeddedAllowedInner(intent, null);
3541        }
3542
3543        /** Throw a SecurityException if allowEmbedded is not true */
3544        @Override
3545        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3546            if (!(intentSender instanceof PendingIntentRecord)) {
3547                throw new IllegalArgumentException("Bad PendingIntent object");
3548            }
3549            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3550            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3551                    pendingIntent.key.requestResolvedType);
3552        }
3553
3554        @Override
3555        public IBinder asBinder() {
3556            return this;
3557        }
3558
3559        @Override
3560        public void setSurface(Surface surface, int width, int height, int density) {
3561            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3562        }
3563
3564        ActivityStackSupervisor getOuter() {
3565            return ActivityStackSupervisor.this;
3566        }
3567
3568        boolean isAttachedLocked() {
3569            return mActivityDisplay != null;
3570        }
3571
3572        void getBounds(Point outBounds) {
3573            synchronized (mService) {
3574                    if (mActivityDisplay != null) {
3575                    mActivityDisplay.getBounds(outBounds);
3576                } else {
3577                    outBounds.set(0, 0);
3578                }
3579            }
3580        }
3581
3582        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3583        void setVisible(boolean visible) {
3584            if (mVisible != visible) {
3585                mVisible = visible;
3586                if (mCallback != null) {
3587                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3588                            0 /* unused */, this).sendToTarget();
3589                }
3590            }
3591        }
3592
3593        void setDrawn() {
3594        }
3595
3596        // You can always start a new task on a regular ActivityStack.
3597        boolean isEligibleForNewTasks() {
3598            return true;
3599        }
3600
3601        void onTaskListEmptyLocked() {
3602            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3603            if (!mStack.isHomeStack()) {
3604                detachLocked();
3605                deleteActivityContainer(this);
3606            }
3607            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3608        }
3609
3610        @Override
3611        public String toString() {
3612            return mIdString + (mActivityDisplay == null ? "N" : "A");
3613        }
3614    }
3615
3616    private class VirtualActivityContainer extends ActivityContainer {
3617        Surface mSurface;
3618        boolean mDrawn = false;
3619
3620        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3621            super(getNextStackId());
3622            mParentActivity = parent;
3623            mCallback = callback;
3624            mContainerState = CONTAINER_STATE_NO_SURFACE;
3625            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3626        }
3627
3628        @Override
3629        public void setSurface(Surface surface, int width, int height, int density) {
3630            super.setSurface(surface, width, height, density);
3631
3632            synchronized (mService) {
3633                final long origId = Binder.clearCallingIdentity();
3634                try {
3635                    setSurfaceLocked(surface, width, height, density);
3636                } finally {
3637                    Binder.restoreCallingIdentity(origId);
3638                }
3639            }
3640        }
3641
3642        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3643            if (mContainerState == CONTAINER_STATE_FINISHING) {
3644                return;
3645            }
3646            VirtualActivityDisplay virtualActivityDisplay =
3647                    (VirtualActivityDisplay) mActivityDisplay;
3648            if (virtualActivityDisplay == null) {
3649                virtualActivityDisplay =
3650                        new VirtualActivityDisplay(width, height, density);
3651                mActivityDisplay = virtualActivityDisplay;
3652                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3653                attachToDisplayLocked(virtualActivityDisplay);
3654            }
3655
3656            if (mSurface != null) {
3657                mSurface.release();
3658            }
3659
3660            mSurface = surface;
3661            if (surface != null) {
3662                mStack.resumeTopActivityLocked(null);
3663            } else {
3664                mContainerState = CONTAINER_STATE_NO_SURFACE;
3665                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3666                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3667                    mStack.startPausingLocked(false, true);
3668                }
3669            }
3670
3671            setSurfaceIfReadyLocked();
3672
3673            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3674                    + virtualActivityDisplay);
3675        }
3676
3677        @Override
3678        boolean isAttachedLocked() {
3679            return mSurface != null && super.isAttachedLocked();
3680        }
3681
3682        @Override
3683        void setDrawn() {
3684            synchronized (mService) {
3685                mDrawn = true;
3686                setSurfaceIfReadyLocked();
3687            }
3688        }
3689
3690        // Never start a new task on an ActivityView if it isn't explicitly specified.
3691        @Override
3692        boolean isEligibleForNewTasks() {
3693            return false;
3694        }
3695
3696        private void setSurfaceIfReadyLocked() {
3697            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
3698                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3699            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3700                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3701                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3702            }
3703        }
3704    }
3705
3706    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3707     * attached {@link ActivityStack}s */
3708    class ActivityDisplay {
3709        /** Actual Display this object tracks. */
3710        int mDisplayId;
3711        Display mDisplay;
3712        DisplayInfo mDisplayInfo = new DisplayInfo();
3713
3714        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3715         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3716        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3717
3718        ActivityRecord mMediaPlayingActivity;
3719
3720        ActivityDisplay() {
3721        }
3722
3723        ActivityDisplay(int displayId) {
3724            init(mDisplayManager.getDisplay(displayId));
3725        }
3726
3727        void init(Display display) {
3728            mDisplay = display;
3729            mDisplayId = display.getDisplayId();
3730            mDisplay.getDisplayInfo(mDisplayInfo);
3731        }
3732
3733        void attachActivities(ActivityStack stack) {
3734            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3735                    + mDisplayId);
3736            mStacks.add(stack);
3737        }
3738
3739        void detachActivitiesLocked(ActivityStack stack) {
3740            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3741                    + " from displayId=" + mDisplayId);
3742            mStacks.remove(stack);
3743        }
3744
3745        void getBounds(Point bounds) {
3746            mDisplay.getDisplayInfo(mDisplayInfo);
3747            bounds.x = mDisplayInfo.appWidth;
3748            bounds.y = mDisplayInfo.appHeight;
3749        }
3750
3751        void setMediaPlaying(ActivityRecord r) {
3752            mMediaPlayingActivity = r;
3753        }
3754
3755        boolean isMediaPlaying() {
3756            return mMediaPlayingActivity != null;
3757        }
3758
3759        @Override
3760        public String toString() {
3761            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3762        }
3763    }
3764
3765    class VirtualActivityDisplay extends ActivityDisplay {
3766        VirtualDisplay mVirtualDisplay;
3767
3768        VirtualActivityDisplay(int width, int height, int density) {
3769            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3770            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
3771                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
3772                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3773                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
3774
3775            init(mVirtualDisplay.getDisplay());
3776
3777            mWindowManager.handleDisplayAdded(mDisplayId);
3778        }
3779
3780        void setSurface(Surface surface) {
3781            if (mVirtualDisplay != null) {
3782                mVirtualDisplay.setSurface(surface);
3783            }
3784        }
3785
3786        @Override
3787        void detachActivitiesLocked(ActivityStack stack) {
3788            super.detachActivitiesLocked(stack);
3789            if (mVirtualDisplay != null) {
3790                mVirtualDisplay.release();
3791                mVirtualDisplay = null;
3792            }
3793        }
3794
3795        @Override
3796        public String toString() {
3797            return "VirtualActivityDisplay={" + mDisplayId + "}";
3798        }
3799    }
3800
3801    private boolean isLeanbackOnlyDevice() {
3802        boolean onLeanbackOnly = false;
3803        try {
3804            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
3805                    PackageManager.FEATURE_LEANBACK_ONLY);
3806        } catch (RemoteException e) {
3807            // noop
3808        }
3809
3810        return onLeanbackOnly;
3811    }
3812}
3813