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