ActivityStackSupervisor.java revision c0ffce5ddd6446f1d46a49cdfaeda4a2ce408e1d
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), true);
1898                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1899                        r.task);
1900            } else {
1901                r.setTask(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, 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 : targetStack.createTaskRecord(getNextTaskId(),
1974                            r.info, intent, null, null, true), true);
1975            mWindowManager.moveTaskToTop(r.task.taskId);
1976            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1977                    + " in new guessed " + r.task);
1978        }
1979
1980        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1981                intent, r.getUriPermissionsLocked(), r.userId);
1982
1983        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
1984            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
1985        }
1986        if (newTask) {
1987            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1988        }
1989        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1990        targetStack.mLastPausedActivity = null;
1991        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1992        mService.setFocusedActivityLocked(r);
1993        return ActivityManager.START_SUCCESS;
1994    }
1995
1996    void acquireLaunchWakelock() {
1997        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1998            throw new IllegalStateException("Calling must be system uid");
1999        }
2000        mLaunchingActivity.acquire();
2001        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2002            // To be safe, don't allow the wake lock to be held for too long.
2003            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2004        }
2005    }
2006
2007    // Checked.
2008    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2009            Configuration config) {
2010        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
2011
2012        ArrayList<ActivityRecord> stops = null;
2013        ArrayList<ActivityRecord> finishes = null;
2014        ArrayList<UserStartedState> startingUsers = null;
2015        int NS = 0;
2016        int NF = 0;
2017        boolean booting = false;
2018        boolean enableScreen = false;
2019        boolean activityRemoved = false;
2020
2021        ActivityRecord r = ActivityRecord.forToken(token);
2022        if (r != null) {
2023            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
2024                    Debug.getCallers(4));
2025            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2026            r.finishLaunchTickingLocked();
2027            if (fromTimeout) {
2028                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2029            }
2030
2031            // This is a hack to semi-deal with a race condition
2032            // in the client where it can be constructed with a
2033            // newer configuration from when we asked it to launch.
2034            // We'll update with whatever configuration it now says
2035            // it used to launch.
2036            if (config != null) {
2037                r.configuration = config;
2038            }
2039
2040            // We are now idle.  If someone is waiting for a thumbnail from
2041            // us, we can now deliver.
2042            r.idle = true;
2043
2044            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2045            if (!mService.mBooted && isFrontStack(r.task.stack)) {
2046                mService.mBooted = true;
2047                enableScreen = true;
2048            }
2049        }
2050
2051        if (allResumedActivitiesIdle()) {
2052            if (r != null) {
2053                mService.scheduleAppGcsLocked();
2054            }
2055
2056            if (mLaunchingActivity.isHeld()) {
2057                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2058                if (VALIDATE_WAKE_LOCK_CALLER &&
2059                        Binder.getCallingUid() != Process.myUid()) {
2060                    throw new IllegalStateException("Calling must be system uid");
2061                }
2062                mLaunchingActivity.release();
2063            }
2064            ensureActivitiesVisibleLocked(null, 0);
2065        }
2066
2067        // Atomically retrieve all of the other things to do.
2068        stops = processStoppingActivitiesLocked(true);
2069        NS = stops != null ? stops.size() : 0;
2070        if ((NF=mFinishingActivities.size()) > 0) {
2071            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
2072            mFinishingActivities.clear();
2073        }
2074
2075        if (isFrontStack(mHomeStack)) {
2076            booting = mService.mBooting;
2077            mService.mBooting = false;
2078        }
2079
2080        if (mStartingUsers.size() > 0) {
2081            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
2082            mStartingUsers.clear();
2083        }
2084
2085        // Stop any activities that are scheduled to do so but have been
2086        // waiting for the next one to start.
2087        for (int i = 0; i < NS; i++) {
2088            r = stops.get(i);
2089            final ActivityStack stack = r.task.stack;
2090            if (r.finishing) {
2091                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2092            } else {
2093                stack.stopActivityLocked(r);
2094            }
2095        }
2096
2097        // Finish any activities that are scheduled to do so but have been
2098        // waiting for the next one to start.
2099        for (int i = 0; i < NF; i++) {
2100            r = finishes.get(i);
2101            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
2102        }
2103
2104        if (booting) {
2105            mService.finishBooting();
2106        } else {
2107            // Complete user switch
2108            if (startingUsers != null) {
2109                for (int i = 0; i < startingUsers.size(); i++) {
2110                    mService.finishUserSwitch(startingUsers.get(i));
2111                }
2112            }
2113            // Complete starting up of background users
2114            if (mStartingBackgroundUsers.size() > 0) {
2115                startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
2116                mStartingBackgroundUsers.clear();
2117                for (int i = 0; i < startingUsers.size(); i++) {
2118                    mService.finishUserBoot(startingUsers.get(i));
2119                }
2120            }
2121        }
2122
2123        mService.trimApplications();
2124        //dump();
2125        //mWindowManager.dump();
2126
2127        if (enableScreen) {
2128            mService.enableScreenAfterBoot();
2129        }
2130
2131        if (activityRemoved) {
2132            resumeTopActivitiesLocked();
2133        }
2134
2135        return r;
2136    }
2137
2138    boolean handleAppDiedLocked(ProcessRecord app) {
2139        boolean hasVisibleActivities = false;
2140        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2141            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2142            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2143                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2144            }
2145        }
2146        return hasVisibleActivities;
2147    }
2148
2149    void closeSystemDialogsLocked() {
2150        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2151            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2152            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2153                stacks.get(stackNdx).closeSystemDialogsLocked();
2154            }
2155        }
2156    }
2157
2158    void removeUserLocked(int userId) {
2159        mUserStackInFront.delete(userId);
2160    }
2161
2162    /**
2163     * @return true if some activity was finished (or would have finished if doit were true).
2164     */
2165    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2166        boolean didSomething = false;
2167        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2168            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2169            final int numStacks = stacks.size();
2170            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2171                final ActivityStack stack = stacks.get(stackNdx);
2172                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2173                    didSomething = true;
2174                }
2175            }
2176        }
2177        return didSomething;
2178    }
2179
2180    void updatePreviousProcessLocked(ActivityRecord r) {
2181        // Now that this process has stopped, we may want to consider
2182        // it to be the previous app to try to keep around in case
2183        // the user wants to return to it.
2184
2185        // First, found out what is currently the foreground app, so that
2186        // we don't blow away the previous app if this activity is being
2187        // hosted by the process that is actually still the foreground.
2188        ProcessRecord fgApp = null;
2189        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2190            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2191            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2192                final ActivityStack stack = stacks.get(stackNdx);
2193                if (isFrontStack(stack)) {
2194                    if (stack.mResumedActivity != null) {
2195                        fgApp = stack.mResumedActivity.app;
2196                    } else if (stack.mPausingActivity != null) {
2197                        fgApp = stack.mPausingActivity.app;
2198                    }
2199                    break;
2200                }
2201            }
2202        }
2203
2204        // Now set this one as the previous process, only if that really
2205        // makes sense to.
2206        if (r.app != null && fgApp != null && r.app != fgApp
2207                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2208                && r.app != mService.mHomeProcess) {
2209            mService.mPreviousProcess = r.app;
2210            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2211        }
2212    }
2213
2214    boolean resumeTopActivitiesLocked() {
2215        return resumeTopActivitiesLocked(null, null, null);
2216    }
2217
2218    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2219            Bundle targetOptions) {
2220        if (targetStack == null) {
2221            targetStack = getFocusedStack();
2222        }
2223        // Do targetStack first.
2224        boolean result = false;
2225        if (isFrontStack(targetStack)) {
2226            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2227        }
2228        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2229            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2230            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2231                final ActivityStack stack = stacks.get(stackNdx);
2232                if (stack == targetStack) {
2233                    // Already started above.
2234                    continue;
2235                }
2236                if (isFrontStack(stack)) {
2237                    stack.resumeTopActivityLocked(null);
2238                }
2239            }
2240        }
2241        return result;
2242    }
2243
2244    void finishTopRunningActivityLocked(ProcessRecord app) {
2245        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2246            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2247            final int numStacks = stacks.size();
2248            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2249                final ActivityStack stack = stacks.get(stackNdx);
2250                stack.finishTopRunningActivityLocked(app);
2251            }
2252        }
2253    }
2254
2255    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2256        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2257            mUserLeaving = true;
2258        }
2259        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2260            // Caller wants the home activity moved with it.  To accomplish this,
2261            // we'll just indicate that this task returns to the home task.
2262            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2263        }
2264        task.stack.moveTaskToFrontLocked(task, null, options);
2265        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2266                + task.stack);
2267    }
2268
2269    ActivityStack getStack(int stackId) {
2270        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2271        if (activityContainer != null) {
2272            return activityContainer.mStack;
2273        }
2274        return null;
2275    }
2276
2277    ArrayList<ActivityStack> getStacks() {
2278        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2279        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2280            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2281        }
2282        return allStacks;
2283    }
2284
2285    IBinder getHomeActivityToken() {
2286        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2287        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2288            final TaskRecord task = tasks.get(taskNdx);
2289            if (task.isHomeTask()) {
2290                final ArrayList<ActivityRecord> activities = task.mActivities;
2291                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2292                    final ActivityRecord r = activities.get(activityNdx);
2293                    if (r.isHomeActivity()) {
2294                        return r.appToken;
2295                    }
2296                }
2297            }
2298        }
2299        return null;
2300    }
2301
2302    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2303            IActivityContainerCallback callback) {
2304        ActivityContainer activityContainer =
2305                new VirtualActivityContainer(parentActivity, callback);
2306        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2307        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
2308        parentActivity.mChildContainers.add(activityContainer);
2309        return activityContainer;
2310    }
2311
2312    void removeChildActivityContainers(ActivityRecord parentActivity) {
2313        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2314        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2315            ActivityContainer container = childStacks.remove(containerNdx);
2316            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
2317                    container);
2318            container.release();
2319        }
2320    }
2321
2322    void deleteActivityContainer(IActivityContainer container) {
2323        ActivityContainer activityContainer = (ActivityContainer)container;
2324        if (activityContainer != null) {
2325            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
2326                    new RuntimeException("here").fillInStackTrace());
2327            final int stackId = activityContainer.mStackId;
2328            mActivityContainers.remove(stackId);
2329            mWindowManager.removeStack(stackId);
2330        }
2331    }
2332
2333    private int createStackOnDisplay(int stackId, int displayId) {
2334        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2335        if (activityDisplay == null) {
2336            return -1;
2337        }
2338
2339        ActivityContainer activityContainer = new ActivityContainer(stackId);
2340        mActivityContainers.put(stackId, activityContainer);
2341        activityContainer.attachToDisplayLocked(activityDisplay);
2342        return stackId;
2343    }
2344
2345    int getNextStackId() {
2346        while (true) {
2347            if (++mLastStackId <= HOME_STACK_ID) {
2348                mLastStackId = HOME_STACK_ID + 1;
2349            }
2350            if (getStack(mLastStackId) == null) {
2351                break;
2352            }
2353        }
2354        return mLastStackId;
2355    }
2356
2357    void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) {
2358        int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2359        final ActivityStack stack = getStack(stackId);
2360        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2361            final TaskRecord task = tasks.get(taskNdx);
2362            stack.addTask(task, false, false);
2363            final int taskId = task.taskId;
2364            final ArrayList<ActivityRecord> activities = task.mActivities;
2365            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2366                final ActivityRecord r = activities.get(activityNdx);
2367                mWindowManager.addAppToken(0, r.appToken, taskId, stackId,
2368                        r.info.screenOrientation, r.fullscreen,
2369                        (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
2370                        r.userId, r.info.configChanges, task.voiceSession != null);
2371            }
2372            mWindowManager.addTask(taskId, stackId, false);
2373        }
2374        resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2375    }
2376
2377    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2378        final TaskRecord task = anyTaskForIdLocked(taskId);
2379        if (task == null) {
2380            return;
2381        }
2382        final ActivityStack stack = getStack(stackId);
2383        if (stack == null) {
2384            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2385            return;
2386        }
2387        task.stack.removeTask(task);
2388        stack.addTask(task, toTop, true);
2389        mWindowManager.addTask(taskId, stackId, toTop);
2390        resumeTopActivitiesLocked();
2391    }
2392
2393    ActivityRecord findTaskLocked(ActivityRecord r) {
2394        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2395        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2396            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2397            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2398                final ActivityStack stack = stacks.get(stackNdx);
2399                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2400                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2401                    continue;
2402                }
2403                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2404                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2405                            stack);
2406                    continue;
2407                }
2408                final ActivityRecord ar = stack.findTaskLocked(r);
2409                if (ar != null) {
2410                    return ar;
2411                }
2412            }
2413        }
2414        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2415        return null;
2416    }
2417
2418    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2419        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2420            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2421            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2422                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2423                if (ar != null) {
2424                    return ar;
2425                }
2426            }
2427        }
2428        return null;
2429    }
2430
2431    void goingToSleepLocked() {
2432        scheduleSleepTimeout();
2433        if (!mGoingToSleep.isHeld()) {
2434            mGoingToSleep.acquire();
2435            if (mLaunchingActivity.isHeld()) {
2436                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2437                    throw new IllegalStateException("Calling must be system uid");
2438                }
2439                mLaunchingActivity.release();
2440                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2441            }
2442        }
2443        checkReadyForSleepLocked();
2444    }
2445
2446    boolean shutdownLocked(int timeout) {
2447        goingToSleepLocked();
2448
2449        boolean timedout = false;
2450        final long endTime = System.currentTimeMillis() + timeout;
2451        while (true) {
2452            boolean cantShutdown = false;
2453            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2454                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2455                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2456                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2457                }
2458            }
2459            if (cantShutdown) {
2460                long timeRemaining = endTime - System.currentTimeMillis();
2461                if (timeRemaining > 0) {
2462                    try {
2463                        mService.wait(timeRemaining);
2464                    } catch (InterruptedException e) {
2465                    }
2466                } else {
2467                    Slog.w(TAG, "Activity manager shutdown timed out");
2468                    timedout = true;
2469                    break;
2470                }
2471            } else {
2472                break;
2473            }
2474        }
2475
2476        // Force checkReadyForSleep to complete.
2477        mSleepTimeout = true;
2478        checkReadyForSleepLocked();
2479
2480        return timedout;
2481    }
2482
2483    void comeOutOfSleepIfNeededLocked() {
2484        removeSleepTimeouts();
2485        if (mGoingToSleep.isHeld()) {
2486            mGoingToSleep.release();
2487        }
2488        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2489            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2490            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2491                final ActivityStack stack = stacks.get(stackNdx);
2492                stack.awakeFromSleepingLocked();
2493                if (isFrontStack(stack)) {
2494                    resumeTopActivitiesLocked();
2495                }
2496            }
2497        }
2498        mGoingToSleepActivities.clear();
2499    }
2500
2501    void activitySleptLocked(ActivityRecord r) {
2502        mGoingToSleepActivities.remove(r);
2503        checkReadyForSleepLocked();
2504    }
2505
2506    void checkReadyForSleepLocked() {
2507        if (!mService.isSleepingOrShuttingDown()) {
2508            // Do not care.
2509            return;
2510        }
2511
2512        if (!mSleepTimeout) {
2513            boolean dontSleep = false;
2514            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2515                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2516                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2517                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2518                }
2519            }
2520
2521            if (mStoppingActivities.size() > 0) {
2522                // Still need to tell some activities to stop; can't sleep yet.
2523                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2524                        + mStoppingActivities.size() + " activities");
2525                scheduleIdleLocked();
2526                dontSleep = true;
2527            }
2528
2529            if (mGoingToSleepActivities.size() > 0) {
2530                // Still need to tell some activities to sleep; can't sleep yet.
2531                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2532                        + mGoingToSleepActivities.size() + " activities");
2533                dontSleep = true;
2534            }
2535
2536            if (dontSleep) {
2537                return;
2538            }
2539        }
2540
2541        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2542            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2543            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2544                stacks.get(stackNdx).goToSleep();
2545            }
2546        }
2547
2548        removeSleepTimeouts();
2549
2550        if (mGoingToSleep.isHeld()) {
2551            mGoingToSleep.release();
2552        }
2553        if (mService.mShuttingDown) {
2554            mService.notifyAll();
2555        }
2556    }
2557
2558    boolean reportResumedActivityLocked(ActivityRecord r) {
2559        final ActivityStack stack = r.task.stack;
2560        if (isFrontStack(stack)) {
2561            mService.updateUsageStats(r, true);
2562        }
2563        if (allResumedActivitiesComplete()) {
2564            ensureActivitiesVisibleLocked(null, 0);
2565            mWindowManager.executeAppTransition();
2566            return true;
2567        }
2568        return false;
2569    }
2570
2571    void handleAppCrashLocked(ProcessRecord app) {
2572        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2573            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2574            final int numStacks = stacks.size();
2575            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2576                final ActivityStack stack = stacks.get(stackNdx);
2577                stack.handleAppCrashLocked(app);
2578            }
2579        }
2580    }
2581
2582    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2583        // First the front stacks. In case any are not fullscreen and are in front of home.
2584        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2585            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2586            final int topStackNdx = stacks.size() - 1;
2587            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2588                final ActivityStack stack = stacks.get(stackNdx);
2589                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2590            }
2591        }
2592    }
2593
2594    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2595        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2596            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2597            final int numStacks = stacks.size();
2598            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2599                final ActivityStack stack = stacks.get(stackNdx);
2600                stack.scheduleDestroyActivities(app, false, reason);
2601            }
2602        }
2603    }
2604
2605    boolean switchUserLocked(int userId, UserStartedState uss) {
2606        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2607        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2608        mCurrentUser = userId;
2609
2610        mStartingUsers.add(uss);
2611        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2612            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2613            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2614                final ActivityStack stack = stacks.get(stackNdx);
2615                stack.switchUserLocked(userId);
2616                TaskRecord task = stack.topTask();
2617                if (task != null) {
2618                    mWindowManager.moveTaskToTop(task.taskId);
2619                }
2620            }
2621        }
2622
2623        ActivityStack stack = getStack(restoreStackId);
2624        if (stack == null) {
2625            stack = mHomeStack;
2626        }
2627        final boolean homeInFront = stack.isHomeStack();
2628        if (stack.isOnHomeDisplay()) {
2629            moveHomeStack(homeInFront);
2630            TaskRecord task = stack.topTask();
2631            if (task != null) {
2632                mWindowManager.moveTaskToTop(task.taskId);
2633            }
2634        } else {
2635            // Stack was moved to another display while user was swapped out.
2636            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2637        }
2638        return homeInFront;
2639    }
2640
2641    /**
2642     * Add background users to send boot completed events to.
2643     * @param userId The user being started in the background
2644     * @param uss The state object for the user.
2645     */
2646    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
2647        mStartingBackgroundUsers.add(uss);
2648    }
2649
2650    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2651        int N = mStoppingActivities.size();
2652        if (N <= 0) return null;
2653
2654        ArrayList<ActivityRecord> stops = null;
2655
2656        final boolean nowVisible = allResumedActivitiesVisible();
2657        for (int i=0; i<N; i++) {
2658            ActivityRecord s = mStoppingActivities.get(i);
2659            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2660                    + nowVisible + " waitingVisible=" + s.waitingVisible
2661                    + " finishing=" + s.finishing);
2662            if (s.waitingVisible && nowVisible) {
2663                mWaitingVisibleActivities.remove(s);
2664                s.waitingVisible = false;
2665                if (s.finishing) {
2666                    // If this activity is finishing, it is sitting on top of
2667                    // everyone else but we now know it is no longer needed...
2668                    // so get rid of it.  Otherwise, we need to go through the
2669                    // normal flow and hide it once we determine that it is
2670                    // hidden by the activities in front of it.
2671                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2672                    mWindowManager.setAppVisibility(s.appToken, false);
2673                }
2674            }
2675            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2676                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2677                if (stops == null) {
2678                    stops = new ArrayList<ActivityRecord>();
2679                }
2680                stops.add(s);
2681                mStoppingActivities.remove(i);
2682                N--;
2683                i--;
2684            }
2685        }
2686
2687        return stops;
2688    }
2689
2690    void validateTopActivitiesLocked() {
2691        // FIXME
2692/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2693            final ActivityStack stack = stacks.get(stackNdx);
2694            final ActivityRecord r = stack.topRunningActivityLocked(null);
2695            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2696            if (isFrontStack(stack)) {
2697                if (r == null) {
2698                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2699                } else {
2700                    final ActivityRecord pausing = stack.mPausingActivity;
2701                    if (pausing != null && pausing == r) {
2702                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2703                            " state=" + state);
2704                    }
2705                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2706                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2707                                " state=" + state);
2708                    }
2709                }
2710            } else {
2711                final ActivityRecord resumed = stack.mResumedActivity;
2712                if (resumed != null && resumed == r) {
2713                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2714                        " state=" + state);
2715                }
2716                if (r != null && (state == ActivityState.INITIALIZING
2717                        || state == ActivityState.RESUMED)) {
2718                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2719                            " state=" + state);
2720                }
2721            }
2722        }
2723*/
2724    }
2725
2726    public void dump(PrintWriter pw, String prefix) {
2727        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2728                pw.println(mDismissKeyguardOnNextActivity);
2729        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2730                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2731        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2732        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2733        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2734        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2735    }
2736
2737    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2738        return getFocusedStack().getDumpActivitiesLocked(name);
2739    }
2740
2741    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2742            boolean needSep, String prefix) {
2743        if (activity != null) {
2744            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2745                if (needSep) {
2746                    pw.println();
2747                }
2748                pw.print(prefix);
2749                pw.println(activity);
2750                return true;
2751            }
2752        }
2753        return false;
2754    }
2755
2756    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2757            boolean dumpClient, String dumpPackage) {
2758        boolean printed = false;
2759        boolean needSep = false;
2760        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2761            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2762            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2763            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2764            final int numStacks = stacks.size();
2765            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2766                final ActivityStack stack = stacks.get(stackNdx);
2767                StringBuilder stackHeader = new StringBuilder(128);
2768                stackHeader.append("  Stack #");
2769                stackHeader.append(stack.mStackId);
2770                stackHeader.append(":");
2771                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2772                        needSep, stackHeader.toString());
2773                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2774                        !dumpAll, false, dumpPackage, true,
2775                        "    Running activities (most recent first):", null);
2776
2777                needSep = printed;
2778                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2779                        "    mPausingActivity: ");
2780                if (pr) {
2781                    printed = true;
2782                    needSep = false;
2783                }
2784                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2785                        "    mResumedActivity: ");
2786                if (pr) {
2787                    printed = true;
2788                    needSep = false;
2789                }
2790                if (dumpAll) {
2791                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2792                            "    mLastPausedActivity: ");
2793                    if (pr) {
2794                        printed = true;
2795                        needSep = true;
2796                    }
2797                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2798                            needSep, "    mLastNoHistoryActivity: ");
2799                }
2800                needSep = printed;
2801            }
2802        }
2803
2804        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2805                false, dumpPackage, true, "  Activities waiting to finish:", null);
2806        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2807                false, dumpPackage, true, "  Activities waiting to stop:", null);
2808        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2809                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2810                null);
2811        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2812                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2813        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2814                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2815
2816        return printed;
2817    }
2818
2819    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2820            String prefix, String label, boolean complete, boolean brief, boolean client,
2821            String dumpPackage, boolean needNL, String header1, String header2) {
2822        TaskRecord lastTask = null;
2823        String innerPrefix = null;
2824        String[] args = null;
2825        boolean printed = false;
2826        for (int i=list.size()-1; i>=0; i--) {
2827            final ActivityRecord r = list.get(i);
2828            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2829                continue;
2830            }
2831            if (innerPrefix == null) {
2832                innerPrefix = prefix + "      ";
2833                args = new String[0];
2834            }
2835            printed = true;
2836            final boolean full = !brief && (complete || !r.isInHistory());
2837            if (needNL) {
2838                pw.println("");
2839                needNL = false;
2840            }
2841            if (header1 != null) {
2842                pw.println(header1);
2843                header1 = null;
2844            }
2845            if (header2 != null) {
2846                pw.println(header2);
2847                header2 = null;
2848            }
2849            if (lastTask != r.task) {
2850                lastTask = r.task;
2851                pw.print(prefix);
2852                pw.print(full ? "* " : "  ");
2853                pw.println(lastTask);
2854                if (full) {
2855                    lastTask.dump(pw, prefix + "  ");
2856                } else if (complete) {
2857                    // Complete + brief == give a summary.  Isn't that obvious?!?
2858                    if (lastTask.intent != null) {
2859                        pw.print(prefix); pw.print("  ");
2860                                pw.println(lastTask.intent.toInsecureStringWithClip());
2861                    }
2862                }
2863            }
2864            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2865            pw.print(" #"); pw.print(i); pw.print(": ");
2866            pw.println(r);
2867            if (full) {
2868                r.dump(pw, innerPrefix);
2869            } else if (complete) {
2870                // Complete + brief == give a summary.  Isn't that obvious?!?
2871                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2872                if (r.app != null) {
2873                    pw.print(innerPrefix); pw.println(r.app);
2874                }
2875            }
2876            if (client && r.app != null && r.app.thread != null) {
2877                // flush anything that is already in the PrintWriter since the thread is going
2878                // to write to the file descriptor directly
2879                pw.flush();
2880                try {
2881                    TransferPipe tp = new TransferPipe();
2882                    try {
2883                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2884                                r.appToken, innerPrefix, args);
2885                        // Short timeout, since blocking here can
2886                        // deadlock with the application.
2887                        tp.go(fd, 2000);
2888                    } finally {
2889                        tp.kill();
2890                    }
2891                } catch (IOException e) {
2892                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2893                } catch (RemoteException e) {
2894                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2895                }
2896                needNL = true;
2897            }
2898        }
2899        return printed;
2900    }
2901
2902    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2903        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2904        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2905        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2906    }
2907
2908    final void scheduleIdleLocked() {
2909        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2910    }
2911
2912    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2913        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2914        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2915    }
2916
2917    final void scheduleResumeTopActivities() {
2918        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2919            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2920        }
2921    }
2922
2923    void removeSleepTimeouts() {
2924        mSleepTimeout = false;
2925        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2926    }
2927
2928    final void scheduleSleepTimeout() {
2929        removeSleepTimeouts();
2930        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2931    }
2932
2933    @Override
2934    public void onDisplayAdded(int displayId) {
2935        Slog.v(TAG, "Display added displayId=" + displayId);
2936        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2937    }
2938
2939    @Override
2940    public void onDisplayRemoved(int displayId) {
2941        Slog.v(TAG, "Display removed displayId=" + displayId);
2942        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2943    }
2944
2945    @Override
2946    public void onDisplayChanged(int displayId) {
2947        Slog.v(TAG, "Display changed displayId=" + displayId);
2948        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2949    }
2950
2951    public void handleDisplayAddedLocked(int displayId) {
2952        boolean newDisplay;
2953        synchronized (mService) {
2954            newDisplay = mActivityDisplays.get(displayId) == null;
2955            if (newDisplay) {
2956                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2957                mActivityDisplays.put(displayId, activityDisplay);
2958            }
2959        }
2960        if (newDisplay) {
2961            mWindowManager.onDisplayAdded(displayId);
2962        }
2963    }
2964
2965    public void handleDisplayRemovedLocked(int displayId) {
2966        synchronized (mService) {
2967            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2968            if (activityDisplay != null) {
2969                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2970                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2971                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2972                }
2973                mActivityDisplays.remove(displayId);
2974            }
2975        }
2976        mWindowManager.onDisplayRemoved(displayId);
2977    }
2978
2979    public void handleDisplayChangedLocked(int displayId) {
2980        synchronized (mService) {
2981            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2982            if (activityDisplay != null) {
2983                // TODO: Update the bounds.
2984            }
2985        }
2986        mWindowManager.onDisplayChanged(displayId);
2987    }
2988
2989    StackInfo getStackInfo(ActivityStack stack) {
2990        StackInfo info = new StackInfo();
2991        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2992        info.displayId = Display.DEFAULT_DISPLAY;
2993        info.stackId = stack.mStackId;
2994
2995        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2996        final int numTasks = tasks.size();
2997        int[] taskIds = new int[numTasks];
2998        String[] taskNames = new String[numTasks];
2999        for (int i = 0; i < numTasks; ++i) {
3000            final TaskRecord task = tasks.get(i);
3001            taskIds[i] = task.taskId;
3002            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3003                    : task.realActivity != null ? task.realActivity.flattenToString()
3004                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3005                    : "unknown";
3006        }
3007        info.taskIds = taskIds;
3008        info.taskNames = taskNames;
3009        return info;
3010    }
3011
3012    StackInfo getStackInfoLocked(int stackId) {
3013        ActivityStack stack = getStack(stackId);
3014        if (stack != null) {
3015            return getStackInfo(stack);
3016        }
3017        return null;
3018    }
3019
3020    ArrayList<StackInfo> getAllStackInfosLocked() {
3021        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3022        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3023            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3024            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3025                list.add(getStackInfo(stacks.get(ndx)));
3026            }
3027        }
3028        return list;
3029    }
3030
3031    void setLockTaskModeLocked(TaskRecord task, boolean showHomeRecents) {
3032        if (task == null) {
3033            // Take out of lock task mode if necessary
3034            if (mLockTaskModeTask != null) {
3035                final Message lockTaskMsg = Message.obtain();
3036                lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3037                lockTaskMsg.what = LOCK_TASK_END_MSG;
3038                mLockTaskModeTask = null;
3039                mHandler.sendMessage(lockTaskMsg);
3040            }
3041            return;
3042        }
3043        if (isLockTaskModeViolation(task)) {
3044            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
3045            return;
3046        }
3047        mLockTaskModeTask = task;
3048        findTaskToMoveToFrontLocked(task, 0, null);
3049        resumeTopActivitiesLocked();
3050
3051        final Message lockTaskMsg = Message.obtain();
3052        lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
3053        lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3054        lockTaskMsg.what = LOCK_TASK_START_MSG;
3055        lockTaskMsg.arg2 = showHomeRecents ? 1 : 0;
3056        mHandler.sendMessage(lockTaskMsg);
3057    }
3058
3059    boolean isLockTaskModeViolation(TaskRecord task) {
3060        return mLockTaskModeTask != null && mLockTaskModeTask != task;
3061    }
3062
3063    void endLockTaskModeIfTaskEnding(TaskRecord task) {
3064        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
3065            mLockTaskModeTask = null;
3066        }
3067    }
3068
3069    boolean isInLockTaskMode() {
3070        return mLockTaskModeTask != null;
3071    }
3072
3073    private final class ActivityStackSupervisorHandler extends Handler {
3074
3075        public ActivityStackSupervisorHandler(Looper looper) {
3076            super(looper);
3077        }
3078
3079        void activityIdleInternal(ActivityRecord r) {
3080            synchronized (mService) {
3081                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3082            }
3083        }
3084
3085        @Override
3086        public void handleMessage(Message msg) {
3087            switch (msg.what) {
3088                case IDLE_TIMEOUT_MSG: {
3089                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3090                    if (mService.mDidDexOpt) {
3091                        mService.mDidDexOpt = false;
3092                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3093                        nmsg.obj = msg.obj;
3094                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3095                        return;
3096                    }
3097                    // We don't at this point know if the activity is fullscreen,
3098                    // so we need to be conservative and assume it isn't.
3099                    activityIdleInternal((ActivityRecord)msg.obj);
3100                } break;
3101                case IDLE_NOW_MSG: {
3102                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3103                    activityIdleInternal((ActivityRecord)msg.obj);
3104                } break;
3105                case RESUME_TOP_ACTIVITY_MSG: {
3106                    synchronized (mService) {
3107                        resumeTopActivitiesLocked();
3108                    }
3109                } break;
3110                case SLEEP_TIMEOUT_MSG: {
3111                    synchronized (mService) {
3112                        if (mService.isSleepingOrShuttingDown()) {
3113                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3114                            mSleepTimeout = true;
3115                            checkReadyForSleepLocked();
3116                        }
3117                    }
3118                } break;
3119                case LAUNCH_TIMEOUT_MSG: {
3120                    if (mService.mDidDexOpt) {
3121                        mService.mDidDexOpt = false;
3122                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3123                        return;
3124                    }
3125                    synchronized (mService) {
3126                        if (mLaunchingActivity.isHeld()) {
3127                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3128                            if (VALIDATE_WAKE_LOCK_CALLER
3129                                    && Binder.getCallingUid() != Process.myUid()) {
3130                                throw new IllegalStateException("Calling must be system uid");
3131                            }
3132                            mLaunchingActivity.release();
3133                        }
3134                    }
3135                } break;
3136                case HANDLE_DISPLAY_ADDED: {
3137                    handleDisplayAddedLocked(msg.arg1);
3138                } break;
3139                case HANDLE_DISPLAY_CHANGED: {
3140                    handleDisplayChangedLocked(msg.arg1);
3141                } break;
3142                case HANDLE_DISPLAY_REMOVED: {
3143                    handleDisplayRemovedLocked(msg.arg1);
3144                } break;
3145                case CONTAINER_CALLBACK_VISIBILITY: {
3146                    final ActivityContainer container = (ActivityContainer) msg.obj;
3147                    final IActivityContainerCallback callback = container.mCallback;
3148                    if (callback != null) {
3149                        try {
3150                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3151                        } catch (RemoteException e) {
3152                        }
3153                    }
3154                } break;
3155                case LOCK_TASK_START_MSG: {
3156                    // When lock task starts, we disable the status bars.
3157                    try {
3158                        if (mLockTaskNotify == null) {
3159                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3160                        }
3161                        mLockTaskNotify.show(true);
3162                        if (getStatusBarService() != null) {
3163                            int flags =
3164                                    StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
3165                            if (msg.arg2 != 0) {
3166                                flags ^= StatusBarManager.DISABLE_HOME
3167                                        | StatusBarManager.DISABLE_RECENT;
3168                            }
3169                            getStatusBarService().disable(flags, mToken,
3170                                    mService.mContext.getPackageName());
3171                        }
3172                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3173                        if (getDevicePolicyManager() != null) {
3174                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3175                                    (String)msg.obj, msg.arg1);
3176                        }
3177                    } catch (RemoteException ex) {
3178                        throw new RuntimeException(ex);
3179                    }
3180                } break;
3181                case LOCK_TASK_END_MSG: {
3182                    // When lock task ends, we enable the status bars.
3183                    try {
3184                        if (getStatusBarService() != null) {
3185                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3186                                    mService.mContext.getPackageName());
3187                        }
3188                        mWindowManager.reenableKeyguard(mToken);
3189                        if (getDevicePolicyManager() != null) {
3190                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3191                                    msg.arg1);
3192                        }
3193                        if (mLockTaskNotify == null) {
3194                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3195                        }
3196                        mLockTaskNotify.show(false);
3197                        try {
3198                            boolean shouldLockKeyguard = Settings.System.getInt(
3199                                    mService.mContext.getContentResolver(),
3200                                    Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
3201                            if (shouldLockKeyguard) {
3202                                mWindowManager.lockNow(null);
3203                            }
3204                        } catch (SettingNotFoundException e) {
3205                            // No setting, don't lock.
3206                        }
3207                    } catch (RemoteException ex) {
3208                        throw new RuntimeException(ex);
3209                    }
3210                } break;
3211                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3212                    final ActivityContainer container = (ActivityContainer) msg.obj;
3213                    final IActivityContainerCallback callback = container.mCallback;
3214                    if (callback != null) {
3215                        try {
3216                            callback.onAllActivitiesComplete(container.asBinder());
3217                        } catch (RemoteException e) {
3218                        }
3219                    }
3220                } break;
3221                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
3222                    synchronized (mService) {
3223                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
3224                                msg.obj);
3225                        ((ActivityContainer) msg.obj).onTaskListEmptyLocked();
3226                    }
3227                } break;
3228            }
3229        }
3230    }
3231
3232    class ActivityContainer extends android.app.IActivityContainer.Stub {
3233        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3234                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3235        final int mStackId;
3236        IActivityContainerCallback mCallback = null;
3237        final ActivityStack mStack;
3238        ActivityRecord mParentActivity = null;
3239        String mIdString;
3240
3241        boolean mVisible = true;
3242
3243        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3244        ActivityDisplay mActivityDisplay;
3245
3246        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3247        final static int CONTAINER_STATE_NO_SURFACE = 1;
3248        final static int CONTAINER_STATE_FINISHING = 2;
3249        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3250
3251        ActivityContainer(int stackId) {
3252            synchronized (mService) {
3253                mStackId = stackId;
3254                mStack = new ActivityStack(this);
3255                mIdString = "ActivtyContainer{" + mStackId + "}";
3256                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3257            }
3258        }
3259
3260        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3261            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3262                    + " to display=" + activityDisplay);
3263            mActivityDisplay = activityDisplay;
3264            mStack.mDisplayId = activityDisplay.mDisplayId;
3265            mStack.mStacks = activityDisplay.mStacks;
3266
3267            activityDisplay.attachActivities(mStack);
3268            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3269        }
3270
3271        @Override
3272        public void attachToDisplay(int displayId) {
3273            synchronized (mService) {
3274                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3275                if (activityDisplay == null) {
3276                    return;
3277                }
3278                attachToDisplayLocked(activityDisplay);
3279            }
3280        }
3281
3282        @Override
3283        public int getDisplayId() {
3284            synchronized (mService) {
3285                if (mActivityDisplay != null) {
3286                    return mActivityDisplay.mDisplayId;
3287                }
3288            }
3289            return -1;
3290        }
3291
3292        @Override
3293        public boolean injectEvent(InputEvent event) {
3294            final long origId = Binder.clearCallingIdentity();
3295            try {
3296                synchronized (mService) {
3297                    if (mActivityDisplay != null) {
3298                        return mInputManagerInternal.injectInputEvent(event,
3299                                mActivityDisplay.mDisplayId,
3300                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3301                    }
3302                }
3303                return false;
3304            } finally {
3305                Binder.restoreCallingIdentity(origId);
3306            }
3307        }
3308
3309        @Override
3310        public void release() {
3311            synchronized (mService) {
3312                if (mContainerState == CONTAINER_STATE_FINISHING) {
3313                    return;
3314                }
3315                mContainerState = CONTAINER_STATE_FINISHING;
3316
3317                final Message msg =
3318                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3319                mHandler.sendMessageDelayed(msg, 1000);
3320
3321                long origId = Binder.clearCallingIdentity();
3322                try {
3323                    mStack.finishAllActivitiesLocked();
3324                } finally {
3325                    Binder.restoreCallingIdentity(origId);
3326                }
3327            }
3328        }
3329
3330        private void detachLocked() {
3331            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3332                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3333            if (mActivityDisplay != null) {
3334                mActivityDisplay.detachActivitiesLocked(mStack);
3335                mActivityDisplay = null;
3336                mStack.mDisplayId = -1;
3337                mStack.mStacks = null;
3338                mWindowManager.detachStack(mStackId);
3339            }
3340        }
3341
3342        @Override
3343        public final int startActivity(Intent intent) {
3344            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3345            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3346                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3347            // TODO: Switch to user app stacks here.
3348            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3349            String mimeType = intent.getType();
3350            if (mimeType == null && intent.getData() != null
3351                    && "content".equals(intent.getData().getScheme())) {
3352                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3353            }
3354            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null,
3355                    null, null, null, null, userId, this);
3356        }
3357
3358        @Override
3359        public final int startActivityIntentSender(IIntentSender intentSender) {
3360            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3361
3362            if (!(intentSender instanceof PendingIntentRecord)) {
3363                throw new IllegalArgumentException("Bad PendingIntent object");
3364            }
3365
3366            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3367                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3368        }
3369
3370        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3371            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3372                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3373            if (resolvedType == null) {
3374                resolvedType = intent.getType();
3375                if (resolvedType == null && intent.getData() != null
3376                        && "content".equals(intent.getData().getScheme())) {
3377                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3378                }
3379            }
3380            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
3381            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3382                throw new SecurityException(
3383                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3384            }
3385        }
3386
3387        /** Throw a SecurityException if allowEmbedded is not true */
3388        @Override
3389        public final void checkEmbeddedAllowed(Intent intent) {
3390            checkEmbeddedAllowedInner(intent, null);
3391        }
3392
3393        /** Throw a SecurityException if allowEmbedded is not true */
3394        @Override
3395        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3396            if (!(intentSender instanceof PendingIntentRecord)) {
3397                throw new IllegalArgumentException("Bad PendingIntent object");
3398            }
3399            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3400            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3401                    pendingIntent.key.requestResolvedType);
3402        }
3403
3404        @Override
3405        public IBinder asBinder() {
3406            return this;
3407        }
3408
3409        @Override
3410        public void setSurface(Surface surface, int width, int height, int density) {
3411            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3412        }
3413
3414        ActivityStackSupervisor getOuter() {
3415            return ActivityStackSupervisor.this;
3416        }
3417
3418        boolean isAttachedLocked() {
3419            return mActivityDisplay != null;
3420        }
3421
3422        void getBounds(Point outBounds) {
3423            synchronized (mService) {
3424                    if (mActivityDisplay != null) {
3425                    mActivityDisplay.getBounds(outBounds);
3426                } else {
3427                    outBounds.set(0, 0);
3428                }
3429            }
3430        }
3431
3432        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3433        void setVisible(boolean visible) {
3434            if (mVisible != visible) {
3435                mVisible = visible;
3436                if (mCallback != null) {
3437                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3438                            0 /* unused */, this).sendToTarget();
3439                }
3440            }
3441        }
3442
3443        void setDrawn() {
3444        }
3445
3446        // You can always start a new task on a regular ActivityStack.
3447        boolean isEligibleForNewTasks() {
3448            return true;
3449        }
3450
3451        void onTaskListEmptyLocked() {
3452            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3453            if (!mStack.isHomeStack()) {
3454                detachLocked();
3455                deleteActivityContainer(this);
3456            }
3457            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3458        }
3459
3460        @Override
3461        public String toString() {
3462            return mIdString + (mActivityDisplay == null ? "N" : "A");
3463        }
3464    }
3465
3466    private class VirtualActivityContainer extends ActivityContainer {
3467        Surface mSurface;
3468        boolean mDrawn = false;
3469
3470        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3471            super(getNextStackId());
3472            mParentActivity = parent;
3473            mCallback = callback;
3474            mContainerState = CONTAINER_STATE_NO_SURFACE;
3475            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3476        }
3477
3478        @Override
3479        public void setSurface(Surface surface, int width, int height, int density) {
3480            super.setSurface(surface, width, height, density);
3481
3482            synchronized (mService) {
3483                final long origId = Binder.clearCallingIdentity();
3484                try {
3485                    setSurfaceLocked(surface, width, height, density);
3486                } finally {
3487                    Binder.restoreCallingIdentity(origId);
3488                }
3489            }
3490        }
3491
3492        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3493            if (mContainerState == CONTAINER_STATE_FINISHING) {
3494                return;
3495            }
3496            VirtualActivityDisplay virtualActivityDisplay =
3497                    (VirtualActivityDisplay) mActivityDisplay;
3498            if (virtualActivityDisplay == null) {
3499                virtualActivityDisplay =
3500                        new VirtualActivityDisplay(width, height, density);
3501                mActivityDisplay = virtualActivityDisplay;
3502                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3503                attachToDisplayLocked(virtualActivityDisplay);
3504            }
3505
3506            if (mSurface != null) {
3507                mSurface.release();
3508            }
3509
3510            mSurface = surface;
3511            if (surface != null) {
3512                mStack.resumeTopActivityLocked(null);
3513            } else {
3514                mContainerState = CONTAINER_STATE_NO_SURFACE;
3515                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3516                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3517                    mStack.startPausingLocked(false, true);
3518                }
3519            }
3520
3521            setSurfaceIfReadyLocked();
3522
3523            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3524                    + virtualActivityDisplay);
3525        }
3526
3527        @Override
3528        boolean isAttachedLocked() {
3529            return mSurface != null && super.isAttachedLocked();
3530        }
3531
3532        @Override
3533        void setDrawn() {
3534            synchronized (mService) {
3535                mDrawn = true;
3536                setSurfaceIfReadyLocked();
3537            }
3538        }
3539
3540        // Never start a new task on an ActivityView if it isn't explicitly specified.
3541        @Override
3542        boolean isEligibleForNewTasks() {
3543            return false;
3544        }
3545
3546        private void setSurfaceIfReadyLocked() {
3547            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
3548                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3549            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3550                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3551                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3552            }
3553        }
3554    }
3555
3556    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3557     * attached {@link ActivityStack}s */
3558    class ActivityDisplay {
3559        /** Actual Display this object tracks. */
3560        int mDisplayId;
3561        Display mDisplay;
3562        DisplayInfo mDisplayInfo = new DisplayInfo();
3563
3564        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3565         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3566        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3567
3568        ActivityDisplay() {
3569        }
3570
3571        ActivityDisplay(int displayId) {
3572            init(mDisplayManager.getDisplay(displayId));
3573        }
3574
3575        void init(Display display) {
3576            mDisplay = display;
3577            mDisplayId = display.getDisplayId();
3578            mDisplay.getDisplayInfo(mDisplayInfo);
3579        }
3580
3581        void attachActivities(ActivityStack stack) {
3582            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3583                    + mDisplayId);
3584            mStacks.add(stack);
3585        }
3586
3587        void detachActivitiesLocked(ActivityStack stack) {
3588            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3589                    + " from displayId=" + mDisplayId);
3590            mStacks.remove(stack);
3591        }
3592
3593        void getBounds(Point bounds) {
3594            mDisplay.getDisplayInfo(mDisplayInfo);
3595            bounds.x = mDisplayInfo.appWidth;
3596            bounds.y = mDisplayInfo.appHeight;
3597        }
3598
3599        @Override
3600        public String toString() {
3601            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3602        }
3603    }
3604
3605    class VirtualActivityDisplay extends ActivityDisplay {
3606        VirtualDisplay mVirtualDisplay;
3607
3608        VirtualActivityDisplay(int width, int height, int density) {
3609            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3610            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
3611                    width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3612                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3613
3614            init(mVirtualDisplay.getDisplay());
3615
3616            mWindowManager.handleDisplayAdded(mDisplayId);
3617        }
3618
3619        void setSurface(Surface surface) {
3620            if (mVirtualDisplay != null) {
3621                mVirtualDisplay.setSurface(surface);
3622            }
3623        }
3624
3625        @Override
3626        void detachActivitiesLocked(ActivityStack stack) {
3627            super.detachActivitiesLocked(stack);
3628            if (mVirtualDisplay != null) {
3629                mVirtualDisplay.release();
3630                mVirtualDisplay = null;
3631            }
3632        }
3633
3634        @Override
3635        public String toString() {
3636            return "VirtualActivityDisplay={" + mDisplayId + "}";
3637        }
3638    }
3639
3640    private boolean isLeanbackOnlyDevice() {
3641        boolean onLeanbackOnly = false;
3642        try {
3643            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
3644                    PackageManager.FEATURE_LEANBACK_ONLY);
3645        } catch (RemoteException e) {
3646            // noop
3647        }
3648
3649        return onLeanbackOnly;
3650    }
3651}
3652