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