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