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