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