ActivityStackSupervisor.java revision f7097a5b697fedb6976774e55a51471405a23c0e
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, r.info.applicationInfo.versionCode,
1162                            mService.mProcessStats);
1163                }
1164                realStartActivityLocked(r, app, andResume, checkConfig);
1165                return;
1166            } catch (RemoteException e) {
1167                Slog.w(TAG, "Exception when starting activity "
1168                        + r.intent.getComponent().flattenToShortString(), e);
1169            }
1170
1171            // If a dead object exception was thrown -- fall through to
1172            // restart the application.
1173        }
1174
1175        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1176                "activity", r.intent.getComponent(), false, false, true);
1177    }
1178
1179    final int startActivityLocked(IApplicationThread caller,
1180            Intent intent, String resolvedType, ActivityInfo aInfo,
1181            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1182            IBinder resultTo, String resultWho, int requestCode,
1183            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1184            boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
1185        int err = ActivityManager.START_SUCCESS;
1186
1187        ProcessRecord callerApp = null;
1188        if (caller != null) {
1189            callerApp = mService.getRecordForAppLocked(caller);
1190            if (callerApp != null) {
1191                callingPid = callerApp.pid;
1192                callingUid = callerApp.info.uid;
1193            } else {
1194                Slog.w(TAG, "Unable to find app for caller " + caller
1195                      + " (pid=" + callingPid + ") when starting: "
1196                      + intent.toString());
1197                err = ActivityManager.START_PERMISSION_DENIED;
1198            }
1199        }
1200
1201        if (err == ActivityManager.START_SUCCESS) {
1202            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1203            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1204                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1205                    + " on display " + (container == null ? (mFocusedStack == null ?
1206                            Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1207                            (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1208                                    container.mActivityDisplay.mDisplayId)));
1209        }
1210
1211        ActivityRecord sourceRecord = null;
1212        ActivityRecord resultRecord = null;
1213        if (resultTo != null) {
1214            sourceRecord = isInAnyStackLocked(resultTo);
1215            if (DEBUG_RESULTS) Slog.v(
1216                TAG, "Will send result to " + resultTo + " " + sourceRecord);
1217            if (sourceRecord != null) {
1218                if (requestCode >= 0 && !sourceRecord.finishing) {
1219                    resultRecord = sourceRecord;
1220                }
1221            }
1222        }
1223        ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1224
1225        final int launchFlags = intent.getFlags();
1226
1227        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1228                && sourceRecord != null) {
1229            // Transfer the result target from the source activity to the new
1230            // one being started, including any failures.
1231            if (requestCode >= 0) {
1232                ActivityOptions.abort(options);
1233                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1234            }
1235            resultRecord = sourceRecord.resultTo;
1236            resultWho = sourceRecord.resultWho;
1237            requestCode = sourceRecord.requestCode;
1238            sourceRecord.resultTo = null;
1239            if (resultRecord != null) {
1240                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
1241            }
1242            if (sourceRecord.launchedFromUid == callingUid) {
1243                // The new activity is being launched from the same uid as the previous
1244                // activity in the flow, and asking to forward its result back to the
1245                // previous.  In this case the activity is serving as a trampoline between
1246                // the two, so we also want to update its launchedFromPackage to be the
1247                // same as the previous activity.  Note that this is safe, since we know
1248                // these two packages come from the same uid; the caller could just as
1249                // well have supplied that same package name itself.  This specifially
1250                // deals with the case of an intent picker/chooser being launched in the app
1251                // flow to redirect to an activity picked by the user, where we want the final
1252                // activity to consider it to have been launched by the previous app activity.
1253                callingPackage = sourceRecord.launchedFromPackage;
1254            }
1255        }
1256
1257        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1258            // We couldn't find a class that can handle the given Intent.
1259            // That's the end of that!
1260            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1261        }
1262
1263        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1264            // We couldn't find the specific class specified in the Intent.
1265            // Also the end of the line.
1266            err = ActivityManager.START_CLASS_NOT_FOUND;
1267        }
1268
1269        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
1270                && sourceRecord.task.voiceSession != null) {
1271            // If this activity is being launched as part of a voice session, we need
1272            // to ensure that it is safe to do so.  If the upcoming activity will also
1273            // be part of the voice session, we can only launch it if it has explicitly
1274            // said it supports the VOICE category, or it is a part of the calling app.
1275            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
1276                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
1277                try {
1278                    if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1279                            intent, resolvedType)) {
1280                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1281                    }
1282                } catch (RemoteException e) {
1283                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1284                }
1285            }
1286        }
1287
1288        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
1289            // If the caller is starting a new voice session, just make sure the target
1290            // is actually allowing it to run this way.
1291            try {
1292                if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1293                        intent, resolvedType)) {
1294                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1295                }
1296            } catch (RemoteException e) {
1297                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1298            }
1299        }
1300
1301        if (err != ActivityManager.START_SUCCESS) {
1302            if (resultRecord != null) {
1303                resultStack.sendActivityResultLocked(-1,
1304                    resultRecord, resultWho, requestCode,
1305                    Activity.RESULT_CANCELED, null);
1306            }
1307            setDismissKeyguard(false);
1308            ActivityOptions.abort(options);
1309            return err;
1310        }
1311
1312        final int startAnyPerm = mService.checkPermission(
1313                START_ANY_ACTIVITY, callingPid, callingUid);
1314        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1315                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1316        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1317            if (resultRecord != null) {
1318                resultStack.sendActivityResultLocked(-1,
1319                    resultRecord, resultWho, requestCode,
1320                    Activity.RESULT_CANCELED, null);
1321            }
1322            setDismissKeyguard(false);
1323            String msg;
1324            if (!aInfo.exported) {
1325                msg = "Permission Denial: starting " + intent.toString()
1326                        + " from " + callerApp + " (pid=" + callingPid
1327                        + ", uid=" + callingUid + ")"
1328                        + " not exported from uid " + aInfo.applicationInfo.uid;
1329            } else {
1330                msg = "Permission Denial: starting " + intent.toString()
1331                        + " from " + callerApp + " (pid=" + callingPid
1332                        + ", uid=" + callingUid + ")"
1333                        + " requires " + aInfo.permission;
1334            }
1335            Slog.w(TAG, msg);
1336            throw new SecurityException(msg);
1337        }
1338
1339        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1340                callingPid, resolvedType, aInfo.applicationInfo);
1341
1342        if (mService.mController != null) {
1343            try {
1344                // The Intent we give to the watcher has the extra data
1345                // stripped off, since it can contain private information.
1346                Intent watchIntent = intent.cloneFilter();
1347                abort |= !mService.mController.activityStarting(watchIntent,
1348                        aInfo.applicationInfo.packageName);
1349            } catch (RemoteException e) {
1350                mService.mController = null;
1351            }
1352        }
1353
1354        if (abort) {
1355            if (resultRecord != null) {
1356                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1357                        Activity.RESULT_CANCELED, null);
1358            }
1359            // We pretend to the caller that it was really started, but
1360            // they will just get a cancel result.
1361            setDismissKeyguard(false);
1362            ActivityOptions.abort(options);
1363            return ActivityManager.START_SUCCESS;
1364        }
1365
1366        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1367                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1368                requestCode, componentSpecified, this, container, options);
1369        if (outActivity != null) {
1370            outActivity[0] = r;
1371        }
1372
1373        final ActivityStack stack = getFocusedStack();
1374        if (voiceSession == null && (stack.mResumedActivity == null
1375                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
1376            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1377                PendingActivityLaunch pal =
1378                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1379                mService.mPendingActivityLaunches.add(pal);
1380                setDismissKeyguard(false);
1381                ActivityOptions.abort(options);
1382                return ActivityManager.START_SWITCHES_CANCELED;
1383            }
1384        }
1385
1386        if (mService.mDidAppSwitch) {
1387            // This is the second allowed switch since we stopped switches,
1388            // so now just generally allow switches.  Use case: user presses
1389            // home (switches disabled, switch to home, mDidAppSwitch now true);
1390            // user taps a home icon (coming from home so allowed, we hit here
1391            // and now allow anyone to switch again).
1392            mService.mAppSwitchesAllowedTime = 0;
1393        } else {
1394            mService.mDidAppSwitch = true;
1395        }
1396
1397        mService.doPendingActivityLaunchesLocked(false);
1398
1399        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
1400                startFlags, true, options);
1401
1402        if (allPausedActivitiesComplete()) {
1403            // If someone asked to have the keyguard dismissed on the next
1404            // activity start, but we are not actually doing an activity
1405            // switch...  just dismiss the keyguard now, because we
1406            // probably want to see whatever is behind it.
1407            dismissKeyguard();
1408        }
1409        return err;
1410    }
1411
1412    ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) {
1413        final TaskRecord task = r.task;
1414
1415        // On leanback only devices we should keep all activities in the same stack.
1416        if (!mLeanbackOnlyDevice &&
1417                (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
1418            if (task != null) {
1419                final ActivityStack taskStack = task.stack;
1420                if (taskStack.isOnHomeDisplay()) {
1421                    if (mFocusedStack != taskStack) {
1422                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1423                                "focused stack to r=" + r + " task=" + task);
1424                        mFocusedStack = taskStack;
1425                    } else {
1426                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1427                            "adjustStackFocus: Focused stack already=" + mFocusedStack);
1428                    }
1429                }
1430                return taskStack;
1431            }
1432
1433            final ActivityContainer container = r.mInitialActivityContainer;
1434            if (container != null) {
1435                // The first time put it on the desired stack, after this put on task stack.
1436                r.mInitialActivityContainer = null;
1437                return container.mStack;
1438            }
1439
1440            if (mFocusedStack != mHomeStack && (!newTask ||
1441                    mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
1442                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1443                        "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1444                return mFocusedStack;
1445            }
1446
1447            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1448            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1449                final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1450                if (!stack.isHomeStack()) {
1451                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1452                            "adjustStackFocus: Setting focused stack=" + stack);
1453                    mFocusedStack = stack;
1454                    return mFocusedStack;
1455                }
1456            }
1457
1458            // Need to create an app stack for this user.
1459            int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
1460            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1461                    " stackId=" + stackId);
1462            mFocusedStack = getStack(stackId);
1463            return mFocusedStack;
1464        }
1465        return mHomeStack;
1466    }
1467
1468    void setFocusedStack(ActivityRecord r) {
1469        if (r != null) {
1470            final TaskRecord task = r.task;
1471            boolean isHomeActivity = !r.isApplicationActivity();
1472            if (!isHomeActivity && task != null) {
1473                isHomeActivity = !task.isApplicationTask();
1474            }
1475            if (!isHomeActivity && task != null) {
1476                final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1477                isHomeActivity = parent != null && parent.isHomeActivity();
1478            }
1479            moveHomeStack(isHomeActivity);
1480        }
1481    }
1482
1483    final int startActivityUncheckedLocked(ActivityRecord r,
1484            ActivityRecord sourceRecord,
1485            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
1486            boolean doResume, Bundle options) {
1487        final Intent intent = r.intent;
1488        final int callingUid = r.launchedFromUid;
1489
1490        int launchFlags = intent.getFlags();
1491
1492        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1493                (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
1494                        r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK)) {
1495            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1496            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1497                    "\"singleInstance\" or \"singleTask\"");
1498            launchFlags &=
1499                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
1500        } else {
1501            switch (r.info.documentLaunchMode) {
1502                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1503                    break;
1504                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1505                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1506                    break;
1507                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1508                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1509                    break;
1510                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1511                    launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1512                    break;
1513            }
1514        }
1515
1516        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1517            // For whatever reason this activity is being launched into a new
1518            // task...  yet the caller has requested a result back.  Well, that
1519            // is pretty messed up, so instead immediately send back a cancel
1520            // and let the new task continue launched as normal without a
1521            // dependency on its originator.
1522            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1523            r.resultTo.task.stack.sendActivityResultLocked(-1,
1524                    r.resultTo, r.resultWho, r.requestCode,
1525                    Activity.RESULT_CANCELED, null);
1526            r.resultTo = null;
1527        }
1528
1529        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1530            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1531        }
1532
1533        // We'll invoke onUserLeaving before onPause only if the launching
1534        // activity did not explicitly state that this is an automated launch.
1535        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1536        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1537
1538        // If the caller has asked not to resume at this point, we make note
1539        // of this in the record so that we can skip it when trying to find
1540        // the top running activity.
1541        if (!doResume) {
1542            r.delayedResume = true;
1543        }
1544
1545        ActivityRecord notTop =
1546                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1547
1548        // If the onlyIfNeeded flag is set, then we can do this if the activity
1549        // being launched is the same as the one making the call...  or, as
1550        // a special case, if we do not know the caller then we count the
1551        // current top activity as the caller.
1552        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1553            ActivityRecord checkedCaller = sourceRecord;
1554            if (checkedCaller == null) {
1555                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1556            }
1557            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1558                // Caller is not the same as launcher, so always needed.
1559                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1560            }
1561        }
1562
1563        if (sourceRecord == null) {
1564            // This activity is not being started from another...  in this
1565            // case we -always- start a new task.
1566            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1567                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1568                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1569                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1570            }
1571        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1572            // The original activity who is starting us is running as a single
1573            // instance...  this new activity it is starting must go on its
1574            // own task.
1575            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1576        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1577                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1578            // The activity being started is a single instance...  it always
1579            // gets launched into its own task.
1580            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1581        }
1582
1583        ActivityInfo newTaskInfo = null;
1584        Intent newTaskIntent = null;
1585        final ActivityStack sourceStack;
1586        if (sourceRecord != null) {
1587            if (sourceRecord.finishing) {
1588                // If the source is finishing, we can't further count it as our source.  This
1589                // is because the task it is associated with may now be empty and on its way out,
1590                // so we don't want to blindly throw it in to that task.  Instead we will take
1591                // the NEW_TASK flow and try to find a task for it. But save the task information
1592                // so it can be used when creating the new task.
1593                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1594                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1595                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1596                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1597                    newTaskInfo = sourceRecord.info;
1598                    newTaskIntent = sourceRecord.task.intent;
1599                }
1600                sourceRecord = null;
1601                sourceStack = null;
1602            } else {
1603                sourceStack = sourceRecord.task.stack;
1604            }
1605        } else {
1606            sourceStack = null;
1607        }
1608
1609        intent.setFlags(launchFlags);
1610
1611        boolean addingToTask = false;
1612        boolean movedHome = false;
1613        TaskRecord reuseTask = null;
1614        ActivityStack targetStack;
1615        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1616                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1617                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1618                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1619            // If bring to front is requested, and no result is requested, and
1620            // we can find a task that was started with this same
1621            // component, then instead of launching bring that one to the front.
1622            if (r.resultTo == null) {
1623                // See if there is a task to bring to the front.  If this is
1624                // a SINGLE_INSTANCE activity, there can be one and only one
1625                // instance of it in the history, and it is always in its own
1626                // unique task, so we do a special search.
1627                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1628                        ? findTaskLocked(r)
1629                        : findActivityLocked(intent, r.info);
1630                if (intentActivity != null) {
1631                    if (isLockTaskModeViolation(intentActivity.task)) {
1632                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1633                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1634                    }
1635                    if (r.task == null) {
1636                        r.task = intentActivity.task;
1637                    }
1638                    targetStack = intentActivity.task.stack;
1639                    targetStack.mLastPausedActivity = null;
1640                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1641                            + " from " + intentActivity);
1642                    targetStack.moveToFront();
1643                    if (intentActivity.task.intent == null) {
1644                        // This task was started because of movement of
1645                        // the activity based on affinity...  now that we
1646                        // are actually launching it, we can assign the
1647                        // base intent.
1648                        intentActivity.task.setIntent(intent, r.info);
1649                    }
1650                    // If the target task is not in the front, then we need
1651                    // to bring it to the front...  except...  well, with
1652                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1653                    // to have the same behavior as if a new instance was
1654                    // being started, which means not bringing it to the front
1655                    // if the caller is not itself in the front.
1656                    final ActivityStack lastStack = getLastStack();
1657                    ActivityRecord curTop = lastStack == null?
1658                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1659                    if (curTop != null && (curTop.task != intentActivity.task ||
1660                            curTop.task != lastStack.topTask())) {
1661                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1662                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1663                                sourceStack.topActivity().task == sourceRecord.task)) {
1664                            // We really do want to push this one into the
1665                            // user's face, right now.
1666                            movedHome = true;
1667                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1668                            if ((launchFlags &
1669                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1670                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1671                                // Caller wants to appear on home activity.
1672                                intentActivity.task.mOnTopOfHome = true;
1673                            }
1674                            options = null;
1675                        }
1676                    }
1677                    // If the caller has requested that the target task be
1678                    // reset, then do so.
1679                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1680                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1681                    }
1682                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1683                        // We don't need to start a new activity, and
1684                        // the client said not to do anything if that
1685                        // is the case, so this is it!  And for paranoia, make
1686                        // sure we have correctly resumed the top activity.
1687                        if (doResume) {
1688                            resumeTopActivitiesLocked(targetStack, null, options);
1689                        } else {
1690                            ActivityOptions.abort(options);
1691                        }
1692                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1693                    }
1694                    if ((launchFlags &
1695                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1696                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1697                        // The caller has requested to completely replace any
1698                        // existing task with its new activity.  Well that should
1699                        // not be too hard...
1700                        reuseTask = intentActivity.task;
1701                        reuseTask.performClearTaskLocked();
1702                        reuseTask.setIntent(r.intent, r.info);
1703                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1704                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1705                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1706                        // In this situation we want to remove all activities
1707                        // from the task up to the one being started.  In most
1708                        // cases this means we are resetting the task to its
1709                        // initial state.
1710                        ActivityRecord top =
1711                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1712                        if (top != null) {
1713                            if (top.frontOfTask) {
1714                                // Activity aliases may mean we use different
1715                                // intents for the top activity, so make sure
1716                                // the task now has the identity of the new
1717                                // intent.
1718                                top.task.setIntent(r.intent, r.info);
1719                            }
1720                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1721                                    r, top.task);
1722                            top.deliverNewIntentLocked(callingUid, r.intent);
1723                        } else {
1724                            // A special case: we need to
1725                            // start the activity because it is not currently
1726                            // running, and the caller has asked to clear the
1727                            // current task to have this activity at the top.
1728                            addingToTask = true;
1729                            // Now pretend like this activity is being started
1730                            // by the top of its task, so it is put in the
1731                            // right place.
1732                            sourceRecord = intentActivity;
1733                        }
1734                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1735                        // In this case the top activity on the task is the
1736                        // same as the one being launched, so we take that
1737                        // as a request to bring the task to the foreground.
1738                        // If the top activity in the task is the root
1739                        // activity, deliver this new intent to it if it
1740                        // desires.
1741                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1742                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1743                                && intentActivity.realActivity.equals(r.realActivity)) {
1744                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1745                                    intentActivity.task);
1746                            if (intentActivity.frontOfTask) {
1747                                intentActivity.task.setIntent(r.intent, r.info);
1748                            }
1749                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1750                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1751                            // In this case we are launching the root activity
1752                            // of the task, but with a different intent.  We
1753                            // should start a new instance on top.
1754                            addingToTask = true;
1755                            sourceRecord = intentActivity;
1756                        }
1757                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1758                        // In this case an activity is being launched in to an
1759                        // existing task, without resetting that task.  This
1760                        // is typically the situation of launching an activity
1761                        // from a notification or shortcut.  We want to place
1762                        // the new activity on top of the current task.
1763                        addingToTask = true;
1764                        sourceRecord = intentActivity;
1765                    } else if (!intentActivity.task.rootWasReset) {
1766                        // In this case we are launching in to an existing task
1767                        // that has not yet been started from its front door.
1768                        // The current task has been brought to the front.
1769                        // Ideally, we'd probably like to place this new task
1770                        // at the bottom of its stack, but that's a little hard
1771                        // to do with the current organization of the code so
1772                        // for now we'll just drop it.
1773                        intentActivity.task.setIntent(r.intent, r.info);
1774                    }
1775                    if (!addingToTask && reuseTask == null) {
1776                        // We didn't do anything...  but it was needed (a.k.a., client
1777                        // don't use that intent!)  And for paranoia, make
1778                        // sure we have correctly resumed the top activity.
1779                        if (doResume) {
1780                            targetStack.resumeTopActivityLocked(null, options);
1781                        } else {
1782                            ActivityOptions.abort(options);
1783                        }
1784                        return ActivityManager.START_TASK_TO_FRONT;
1785                    }
1786                }
1787            }
1788        }
1789
1790        //String uri = r.intent.toURI();
1791        //Intent intent2 = new Intent(uri);
1792        //Slog.i(TAG, "Given intent: " + r.intent);
1793        //Slog.i(TAG, "URI is: " + uri);
1794        //Slog.i(TAG, "To intent: " + intent2);
1795
1796        if (r.packageName != null) {
1797            // If the activity being launched is the same as the one currently
1798            // at the top, then we need to check if it should only be launched
1799            // once.
1800            ActivityStack topStack = getFocusedStack();
1801            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1802            if (top != null && r.resultTo == null) {
1803                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1804                    if (top.app != null && top.app.thread != null) {
1805                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1806                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1807                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1808                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1809                                    top.task);
1810                            // For paranoia, make sure we have correctly
1811                            // resumed the top activity.
1812                            topStack.mLastPausedActivity = null;
1813                            if (doResume) {
1814                                resumeTopActivitiesLocked();
1815                            }
1816                            ActivityOptions.abort(options);
1817                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1818                                // We don't need to start a new activity, and
1819                                // the client said not to do anything if that
1820                                // is the case, so this is it!
1821                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1822                            }
1823                            top.deliverNewIntentLocked(callingUid, r.intent);
1824                            return ActivityManager.START_DELIVERED_TO_TOP;
1825                        }
1826                    }
1827                }
1828            }
1829
1830        } else {
1831            if (r.resultTo != null) {
1832                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1833                        r.requestCode, Activity.RESULT_CANCELED, null);
1834            }
1835            ActivityOptions.abort(options);
1836            return ActivityManager.START_CLASS_NOT_FOUND;
1837        }
1838
1839        boolean newTask = false;
1840        boolean keepCurTransition = false;
1841
1842        // Should this be considered a new task?
1843        if (r.resultTo == null && !addingToTask
1844                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1845            if (isLockTaskModeViolation(reuseTask)) {
1846                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1847                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1848            }
1849            newTask = true;
1850            targetStack = adjustStackFocus(r, newTask);
1851            targetStack.moveToFront();
1852            if (reuseTask == null) {
1853                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1854                        newTaskInfo != null ? newTaskInfo : r.info,
1855                        newTaskIntent != null ? newTaskIntent : intent,
1856                        voiceSession, voiceInteractor, true), null, true);
1857                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1858                        r.task);
1859            } else {
1860                r.setTask(reuseTask, reuseTask, true);
1861            }
1862            if (!movedHome) {
1863                if ((launchFlags &
1864                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1865                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1866                    // Caller wants to appear on home activity, so before starting
1867                    // their own activity we will bring home to the front.
1868                    r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
1869                }
1870            }
1871        } else if (sourceRecord != null) {
1872            TaskRecord sourceTask = sourceRecord.task;
1873            if (isLockTaskModeViolation(sourceTask)) {
1874                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1875                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1876            }
1877            targetStack = sourceTask.stack;
1878            targetStack.moveToFront();
1879            mWindowManager.moveTaskToTop(targetStack.topTask().taskId);
1880            if (!addingToTask &&
1881                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1882                // In this case, we are adding the activity to an existing
1883                // task, but the caller has asked to clear that task if the
1884                // activity is already running.
1885                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1886                keepCurTransition = true;
1887                if (top != null) {
1888                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1889                    top.deliverNewIntentLocked(callingUid, r.intent);
1890                    // For paranoia, make sure we have correctly
1891                    // resumed the top activity.
1892                    targetStack.mLastPausedActivity = null;
1893                    if (doResume) {
1894                        targetStack.resumeTopActivityLocked(null);
1895                    }
1896                    ActivityOptions.abort(options);
1897                    return ActivityManager.START_DELIVERED_TO_TOP;
1898                }
1899            } else if (!addingToTask &&
1900                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1901                // In this case, we are launching an activity in our own task
1902                // that may already be running somewhere in the history, and
1903                // we want to shuffle it to the front of the stack if so.
1904                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1905                if (top != null) {
1906                    final TaskRecord task = top.task;
1907                    task.moveActivityToFrontLocked(top);
1908                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1909                    top.updateOptionsLocked(options);
1910                    top.deliverNewIntentLocked(callingUid, r.intent);
1911                    targetStack.mLastPausedActivity = null;
1912                    if (doResume) {
1913                        targetStack.resumeTopActivityLocked(null);
1914                    }
1915                    return ActivityManager.START_DELIVERED_TO_TOP;
1916                }
1917            }
1918            // An existing activity is starting this new activity, so we want
1919            // to keep the new one in the same task as the one that is starting
1920            // it.
1921            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
1922            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1923                    + " in existing task " + r.task + " from source " + sourceRecord);
1924
1925        } else {
1926            // This not being started from an existing activity, and not part
1927            // of a new task...  just put it in the top task, though these days
1928            // this case should never happen.
1929            targetStack = adjustStackFocus(r, newTask);
1930            targetStack.moveToFront();
1931            ActivityRecord prev = targetStack.topActivity();
1932            r.setTask(prev != null ? prev.task
1933                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, null, null, true),
1934                    null, true);
1935            mWindowManager.moveTaskToTop(r.task.taskId);
1936            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1937                    + " in new guessed " + r.task);
1938        }
1939
1940        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1941                intent, r.getUriPermissionsLocked(), r.userId);
1942
1943        if (newTask) {
1944            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1945        }
1946        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1947        targetStack.mLastPausedActivity = null;
1948        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1949        mService.setFocusedActivityLocked(r);
1950        return ActivityManager.START_SUCCESS;
1951    }
1952
1953    void acquireLaunchWakelock() {
1954        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1955            throw new IllegalStateException("Calling must be system uid");
1956        }
1957        mLaunchingActivity.acquire();
1958        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1959            // To be safe, don't allow the wake lock to be held for too long.
1960            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1961        }
1962    }
1963
1964    // Checked.
1965    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1966            Configuration config) {
1967        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1968
1969        ArrayList<ActivityRecord> stops = null;
1970        ArrayList<ActivityRecord> finishes = null;
1971        ArrayList<UserStartedState> startingUsers = null;
1972        int NS = 0;
1973        int NF = 0;
1974        boolean booting = false;
1975        boolean enableScreen = false;
1976        boolean activityRemoved = false;
1977
1978        ActivityRecord r = ActivityRecord.forToken(token);
1979        if (r != null) {
1980            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1981                    Debug.getCallers(4));
1982            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1983            r.finishLaunchTickingLocked();
1984            if (fromTimeout) {
1985                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1986            }
1987
1988            // This is a hack to semi-deal with a race condition
1989            // in the client where it can be constructed with a
1990            // newer configuration from when we asked it to launch.
1991            // We'll update with whatever configuration it now says
1992            // it used to launch.
1993            if (config != null) {
1994                r.configuration = config;
1995            }
1996
1997            // We are now idle.  If someone is waiting for a thumbnail from
1998            // us, we can now deliver.
1999            r.idle = true;
2000
2001            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2002            if (!mService.mBooted && isFrontStack(r.task.stack)) {
2003                mService.mBooted = true;
2004                enableScreen = true;
2005            }
2006        }
2007
2008        if (allResumedActivitiesIdle()) {
2009            if (r != null) {
2010                mService.scheduleAppGcsLocked();
2011            }
2012
2013            if (mLaunchingActivity.isHeld()) {
2014                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2015                if (VALIDATE_WAKE_LOCK_CALLER &&
2016                        Binder.getCallingUid() != Process.myUid()) {
2017                    throw new IllegalStateException("Calling must be system uid");
2018                }
2019                mLaunchingActivity.release();
2020            }
2021            ensureActivitiesVisibleLocked(null, 0);
2022        }
2023
2024        // Atomically retrieve all of the other things to do.
2025        stops = processStoppingActivitiesLocked(true);
2026        NS = stops != null ? stops.size() : 0;
2027        if ((NF=mFinishingActivities.size()) > 0) {
2028            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
2029            mFinishingActivities.clear();
2030        }
2031
2032        if (isFrontStack(mHomeStack)) {
2033            booting = mService.mBooting;
2034            mService.mBooting = false;
2035        }
2036
2037        if (mStartingUsers.size() > 0) {
2038            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
2039            mStartingUsers.clear();
2040        }
2041
2042        // Stop any activities that are scheduled to do so but have been
2043        // waiting for the next one to start.
2044        for (int i = 0; i < NS; i++) {
2045            r = stops.get(i);
2046            final ActivityStack stack = r.task.stack;
2047            if (r.finishing) {
2048                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2049            } else {
2050                stack.stopActivityLocked(r);
2051            }
2052        }
2053
2054        // Finish any activities that are scheduled to do so but have been
2055        // waiting for the next one to start.
2056        for (int i = 0; i < NF; i++) {
2057            r = finishes.get(i);
2058            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
2059        }
2060
2061        if (booting) {
2062            mService.finishBooting();
2063        } else {
2064            // Complete user switch
2065            if (startingUsers != null) {
2066                for (int i = 0; i < startingUsers.size(); i++) {
2067                    mService.finishUserSwitch(startingUsers.get(i));
2068                }
2069            }
2070            // Complete starting up of background users
2071            if (mStartingBackgroundUsers.size() > 0) {
2072                startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
2073                mStartingBackgroundUsers.clear();
2074                for (int i = 0; i < startingUsers.size(); i++) {
2075                    mService.finishUserBoot(startingUsers.get(i));
2076                }
2077            }
2078        }
2079
2080        mService.trimApplications();
2081        //dump();
2082        //mWindowManager.dump();
2083
2084        if (enableScreen) {
2085            mService.enableScreenAfterBoot();
2086        }
2087
2088        if (activityRemoved) {
2089            resumeTopActivitiesLocked();
2090        }
2091
2092        return r;
2093    }
2094
2095    boolean handleAppDiedLocked(ProcessRecord app) {
2096        boolean hasVisibleActivities = false;
2097        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2098            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2099            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2100                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2101            }
2102        }
2103        return hasVisibleActivities;
2104    }
2105
2106    void closeSystemDialogsLocked() {
2107        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2108            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2109            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2110                stacks.get(stackNdx).closeSystemDialogsLocked();
2111            }
2112        }
2113    }
2114
2115    void removeUserLocked(int userId) {
2116        mUserStackInFront.delete(userId);
2117    }
2118
2119    /**
2120     * @return true if some activity was finished (or would have finished if doit were true).
2121     */
2122    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2123        boolean didSomething = false;
2124        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2125            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2126            final int numStacks = stacks.size();
2127            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2128                final ActivityStack stack = stacks.get(stackNdx);
2129                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2130                    didSomething = true;
2131                }
2132            }
2133        }
2134        return didSomething;
2135    }
2136
2137    void updatePreviousProcessLocked(ActivityRecord r) {
2138        // Now that this process has stopped, we may want to consider
2139        // it to be the previous app to try to keep around in case
2140        // the user wants to return to it.
2141
2142        // First, found out what is currently the foreground app, so that
2143        // we don't blow away the previous app if this activity is being
2144        // hosted by the process that is actually still the foreground.
2145        ProcessRecord fgApp = null;
2146        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2147            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2148            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2149                final ActivityStack stack = stacks.get(stackNdx);
2150                if (isFrontStack(stack)) {
2151                    if (stack.mResumedActivity != null) {
2152                        fgApp = stack.mResumedActivity.app;
2153                    } else if (stack.mPausingActivity != null) {
2154                        fgApp = stack.mPausingActivity.app;
2155                    }
2156                    break;
2157                }
2158            }
2159        }
2160
2161        // Now set this one as the previous process, only if that really
2162        // makes sense to.
2163        if (r.app != null && fgApp != null && r.app != fgApp
2164                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2165                && r.app != mService.mHomeProcess) {
2166            mService.mPreviousProcess = r.app;
2167            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2168        }
2169    }
2170
2171    boolean resumeTopActivitiesLocked() {
2172        return resumeTopActivitiesLocked(null, null, null);
2173    }
2174
2175    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2176            Bundle targetOptions) {
2177        if (targetStack == null) {
2178            targetStack = getFocusedStack();
2179        }
2180        // Do targetStack first.
2181        boolean result = false;
2182        if (isFrontStack(targetStack)) {
2183            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2184        }
2185        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2186            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2187            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2188                final ActivityStack stack = stacks.get(stackNdx);
2189                if (stack == targetStack) {
2190                    // Already started above.
2191                    continue;
2192                }
2193                if (isFrontStack(stack)) {
2194                    stack.resumeTopActivityLocked(null);
2195                }
2196            }
2197        }
2198        return result;
2199    }
2200
2201    void finishTopRunningActivityLocked(ProcessRecord app) {
2202        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2203            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2204            final int numStacks = stacks.size();
2205            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2206                final ActivityStack stack = stacks.get(stackNdx);
2207                stack.finishTopRunningActivityLocked(app);
2208            }
2209        }
2210    }
2211
2212    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2213        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2214            mUserLeaving = true;
2215        }
2216        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2217            // Caller wants the home activity moved with it.  To accomplish this,
2218            // we'll just indicate that this task returns to the home task.
2219            task.mOnTopOfHome = true;
2220        }
2221        task.stack.moveTaskToFrontLocked(task, null, options);
2222        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2223                + task.stack);
2224    }
2225
2226    ActivityStack getStack(int stackId) {
2227        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2228        if (activityContainer != null) {
2229            return activityContainer.mStack;
2230        }
2231        return null;
2232    }
2233
2234    ArrayList<ActivityStack> getStacks() {
2235        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2236        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2237            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2238        }
2239        return allStacks;
2240    }
2241
2242    IBinder getHomeActivityToken() {
2243        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2244        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2245            final TaskRecord task = tasks.get(taskNdx);
2246            if (task.isHomeTask()) {
2247                final ArrayList<ActivityRecord> activities = task.mActivities;
2248                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2249                    final ActivityRecord r = activities.get(activityNdx);
2250                    if (r.isHomeActivity()) {
2251                        return r.appToken;
2252                    }
2253                }
2254            }
2255        }
2256        return null;
2257    }
2258
2259    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2260            IActivityContainerCallback callback) {
2261        ActivityContainer activityContainer =
2262                new VirtualActivityContainer(parentActivity, callback);
2263        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2264        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
2265        parentActivity.mChildContainers.add(activityContainer);
2266        return activityContainer;
2267    }
2268
2269    void removeChildActivityContainers(ActivityRecord parentActivity) {
2270        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2271        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2272            ActivityContainer container = childStacks.remove(containerNdx);
2273            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
2274                    container);
2275            container.release();
2276        }
2277    }
2278
2279    void deleteActivityContainer(IActivityContainer container) {
2280        ActivityContainer activityContainer = (ActivityContainer)container;
2281        if (activityContainer != null) {
2282            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
2283                    new RuntimeException("here").fillInStackTrace());
2284            final int stackId = activityContainer.mStackId;
2285            mActivityContainers.remove(stackId);
2286            mWindowManager.removeStack(stackId);
2287        }
2288    }
2289
2290    private int createStackOnDisplay(int stackId, int displayId) {
2291        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2292        if (activityDisplay == null) {
2293            return -1;
2294        }
2295
2296        ActivityContainer activityContainer = new ActivityContainer(stackId);
2297        mActivityContainers.put(stackId, activityContainer);
2298        activityContainer.attachToDisplayLocked(activityDisplay);
2299        return stackId;
2300    }
2301
2302    int getNextStackId() {
2303        while (true) {
2304            if (++mLastStackId <= HOME_STACK_ID) {
2305                mLastStackId = HOME_STACK_ID + 1;
2306            }
2307            if (getStack(mLastStackId) == null) {
2308                break;
2309            }
2310        }
2311        return mLastStackId;
2312    }
2313
2314    void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) {
2315        int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2316        final ActivityStack stack = getStack(stackId);
2317        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2318            final TaskRecord task = tasks.get(taskNdx);
2319            stack.addTask(task, false, false);
2320            final int taskId = task.taskId;
2321            final ArrayList<ActivityRecord> activities = task.mActivities;
2322            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2323                final ActivityRecord r = activities.get(activityNdx);
2324                mWindowManager.addAppToken(0, r.appToken, taskId, stackId,
2325                        r.info.screenOrientation, r.fullscreen,
2326                        (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
2327                        r.userId, r.info.configChanges, task.voiceSession != null);
2328            }
2329            mWindowManager.addTask(taskId, stackId, false);
2330        }
2331        resumeHomeActivity(null);
2332    }
2333
2334    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2335        final TaskRecord task = anyTaskForIdLocked(taskId);
2336        if (task == null) {
2337            return;
2338        }
2339        final ActivityStack stack = getStack(stackId);
2340        if (stack == null) {
2341            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2342            return;
2343        }
2344        task.stack.removeTask(task);
2345        stack.addTask(task, toTop, true);
2346        mWindowManager.addTask(taskId, stackId, toTop);
2347        resumeTopActivitiesLocked();
2348    }
2349
2350    ActivityRecord findTaskLocked(ActivityRecord r) {
2351        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2352        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2353            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2354            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2355                final ActivityStack stack = stacks.get(stackNdx);
2356                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2357                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2358                    continue;
2359                }
2360                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2361                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2362                            stack);
2363                    continue;
2364                }
2365                final ActivityRecord ar = stack.findTaskLocked(r);
2366                if (ar != null) {
2367                    return ar;
2368                }
2369            }
2370        }
2371        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2372        return null;
2373    }
2374
2375    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2376        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2377            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2378            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2379                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2380                if (ar != null) {
2381                    return ar;
2382                }
2383            }
2384        }
2385        return null;
2386    }
2387
2388    void goingToSleepLocked() {
2389        scheduleSleepTimeout();
2390        if (!mGoingToSleep.isHeld()) {
2391            mGoingToSleep.acquire();
2392            if (mLaunchingActivity.isHeld()) {
2393                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2394                    throw new IllegalStateException("Calling must be system uid");
2395                }
2396                mLaunchingActivity.release();
2397                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2398            }
2399        }
2400        checkReadyForSleepLocked();
2401    }
2402
2403    boolean shutdownLocked(int timeout) {
2404        goingToSleepLocked();
2405
2406        boolean timedout = false;
2407        final long endTime = System.currentTimeMillis() + timeout;
2408        while (true) {
2409            boolean cantShutdown = false;
2410            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2411                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2412                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2413                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2414                }
2415            }
2416            if (cantShutdown) {
2417                long timeRemaining = endTime - System.currentTimeMillis();
2418                if (timeRemaining > 0) {
2419                    try {
2420                        mService.wait(timeRemaining);
2421                    } catch (InterruptedException e) {
2422                    }
2423                } else {
2424                    Slog.w(TAG, "Activity manager shutdown timed out");
2425                    timedout = true;
2426                    break;
2427                }
2428            } else {
2429                break;
2430            }
2431        }
2432
2433        // Force checkReadyForSleep to complete.
2434        mSleepTimeout = true;
2435        checkReadyForSleepLocked();
2436
2437        return timedout;
2438    }
2439
2440    void comeOutOfSleepIfNeededLocked() {
2441        removeSleepTimeouts();
2442        if (mGoingToSleep.isHeld()) {
2443            mGoingToSleep.release();
2444        }
2445        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2446            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2447            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2448                final ActivityStack stack = stacks.get(stackNdx);
2449                stack.awakeFromSleepingLocked();
2450                if (isFrontStack(stack)) {
2451                    resumeTopActivitiesLocked();
2452                }
2453            }
2454        }
2455        mGoingToSleepActivities.clear();
2456    }
2457
2458    void activitySleptLocked(ActivityRecord r) {
2459        mGoingToSleepActivities.remove(r);
2460        checkReadyForSleepLocked();
2461    }
2462
2463    void checkReadyForSleepLocked() {
2464        if (!mService.isSleepingOrShuttingDown()) {
2465            // Do not care.
2466            return;
2467        }
2468
2469        if (!mSleepTimeout) {
2470            boolean dontSleep = false;
2471            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2472                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2473                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2474                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2475                }
2476            }
2477
2478            if (mStoppingActivities.size() > 0) {
2479                // Still need to tell some activities to stop; can't sleep yet.
2480                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2481                        + mStoppingActivities.size() + " activities");
2482                scheduleIdleLocked();
2483                dontSleep = true;
2484            }
2485
2486            if (mGoingToSleepActivities.size() > 0) {
2487                // Still need to tell some activities to sleep; can't sleep yet.
2488                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2489                        + mGoingToSleepActivities.size() + " activities");
2490                dontSleep = true;
2491            }
2492
2493            if (dontSleep) {
2494                return;
2495            }
2496        }
2497
2498        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2499            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2500            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2501                stacks.get(stackNdx).goToSleep();
2502            }
2503        }
2504
2505        removeSleepTimeouts();
2506
2507        if (mGoingToSleep.isHeld()) {
2508            mGoingToSleep.release();
2509        }
2510        if (mService.mShuttingDown) {
2511            mService.notifyAll();
2512        }
2513    }
2514
2515    boolean reportResumedActivityLocked(ActivityRecord r) {
2516        final ActivityStack stack = r.task.stack;
2517        if (isFrontStack(stack)) {
2518            mService.updateUsageStats(r, true);
2519        }
2520        if (allResumedActivitiesComplete()) {
2521            ensureActivitiesVisibleLocked(null, 0);
2522            mWindowManager.executeAppTransition();
2523            return true;
2524        }
2525        return false;
2526    }
2527
2528    void handleAppCrashLocked(ProcessRecord app) {
2529        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2530            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2531            final int numStacks = stacks.size();
2532            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2533                final ActivityStack stack = stacks.get(stackNdx);
2534                stack.handleAppCrashLocked(app);
2535            }
2536        }
2537    }
2538
2539    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2540        // First the front stacks. In case any are not fullscreen and are in front of home.
2541        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2542            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2543            final int topStackNdx = stacks.size() - 1;
2544            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2545                final ActivityStack stack = stacks.get(stackNdx);
2546                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2547            }
2548        }
2549    }
2550
2551    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2552        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2553            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2554            final int numStacks = stacks.size();
2555            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2556                final ActivityStack stack = stacks.get(stackNdx);
2557                stack.scheduleDestroyActivities(app, false, reason);
2558            }
2559        }
2560    }
2561
2562    boolean switchUserLocked(int userId, UserStartedState uss) {
2563        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2564        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2565        mCurrentUser = userId;
2566
2567        mStartingUsers.add(uss);
2568        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2569            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2570            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2571                final ActivityStack stack = stacks.get(stackNdx);
2572                stack.switchUserLocked(userId);
2573                TaskRecord task = stack.topTask();
2574                if (task != null) {
2575                    mWindowManager.moveTaskToTop(task.taskId);
2576                }
2577            }
2578        }
2579
2580        ActivityStack stack = getStack(restoreStackId);
2581        if (stack == null) {
2582            stack = mHomeStack;
2583        }
2584        final boolean homeInFront = stack.isHomeStack();
2585        if (stack.isOnHomeDisplay()) {
2586            moveHomeStack(homeInFront);
2587            TaskRecord task = stack.topTask();
2588            if (task != null) {
2589                mWindowManager.moveTaskToTop(task.taskId);
2590            }
2591        } else {
2592            // Stack was moved to another display while user was swapped out.
2593            resumeHomeActivity(null);
2594        }
2595        return homeInFront;
2596    }
2597
2598    /**
2599     * Add background users to send boot completed events to.
2600     * @param userId The user being started in the background
2601     * @param uss The state object for the user.
2602     */
2603    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
2604        mStartingBackgroundUsers.add(uss);
2605    }
2606
2607    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2608        int N = mStoppingActivities.size();
2609        if (N <= 0) return null;
2610
2611        ArrayList<ActivityRecord> stops = null;
2612
2613        final boolean nowVisible = allResumedActivitiesVisible();
2614        for (int i=0; i<N; i++) {
2615            ActivityRecord s = mStoppingActivities.get(i);
2616            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2617                    + nowVisible + " waitingVisible=" + s.waitingVisible
2618                    + " finishing=" + s.finishing);
2619            if (s.waitingVisible && nowVisible) {
2620                mWaitingVisibleActivities.remove(s);
2621                s.waitingVisible = false;
2622                if (s.finishing) {
2623                    // If this activity is finishing, it is sitting on top of
2624                    // everyone else but we now know it is no longer needed...
2625                    // so get rid of it.  Otherwise, we need to go through the
2626                    // normal flow and hide it once we determine that it is
2627                    // hidden by the activities in front of it.
2628                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2629                    mWindowManager.setAppVisibility(s.appToken, false);
2630                }
2631            }
2632            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2633                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2634                if (stops == null) {
2635                    stops = new ArrayList<ActivityRecord>();
2636                }
2637                stops.add(s);
2638                mStoppingActivities.remove(i);
2639                N--;
2640                i--;
2641            }
2642        }
2643
2644        return stops;
2645    }
2646
2647    void validateTopActivitiesLocked() {
2648        // FIXME
2649/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2650            final ActivityStack stack = stacks.get(stackNdx);
2651            final ActivityRecord r = stack.topRunningActivityLocked(null);
2652            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2653            if (isFrontStack(stack)) {
2654                if (r == null) {
2655                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2656                } else {
2657                    final ActivityRecord pausing = stack.mPausingActivity;
2658                    if (pausing != null && pausing == r) {
2659                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2660                            " state=" + state);
2661                    }
2662                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2663                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2664                                " state=" + state);
2665                    }
2666                }
2667            } else {
2668                final ActivityRecord resumed = stack.mResumedActivity;
2669                if (resumed != null && resumed == r) {
2670                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2671                        " state=" + state);
2672                }
2673                if (r != null && (state == ActivityState.INITIALIZING
2674                        || state == ActivityState.RESUMED)) {
2675                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2676                            " state=" + state);
2677                }
2678            }
2679        }
2680*/
2681    }
2682
2683    public void dump(PrintWriter pw, String prefix) {
2684        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2685                pw.println(mDismissKeyguardOnNextActivity);
2686        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2687                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2688        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2689        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2690        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2691        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2692    }
2693
2694    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2695        return getFocusedStack().getDumpActivitiesLocked(name);
2696    }
2697
2698    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2699            boolean needSep, String prefix) {
2700        if (activity != null) {
2701            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2702                if (needSep) {
2703                    pw.println();
2704                }
2705                pw.print(prefix);
2706                pw.println(activity);
2707                return true;
2708            }
2709        }
2710        return false;
2711    }
2712
2713    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2714            boolean dumpClient, String dumpPackage) {
2715        boolean printed = false;
2716        boolean needSep = false;
2717        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2718            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2719            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2720            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2721            final int numStacks = stacks.size();
2722            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2723                final ActivityStack stack = stacks.get(stackNdx);
2724                StringBuilder stackHeader = new StringBuilder(128);
2725                stackHeader.append("  Stack #");
2726                stackHeader.append(stack.mStackId);
2727                stackHeader.append(":");
2728                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2729                        needSep, stackHeader.toString());
2730                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2731                        !dumpAll, false, dumpPackage, true,
2732                        "    Running activities (most recent first):", null);
2733
2734                needSep = printed;
2735                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2736                        "    mPausingActivity: ");
2737                if (pr) {
2738                    printed = true;
2739                    needSep = false;
2740                }
2741                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2742                        "    mResumedActivity: ");
2743                if (pr) {
2744                    printed = true;
2745                    needSep = false;
2746                }
2747                if (dumpAll) {
2748                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2749                            "    mLastPausedActivity: ");
2750                    if (pr) {
2751                        printed = true;
2752                        needSep = true;
2753                    }
2754                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2755                            needSep, "    mLastNoHistoryActivity: ");
2756                }
2757                needSep = printed;
2758            }
2759        }
2760
2761        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2762                false, dumpPackage, true, "  Activities waiting to finish:", null);
2763        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2764                false, dumpPackage, true, "  Activities waiting to stop:", null);
2765        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2766                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2767                null);
2768        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2769                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2770        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2771                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2772
2773        return printed;
2774    }
2775
2776    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2777            String prefix, String label, boolean complete, boolean brief, boolean client,
2778            String dumpPackage, boolean needNL, String header1, String header2) {
2779        TaskRecord lastTask = null;
2780        String innerPrefix = null;
2781        String[] args = null;
2782        boolean printed = false;
2783        for (int i=list.size()-1; i>=0; i--) {
2784            final ActivityRecord r = list.get(i);
2785            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2786                continue;
2787            }
2788            if (innerPrefix == null) {
2789                innerPrefix = prefix + "      ";
2790                args = new String[0];
2791            }
2792            printed = true;
2793            final boolean full = !brief && (complete || !r.isInHistory());
2794            if (needNL) {
2795                pw.println("");
2796                needNL = false;
2797            }
2798            if (header1 != null) {
2799                pw.println(header1);
2800                header1 = null;
2801            }
2802            if (header2 != null) {
2803                pw.println(header2);
2804                header2 = null;
2805            }
2806            if (lastTask != r.task) {
2807                lastTask = r.task;
2808                pw.print(prefix);
2809                pw.print(full ? "* " : "  ");
2810                pw.println(lastTask);
2811                if (full) {
2812                    lastTask.dump(pw, prefix + "  ");
2813                } else if (complete) {
2814                    // Complete + brief == give a summary.  Isn't that obvious?!?
2815                    if (lastTask.intent != null) {
2816                        pw.print(prefix); pw.print("  ");
2817                                pw.println(lastTask.intent.toInsecureStringWithClip());
2818                    }
2819                }
2820            }
2821            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2822            pw.print(" #"); pw.print(i); pw.print(": ");
2823            pw.println(r);
2824            if (full) {
2825                r.dump(pw, innerPrefix);
2826            } else if (complete) {
2827                // Complete + brief == give a summary.  Isn't that obvious?!?
2828                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2829                if (r.app != null) {
2830                    pw.print(innerPrefix); pw.println(r.app);
2831                }
2832            }
2833            if (client && r.app != null && r.app.thread != null) {
2834                // flush anything that is already in the PrintWriter since the thread is going
2835                // to write to the file descriptor directly
2836                pw.flush();
2837                try {
2838                    TransferPipe tp = new TransferPipe();
2839                    try {
2840                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2841                                r.appToken, innerPrefix, args);
2842                        // Short timeout, since blocking here can
2843                        // deadlock with the application.
2844                        tp.go(fd, 2000);
2845                    } finally {
2846                        tp.kill();
2847                    }
2848                } catch (IOException e) {
2849                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2850                } catch (RemoteException e) {
2851                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2852                }
2853                needNL = true;
2854            }
2855        }
2856        return printed;
2857    }
2858
2859    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2860        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2861        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2862        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2863    }
2864
2865    final void scheduleIdleLocked() {
2866        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2867    }
2868
2869    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2870        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2871        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2872    }
2873
2874    final void scheduleResumeTopActivities() {
2875        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2876            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2877        }
2878    }
2879
2880    void removeSleepTimeouts() {
2881        mSleepTimeout = false;
2882        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2883    }
2884
2885    final void scheduleSleepTimeout() {
2886        removeSleepTimeouts();
2887        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2888    }
2889
2890    @Override
2891    public void onDisplayAdded(int displayId) {
2892        Slog.v(TAG, "Display added displayId=" + displayId);
2893        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2894    }
2895
2896    @Override
2897    public void onDisplayRemoved(int displayId) {
2898        Slog.v(TAG, "Display removed displayId=" + displayId);
2899        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2900    }
2901
2902    @Override
2903    public void onDisplayChanged(int displayId) {
2904        Slog.v(TAG, "Display changed displayId=" + displayId);
2905        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2906    }
2907
2908    public void handleDisplayAddedLocked(int displayId) {
2909        boolean newDisplay;
2910        synchronized (mService) {
2911            newDisplay = mActivityDisplays.get(displayId) == null;
2912            if (newDisplay) {
2913                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2914                mActivityDisplays.put(displayId, activityDisplay);
2915            }
2916        }
2917        if (newDisplay) {
2918            mWindowManager.onDisplayAdded(displayId);
2919        }
2920    }
2921
2922    public void handleDisplayRemovedLocked(int displayId) {
2923        synchronized (mService) {
2924            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2925            if (activityDisplay != null) {
2926                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2927                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2928                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2929                }
2930                mActivityDisplays.remove(displayId);
2931            }
2932        }
2933        mWindowManager.onDisplayRemoved(displayId);
2934    }
2935
2936    public void handleDisplayChangedLocked(int displayId) {
2937        synchronized (mService) {
2938            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2939            if (activityDisplay != null) {
2940                // TODO: Update the bounds.
2941            }
2942        }
2943        mWindowManager.onDisplayChanged(displayId);
2944    }
2945
2946    StackInfo getStackInfo(ActivityStack stack) {
2947        StackInfo info = new StackInfo();
2948        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2949        info.displayId = Display.DEFAULT_DISPLAY;
2950        info.stackId = stack.mStackId;
2951
2952        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2953        final int numTasks = tasks.size();
2954        int[] taskIds = new int[numTasks];
2955        String[] taskNames = new String[numTasks];
2956        for (int i = 0; i < numTasks; ++i) {
2957            final TaskRecord task = tasks.get(i);
2958            taskIds[i] = task.taskId;
2959            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2960                    : task.realActivity != null ? task.realActivity.flattenToString()
2961                    : task.getTopActivity() != null ? task.getTopActivity().packageName
2962                    : "unknown";
2963        }
2964        info.taskIds = taskIds;
2965        info.taskNames = taskNames;
2966        return info;
2967    }
2968
2969    StackInfo getStackInfoLocked(int stackId) {
2970        ActivityStack stack = getStack(stackId);
2971        if (stack != null) {
2972            return getStackInfo(stack);
2973        }
2974        return null;
2975    }
2976
2977    ArrayList<StackInfo> getAllStackInfosLocked() {
2978        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2979        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2980            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2981            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2982                list.add(getStackInfo(stacks.get(ndx)));
2983            }
2984        }
2985        return list;
2986    }
2987
2988    void setLockTaskModeLocked(TaskRecord task) {
2989        final Message lockTaskMsg = Message.obtain();
2990        if (task == null) {
2991            // Take out of lock task mode.
2992            mLockTaskModeTask = null;
2993            lockTaskMsg.what = LOCK_TASK_END_MSG;
2994            mHandler.sendMessage(lockTaskMsg);
2995            return;
2996        }
2997        if (isLockTaskModeViolation(task)) {
2998            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2999            return;
3000        }
3001        mLockTaskModeTask = task;
3002        findTaskToMoveToFrontLocked(task, 0, null);
3003        resumeTopActivitiesLocked();
3004        lockTaskMsg.what = LOCK_TASK_START_MSG;
3005        mHandler.sendMessage(lockTaskMsg);
3006    }
3007
3008    boolean isLockTaskModeViolation(TaskRecord task) {
3009        return mLockTaskModeTask != null && mLockTaskModeTask != task;
3010    }
3011
3012    void endLockTaskModeIfTaskEnding(TaskRecord task) {
3013        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
3014            mLockTaskModeTask = null;
3015        }
3016    }
3017
3018    boolean isInLockTaskMode() {
3019        return mLockTaskModeTask != null;
3020    }
3021
3022    private final class ActivityStackSupervisorHandler extends Handler {
3023
3024        public ActivityStackSupervisorHandler(Looper looper) {
3025            super(looper);
3026        }
3027
3028        void activityIdleInternal(ActivityRecord r) {
3029            synchronized (mService) {
3030                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3031            }
3032        }
3033
3034        @Override
3035        public void handleMessage(Message msg) {
3036            switch (msg.what) {
3037                case IDLE_TIMEOUT_MSG: {
3038                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3039                    if (mService.mDidDexOpt) {
3040                        mService.mDidDexOpt = false;
3041                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3042                        nmsg.obj = msg.obj;
3043                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3044                        return;
3045                    }
3046                    // We don't at this point know if the activity is fullscreen,
3047                    // so we need to be conservative and assume it isn't.
3048                    activityIdleInternal((ActivityRecord)msg.obj);
3049                } break;
3050                case IDLE_NOW_MSG: {
3051                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3052                    activityIdleInternal((ActivityRecord)msg.obj);
3053                } break;
3054                case RESUME_TOP_ACTIVITY_MSG: {
3055                    synchronized (mService) {
3056                        resumeTopActivitiesLocked();
3057                    }
3058                } break;
3059                case SLEEP_TIMEOUT_MSG: {
3060                    synchronized (mService) {
3061                        if (mService.isSleepingOrShuttingDown()) {
3062                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3063                            mSleepTimeout = true;
3064                            checkReadyForSleepLocked();
3065                        }
3066                    }
3067                } break;
3068                case LAUNCH_TIMEOUT_MSG: {
3069                    if (mService.mDidDexOpt) {
3070                        mService.mDidDexOpt = false;
3071                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3072                        return;
3073                    }
3074                    synchronized (mService) {
3075                        if (mLaunchingActivity.isHeld()) {
3076                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3077                            if (VALIDATE_WAKE_LOCK_CALLER
3078                                    && Binder.getCallingUid() != Process.myUid()) {
3079                                throw new IllegalStateException("Calling must be system uid");
3080                            }
3081                            mLaunchingActivity.release();
3082                        }
3083                    }
3084                } break;
3085                case HANDLE_DISPLAY_ADDED: {
3086                    handleDisplayAddedLocked(msg.arg1);
3087                } break;
3088                case HANDLE_DISPLAY_CHANGED: {
3089                    handleDisplayChangedLocked(msg.arg1);
3090                } break;
3091                case HANDLE_DISPLAY_REMOVED: {
3092                    handleDisplayRemovedLocked(msg.arg1);
3093                } break;
3094                case CONTAINER_CALLBACK_VISIBILITY: {
3095                    final ActivityContainer container = (ActivityContainer) msg.obj;
3096                    final IActivityContainerCallback callback = container.mCallback;
3097                    if (callback != null) {
3098                        try {
3099                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3100                        } catch (RemoteException e) {
3101                        }
3102                    }
3103                } break;
3104                case LOCK_TASK_START_MSG: {
3105                    // When lock task starts, we disable the status bars.
3106                    try {
3107                        if (getStatusBarService() != null) {
3108                            getStatusBarService().disable
3109                                (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK,
3110                                mToken, mService.mContext.getPackageName());
3111                        }
3112                    } catch (RemoteException ex) {
3113                        throw new RuntimeException(ex);
3114                    }
3115                } break;
3116                case LOCK_TASK_END_MSG: {
3117                    // When lock task ends, we enable the status bars.
3118                    try {
3119                       if (getStatusBarService() != null) {
3120                           getStatusBarService().disable
3121                               (StatusBarManager.DISABLE_NONE,
3122                               mToken, mService.mContext.getPackageName());
3123                       }
3124                    } catch (RemoteException ex) {
3125                        throw new RuntimeException(ex);
3126                    }
3127                } break;
3128                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3129                    final ActivityContainer container = (ActivityContainer) msg.obj;
3130                    final IActivityContainerCallback callback = container.mCallback;
3131                    if (callback != null) {
3132                        try {
3133                            callback.onAllActivitiesComplete(container.asBinder());
3134                        } catch (RemoteException e) {
3135                        }
3136                    }
3137                } break;
3138                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
3139                    synchronized (mService) {
3140                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
3141                                msg.obj);
3142                        ((ActivityContainer) msg.obj).onTaskListEmptyLocked();
3143                    }
3144                } break;
3145            }
3146        }
3147    }
3148
3149    class ActivityContainer extends android.app.IActivityContainer.Stub {
3150        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3151                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3152        final int mStackId;
3153        IActivityContainerCallback mCallback = null;
3154        final ActivityStack mStack;
3155        ActivityRecord mParentActivity = null;
3156        String mIdString;
3157
3158        boolean mVisible = true;
3159
3160        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3161        ActivityDisplay mActivityDisplay;
3162
3163        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3164        final static int CONTAINER_STATE_NO_SURFACE = 1;
3165        final static int CONTAINER_STATE_FINISHING = 2;
3166        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3167
3168        ActivityContainer(int stackId) {
3169            synchronized (mService) {
3170                mStackId = stackId;
3171                mStack = new ActivityStack(this);
3172                mIdString = "ActivtyContainer{" + mStackId + "}";
3173                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3174            }
3175        }
3176
3177        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3178            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3179                    + " to display=" + activityDisplay);
3180            mActivityDisplay = activityDisplay;
3181            mStack.mDisplayId = activityDisplay.mDisplayId;
3182            mStack.mStacks = activityDisplay.mStacks;
3183
3184            activityDisplay.attachActivities(mStack);
3185            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3186        }
3187
3188        @Override
3189        public void attachToDisplay(int displayId) {
3190            synchronized (mService) {
3191                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3192                if (activityDisplay == null) {
3193                    return;
3194                }
3195                attachToDisplayLocked(activityDisplay);
3196            }
3197        }
3198
3199        @Override
3200        public int getDisplayId() {
3201            synchronized (mService) {
3202                if (mActivityDisplay != null) {
3203                    return mActivityDisplay.mDisplayId;
3204                }
3205            }
3206            return -1;
3207        }
3208
3209        @Override
3210        public boolean injectEvent(InputEvent event) {
3211            final long origId = Binder.clearCallingIdentity();
3212            try {
3213                synchronized (mService) {
3214                    if (mActivityDisplay != null) {
3215                        return mInputManagerInternal.injectInputEvent(event,
3216                                mActivityDisplay.mDisplayId,
3217                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3218                    }
3219                }
3220                return false;
3221            } finally {
3222                Binder.restoreCallingIdentity(origId);
3223            }
3224        }
3225
3226        @Override
3227        public void release() {
3228            synchronized (mService) {
3229                if (mContainerState == CONTAINER_STATE_FINISHING) {
3230                    return;
3231                }
3232                mContainerState = CONTAINER_STATE_FINISHING;
3233
3234                final Message msg =
3235                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3236                mHandler.sendMessageDelayed(msg, 1000);
3237
3238                long origId = Binder.clearCallingIdentity();
3239                try {
3240                    mStack.finishAllActivitiesLocked();
3241                } finally {
3242                    Binder.restoreCallingIdentity(origId);
3243                }
3244            }
3245        }
3246
3247        private void detachLocked() {
3248            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3249                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3250            if (mActivityDisplay != null) {
3251                mActivityDisplay.detachActivitiesLocked(mStack);
3252                mActivityDisplay = null;
3253                mStack.mDisplayId = -1;
3254                mStack.mStacks = null;
3255                mWindowManager.detachStack(mStackId);
3256            }
3257        }
3258
3259        @Override
3260        public final int startActivity(Intent intent) {
3261            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3262            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3263                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3264            // TODO: Switch to user app stacks here.
3265            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3266            String mimeType = intent.getType();
3267            if (mimeType == null && intent.getData() != null
3268                    && "content".equals(intent.getData().getScheme())) {
3269                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3270            }
3271            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null,
3272                    null, null, null, null, userId, this);
3273        }
3274
3275        @Override
3276        public final int startActivityIntentSender(IIntentSender intentSender) {
3277            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3278
3279            if (!(intentSender instanceof PendingIntentRecord)) {
3280                throw new IllegalArgumentException("Bad PendingIntent object");
3281            }
3282
3283            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3284                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3285        }
3286
3287        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3288            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3289                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3290            if (resolvedType == null) {
3291                resolvedType = intent.getType();
3292                if (resolvedType == null && intent.getData() != null
3293                        && "content".equals(intent.getData().getScheme())) {
3294                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3295                }
3296            }
3297            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
3298            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3299                throw new SecurityException(
3300                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3301            }
3302        }
3303
3304        /** Throw a SecurityException if allowEmbedded is not true */
3305        @Override
3306        public final void checkEmbeddedAllowed(Intent intent) {
3307            checkEmbeddedAllowedInner(intent, null);
3308        }
3309
3310        /** Throw a SecurityException if allowEmbedded is not true */
3311        @Override
3312        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3313            if (!(intentSender instanceof PendingIntentRecord)) {
3314                throw new IllegalArgumentException("Bad PendingIntent object");
3315            }
3316            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3317            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3318                    pendingIntent.key.requestResolvedType);
3319        }
3320
3321        @Override
3322        public IBinder asBinder() {
3323            return this;
3324        }
3325
3326        @Override
3327        public void setSurface(Surface surface, int width, int height, int density) {
3328            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3329        }
3330
3331        ActivityStackSupervisor getOuter() {
3332            return ActivityStackSupervisor.this;
3333        }
3334
3335        boolean isAttachedLocked() {
3336            return mActivityDisplay != null;
3337        }
3338
3339        void getBounds(Point outBounds) {
3340            synchronized (mService) {
3341                    if (mActivityDisplay != null) {
3342                    mActivityDisplay.getBounds(outBounds);
3343                } else {
3344                    outBounds.set(0, 0);
3345                }
3346            }
3347        }
3348
3349        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3350        void setVisible(boolean visible) {
3351            if (mVisible != visible) {
3352                mVisible = visible;
3353                if (mCallback != null) {
3354                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3355                            0 /* unused */, this).sendToTarget();
3356                }
3357            }
3358        }
3359
3360        void setDrawn() {
3361        }
3362
3363        // You can always start a new task on a regular ActivityStack.
3364        boolean isEligibleForNewTasks() {
3365            return true;
3366        }
3367
3368        void onTaskListEmptyLocked() {
3369            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3370            if (!mStack.isHomeStack()) {
3371                detachLocked();
3372                deleteActivityContainer(this);
3373            }
3374            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3375        }
3376
3377        @Override
3378        public String toString() {
3379            return mIdString + (mActivityDisplay == null ? "N" : "A");
3380        }
3381    }
3382
3383    private class VirtualActivityContainer extends ActivityContainer {
3384        Surface mSurface;
3385        boolean mDrawn = false;
3386
3387        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3388            super(getNextStackId());
3389            mParentActivity = parent;
3390            mCallback = callback;
3391            mContainerState = CONTAINER_STATE_NO_SURFACE;
3392            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3393        }
3394
3395        @Override
3396        public void setSurface(Surface surface, int width, int height, int density) {
3397            super.setSurface(surface, width, height, density);
3398
3399            synchronized (mService) {
3400                final long origId = Binder.clearCallingIdentity();
3401                try {
3402                    setSurfaceLocked(surface, width, height, density);
3403                } finally {
3404                    Binder.restoreCallingIdentity(origId);
3405                }
3406            }
3407        }
3408
3409        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3410            if (mContainerState == CONTAINER_STATE_FINISHING) {
3411                return;
3412            }
3413            VirtualActivityDisplay virtualActivityDisplay =
3414                    (VirtualActivityDisplay) mActivityDisplay;
3415            if (virtualActivityDisplay == null) {
3416                virtualActivityDisplay =
3417                        new VirtualActivityDisplay(width, height, density);
3418                mActivityDisplay = virtualActivityDisplay;
3419                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3420                attachToDisplayLocked(virtualActivityDisplay);
3421            }
3422
3423            if (mSurface != null) {
3424                mSurface.release();
3425            }
3426
3427            mSurface = surface;
3428            if (surface != null) {
3429                mStack.resumeTopActivityLocked(null);
3430            } else {
3431                mContainerState = CONTAINER_STATE_NO_SURFACE;
3432                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3433                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3434                    mStack.startPausingLocked(false, true);
3435                }
3436            }
3437
3438            setSurfaceIfReadyLocked();
3439
3440            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3441                    + virtualActivityDisplay);
3442        }
3443
3444        @Override
3445        boolean isAttachedLocked() {
3446            return mSurface != null && super.isAttachedLocked();
3447        }
3448
3449        @Override
3450        void setDrawn() {
3451            synchronized (mService) {
3452                mDrawn = true;
3453                setSurfaceIfReadyLocked();
3454            }
3455        }
3456
3457        // Never start a new task on an ActivityView if it isn't explicitly specified.
3458        @Override
3459        boolean isEligibleForNewTasks() {
3460            return false;
3461        }
3462
3463        private void setSurfaceIfReadyLocked() {
3464            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
3465                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3466            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3467                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3468                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3469            }
3470        }
3471    }
3472
3473    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3474     * attached {@link ActivityStack}s */
3475    class ActivityDisplay {
3476        /** Actual Display this object tracks. */
3477        int mDisplayId;
3478        Display mDisplay;
3479        DisplayInfo mDisplayInfo = new DisplayInfo();
3480
3481        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3482         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3483        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3484
3485        ActivityDisplay() {
3486        }
3487
3488        ActivityDisplay(int displayId) {
3489            init(mDisplayManager.getDisplay(displayId));
3490        }
3491
3492        void init(Display display) {
3493            mDisplay = display;
3494            mDisplayId = display.getDisplayId();
3495            mDisplay.getDisplayInfo(mDisplayInfo);
3496        }
3497
3498        void attachActivities(ActivityStack stack) {
3499            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3500                    + mDisplayId);
3501            mStacks.add(stack);
3502        }
3503
3504        void detachActivitiesLocked(ActivityStack stack) {
3505            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3506                    + " from displayId=" + mDisplayId);
3507            mStacks.remove(stack);
3508        }
3509
3510        void getBounds(Point bounds) {
3511            mDisplay.getDisplayInfo(mDisplayInfo);
3512            bounds.x = mDisplayInfo.appWidth;
3513            bounds.y = mDisplayInfo.appHeight;
3514        }
3515
3516        @Override
3517        public String toString() {
3518            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3519        }
3520    }
3521
3522    class VirtualActivityDisplay extends ActivityDisplay {
3523        VirtualDisplay mVirtualDisplay;
3524
3525        VirtualActivityDisplay(int width, int height, int density) {
3526            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3527            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
3528                    width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3529                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3530
3531            init(mVirtualDisplay.getDisplay());
3532
3533            mWindowManager.handleDisplayAdded(mDisplayId);
3534        }
3535
3536        void setSurface(Surface surface) {
3537            if (mVirtualDisplay != null) {
3538                mVirtualDisplay.setSurface(surface);
3539            }
3540        }
3541
3542        @Override
3543        void detachActivitiesLocked(ActivityStack stack) {
3544            super.detachActivitiesLocked(stack);
3545            if (mVirtualDisplay != null) {
3546                mVirtualDisplay.release();
3547                mVirtualDisplay = null;
3548            }
3549        }
3550
3551        @Override
3552        public String toString() {
3553            return "VirtualActivityDisplay={" + mDisplayId + "}";
3554        }
3555    }
3556
3557    private boolean isLeanbackOnlyDevice() {
3558        boolean onLeanbackOnly = false;
3559        try {
3560            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
3561                    PackageManager.FEATURE_LEANBACK_ONLY);
3562        } catch (RemoteException e) {
3563            // noop
3564        }
3565
3566        return onLeanbackOnly;
3567    }
3568}
3569