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