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