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