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