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