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