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