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