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