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