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