ActivityStackSupervisor.java revision 409297da182267465adbc21cfb75a23e8d678117
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        int launchFlags = intent.getFlags();
1535
1536        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1537                (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
1538                        r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK)) {
1539            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1540            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1541                    "\"singleInstance\" or \"singleTask\"");
1542            launchFlags &=
1543                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
1544        } else {
1545            switch (r.info.documentLaunchMode) {
1546                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1547                    break;
1548                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1549                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1550                    break;
1551                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1552                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1553                    break;
1554                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1555                    launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1556                    break;
1557            }
1558        }
1559
1560        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1561            // For whatever reason this activity is being launched into a new
1562            // task...  yet the caller has requested a result back.  Well, that
1563            // is pretty messed up, so instead immediately send back a cancel
1564            // and let the new task continue launched as normal without a
1565            // dependency on its originator.
1566            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1567            r.resultTo.task.stack.sendActivityResultLocked(-1,
1568                    r.resultTo, r.resultWho, r.requestCode,
1569                    Activity.RESULT_CANCELED, null);
1570            r.resultTo = null;
1571        }
1572
1573        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1574            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1575        }
1576
1577        // We'll invoke onUserLeaving before onPause only if the launching
1578        // activity did not explicitly state that this is an automated launch.
1579        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1580        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1581
1582        // If the caller has asked not to resume at this point, we make note
1583        // of this in the record so that we can skip it when trying to find
1584        // the top running activity.
1585        if (!doResume) {
1586            r.delayedResume = true;
1587        }
1588
1589        ActivityRecord notTop =
1590                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1591
1592        // If the onlyIfNeeded flag is set, then we can do this if the activity
1593        // being launched is the same as the one making the call...  or, as
1594        // a special case, if we do not know the caller then we count the
1595        // current top activity as the caller.
1596        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1597            ActivityRecord checkedCaller = sourceRecord;
1598            if (checkedCaller == null) {
1599                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1600            }
1601            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1602                // Caller is not the same as launcher, so always needed.
1603                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1604            }
1605        }
1606
1607        if (sourceRecord == null) {
1608            // This activity is not being started from another...  in this
1609            // case we -always- start a new task.
1610            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1611                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1612                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1613                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1614            }
1615        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1616            // The original activity who is starting us is running as a single
1617            // instance...  this new activity it is starting must go on its
1618            // own task.
1619            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1620        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1621                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1622            // The activity being started is a single instance...  it always
1623            // gets launched into its own task.
1624            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1625        }
1626
1627        ActivityInfo newTaskInfo = null;
1628        Intent newTaskIntent = null;
1629        final ActivityStack sourceStack;
1630        if (sourceRecord != null) {
1631            if (sourceRecord.finishing) {
1632                // If the source is finishing, we can't further count it as our source.  This
1633                // is because the task it is associated with may now be empty and on its way out,
1634                // so we don't want to blindly throw it in to that task.  Instead we will take
1635                // the NEW_TASK flow and try to find a task for it. But save the task information
1636                // so it can be used when creating the new task.
1637                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1638                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1639                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1640                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1641                    newTaskInfo = sourceRecord.info;
1642                    newTaskIntent = sourceRecord.task.intent;
1643                }
1644                sourceRecord = null;
1645                sourceStack = null;
1646            } else {
1647                sourceStack = sourceRecord.task.stack;
1648            }
1649        } else {
1650            sourceStack = null;
1651        }
1652
1653        intent.setFlags(launchFlags);
1654
1655        boolean addingToTask = false;
1656        boolean movedHome = false;
1657        TaskRecord reuseTask = null;
1658        ActivityStack targetStack;
1659        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1660                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1661                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1662                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1663            // If bring to front is requested, and no result is requested, and
1664            // we can find a task that was started with this same
1665            // component, then instead of launching bring that one to the front.
1666            if (r.resultTo == null) {
1667                // See if there is a task to bring to the front.  If this is
1668                // a SINGLE_INSTANCE activity, there can be one and only one
1669                // instance of it in the history, and it is always in its own
1670                // unique task, so we do a special search.
1671                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1672                        ? findTaskLocked(r)
1673                        : findActivityLocked(intent, r.info);
1674                if (intentActivity != null) {
1675                    if (isLockTaskModeViolation(intentActivity.task)) {
1676                        showLockTaskToast();
1677                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1678                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1679                    }
1680                    if (r.task == null) {
1681                        r.task = intentActivity.task;
1682                    }
1683                    targetStack = intentActivity.task.stack;
1684                    targetStack.mLastPausedActivity = null;
1685                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1686                            + " from " + intentActivity);
1687                    targetStack.moveToFront();
1688                    if (intentActivity.task.intent == null) {
1689                        // This task was started because of movement of
1690                        // the activity based on affinity...  now that we
1691                        // are actually launching it, we can assign the
1692                        // base intent.
1693                        intentActivity.task.setIntent(intent, r.info);
1694                    }
1695                    // If the target task is not in the front, then we need
1696                    // to bring it to the front...  except...  well, with
1697                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1698                    // to have the same behavior as if a new instance was
1699                    // being started, which means not bringing it to the front
1700                    // if the caller is not itself in the front.
1701                    final ActivityStack lastStack = getLastStack();
1702                    ActivityRecord curTop = lastStack == null?
1703                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1704                    if (curTop != null && (curTop.task != intentActivity.task ||
1705                            curTop.task != lastStack.topTask())) {
1706                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1707                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1708                                sourceStack.topActivity().task == sourceRecord.task)) {
1709                            // We really do want to push this one into the
1710                            // user's face, right now.
1711                            movedHome = true;
1712                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1713                            if ((launchFlags &
1714                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1715                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1716                                // Caller wants to appear on home activity.
1717                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1718                            }
1719                            options = null;
1720                        }
1721                    }
1722                    // If the caller has requested that the target task be
1723                    // reset, then do so.
1724                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1725                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1726                    }
1727                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1728                        // We don't need to start a new activity, and
1729                        // the client said not to do anything if that
1730                        // is the case, so this is it!  And for paranoia, make
1731                        // sure we have correctly resumed the top activity.
1732                        if (doResume) {
1733                            resumeTopActivitiesLocked(targetStack, null, options);
1734                        } else {
1735                            ActivityOptions.abort(options);
1736                        }
1737                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1738                    }
1739                    if ((launchFlags &
1740                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1741                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1742                        // The caller has requested to completely replace any
1743                        // existing task with its new activity.  Well that should
1744                        // not be too hard...
1745                        reuseTask = intentActivity.task;
1746                        reuseTask.performClearTaskLocked();
1747                        reuseTask.setIntent(r.intent, r.info);
1748                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1749                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1750                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1751                        // In this situation we want to remove all activities
1752                        // from the task up to the one being started.  In most
1753                        // cases this means we are resetting the task to its
1754                        // initial state.
1755                        ActivityRecord top =
1756                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1757                        if (top != null) {
1758                            if (top.frontOfTask) {
1759                                // Activity aliases may mean we use different
1760                                // intents for the top activity, so make sure
1761                                // the task now has the identity of the new
1762                                // intent.
1763                                top.task.setIntent(r.intent, r.info);
1764                            }
1765                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1766                                    r, top.task);
1767                            top.deliverNewIntentLocked(callingUid, r.intent);
1768                        } else {
1769                            // A special case: we need to
1770                            // start the activity because it is not currently
1771                            // running, and the caller has asked to clear the
1772                            // current task to have this activity at the top.
1773                            addingToTask = true;
1774                            // Now pretend like this activity is being started
1775                            // by the top of its task, so it is put in the
1776                            // right place.
1777                            sourceRecord = intentActivity;
1778                        }
1779                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1780                        // In this case the top activity on the task is the
1781                        // same as the one being launched, so we take that
1782                        // as a request to bring the task to the foreground.
1783                        // If the top activity in the task is the root
1784                        // activity, deliver this new intent to it if it
1785                        // desires.
1786                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1787                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1788                                && intentActivity.realActivity.equals(r.realActivity)) {
1789                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1790                                    intentActivity.task);
1791                            if (intentActivity.frontOfTask) {
1792                                intentActivity.task.setIntent(r.intent, r.info);
1793                            }
1794                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1795                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1796                            // In this case we are launching the root activity
1797                            // of the task, but with a different intent.  We
1798                            // should start a new instance on top.
1799                            addingToTask = true;
1800                            sourceRecord = intentActivity;
1801                        }
1802                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1803                        // In this case an activity is being launched in to an
1804                        // existing task, without resetting that task.  This
1805                        // is typically the situation of launching an activity
1806                        // from a notification or shortcut.  We want to place
1807                        // the new activity on top of the current task.
1808                        addingToTask = true;
1809                        sourceRecord = intentActivity;
1810                    } else if (!intentActivity.task.rootWasReset) {
1811                        // In this case we are launching in to an existing task
1812                        // that has not yet been started from its front door.
1813                        // The current task has been brought to the front.
1814                        // Ideally, we'd probably like to place this new task
1815                        // at the bottom of its stack, but that's a little hard
1816                        // to do with the current organization of the code so
1817                        // for now we'll just drop it.
1818                        intentActivity.task.setIntent(r.intent, r.info);
1819                    }
1820                    if (!addingToTask && reuseTask == null) {
1821                        // We didn't do anything...  but it was needed (a.k.a., client
1822                        // don't use that intent!)  And for paranoia, make
1823                        // sure we have correctly resumed the top activity.
1824                        if (doResume) {
1825                            targetStack.resumeTopActivityLocked(null, options);
1826                        } else {
1827                            ActivityOptions.abort(options);
1828                        }
1829                        return ActivityManager.START_TASK_TO_FRONT;
1830                    }
1831                }
1832            }
1833        }
1834
1835        //String uri = r.intent.toURI();
1836        //Intent intent2 = new Intent(uri);
1837        //Slog.i(TAG, "Given intent: " + r.intent);
1838        //Slog.i(TAG, "URI is: " + uri);
1839        //Slog.i(TAG, "To intent: " + intent2);
1840
1841        if (r.packageName != null) {
1842            // If the activity being launched is the same as the one currently
1843            // at the top, then we need to check if it should only be launched
1844            // once.
1845            ActivityStack topStack = getFocusedStack();
1846            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1847            if (top != null && r.resultTo == null) {
1848                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1849                    if (top.app != null && top.app.thread != null) {
1850                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1851                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1852                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1853                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1854                                    top.task);
1855                            // For paranoia, make sure we have correctly
1856                            // resumed the top activity.
1857                            topStack.mLastPausedActivity = null;
1858                            if (doResume) {
1859                                resumeTopActivitiesLocked();
1860                            }
1861                            ActivityOptions.abort(options);
1862                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1863                                // We don't need to start a new activity, and
1864                                // the client said not to do anything if that
1865                                // is the case, so this is it!
1866                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1867                            }
1868                            top.deliverNewIntentLocked(callingUid, r.intent);
1869                            return ActivityManager.START_DELIVERED_TO_TOP;
1870                        }
1871                    }
1872                }
1873            }
1874
1875        } else {
1876            if (r.resultTo != null) {
1877                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1878                        r.requestCode, Activity.RESULT_CANCELED, null);
1879            }
1880            ActivityOptions.abort(options);
1881            return ActivityManager.START_CLASS_NOT_FOUND;
1882        }
1883
1884        boolean newTask = false;
1885        boolean keepCurTransition = false;
1886
1887        // Should this be considered a new task?
1888        if (r.resultTo == null && !addingToTask
1889                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1890            if (isLockTaskModeViolation(reuseTask)) {
1891                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1892                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1893            }
1894            newTask = true;
1895            targetStack = adjustStackFocus(r, newTask);
1896            targetStack.moveToFront();
1897            if (reuseTask == null) {
1898                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1899                        newTaskInfo != null ? newTaskInfo : r.info,
1900                        newTaskIntent != null ? newTaskIntent : intent,
1901                        voiceSession, voiceInteractor, true), true);
1902                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1903                        r.task);
1904            } else {
1905                r.setTask(reuseTask, true);
1906            }
1907            if (!movedHome) {
1908                if ((launchFlags &
1909                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1910                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1911                    // Caller wants to appear on home activity, so before starting
1912                    // their own activity we will bring home to the front.
1913                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1914                }
1915            }
1916        } else if (sourceRecord != null) {
1917            TaskRecord sourceTask = sourceRecord.task;
1918            if (isLockTaskModeViolation(sourceTask)) {
1919                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1920                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1921            }
1922            targetStack = sourceTask.stack;
1923            targetStack.moveToFront();
1924            mWindowManager.moveTaskToTop(targetStack.topTask().taskId);
1925            if (!addingToTask &&
1926                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1927                // In this case, we are adding the activity to an existing
1928                // task, but the caller has asked to clear that task if the
1929                // activity is already running.
1930                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1931                keepCurTransition = true;
1932                if (top != null) {
1933                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1934                    top.deliverNewIntentLocked(callingUid, r.intent);
1935                    // For paranoia, make sure we have correctly
1936                    // resumed the top activity.
1937                    targetStack.mLastPausedActivity = null;
1938                    if (doResume) {
1939                        targetStack.resumeTopActivityLocked(null);
1940                    }
1941                    ActivityOptions.abort(options);
1942                    return ActivityManager.START_DELIVERED_TO_TOP;
1943                }
1944            } else if (!addingToTask &&
1945                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1946                // In this case, we are launching an activity in our own task
1947                // that may already be running somewhere in the history, and
1948                // we want to shuffle it to the front of the stack if so.
1949                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1950                if (top != null) {
1951                    final TaskRecord task = top.task;
1952                    task.moveActivityToFrontLocked(top);
1953                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1954                    top.updateOptionsLocked(options);
1955                    top.deliverNewIntentLocked(callingUid, r.intent);
1956                    targetStack.mLastPausedActivity = null;
1957                    if (doResume) {
1958                        targetStack.resumeTopActivityLocked(null);
1959                    }
1960                    return ActivityManager.START_DELIVERED_TO_TOP;
1961                }
1962            }
1963            // An existing activity is starting this new activity, so we want
1964            // to keep the new one in the same task as the one that is starting
1965            // it.
1966            r.setTask(sourceTask, false);
1967            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1968                    + " in existing task " + r.task + " from source " + sourceRecord);
1969
1970        } else {
1971            // This not being started from an existing activity, and not part
1972            // of a new task...  just put it in the top task, though these days
1973            // this case should never happen.
1974            targetStack = adjustStackFocus(r, newTask);
1975            targetStack.moveToFront();
1976            ActivityRecord prev = targetStack.topActivity();
1977            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
1978                            r.info, intent, null, null, true), true);
1979            mWindowManager.moveTaskToTop(r.task.taskId);
1980            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1981                    + " in new guessed " + r.task);
1982        }
1983
1984        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1985                intent, r.getUriPermissionsLocked(), r.userId);
1986
1987        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
1988            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
1989        }
1990        if (newTask) {
1991            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1992        }
1993        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1994        targetStack.mLastPausedActivity = null;
1995        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1996        mService.setFocusedActivityLocked(r);
1997        return ActivityManager.START_SUCCESS;
1998    }
1999
2000    void acquireLaunchWakelock() {
2001        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2002            throw new IllegalStateException("Calling must be system uid");
2003        }
2004        mLaunchingActivity.acquire();
2005        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2006            // To be safe, don't allow the wake lock to be held for too long.
2007            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2008        }
2009    }
2010
2011    // Checked.
2012    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2013            Configuration config) {
2014        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
2015
2016        ArrayList<ActivityRecord> stops = null;
2017        ArrayList<ActivityRecord> finishes = null;
2018        ArrayList<UserStartedState> startingUsers = null;
2019        int NS = 0;
2020        int NF = 0;
2021        boolean booting = false;
2022        boolean enableScreen = false;
2023        boolean activityRemoved = false;
2024
2025        ActivityRecord r = ActivityRecord.forToken(token);
2026        if (r != null) {
2027            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
2028                    Debug.getCallers(4));
2029            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2030            r.finishLaunchTickingLocked();
2031            if (fromTimeout) {
2032                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2033            }
2034
2035            // This is a hack to semi-deal with a race condition
2036            // in the client where it can be constructed with a
2037            // newer configuration from when we asked it to launch.
2038            // We'll update with whatever configuration it now says
2039            // it used to launch.
2040            if (config != null) {
2041                r.configuration = config;
2042            }
2043
2044            // We are now idle.  If someone is waiting for a thumbnail from
2045            // us, we can now deliver.
2046            r.idle = true;
2047
2048            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2049            if (!mService.mBooted && isFrontStack(r.task.stack)) {
2050                mService.mBooted = true;
2051                enableScreen = true;
2052            }
2053        }
2054
2055        if (allResumedActivitiesIdle()) {
2056            if (r != null) {
2057                mService.scheduleAppGcsLocked();
2058            }
2059
2060            if (mLaunchingActivity.isHeld()) {
2061                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2062                if (VALIDATE_WAKE_LOCK_CALLER &&
2063                        Binder.getCallingUid() != Process.myUid()) {
2064                    throw new IllegalStateException("Calling must be system uid");
2065                }
2066                mLaunchingActivity.release();
2067            }
2068            ensureActivitiesVisibleLocked(null, 0);
2069        }
2070
2071        // Atomically retrieve all of the other things to do.
2072        stops = processStoppingActivitiesLocked(true);
2073        NS = stops != null ? stops.size() : 0;
2074        if ((NF=mFinishingActivities.size()) > 0) {
2075            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
2076            mFinishingActivities.clear();
2077        }
2078
2079        if (isFrontStack(mHomeStack)) {
2080            booting = mService.mBooting;
2081            mService.mBooting = false;
2082        }
2083
2084        if (mStartingUsers.size() > 0) {
2085            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
2086            mStartingUsers.clear();
2087        }
2088
2089        // Stop any activities that are scheduled to do so but have been
2090        // waiting for the next one to start.
2091        for (int i = 0; i < NS; i++) {
2092            r = stops.get(i);
2093            final ActivityStack stack = r.task.stack;
2094            if (r.finishing) {
2095                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2096            } else {
2097                stack.stopActivityLocked(r);
2098            }
2099        }
2100
2101        // Finish any activities that are scheduled to do so but have been
2102        // waiting for the next one to start.
2103        for (int i = 0; i < NF; i++) {
2104            r = finishes.get(i);
2105            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle");
2106        }
2107
2108        if (booting) {
2109            mService.finishBooting();
2110        } else {
2111            // Complete user switch
2112            if (startingUsers != null) {
2113                for (int i = 0; i < startingUsers.size(); i++) {
2114                    mService.finishUserSwitch(startingUsers.get(i));
2115                }
2116            }
2117            // Complete starting up of background users
2118            if (mStartingBackgroundUsers.size() > 0) {
2119                startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
2120                mStartingBackgroundUsers.clear();
2121                for (int i = 0; i < startingUsers.size(); i++) {
2122                    mService.finishUserBoot(startingUsers.get(i));
2123                }
2124            }
2125        }
2126
2127        mService.trimApplications();
2128        //dump();
2129        //mWindowManager.dump();
2130
2131        if (enableScreen) {
2132            mService.enableScreenAfterBoot();
2133        }
2134
2135        if (activityRemoved) {
2136            resumeTopActivitiesLocked();
2137        }
2138
2139        return r;
2140    }
2141
2142    boolean handleAppDiedLocked(ProcessRecord app) {
2143        boolean hasVisibleActivities = false;
2144        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2145            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2146            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2147                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2148            }
2149        }
2150        return hasVisibleActivities;
2151    }
2152
2153    void closeSystemDialogsLocked() {
2154        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2155            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2156            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2157                stacks.get(stackNdx).closeSystemDialogsLocked();
2158            }
2159        }
2160    }
2161
2162    void removeUserLocked(int userId) {
2163        mUserStackInFront.delete(userId);
2164    }
2165
2166    /**
2167     * @return true if some activity was finished (or would have finished if doit were true).
2168     */
2169    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2170        boolean didSomething = false;
2171        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2172            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2173            final int numStacks = stacks.size();
2174            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2175                final ActivityStack stack = stacks.get(stackNdx);
2176                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2177                    didSomething = true;
2178                }
2179            }
2180        }
2181        return didSomething;
2182    }
2183
2184    void updatePreviousProcessLocked(ActivityRecord r) {
2185        // Now that this process has stopped, we may want to consider
2186        // it to be the previous app to try to keep around in case
2187        // the user wants to return to it.
2188
2189        // First, found out what is currently the foreground app, so that
2190        // we don't blow away the previous app if this activity is being
2191        // hosted by the process that is actually still the foreground.
2192        ProcessRecord fgApp = null;
2193        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2194            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2195            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2196                final ActivityStack stack = stacks.get(stackNdx);
2197                if (isFrontStack(stack)) {
2198                    if (stack.mResumedActivity != null) {
2199                        fgApp = stack.mResumedActivity.app;
2200                    } else if (stack.mPausingActivity != null) {
2201                        fgApp = stack.mPausingActivity.app;
2202                    }
2203                    break;
2204                }
2205            }
2206        }
2207
2208        // Now set this one as the previous process, only if that really
2209        // makes sense to.
2210        if (r.app != null && fgApp != null && r.app != fgApp
2211                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2212                && r.app != mService.mHomeProcess) {
2213            mService.mPreviousProcess = r.app;
2214            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2215        }
2216    }
2217
2218    boolean resumeTopActivitiesLocked() {
2219        return resumeTopActivitiesLocked(null, null, null);
2220    }
2221
2222    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2223            Bundle targetOptions) {
2224        if (targetStack == null) {
2225            targetStack = getFocusedStack();
2226        }
2227        // Do targetStack first.
2228        boolean result = false;
2229        if (isFrontStack(targetStack)) {
2230            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2231        }
2232        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2233            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2234            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2235                final ActivityStack stack = stacks.get(stackNdx);
2236                if (stack == targetStack) {
2237                    // Already started above.
2238                    continue;
2239                }
2240                if (isFrontStack(stack)) {
2241                    stack.resumeTopActivityLocked(null);
2242                }
2243            }
2244        }
2245        return result;
2246    }
2247
2248    void finishTopRunningActivityLocked(ProcessRecord app) {
2249        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2250            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2251            final int numStacks = stacks.size();
2252            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2253                final ActivityStack stack = stacks.get(stackNdx);
2254                stack.finishTopRunningActivityLocked(app);
2255            }
2256        }
2257    }
2258
2259    void finishVoiceTask(IVoiceInteractionSession session) {
2260        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2261            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2262            final int numStacks = stacks.size();
2263            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2264                final ActivityStack stack = stacks.get(stackNdx);
2265                stack.finishVoiceTask(session);
2266            }
2267        }
2268    }
2269
2270    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2271        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2272            mUserLeaving = true;
2273        }
2274        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2275            // Caller wants the home activity moved with it.  To accomplish this,
2276            // we'll just indicate that this task returns to the home task.
2277            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2278        }
2279        task.stack.moveTaskToFrontLocked(task, null, options);
2280        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2281                + task.stack);
2282    }
2283
2284    ActivityStack getStack(int stackId) {
2285        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2286        if (activityContainer != null) {
2287            return activityContainer.mStack;
2288        }
2289        return null;
2290    }
2291
2292    ArrayList<ActivityStack> getStacks() {
2293        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2294        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2295            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2296        }
2297        return allStacks;
2298    }
2299
2300    IBinder getHomeActivityToken() {
2301        ActivityRecord homeActivity = getHomeActivity();
2302        if (homeActivity != null) {
2303            return homeActivity.appToken;
2304        }
2305        return null;
2306    }
2307
2308    ActivityRecord getHomeActivity() {
2309        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2310        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2311            final TaskRecord task = tasks.get(taskNdx);
2312            if (task.isHomeTask()) {
2313                final ArrayList<ActivityRecord> activities = task.mActivities;
2314                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2315                    final ActivityRecord r = activities.get(activityNdx);
2316                    if (r.isHomeActivity()) {
2317                        return r;
2318                    }
2319                }
2320            }
2321        }
2322        return null;
2323    }
2324
2325    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2326            IActivityContainerCallback callback) {
2327        ActivityContainer activityContainer =
2328                new VirtualActivityContainer(parentActivity, callback);
2329        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2330        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
2331        parentActivity.mChildContainers.add(activityContainer);
2332        return activityContainer;
2333    }
2334
2335    void removeChildActivityContainers(ActivityRecord parentActivity) {
2336        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2337        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2338            ActivityContainer container = childStacks.remove(containerNdx);
2339            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
2340                    container);
2341            container.release();
2342        }
2343    }
2344
2345    void deleteActivityContainer(IActivityContainer container) {
2346        ActivityContainer activityContainer = (ActivityContainer)container;
2347        if (activityContainer != null) {
2348            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
2349                    new RuntimeException("here").fillInStackTrace());
2350            final int stackId = activityContainer.mStackId;
2351            mActivityContainers.remove(stackId);
2352            mWindowManager.removeStack(stackId);
2353        }
2354    }
2355
2356    private int createStackOnDisplay(int stackId, int displayId) {
2357        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2358        if (activityDisplay == null) {
2359            return -1;
2360        }
2361
2362        ActivityContainer activityContainer = new ActivityContainer(stackId);
2363        mActivityContainers.put(stackId, activityContainer);
2364        activityContainer.attachToDisplayLocked(activityDisplay);
2365        return stackId;
2366    }
2367
2368    int getNextStackId() {
2369        while (true) {
2370            if (++mLastStackId <= HOME_STACK_ID) {
2371                mLastStackId = HOME_STACK_ID + 1;
2372            }
2373            if (getStack(mLastStackId) == null) {
2374                break;
2375            }
2376        }
2377        return mLastStackId;
2378    }
2379
2380    void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) {
2381        int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2382        final ActivityStack stack = getStack(stackId);
2383        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2384            final TaskRecord task = tasks.get(taskNdx);
2385            stack.addTask(task, false, false);
2386            final int taskId = task.taskId;
2387            final ArrayList<ActivityRecord> activities = task.mActivities;
2388            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2389                final ActivityRecord r = activities.get(activityNdx);
2390                mWindowManager.addAppToken(0, r.appToken, taskId, stackId,
2391                        r.info.screenOrientation, r.fullscreen,
2392                        (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
2393                        r.userId, r.info.configChanges, task.voiceSession != null);
2394            }
2395            mWindowManager.addTask(taskId, stackId, false);
2396        }
2397        resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2398    }
2399
2400    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2401        final TaskRecord task = anyTaskForIdLocked(taskId);
2402        if (task == null) {
2403            return;
2404        }
2405        final ActivityStack stack = getStack(stackId);
2406        if (stack == null) {
2407            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2408            return;
2409        }
2410        task.stack.removeTask(task);
2411        stack.addTask(task, toTop, true);
2412        mWindowManager.addTask(taskId, stackId, toTop);
2413        resumeTopActivitiesLocked();
2414    }
2415
2416    ActivityRecord findTaskLocked(ActivityRecord r) {
2417        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2418        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2419            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2420            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2421                final ActivityStack stack = stacks.get(stackNdx);
2422                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2423                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2424                    continue;
2425                }
2426                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2427                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2428                            stack);
2429                    continue;
2430                }
2431                final ActivityRecord ar = stack.findTaskLocked(r);
2432                if (ar != null) {
2433                    return ar;
2434                }
2435            }
2436        }
2437        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2438        return null;
2439    }
2440
2441    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2442        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2443            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2444            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2445                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2446                if (ar != null) {
2447                    return ar;
2448                }
2449            }
2450        }
2451        return null;
2452    }
2453
2454    void goingToSleepLocked() {
2455        scheduleSleepTimeout();
2456        if (!mGoingToSleep.isHeld()) {
2457            mGoingToSleep.acquire();
2458            if (mLaunchingActivity.isHeld()) {
2459                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2460                    throw new IllegalStateException("Calling must be system uid");
2461                }
2462                mLaunchingActivity.release();
2463                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2464            }
2465        }
2466        checkReadyForSleepLocked();
2467    }
2468
2469    boolean shutdownLocked(int timeout) {
2470        goingToSleepLocked();
2471
2472        boolean timedout = false;
2473        final long endTime = System.currentTimeMillis() + timeout;
2474        while (true) {
2475            boolean cantShutdown = false;
2476            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2477                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2478                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2479                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2480                }
2481            }
2482            if (cantShutdown) {
2483                long timeRemaining = endTime - System.currentTimeMillis();
2484                if (timeRemaining > 0) {
2485                    try {
2486                        mService.wait(timeRemaining);
2487                    } catch (InterruptedException e) {
2488                    }
2489                } else {
2490                    Slog.w(TAG, "Activity manager shutdown timed out");
2491                    timedout = true;
2492                    break;
2493                }
2494            } else {
2495                break;
2496            }
2497        }
2498
2499        // Force checkReadyForSleep to complete.
2500        mSleepTimeout = true;
2501        checkReadyForSleepLocked();
2502
2503        return timedout;
2504    }
2505
2506    void comeOutOfSleepIfNeededLocked() {
2507        removeSleepTimeouts();
2508        if (mGoingToSleep.isHeld()) {
2509            mGoingToSleep.release();
2510        }
2511        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2512            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2513            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2514                final ActivityStack stack = stacks.get(stackNdx);
2515                stack.awakeFromSleepingLocked();
2516                if (isFrontStack(stack)) {
2517                    resumeTopActivitiesLocked();
2518                }
2519            }
2520        }
2521        mGoingToSleepActivities.clear();
2522    }
2523
2524    void activitySleptLocked(ActivityRecord r) {
2525        mGoingToSleepActivities.remove(r);
2526        checkReadyForSleepLocked();
2527    }
2528
2529    void checkReadyForSleepLocked() {
2530        if (!mService.isSleepingOrShuttingDown()) {
2531            // Do not care.
2532            return;
2533        }
2534
2535        if (!mSleepTimeout) {
2536            boolean dontSleep = false;
2537            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2538                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2539                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2540                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2541                }
2542            }
2543
2544            if (mStoppingActivities.size() > 0) {
2545                // Still need to tell some activities to stop; can't sleep yet.
2546                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2547                        + mStoppingActivities.size() + " activities");
2548                scheduleIdleLocked();
2549                dontSleep = true;
2550            }
2551
2552            if (mGoingToSleepActivities.size() > 0) {
2553                // Still need to tell some activities to sleep; can't sleep yet.
2554                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2555                        + mGoingToSleepActivities.size() + " activities");
2556                dontSleep = true;
2557            }
2558
2559            if (dontSleep) {
2560                return;
2561            }
2562        }
2563
2564        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2565            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2566            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2567                stacks.get(stackNdx).goToSleep();
2568            }
2569        }
2570
2571        removeSleepTimeouts();
2572
2573        if (mGoingToSleep.isHeld()) {
2574            mGoingToSleep.release();
2575        }
2576        if (mService.mShuttingDown) {
2577            mService.notifyAll();
2578        }
2579    }
2580
2581    boolean reportResumedActivityLocked(ActivityRecord r) {
2582        final ActivityStack stack = r.task.stack;
2583        if (isFrontStack(stack)) {
2584            mService.updateUsageStats(r, true);
2585        }
2586        if (allResumedActivitiesComplete()) {
2587            ensureActivitiesVisibleLocked(null, 0);
2588            mWindowManager.executeAppTransition();
2589            return true;
2590        }
2591        return false;
2592    }
2593
2594    void handleAppCrashLocked(ProcessRecord app) {
2595        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2596            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2597            final int numStacks = stacks.size();
2598            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2599                final ActivityStack stack = stacks.get(stackNdx);
2600                stack.handleAppCrashLocked(app);
2601            }
2602        }
2603    }
2604
2605    boolean setMediaPlayingLocked(ActivityRecord r, boolean playing) {
2606        final ActivityStack stack = r.task.stack;
2607        if (stack == null) {
2608            if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: r=" + r + " playing=" +
2609                    playing + " stack is null");
2610            return false;
2611        }
2612        final boolean isPlaying = stack.isMediaPlaying();
2613        if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlayer: r=" + r + " playing=" +
2614                playing + " isPlaying=" + isPlaying);
2615
2616        final ActivityRecord top = topRunningActivityLocked();
2617        if (top == null || top == r || (playing == isPlaying)) {
2618            if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: quick return");
2619            stack.setMediaPlayer(playing ? r : null);
2620            return true;
2621        }
2622
2623        // A non-top activity is reporting a visibility change.
2624        if (top.fullscreen || top.state != ActivityState.RESUMED || top.app == null ||
2625                top.app.thread == null) {
2626            // Can't carry out this request.
2627            if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: returning top.fullscreen=" +
2628                    top.fullscreen+ " top.state=" + top.state + " top.app=" + top.app +
2629                    " top.app.thread=" + top.app.thread);
2630            return false;
2631        }
2632
2633        stack.setMediaPlayer(playing ? r : null);
2634        try {
2635            top.app.thread.scheduleBackgroundMediaPlayingChanged(top.appToken, playing);
2636        } catch (RemoteException e) {
2637        }
2638        return true;
2639    }
2640
2641    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2642        // First the front stacks. In case any are not fullscreen and are in front of home.
2643        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2644            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2645            final int topStackNdx = stacks.size() - 1;
2646            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2647                final ActivityStack stack = stacks.get(stackNdx);
2648                stack.ensureActivitiesVisibleLocked(starting, configChanges);
2649            }
2650        }
2651    }
2652
2653    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2654        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2655            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2656            final int numStacks = stacks.size();
2657            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2658                final ActivityStack stack = stacks.get(stackNdx);
2659                stack.scheduleDestroyActivities(app, reason);
2660            }
2661        }
2662    }
2663
2664    boolean switchUserLocked(int userId, UserStartedState uss) {
2665        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2666        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2667        mCurrentUser = userId;
2668
2669        mStartingUsers.add(uss);
2670        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2671            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2672            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2673                final ActivityStack stack = stacks.get(stackNdx);
2674                stack.switchUserLocked(userId);
2675                TaskRecord task = stack.topTask();
2676                if (task != null) {
2677                    mWindowManager.moveTaskToTop(task.taskId);
2678                }
2679            }
2680        }
2681
2682        ActivityStack stack = getStack(restoreStackId);
2683        if (stack == null) {
2684            stack = mHomeStack;
2685        }
2686        final boolean homeInFront = stack.isHomeStack();
2687        if (stack.isOnHomeDisplay()) {
2688            moveHomeStack(homeInFront);
2689            TaskRecord task = stack.topTask();
2690            if (task != null) {
2691                mWindowManager.moveTaskToTop(task.taskId);
2692            }
2693        } else {
2694            // Stack was moved to another display while user was swapped out.
2695            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
2696        }
2697        return homeInFront;
2698    }
2699
2700    /**
2701     * Add background users to send boot completed events to.
2702     * @param userId The user being started in the background
2703     * @param uss The state object for the user.
2704     */
2705    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
2706        mStartingBackgroundUsers.add(uss);
2707    }
2708
2709    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2710        int N = mStoppingActivities.size();
2711        if (N <= 0) return null;
2712
2713        ArrayList<ActivityRecord> stops = null;
2714
2715        final boolean nowVisible = allResumedActivitiesVisible();
2716        for (int i=0; i<N; i++) {
2717            ActivityRecord s = mStoppingActivities.get(i);
2718            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2719                    + nowVisible + " waitingVisible=" + s.waitingVisible
2720                    + " finishing=" + s.finishing);
2721            if (s.waitingVisible && nowVisible) {
2722                mWaitingVisibleActivities.remove(s);
2723                s.waitingVisible = false;
2724                if (s.finishing) {
2725                    // If this activity is finishing, it is sitting on top of
2726                    // everyone else but we now know it is no longer needed...
2727                    // so get rid of it.  Otherwise, we need to go through the
2728                    // normal flow and hide it once we determine that it is
2729                    // hidden by the activities in front of it.
2730                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2731                    mWindowManager.setAppVisibility(s.appToken, false);
2732                }
2733            }
2734            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2735                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2736                if (stops == null) {
2737                    stops = new ArrayList<ActivityRecord>();
2738                }
2739                stops.add(s);
2740                mStoppingActivities.remove(i);
2741                N--;
2742                i--;
2743            }
2744        }
2745
2746        return stops;
2747    }
2748
2749    void validateTopActivitiesLocked() {
2750        // FIXME
2751/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2752            final ActivityStack stack = stacks.get(stackNdx);
2753            final ActivityRecord r = stack.topRunningActivityLocked(null);
2754            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2755            if (isFrontStack(stack)) {
2756                if (r == null) {
2757                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2758                } else {
2759                    final ActivityRecord pausing = stack.mPausingActivity;
2760                    if (pausing != null && pausing == r) {
2761                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2762                            " state=" + state);
2763                    }
2764                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2765                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2766                                " state=" + state);
2767                    }
2768                }
2769            } else {
2770                final ActivityRecord resumed = stack.mResumedActivity;
2771                if (resumed != null && resumed == r) {
2772                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2773                        " state=" + state);
2774                }
2775                if (r != null && (state == ActivityState.INITIALIZING
2776                        || state == ActivityState.RESUMED)) {
2777                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2778                            " state=" + state);
2779                }
2780            }
2781        }
2782*/
2783    }
2784
2785    public void dump(PrintWriter pw, String prefix) {
2786        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2787                pw.println(mDismissKeyguardOnNextActivity);
2788        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2789                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2790        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2791        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2792        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2793        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2794    }
2795
2796    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2797        return getFocusedStack().getDumpActivitiesLocked(name);
2798    }
2799
2800    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2801            boolean needSep, String prefix) {
2802        if (activity != null) {
2803            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2804                if (needSep) {
2805                    pw.println();
2806                }
2807                pw.print(prefix);
2808                pw.println(activity);
2809                return true;
2810            }
2811        }
2812        return false;
2813    }
2814
2815    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2816            boolean dumpClient, String dumpPackage) {
2817        boolean printed = false;
2818        boolean needSep = false;
2819        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2820            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2821            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
2822                    pw.println(" (activities from bottom to top):");
2823            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2824            final int numStacks = stacks.size();
2825            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2826                final ActivityStack stack = stacks.get(stackNdx);
2827                StringBuilder stackHeader = new StringBuilder(128);
2828                stackHeader.append("  Stack #");
2829                stackHeader.append(stack.mStackId);
2830                stackHeader.append(":");
2831                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2832                        needSep, stackHeader.toString());
2833                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2834                        !dumpAll, false, dumpPackage, true,
2835                        "    Running activities (most recent first):", null);
2836
2837                needSep = printed;
2838                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2839                        "    mPausingActivity: ");
2840                if (pr) {
2841                    printed = true;
2842                    needSep = false;
2843                }
2844                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2845                        "    mResumedActivity: ");
2846                if (pr) {
2847                    printed = true;
2848                    needSep = false;
2849                }
2850                if (dumpAll) {
2851                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2852                            "    mLastPausedActivity: ");
2853                    if (pr) {
2854                        printed = true;
2855                        needSep = true;
2856                    }
2857                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2858                            needSep, "    mLastNoHistoryActivity: ");
2859                }
2860                needSep = printed;
2861            }
2862        }
2863
2864        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2865                false, dumpPackage, true, "  Activities waiting to finish:", null);
2866        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2867                false, dumpPackage, true, "  Activities waiting to stop:", null);
2868        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2869                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2870                null);
2871        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2872                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2873        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2874                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2875
2876        return printed;
2877    }
2878
2879    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2880            String prefix, String label, boolean complete, boolean brief, boolean client,
2881            String dumpPackage, boolean needNL, String header1, String header2) {
2882        TaskRecord lastTask = null;
2883        String innerPrefix = null;
2884        String[] args = null;
2885        boolean printed = false;
2886        for (int i=list.size()-1; i>=0; i--) {
2887            final ActivityRecord r = list.get(i);
2888            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2889                continue;
2890            }
2891            if (innerPrefix == null) {
2892                innerPrefix = prefix + "      ";
2893                args = new String[0];
2894            }
2895            printed = true;
2896            final boolean full = !brief && (complete || !r.isInHistory());
2897            if (needNL) {
2898                pw.println("");
2899                needNL = false;
2900            }
2901            if (header1 != null) {
2902                pw.println(header1);
2903                header1 = null;
2904            }
2905            if (header2 != null) {
2906                pw.println(header2);
2907                header2 = null;
2908            }
2909            if (lastTask != r.task) {
2910                lastTask = r.task;
2911                pw.print(prefix);
2912                pw.print(full ? "* " : "  ");
2913                pw.println(lastTask);
2914                if (full) {
2915                    lastTask.dump(pw, prefix + "  ");
2916                } else if (complete) {
2917                    // Complete + brief == give a summary.  Isn't that obvious?!?
2918                    if (lastTask.intent != null) {
2919                        pw.print(prefix); pw.print("  ");
2920                                pw.println(lastTask.intent.toInsecureStringWithClip());
2921                    }
2922                }
2923            }
2924            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2925            pw.print(" #"); pw.print(i); pw.print(": ");
2926            pw.println(r);
2927            if (full) {
2928                r.dump(pw, innerPrefix);
2929            } else if (complete) {
2930                // Complete + brief == give a summary.  Isn't that obvious?!?
2931                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2932                if (r.app != null) {
2933                    pw.print(innerPrefix); pw.println(r.app);
2934                }
2935            }
2936            if (client && r.app != null && r.app.thread != null) {
2937                // flush anything that is already in the PrintWriter since the thread is going
2938                // to write to the file descriptor directly
2939                pw.flush();
2940                try {
2941                    TransferPipe tp = new TransferPipe();
2942                    try {
2943                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2944                                r.appToken, innerPrefix, args);
2945                        // Short timeout, since blocking here can
2946                        // deadlock with the application.
2947                        tp.go(fd, 2000);
2948                    } finally {
2949                        tp.kill();
2950                    }
2951                } catch (IOException e) {
2952                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2953                } catch (RemoteException e) {
2954                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2955                }
2956                needNL = true;
2957            }
2958        }
2959        return printed;
2960    }
2961
2962    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2963        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2964        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2965        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2966    }
2967
2968    final void scheduleIdleLocked() {
2969        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2970    }
2971
2972    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2973        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2974        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2975    }
2976
2977    final void scheduleResumeTopActivities() {
2978        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2979            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2980        }
2981    }
2982
2983    void removeSleepTimeouts() {
2984        mSleepTimeout = false;
2985        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2986    }
2987
2988    final void scheduleSleepTimeout() {
2989        removeSleepTimeouts();
2990        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2991    }
2992
2993    @Override
2994    public void onDisplayAdded(int displayId) {
2995        Slog.v(TAG, "Display added displayId=" + displayId);
2996        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2997    }
2998
2999    @Override
3000    public void onDisplayRemoved(int displayId) {
3001        Slog.v(TAG, "Display removed displayId=" + displayId);
3002        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3003    }
3004
3005    @Override
3006    public void onDisplayChanged(int displayId) {
3007        Slog.v(TAG, "Display changed displayId=" + displayId);
3008        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3009    }
3010
3011    public void handleDisplayAddedLocked(int displayId) {
3012        boolean newDisplay;
3013        synchronized (mService) {
3014            newDisplay = mActivityDisplays.get(displayId) == null;
3015            if (newDisplay) {
3016                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3017                mActivityDisplays.put(displayId, activityDisplay);
3018            }
3019        }
3020        if (newDisplay) {
3021            mWindowManager.onDisplayAdded(displayId);
3022        }
3023    }
3024
3025    public void handleDisplayRemovedLocked(int displayId) {
3026        synchronized (mService) {
3027            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3028            if (activityDisplay != null) {
3029                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3030                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3031                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3032                }
3033                mActivityDisplays.remove(displayId);
3034            }
3035        }
3036        mWindowManager.onDisplayRemoved(displayId);
3037    }
3038
3039    public void handleDisplayChangedLocked(int displayId) {
3040        synchronized (mService) {
3041            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3042            if (activityDisplay != null) {
3043                // TODO: Update the bounds.
3044            }
3045        }
3046        mWindowManager.onDisplayChanged(displayId);
3047    }
3048
3049    StackInfo getStackInfo(ActivityStack stack) {
3050        StackInfo info = new StackInfo();
3051        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3052        info.displayId = Display.DEFAULT_DISPLAY;
3053        info.stackId = stack.mStackId;
3054
3055        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3056        final int numTasks = tasks.size();
3057        int[] taskIds = new int[numTasks];
3058        String[] taskNames = new String[numTasks];
3059        for (int i = 0; i < numTasks; ++i) {
3060            final TaskRecord task = tasks.get(i);
3061            taskIds[i] = task.taskId;
3062            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3063                    : task.realActivity != null ? task.realActivity.flattenToString()
3064                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3065                    : "unknown";
3066        }
3067        info.taskIds = taskIds;
3068        info.taskNames = taskNames;
3069        return info;
3070    }
3071
3072    StackInfo getStackInfoLocked(int stackId) {
3073        ActivityStack stack = getStack(stackId);
3074        if (stack != null) {
3075            return getStackInfo(stack);
3076        }
3077        return null;
3078    }
3079
3080    ArrayList<StackInfo> getAllStackInfosLocked() {
3081        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3082        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3083            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3084            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3085                list.add(getStackInfo(stacks.get(ndx)));
3086            }
3087        }
3088        return list;
3089    }
3090
3091    void showLockTaskToast() {
3092        mLockTaskNotify.showToast(mLockTaskIsLocked);
3093    }
3094
3095    void setLockTaskModeLocked(TaskRecord task, boolean isLocked) {
3096        if (task == null) {
3097            // Take out of lock task mode if necessary
3098            if (mLockTaskModeTask != null) {
3099                final Message lockTaskMsg = Message.obtain();
3100                lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3101                lockTaskMsg.what = LOCK_TASK_END_MSG;
3102                mLockTaskModeTask = null;
3103                mHandler.sendMessage(lockTaskMsg);
3104            }
3105            return;
3106        }
3107        if (isLockTaskModeViolation(task)) {
3108            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
3109            return;
3110        }
3111        mLockTaskModeTask = task;
3112        findTaskToMoveToFrontLocked(task, 0, null);
3113        resumeTopActivitiesLocked();
3114
3115        final Message lockTaskMsg = Message.obtain();
3116        lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
3117        lockTaskMsg.arg1 = mLockTaskModeTask.userId;
3118        lockTaskMsg.what = LOCK_TASK_START_MSG;
3119        lockTaskMsg.arg2 = !isLocked ? 1 : 0;
3120        mHandler.sendMessage(lockTaskMsg);
3121    }
3122
3123    boolean isLockTaskModeViolation(TaskRecord task) {
3124        return mLockTaskModeTask != null && mLockTaskModeTask != task;
3125    }
3126
3127    void endLockTaskModeIfTaskEnding(TaskRecord task) {
3128        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
3129            mLockTaskModeTask = null;
3130        }
3131    }
3132
3133    boolean isInLockTaskMode() {
3134        return mLockTaskModeTask != null;
3135    }
3136
3137    private final class ActivityStackSupervisorHandler extends Handler {
3138
3139        public ActivityStackSupervisorHandler(Looper looper) {
3140            super(looper);
3141        }
3142
3143        void activityIdleInternal(ActivityRecord r) {
3144            synchronized (mService) {
3145                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
3146            }
3147        }
3148
3149        @Override
3150        public void handleMessage(Message msg) {
3151            switch (msg.what) {
3152                case IDLE_TIMEOUT_MSG: {
3153                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
3154                    if (mService.mDidDexOpt) {
3155                        mService.mDidDexOpt = false;
3156                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
3157                        nmsg.obj = msg.obj;
3158                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
3159                        return;
3160                    }
3161                    // We don't at this point know if the activity is fullscreen,
3162                    // so we need to be conservative and assume it isn't.
3163                    activityIdleInternal((ActivityRecord)msg.obj);
3164                } break;
3165                case IDLE_NOW_MSG: {
3166                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
3167                    activityIdleInternal((ActivityRecord)msg.obj);
3168                } break;
3169                case RESUME_TOP_ACTIVITY_MSG: {
3170                    synchronized (mService) {
3171                        resumeTopActivitiesLocked();
3172                    }
3173                } break;
3174                case SLEEP_TIMEOUT_MSG: {
3175                    synchronized (mService) {
3176                        if (mService.isSleepingOrShuttingDown()) {
3177                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
3178                            mSleepTimeout = true;
3179                            checkReadyForSleepLocked();
3180                        }
3181                    }
3182                } break;
3183                case LAUNCH_TIMEOUT_MSG: {
3184                    if (mService.mDidDexOpt) {
3185                        mService.mDidDexOpt = false;
3186                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
3187                        return;
3188                    }
3189                    synchronized (mService) {
3190                        if (mLaunchingActivity.isHeld()) {
3191                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3192                            if (VALIDATE_WAKE_LOCK_CALLER
3193                                    && Binder.getCallingUid() != Process.myUid()) {
3194                                throw new IllegalStateException("Calling must be system uid");
3195                            }
3196                            mLaunchingActivity.release();
3197                        }
3198                    }
3199                } break;
3200                case HANDLE_DISPLAY_ADDED: {
3201                    handleDisplayAddedLocked(msg.arg1);
3202                } break;
3203                case HANDLE_DISPLAY_CHANGED: {
3204                    handleDisplayChangedLocked(msg.arg1);
3205                } break;
3206                case HANDLE_DISPLAY_REMOVED: {
3207                    handleDisplayRemovedLocked(msg.arg1);
3208                } break;
3209                case CONTAINER_CALLBACK_VISIBILITY: {
3210                    final ActivityContainer container = (ActivityContainer) msg.obj;
3211                    final IActivityContainerCallback callback = container.mCallback;
3212                    if (callback != null) {
3213                        try {
3214                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
3215                        } catch (RemoteException e) {
3216                        }
3217                    }
3218                } break;
3219                case LOCK_TASK_START_MSG: {
3220                    // When lock task starts, we disable the status bars.
3221                    try {
3222                        if (mLockTaskNotify == null) {
3223                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3224                        }
3225                        mLockTaskNotify.show(true);
3226                        if (getStatusBarService() != null) {
3227                            int flags =
3228                                    StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
3229                            if (msg.arg2 != 0) {
3230                                flags ^= StatusBarManager.DISABLE_HOME
3231                                        | StatusBarManager.DISABLE_RECENT;
3232                            }
3233                            getStatusBarService().disable(flags, mToken,
3234                                    mService.mContext.getPackageName());
3235                        }
3236                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
3237                        if (getDevicePolicyManager() != null) {
3238                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
3239                                    (String)msg.obj, msg.arg1);
3240                        }
3241                    } catch (RemoteException ex) {
3242                        throw new RuntimeException(ex);
3243                    }
3244                } break;
3245                case LOCK_TASK_END_MSG: {
3246                    // When lock task ends, we enable the status bars.
3247                    try {
3248                        if (getStatusBarService() != null) {
3249                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
3250                                    mService.mContext.getPackageName());
3251                        }
3252                        mWindowManager.reenableKeyguard(mToken);
3253                        if (getDevicePolicyManager() != null) {
3254                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
3255                                    msg.arg1);
3256                        }
3257                        if (mLockTaskNotify == null) {
3258                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
3259                        }
3260                        mLockTaskNotify.show(false);
3261                        try {
3262                            boolean shouldLockKeyguard = Settings.System.getInt(
3263                                    mService.mContext.getContentResolver(),
3264                                    Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
3265                            if (shouldLockKeyguard) {
3266                                mWindowManager.lockNow(null);
3267                            }
3268                        } catch (SettingNotFoundException e) {
3269                            // No setting, don't lock.
3270                        }
3271                    } catch (RemoteException ex) {
3272                        throw new RuntimeException(ex);
3273                    }
3274                } break;
3275                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
3276                    final ActivityContainer container = (ActivityContainer) msg.obj;
3277                    final IActivityContainerCallback callback = container.mCallback;
3278                    if (callback != null) {
3279                        try {
3280                            callback.onAllActivitiesComplete(container.asBinder());
3281                        } catch (RemoteException e) {
3282                        }
3283                    }
3284                } break;
3285                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
3286                    synchronized (mService) {
3287                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
3288                                msg.obj);
3289                        ((ActivityContainer) msg.obj).onTaskListEmptyLocked();
3290                    }
3291                } break;
3292            }
3293        }
3294    }
3295
3296    class ActivityContainer extends android.app.IActivityContainer.Stub {
3297        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
3298                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
3299        final int mStackId;
3300        IActivityContainerCallback mCallback = null;
3301        final ActivityStack mStack;
3302        ActivityRecord mParentActivity = null;
3303        String mIdString;
3304
3305        boolean mVisible = true;
3306
3307        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3308        ActivityDisplay mActivityDisplay;
3309
3310        final static int CONTAINER_STATE_HAS_SURFACE = 0;
3311        final static int CONTAINER_STATE_NO_SURFACE = 1;
3312        final static int CONTAINER_STATE_FINISHING = 2;
3313        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3314
3315        ActivityContainer(int stackId) {
3316            synchronized (mService) {
3317                mStackId = stackId;
3318                mStack = new ActivityStack(this);
3319                mIdString = "ActivtyContainer{" + mStackId + "}";
3320                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3321            }
3322        }
3323
3324        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3325            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3326                    + " to display=" + activityDisplay);
3327            mActivityDisplay = activityDisplay;
3328            mStack.mDisplayId = activityDisplay.mDisplayId;
3329            mStack.mStacks = activityDisplay.mStacks;
3330
3331            activityDisplay.attachActivities(mStack);
3332            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3333        }
3334
3335        @Override
3336        public void attachToDisplay(int displayId) {
3337            synchronized (mService) {
3338                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3339                if (activityDisplay == null) {
3340                    return;
3341                }
3342                attachToDisplayLocked(activityDisplay);
3343            }
3344        }
3345
3346        @Override
3347        public int getDisplayId() {
3348            synchronized (mService) {
3349                if (mActivityDisplay != null) {
3350                    return mActivityDisplay.mDisplayId;
3351                }
3352            }
3353            return -1;
3354        }
3355
3356        @Override
3357        public boolean injectEvent(InputEvent event) {
3358            final long origId = Binder.clearCallingIdentity();
3359            try {
3360                synchronized (mService) {
3361                    if (mActivityDisplay != null) {
3362                        return mInputManagerInternal.injectInputEvent(event,
3363                                mActivityDisplay.mDisplayId,
3364                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3365                    }
3366                }
3367                return false;
3368            } finally {
3369                Binder.restoreCallingIdentity(origId);
3370            }
3371        }
3372
3373        @Override
3374        public void release() {
3375            synchronized (mService) {
3376                if (mContainerState == CONTAINER_STATE_FINISHING) {
3377                    return;
3378                }
3379                mContainerState = CONTAINER_STATE_FINISHING;
3380
3381                final Message msg =
3382                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3383                mHandler.sendMessageDelayed(msg, 1000);
3384
3385                long origId = Binder.clearCallingIdentity();
3386                try {
3387                    mStack.finishAllActivitiesLocked();
3388                } finally {
3389                    Binder.restoreCallingIdentity(origId);
3390                }
3391            }
3392        }
3393
3394        private void detachLocked() {
3395            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3396                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3397            if (mActivityDisplay != null) {
3398                mActivityDisplay.detachActivitiesLocked(mStack);
3399                mActivityDisplay = null;
3400                mStack.mDisplayId = -1;
3401                mStack.mStacks = null;
3402                mWindowManager.detachStack(mStackId);
3403            }
3404        }
3405
3406        @Override
3407        public final int startActivity(Intent intent) {
3408            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3409            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3410                    Binder.getCallingUid(), mCurrentUser, false,
3411                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3412            // TODO: Switch to user app stacks here.
3413            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3414            String mimeType = intent.getType();
3415            if (mimeType == null && intent.getData() != null
3416                    && "content".equals(intent.getData().getScheme())) {
3417                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3418            }
3419            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null,
3420                    null, null, null, null, userId, this);
3421        }
3422
3423        @Override
3424        public final int startActivityIntentSender(IIntentSender intentSender) {
3425            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3426
3427            if (!(intentSender instanceof PendingIntentRecord)) {
3428                throw new IllegalArgumentException("Bad PendingIntent object");
3429            }
3430
3431            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3432                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3433        }
3434
3435        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3436            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3437                    Binder.getCallingUid(), mCurrentUser, false,
3438                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
3439            if (resolvedType == null) {
3440                resolvedType = intent.getType();
3441                if (resolvedType == null && intent.getData() != null
3442                        && "content".equals(intent.getData().getScheme())) {
3443                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3444                }
3445            }
3446            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
3447            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3448                throw new SecurityException(
3449                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3450            }
3451        }
3452
3453        /** Throw a SecurityException if allowEmbedded is not true */
3454        @Override
3455        public final void checkEmbeddedAllowed(Intent intent) {
3456            checkEmbeddedAllowedInner(intent, null);
3457        }
3458
3459        /** Throw a SecurityException if allowEmbedded is not true */
3460        @Override
3461        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3462            if (!(intentSender instanceof PendingIntentRecord)) {
3463                throw new IllegalArgumentException("Bad PendingIntent object");
3464            }
3465            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3466            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3467                    pendingIntent.key.requestResolvedType);
3468        }
3469
3470        @Override
3471        public IBinder asBinder() {
3472            return this;
3473        }
3474
3475        @Override
3476        public void setSurface(Surface surface, int width, int height, int density) {
3477            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3478        }
3479
3480        ActivityStackSupervisor getOuter() {
3481            return ActivityStackSupervisor.this;
3482        }
3483
3484        boolean isAttachedLocked() {
3485            return mActivityDisplay != null;
3486        }
3487
3488        void getBounds(Point outBounds) {
3489            synchronized (mService) {
3490                    if (mActivityDisplay != null) {
3491                    mActivityDisplay.getBounds(outBounds);
3492                } else {
3493                    outBounds.set(0, 0);
3494                }
3495            }
3496        }
3497
3498        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3499        void setVisible(boolean visible) {
3500            if (mVisible != visible) {
3501                mVisible = visible;
3502                if (mCallback != null) {
3503                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3504                            0 /* unused */, this).sendToTarget();
3505                }
3506            }
3507        }
3508
3509        void setDrawn() {
3510        }
3511
3512        // You can always start a new task on a regular ActivityStack.
3513        boolean isEligibleForNewTasks() {
3514            return true;
3515        }
3516
3517        void onTaskListEmptyLocked() {
3518            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3519            if (!mStack.isHomeStack()) {
3520                detachLocked();
3521                deleteActivityContainer(this);
3522            }
3523            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3524        }
3525
3526        @Override
3527        public String toString() {
3528            return mIdString + (mActivityDisplay == null ? "N" : "A");
3529        }
3530    }
3531
3532    private class VirtualActivityContainer extends ActivityContainer {
3533        Surface mSurface;
3534        boolean mDrawn = false;
3535
3536        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3537            super(getNextStackId());
3538            mParentActivity = parent;
3539            mCallback = callback;
3540            mContainerState = CONTAINER_STATE_NO_SURFACE;
3541            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3542        }
3543
3544        @Override
3545        public void setSurface(Surface surface, int width, int height, int density) {
3546            super.setSurface(surface, width, height, density);
3547
3548            synchronized (mService) {
3549                final long origId = Binder.clearCallingIdentity();
3550                try {
3551                    setSurfaceLocked(surface, width, height, density);
3552                } finally {
3553                    Binder.restoreCallingIdentity(origId);
3554                }
3555            }
3556        }
3557
3558        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3559            if (mContainerState == CONTAINER_STATE_FINISHING) {
3560                return;
3561            }
3562            VirtualActivityDisplay virtualActivityDisplay =
3563                    (VirtualActivityDisplay) mActivityDisplay;
3564            if (virtualActivityDisplay == null) {
3565                virtualActivityDisplay =
3566                        new VirtualActivityDisplay(width, height, density);
3567                mActivityDisplay = virtualActivityDisplay;
3568                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3569                attachToDisplayLocked(virtualActivityDisplay);
3570            }
3571
3572            if (mSurface != null) {
3573                mSurface.release();
3574            }
3575
3576            mSurface = surface;
3577            if (surface != null) {
3578                mStack.resumeTopActivityLocked(null);
3579            } else {
3580                mContainerState = CONTAINER_STATE_NO_SURFACE;
3581                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3582                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3583                    mStack.startPausingLocked(false, true);
3584                }
3585            }
3586
3587            setSurfaceIfReadyLocked();
3588
3589            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3590                    + virtualActivityDisplay);
3591        }
3592
3593        @Override
3594        boolean isAttachedLocked() {
3595            return mSurface != null && super.isAttachedLocked();
3596        }
3597
3598        @Override
3599        void setDrawn() {
3600            synchronized (mService) {
3601                mDrawn = true;
3602                setSurfaceIfReadyLocked();
3603            }
3604        }
3605
3606        // Never start a new task on an ActivityView if it isn't explicitly specified.
3607        @Override
3608        boolean isEligibleForNewTasks() {
3609            return false;
3610        }
3611
3612        private void setSurfaceIfReadyLocked() {
3613            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
3614                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3615            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3616                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3617                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3618            }
3619        }
3620    }
3621
3622    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3623     * attached {@link ActivityStack}s */
3624    class ActivityDisplay {
3625        /** Actual Display this object tracks. */
3626        int mDisplayId;
3627        Display mDisplay;
3628        DisplayInfo mDisplayInfo = new DisplayInfo();
3629
3630        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3631         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3632        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3633
3634        ActivityRecord mMediaPlayingActivity;
3635
3636        ActivityDisplay() {
3637        }
3638
3639        ActivityDisplay(int displayId) {
3640            init(mDisplayManager.getDisplay(displayId));
3641        }
3642
3643        void init(Display display) {
3644            mDisplay = display;
3645            mDisplayId = display.getDisplayId();
3646            mDisplay.getDisplayInfo(mDisplayInfo);
3647        }
3648
3649        void attachActivities(ActivityStack stack) {
3650            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3651                    + mDisplayId);
3652            mStacks.add(stack);
3653        }
3654
3655        void detachActivitiesLocked(ActivityStack stack) {
3656            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3657                    + " from displayId=" + mDisplayId);
3658            mStacks.remove(stack);
3659        }
3660
3661        void getBounds(Point bounds) {
3662            mDisplay.getDisplayInfo(mDisplayInfo);
3663            bounds.x = mDisplayInfo.appWidth;
3664            bounds.y = mDisplayInfo.appHeight;
3665        }
3666
3667        void setMediaPlaying(ActivityRecord r) {
3668            mMediaPlayingActivity = r;
3669        }
3670
3671        boolean isMediaPlaying() {
3672            return mMediaPlayingActivity != null;
3673        }
3674
3675        @Override
3676        public String toString() {
3677            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3678        }
3679    }
3680
3681    class VirtualActivityDisplay extends ActivityDisplay {
3682        VirtualDisplay mVirtualDisplay;
3683
3684        VirtualActivityDisplay(int width, int height, int density) {
3685            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3686            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
3687                    width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3688                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3689
3690            init(mVirtualDisplay.getDisplay());
3691
3692            mWindowManager.handleDisplayAdded(mDisplayId);
3693        }
3694
3695        void setSurface(Surface surface) {
3696            if (mVirtualDisplay != null) {
3697                mVirtualDisplay.setSurface(surface);
3698            }
3699        }
3700
3701        @Override
3702        void detachActivitiesLocked(ActivityStack stack) {
3703            super.detachActivitiesLocked(stack);
3704            if (mVirtualDisplay != null) {
3705                mVirtualDisplay.release();
3706                mVirtualDisplay = null;
3707            }
3708        }
3709
3710        @Override
3711        public String toString() {
3712            return "VirtualActivityDisplay={" + mDisplayId + "}";
3713        }
3714    }
3715
3716    private boolean isLeanbackOnlyDevice() {
3717        boolean onLeanbackOnly = false;
3718        try {
3719            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
3720                    PackageManager.FEATURE_LEANBACK_ONLY);
3721        } catch (RemoteException e) {
3722            // noop
3723        }
3724
3725        return onLeanbackOnly;
3726    }
3727}
3728