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