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