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