ActivityStackSupervisor.java revision 2c92c9700c7b06f3c7dd5ab15d8343dfce68c833
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)) {
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)
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            Bundle options = (r.pendingOptions == null) ? null : r.pendingOptions.toBundle();
1033            r.clearOptionsLocked();
1034            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1035                    System.identityHashCode(r), r.info,
1036                    new Configuration(mService.mConfiguration), r.compat,
1037                    app.repProcState, r.icicle, results, newIntents, !andResume,
1038                    mService.isNextTransitionForward(), profileFile, profileFd,
1039                    profileAutoStop, options);
1040
1041            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1042                // This may be a heavy-weight process!  Note that the package
1043                // manager will ensure that only activity can run in the main
1044                // process of the .apk, which is the only thing that will be
1045                // considered heavy-weight.
1046                if (app.processName.equals(app.info.packageName)) {
1047                    if (mService.mHeavyWeightProcess != null
1048                            && mService.mHeavyWeightProcess != app) {
1049                        Slog.w(TAG, "Starting new heavy weight process " + app
1050                                + " when already running "
1051                                + mService.mHeavyWeightProcess);
1052                    }
1053                    mService.mHeavyWeightProcess = app;
1054                    Message msg = mService.mHandler.obtainMessage(
1055                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1056                    msg.obj = r;
1057                    mService.mHandler.sendMessage(msg);
1058                }
1059            }
1060
1061        } catch (RemoteException e) {
1062            if (r.launchFailed) {
1063                // This is the second time we failed -- finish activity
1064                // and give up.
1065                Slog.e(TAG, "Second failure launching "
1066                      + r.intent.getComponent().flattenToShortString()
1067                      + ", giving up", e);
1068                mService.appDiedLocked(app, app.pid, app.thread);
1069                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1070                        "2nd-crash", false);
1071                return false;
1072            }
1073
1074            // This is the first time we failed -- restart process and
1075            // retry.
1076            app.activities.remove(r);
1077            throw e;
1078        }
1079
1080        r.launchFailed = false;
1081        if (stack.updateLRUListLocked(r)) {
1082            Slog.w(TAG, "Activity " + r
1083                  + " being launched, but already in LRU list");
1084        }
1085
1086        if (andResume) {
1087            // As part of the process of launching, ActivityThread also performs
1088            // a resume.
1089            stack.minimalResumeActivityLocked(r);
1090        } else {
1091            // This activity is not starting in the resumed state... which
1092            // should look like we asked it to pause+stop (but remain visible),
1093            // and it has done so and reported back the current icicle and
1094            // other state.
1095            if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1096                    + " (starting in stopped state)");
1097            r.state = ActivityState.STOPPED;
1098            r.stopped = true;
1099        }
1100
1101        // Launch the new version setup screen if needed.  We do this -after-
1102        // launching the initial activity (that is, home), so that it can have
1103        // a chance to initialize itself while in the background, making the
1104        // switch back to it faster and look better.
1105        if (isFrontStack(stack)) {
1106            mService.startSetupActivityLocked();
1107        }
1108
1109        return true;
1110    }
1111
1112    void startSpecificActivityLocked(ActivityRecord r,
1113            boolean andResume, boolean checkConfig) {
1114        // Is this activity's application already running?
1115        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1116                r.info.applicationInfo.uid, true);
1117
1118        r.task.stack.setLaunchTime(r);
1119
1120        if (app != null && app.thread != null) {
1121            try {
1122                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1123                        || !"android".equals(r.info.packageName)) {
1124                    // Don't add this if it is a platform component that is marked
1125                    // to run in multiple processes, because this is actually
1126                    // part of the framework so doesn't make sense to track as a
1127                    // separate apk in the process.
1128                    app.addPackage(r.info.packageName, mService.mProcessStats);
1129                }
1130                realStartActivityLocked(r, app, andResume, checkConfig);
1131                return;
1132            } catch (RemoteException e) {
1133                Slog.w(TAG, "Exception when starting activity "
1134                        + r.intent.getComponent().flattenToShortString(), e);
1135            }
1136
1137            // If a dead object exception was thrown -- fall through to
1138            // restart the application.
1139        }
1140
1141        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1142                "activity", r.intent.getComponent(), false, false, true);
1143    }
1144
1145    final int startActivityLocked(IApplicationThread caller,
1146            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1147            String resultWho, int requestCode,
1148            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1149            boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
1150        int err = ActivityManager.START_SUCCESS;
1151
1152        ProcessRecord callerApp = null;
1153        if (caller != null) {
1154            callerApp = mService.getRecordForAppLocked(caller);
1155            if (callerApp != null) {
1156                callingPid = callerApp.pid;
1157                callingUid = callerApp.info.uid;
1158            } else {
1159                Slog.w(TAG, "Unable to find app for caller " + caller
1160                      + " (pid=" + callingPid + ") when starting: "
1161                      + intent.toString());
1162                err = ActivityManager.START_PERMISSION_DENIED;
1163            }
1164        }
1165
1166        if (err == ActivityManager.START_SUCCESS) {
1167            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1168            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1169                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1170                    + " on display " + (container == null ? (mFocusedStack == null ?
1171                            Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1172                            (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1173                                    container.mActivityDisplay.mDisplayId)));
1174        }
1175
1176        ActivityRecord sourceRecord = null;
1177        ActivityRecord resultRecord = null;
1178        if (resultTo != null) {
1179            sourceRecord = isInAnyStackLocked(resultTo);
1180            if (DEBUG_RESULTS) Slog.v(
1181                TAG, "Will send result to " + resultTo + " " + sourceRecord);
1182            if (sourceRecord != null) {
1183                if (requestCode >= 0 && !sourceRecord.finishing) {
1184                    resultRecord = sourceRecord;
1185                }
1186            }
1187        }
1188        ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1189
1190        int launchFlags = intent.getFlags();
1191
1192        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1193                && sourceRecord != null) {
1194            // Transfer the result target from the source activity to the new
1195            // one being started, including any failures.
1196            if (requestCode >= 0) {
1197                ActivityOptions.abort(options);
1198                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1199            }
1200            resultRecord = sourceRecord.resultTo;
1201            resultWho = sourceRecord.resultWho;
1202            requestCode = sourceRecord.requestCode;
1203            sourceRecord.resultTo = null;
1204            if (resultRecord != null) {
1205                resultRecord.removeResultsLocked(
1206                    sourceRecord, resultWho, requestCode);
1207            }
1208            if (sourceRecord.launchedFromUid == callingUid) {
1209                // The new activity is being launched from the same uid as the previous
1210                // activity in the flow, and asking to forward its result back to the
1211                // previous.  In this case the activity is serving as a trampoline between
1212                // the two, so we also want to update its launchedFromPackage to be the
1213                // same as the previous activity.  Note that this is safe, since we know
1214                // these two packages come from the same uid; the caller could just as
1215                // well have supplied that same package name itself.  This specifially
1216                // deals with the case of an intent picker/chooser being launched in the app
1217                // flow to redirect to an activity picked by the user, where we want the final
1218                // activity to consider it to have been launched by the previous app activity.
1219                callingPackage = sourceRecord.launchedFromPackage;
1220            }
1221        }
1222
1223        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1224            // We couldn't find a class that can handle the given Intent.
1225            // That's the end of that!
1226            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1227        }
1228
1229        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1230            // We couldn't find the specific class specified in the Intent.
1231            // Also the end of the line.
1232            err = ActivityManager.START_CLASS_NOT_FOUND;
1233        }
1234
1235        if (err != ActivityManager.START_SUCCESS) {
1236            if (resultRecord != null) {
1237                resultStack.sendActivityResultLocked(-1,
1238                    resultRecord, resultWho, requestCode,
1239                    Activity.RESULT_CANCELED, null);
1240            }
1241            setDismissKeyguard(false);
1242            ActivityOptions.abort(options);
1243            return err;
1244        }
1245
1246        final int startAnyPerm = mService.checkPermission(
1247                START_ANY_ACTIVITY, callingPid, callingUid);
1248        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1249                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1250        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1251            if (resultRecord != null) {
1252                resultStack.sendActivityResultLocked(-1,
1253                    resultRecord, resultWho, requestCode,
1254                    Activity.RESULT_CANCELED, null);
1255            }
1256            setDismissKeyguard(false);
1257            String msg;
1258            if (!aInfo.exported) {
1259                msg = "Permission Denial: starting " + intent.toString()
1260                        + " from " + callerApp + " (pid=" + callingPid
1261                        + ", uid=" + callingUid + ")"
1262                        + " not exported from uid " + aInfo.applicationInfo.uid;
1263            } else {
1264                msg = "Permission Denial: starting " + intent.toString()
1265                        + " from " + callerApp + " (pid=" + callingPid
1266                        + ", uid=" + callingUid + ")"
1267                        + " requires " + aInfo.permission;
1268            }
1269            Slog.w(TAG, msg);
1270            throw new SecurityException(msg);
1271        }
1272
1273        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1274                callingPid, resolvedType, aInfo.applicationInfo);
1275
1276        if (mService.mController != null) {
1277            try {
1278                // The Intent we give to the watcher has the extra data
1279                // stripped off, since it can contain private information.
1280                Intent watchIntent = intent.cloneFilter();
1281                abort |= !mService.mController.activityStarting(watchIntent,
1282                        aInfo.applicationInfo.packageName);
1283            } catch (RemoteException e) {
1284                mService.mController = null;
1285            }
1286        }
1287
1288        if (abort) {
1289            if (resultRecord != null) {
1290                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1291                        Activity.RESULT_CANCELED, null);
1292            }
1293            // We pretend to the caller that it was really started, but
1294            // they will just get a cancel result.
1295            setDismissKeyguard(false);
1296            ActivityOptions.abort(options);
1297            return ActivityManager.START_SUCCESS;
1298        }
1299
1300        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1301                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1302                requestCode, componentSpecified, this, container);
1303        if (outActivity != null) {
1304            outActivity[0] = r;
1305        }
1306
1307        final ActivityStack stack = getFocusedStack();
1308        if (stack.mResumedActivity == null
1309                || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
1310            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1311                PendingActivityLaunch pal =
1312                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1313                mService.mPendingActivityLaunches.add(pal);
1314                setDismissKeyguard(false);
1315                ActivityOptions.abort(options);
1316                return ActivityManager.START_SWITCHES_CANCELED;
1317            }
1318        }
1319
1320        if (mService.mDidAppSwitch) {
1321            // This is the second allowed switch since we stopped switches,
1322            // so now just generally allow switches.  Use case: user presses
1323            // home (switches disabled, switch to home, mDidAppSwitch now true);
1324            // user taps a home icon (coming from home so allowed, we hit here
1325            // and now allow anyone to switch again).
1326            mService.mAppSwitchesAllowedTime = 0;
1327        } else {
1328            mService.mDidAppSwitch = true;
1329        }
1330
1331        mService.doPendingActivityLaunchesLocked(false);
1332
1333        err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
1334
1335        if (allPausedActivitiesComplete()) {
1336            // If someone asked to have the keyguard dismissed on the next
1337            // activity start, but we are not actually doing an activity
1338            // switch...  just dismiss the keyguard now, because we
1339            // probably want to see whatever is behind it.
1340            dismissKeyguard();
1341        }
1342        return err;
1343    }
1344
1345    ActivityStack adjustStackFocus(ActivityRecord r) {
1346        final TaskRecord task = r.task;
1347        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
1348            if (task != null) {
1349                final ActivityStack taskStack = task.stack;
1350                if (taskStack.isOnHomeDisplay()) {
1351                    if (mFocusedStack != taskStack) {
1352                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1353                                "focused stack to r=" + r + " task=" + task);
1354                        mFocusedStack = taskStack;
1355                    } else {
1356                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1357                            "adjustStackFocus: Focused stack already=" + mFocusedStack);
1358                    }
1359                }
1360                return taskStack;
1361            }
1362
1363            final ActivityContainer container = r.mInitialActivityContainer;
1364            if (container != null) {
1365                // The first time put it on the desired stack, after this put on task stack.
1366                r.mInitialActivityContainer = null;
1367                return container.mStack;
1368            }
1369
1370            if (mFocusedStack != mHomeStack) {
1371                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1372                        "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1373                return mFocusedStack;
1374            }
1375
1376            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1377            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1378                final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1379                if (!stack.isHomeStack()) {
1380                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1381                            "adjustStackFocus: Setting focused stack=" + stack);
1382                    mFocusedStack = stack;
1383                    return mFocusedStack;
1384                }
1385            }
1386
1387            // Need to create an app stack for this user.
1388            int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
1389            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1390                    " stackId=" + stackId);
1391            mFocusedStack = getStack(stackId);
1392            return mFocusedStack;
1393        }
1394        return mHomeStack;
1395    }
1396
1397    void setFocusedStack(ActivityRecord r) {
1398        if (r != null) {
1399            final TaskRecord task = r.task;
1400            boolean isHomeActivity = !r.isApplicationActivity();
1401            if (!isHomeActivity && task != null) {
1402                isHomeActivity = !task.isApplicationTask();
1403            }
1404            if (!isHomeActivity && task != null) {
1405                final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1406                isHomeActivity = parent != null && parent.isHomeActivity();
1407            }
1408            moveHomeStack(isHomeActivity);
1409        }
1410    }
1411
1412    final int startActivityUncheckedLocked(ActivityRecord r,
1413            ActivityRecord sourceRecord, int startFlags, boolean doResume,
1414            Bundle options) {
1415        final Intent intent = r.intent;
1416        final int callingUid = r.launchedFromUid;
1417
1418        int launchFlags = intent.getFlags();
1419
1420        // We'll invoke onUserLeaving before onPause only if the launching
1421        // activity did not explicitly state that this is an automated launch.
1422        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1423        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1424
1425        // If the caller has asked not to resume at this point, we make note
1426        // of this in the record so that we can skip it when trying to find
1427        // the top running activity.
1428        if (!doResume) {
1429            r.delayedResume = true;
1430        }
1431
1432        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1433
1434        // If the onlyIfNeeded flag is set, then we can do this if the activity
1435        // being launched is the same as the one making the call...  or, as
1436        // a special case, if we do not know the caller then we count the
1437        // current top activity as the caller.
1438        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1439            ActivityRecord checkedCaller = sourceRecord;
1440            if (checkedCaller == null) {
1441                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1442            }
1443            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1444                // Caller is not the same as launcher, so always needed.
1445                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1446            }
1447        }
1448
1449        final boolean newDocument = intent.isDocument();
1450        if (sourceRecord == null) {
1451            // This activity is not being started from another...  in this
1452            // case we -always- start a new task.
1453            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1454                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1455                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1456                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1457            }
1458        } else if (newDocument) {
1459            if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
1460                Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
1461                r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
1462            }
1463        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1464            // The original activity who is starting us is running as a single
1465            // instance...  this new activity it is starting must go on its
1466            // own task.
1467            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1468        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1469                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1470            // The activity being started is a single instance...  it always
1471            // gets launched into its own task.
1472            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1473        }
1474
1475        ActivityInfo newTaskInfo = null;
1476        Intent newTaskIntent = null;
1477        final ActivityStack sourceStack;
1478        if (sourceRecord != null) {
1479            if (sourceRecord.finishing) {
1480                // If the source is finishing, we can't further count it as our source.  This
1481                // is because the task it is associated with may now be empty and on its way out,
1482                // so we don't want to blindly throw it in to that task.  Instead we will take
1483                // the NEW_TASK flow and try to find a task for it. But save the task information
1484                // so it can be used when creating the new task.
1485                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1486                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1487                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1488                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1489                    newTaskInfo = sourceRecord.info;
1490                    newTaskIntent = sourceRecord.task.intent;
1491                }
1492                sourceRecord = null;
1493                sourceStack = null;
1494            } else {
1495                sourceStack = sourceRecord.task.stack;
1496            }
1497        } else {
1498            sourceStack = null;
1499        }
1500
1501        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1502            // For whatever reason this activity is being launched into a new
1503            // task...  yet the caller has requested a result back.  Well, that
1504            // is pretty messed up, so instead immediately send back a cancel
1505            // and let the new task continue launched as normal without a
1506            // dependency on its originator.
1507            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1508            r.resultTo.task.stack.sendActivityResultLocked(-1,
1509                    r.resultTo, r.resultWho, r.requestCode,
1510                Activity.RESULT_CANCELED, null);
1511            r.resultTo = null;
1512        }
1513
1514        boolean addingToTask = false;
1515        boolean movedHome = false;
1516        TaskRecord reuseTask = null;
1517        ActivityStack targetStack;
1518        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1519                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1520                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1521                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1522            // If bring to front is requested, and no result is requested, and
1523            // we can find a task that was started with this same
1524            // component, then instead of launching bring that one to the front.
1525            if (r.resultTo == null) {
1526                // See if there is a task to bring to the front.  If this is
1527                // a SINGLE_INSTANCE activity, there can be one and only one
1528                // instance of it in the history, and it is always in its own
1529                // unique task, so we do a special search.
1530                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1531                        ? findTaskLocked(r)
1532                        : findActivityLocked(intent, r.info);
1533                if (intentActivity != null) {
1534                    if (isLockTaskModeViolation(intentActivity.task)) {
1535                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1536                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1537                    }
1538                    if (r.task == null) {
1539                        r.task = intentActivity.task;
1540                    }
1541                    targetStack = intentActivity.task.stack;
1542                    targetStack.mLastPausedActivity = null;
1543                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1544                            + " from " + intentActivity);
1545                    targetStack.moveToFront();
1546                    if (intentActivity.task.intent == null) {
1547                        // This task was started because of movement of
1548                        // the activity based on affinity...  now that we
1549                        // are actually launching it, we can assign the
1550                        // base intent.
1551                        intentActivity.task.setIntent(intent, r.info);
1552                    }
1553                    // If the target task is not in the front, then we need
1554                    // to bring it to the front...  except...  well, with
1555                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1556                    // to have the same behavior as if a new instance was
1557                    // being started, which means not bringing it to the front
1558                    // if the caller is not itself in the front.
1559                    final ActivityStack lastStack = getLastStack();
1560                    ActivityRecord curTop = lastStack == null?
1561                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1562                    if (curTop != null && (curTop.task != intentActivity.task ||
1563                            curTop.task != lastStack.topTask())) {
1564                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1565                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
1566                                sourceStack.topActivity().task == sourceRecord.task)) {
1567                            // We really do want to push this one into the
1568                            // user's face, right now.
1569                            movedHome = true;
1570                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1571                            if ((launchFlags &
1572                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1573                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1574                                // Caller wants to appear on home activity.
1575                                intentActivity.task.mOnTopOfHome = true;
1576                            }
1577                            options = null;
1578                        }
1579                    }
1580                    // If the caller has requested that the target task be
1581                    // reset, then do so.
1582                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1583                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1584                    }
1585                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1586                        // We don't need to start a new activity, and
1587                        // the client said not to do anything if that
1588                        // is the case, so this is it!  And for paranoia, make
1589                        // sure we have correctly resumed the top activity.
1590                        if (doResume) {
1591                            resumeTopActivitiesLocked(targetStack, null, options);
1592                        } else {
1593                            ActivityOptions.abort(options);
1594                        }
1595                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1596                    }
1597                    if ((launchFlags &
1598                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1599                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1600                        // The caller has requested to completely replace any
1601                        // existing task with its new activity.  Well that should
1602                        // not be too hard...
1603                        reuseTask = intentActivity.task;
1604                        reuseTask.performClearTaskLocked();
1605                        reuseTask.setIntent(r.intent, r.info);
1606                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1607                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1608                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1609                        // In this situation we want to remove all activities
1610                        // from the task up to the one being started.  In most
1611                        // cases this means we are resetting the task to its
1612                        // initial state.
1613                        ActivityRecord top =
1614                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1615                        if (top != null) {
1616                            if (top.frontOfTask) {
1617                                // Activity aliases may mean we use different
1618                                // intents for the top activity, so make sure
1619                                // the task now has the identity of the new
1620                                // intent.
1621                                top.task.setIntent(r.intent, r.info);
1622                            }
1623                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1624                                    r, top.task);
1625                            top.deliverNewIntentLocked(callingUid, r.intent);
1626                        } else {
1627                            // A special case: we need to
1628                            // start the activity because it is not currently
1629                            // running, and the caller has asked to clear the
1630                            // current task to have this activity at the top.
1631                            addingToTask = true;
1632                            // Now pretend like this activity is being started
1633                            // by the top of its task, so it is put in the
1634                            // right place.
1635                            sourceRecord = intentActivity;
1636                        }
1637                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1638                        // In this case the top activity on the task is the
1639                        // same as the one being launched, so we take that
1640                        // as a request to bring the task to the foreground.
1641                        // If the top activity in the task is the root
1642                        // activity, deliver this new intent to it if it
1643                        // desires.
1644                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1645                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1646                                && intentActivity.realActivity.equals(r.realActivity)) {
1647                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1648                                    intentActivity.task);
1649                            if (intentActivity.frontOfTask) {
1650                                intentActivity.task.setIntent(r.intent, r.info);
1651                            }
1652                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1653                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1654                            // In this case we are launching the root activity
1655                            // of the task, but with a different intent.  We
1656                            // should start a new instance on top.
1657                            addingToTask = true;
1658                            sourceRecord = intentActivity;
1659                        }
1660                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1661                        // In this case an activity is being launched in to an
1662                        // existing task, without resetting that task.  This
1663                        // is typically the situation of launching an activity
1664                        // from a notification or shortcut.  We want to place
1665                        // the new activity on top of the current task.
1666                        addingToTask = true;
1667                        sourceRecord = intentActivity;
1668                    } else if (!intentActivity.task.rootWasReset) {
1669                        // In this case we are launching in to an existing task
1670                        // that has not yet been started from its front door.
1671                        // The current task has been brought to the front.
1672                        // Ideally, we'd probably like to place this new task
1673                        // at the bottom of its stack, but that's a little hard
1674                        // to do with the current organization of the code so
1675                        // for now we'll just drop it.
1676                        intentActivity.task.setIntent(r.intent, r.info);
1677                    }
1678                    if (!addingToTask && reuseTask == null) {
1679                        // We didn't do anything...  but it was needed (a.k.a., client
1680                        // don't use that intent!)  And for paranoia, make
1681                        // sure we have correctly resumed the top activity.
1682                        if (doResume) {
1683                            targetStack.resumeTopActivityLocked(null, options);
1684                        } else {
1685                            ActivityOptions.abort(options);
1686                        }
1687                        return ActivityManager.START_TASK_TO_FRONT;
1688                    }
1689                }
1690            }
1691        }
1692
1693        //String uri = r.intent.toURI();
1694        //Intent intent2 = new Intent(uri);
1695        //Slog.i(TAG, "Given intent: " + r.intent);
1696        //Slog.i(TAG, "URI is: " + uri);
1697        //Slog.i(TAG, "To intent: " + intent2);
1698
1699        if (r.packageName != null) {
1700            // If the activity being launched is the same as the one currently
1701            // at the top, then we need to check if it should only be launched
1702            // once.
1703            ActivityStack topStack = getFocusedStack();
1704            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1705            if (top != null && r.resultTo == null) {
1706                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1707                    if (top.app != null && top.app.thread != null) {
1708                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1709                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1710                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1711                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1712                                    top.task);
1713                            // For paranoia, make sure we have correctly
1714                            // resumed the top activity.
1715                            topStack.mLastPausedActivity = null;
1716                            if (doResume) {
1717                                resumeTopActivitiesLocked();
1718                            }
1719                            ActivityOptions.abort(options);
1720                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1721                                // We don't need to start a new activity, and
1722                                // the client said not to do anything if that
1723                                // is the case, so this is it!
1724                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1725                            }
1726                            top.deliverNewIntentLocked(callingUid, r.intent);
1727                            return ActivityManager.START_DELIVERED_TO_TOP;
1728                        }
1729                    }
1730                }
1731            }
1732
1733        } else {
1734            if (r.resultTo != null) {
1735                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1736                        r.requestCode, Activity.RESULT_CANCELED, null);
1737            }
1738            ActivityOptions.abort(options);
1739            return ActivityManager.START_CLASS_NOT_FOUND;
1740        }
1741
1742        boolean newTask = false;
1743        boolean keepCurTransition = false;
1744
1745        // Should this be considered a new task?
1746        if (r.resultTo == null && !addingToTask
1747                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1748            if (isLockTaskModeViolation(reuseTask)) {
1749                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1750                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1751            }
1752            targetStack = adjustStackFocus(r);
1753            targetStack.moveToFront();
1754            if (reuseTask == null) {
1755                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1756                        newTaskInfo != null ? newTaskInfo : r.info,
1757                        newTaskIntent != null ? newTaskIntent : intent,
1758                        true), null, true);
1759                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1760                        r.task);
1761            } else {
1762                r.setTask(reuseTask, reuseTask, true);
1763            }
1764            newTask = true;
1765            if (!movedHome) {
1766                if ((launchFlags &
1767                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1768                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1769                    // Caller wants to appear on home activity, so before starting
1770                    // their own activity we will bring home to the front.
1771                    r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
1772                }
1773            }
1774        } else if (sourceRecord != null) {
1775            TaskRecord sourceTask = sourceRecord.task;
1776            if (isLockTaskModeViolation(sourceTask)) {
1777                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1778                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1779            }
1780            targetStack = sourceTask.stack;
1781            mWindowManager.moveTaskToTop(sourceTask.taskId);
1782            if (!addingToTask &&
1783                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1784                // In this case, we are adding the activity to an existing
1785                // task, but the caller has asked to clear that task if the
1786                // activity is already running.
1787                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1788                keepCurTransition = true;
1789                if (top != null) {
1790                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1791                    top.deliverNewIntentLocked(callingUid, r.intent);
1792                    // For paranoia, make sure we have correctly
1793                    // resumed the top activity.
1794                    targetStack.mLastPausedActivity = null;
1795                    if (doResume) {
1796                        targetStack.resumeTopActivityLocked(null);
1797                    }
1798                    ActivityOptions.abort(options);
1799                    return ActivityManager.START_DELIVERED_TO_TOP;
1800                }
1801            } else if (!addingToTask &&
1802                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1803                // In this case, we are launching an activity in our own task
1804                // that may already be running somewhere in the history, and
1805                // we want to shuffle it to the front of the stack if so.
1806                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1807                if (top != null) {
1808                    final TaskRecord task = top.task;
1809                    task.moveActivityToFrontLocked(top);
1810                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1811                    top.updateOptionsLocked(options);
1812                    top.deliverNewIntentLocked(callingUid, r.intent);
1813                    targetStack.mLastPausedActivity = null;
1814                    if (doResume) {
1815                        targetStack.resumeTopActivityLocked(null);
1816                    }
1817                    return ActivityManager.START_DELIVERED_TO_TOP;
1818                }
1819            }
1820            // An existing activity is starting this new activity, so we want
1821            // to keep the new one in the same task as the one that is starting
1822            // it.
1823            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
1824            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1825                    + " in existing task " + r.task + " from source " + sourceRecord);
1826
1827        } else {
1828            // This not being started from an existing activity, and not part
1829            // of a new task...  just put it in the top task, though these days
1830            // this case should never happen.
1831            targetStack = adjustStackFocus(r);
1832            ActivityRecord prev = targetStack.topActivity();
1833            r.setTask(prev != null ? prev.task
1834                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1835                    null, true);
1836            mWindowManager.moveTaskToTop(r.task.taskId);
1837            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1838                    + " in new guessed " + r.task);
1839        }
1840
1841        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1842                intent, r.getUriPermissionsLocked());
1843
1844        if (newTask) {
1845            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1846        }
1847        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1848        targetStack.mLastPausedActivity = null;
1849        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1850        mService.setFocusedActivityLocked(r);
1851        return ActivityManager.START_SUCCESS;
1852    }
1853
1854    void acquireLaunchWakelock() {
1855        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1856            throw new IllegalStateException("Calling must be system uid");
1857        }
1858        mLaunchingActivity.acquire();
1859        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1860            // To be safe, don't allow the wake lock to be held for too long.
1861            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1862        }
1863    }
1864
1865    // Checked.
1866    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1867            Configuration config) {
1868        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1869
1870        ArrayList<ActivityRecord> stops = null;
1871        ArrayList<ActivityRecord> finishes = null;
1872        ArrayList<UserStartedState> startingUsers = null;
1873        int NS = 0;
1874        int NF = 0;
1875        IApplicationThread sendThumbnail = null;
1876        boolean booting = false;
1877        boolean enableScreen = false;
1878        boolean activityRemoved = false;
1879
1880        ActivityRecord r = ActivityRecord.forToken(token);
1881        if (r != null) {
1882            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1883                    Debug.getCallers(4));
1884            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1885            r.finishLaunchTickingLocked();
1886            if (fromTimeout) {
1887                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1888            }
1889
1890            // This is a hack to semi-deal with a race condition
1891            // in the client where it can be constructed with a
1892            // newer configuration from when we asked it to launch.
1893            // We'll update with whatever configuration it now says
1894            // it used to launch.
1895            if (config != null) {
1896                r.configuration = config;
1897            }
1898
1899            // We are now idle.  If someone is waiting for a thumbnail from
1900            // us, we can now deliver.
1901            r.idle = true;
1902
1903            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1904                sendThumbnail = r.app.thread;
1905                r.thumbnailNeeded = false;
1906            }
1907
1908            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1909            if (!mService.mBooted && isFrontStack(r.task.stack)) {
1910                mService.mBooted = true;
1911                enableScreen = true;
1912            }
1913        }
1914
1915        if (allResumedActivitiesIdle()) {
1916            if (r != null) {
1917                mService.scheduleAppGcsLocked();
1918            }
1919
1920            if (mLaunchingActivity.isHeld()) {
1921                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1922                if (VALIDATE_WAKE_LOCK_CALLER &&
1923                        Binder.getCallingUid() != Process.myUid()) {
1924                    throw new IllegalStateException("Calling must be system uid");
1925                }
1926                mLaunchingActivity.release();
1927            }
1928            ensureActivitiesVisibleLocked(null, 0);
1929        }
1930
1931        // Atomically retrieve all of the other things to do.
1932        stops = processStoppingActivitiesLocked(true);
1933        NS = stops != null ? stops.size() : 0;
1934        if ((NF=mFinishingActivities.size()) > 0) {
1935            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1936            mFinishingActivities.clear();
1937        }
1938
1939        final ArrayList<ActivityRecord> thumbnails;
1940        final int NT = mCancelledThumbnails.size();
1941        if (NT > 0) {
1942            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1943            mCancelledThumbnails.clear();
1944        } else {
1945            thumbnails = null;
1946        }
1947
1948        if (isFrontStack(mHomeStack)) {
1949            booting = mService.mBooting;
1950            mService.mBooting = false;
1951        }
1952
1953        if (mStartingUsers.size() > 0) {
1954            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1955            mStartingUsers.clear();
1956        }
1957
1958        // Perform the following actions from unsynchronized state.
1959        final IApplicationThread thumbnailThread = sendThumbnail;
1960        mHandler.post(new Runnable() {
1961            @Override
1962            public void run() {
1963                if (thumbnailThread != null) {
1964                    try {
1965                        thumbnailThread.requestThumbnail(token);
1966                    } catch (Exception e) {
1967                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1968                        mService.sendPendingThumbnail(null, token, null, null, true);
1969                    }
1970                }
1971
1972                // Report back to any thumbnail receivers.
1973                for (int i = 0; i < NT; i++) {
1974                    ActivityRecord r = thumbnails.get(i);
1975                    mService.sendPendingThumbnail(r, null, null, null, true);
1976                }
1977            }
1978        });
1979
1980        // Stop any activities that are scheduled to do so but have been
1981        // waiting for the next one to start.
1982        for (int i = 0; i < NS; i++) {
1983            r = stops.get(i);
1984            final ActivityStack stack = r.task.stack;
1985            if (r.finishing) {
1986                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1987            } else {
1988                stack.stopActivityLocked(r);
1989            }
1990        }
1991
1992        // Finish any activities that are scheduled to do so but have been
1993        // waiting for the next one to start.
1994        for (int i = 0; i < NF; i++) {
1995            r = finishes.get(i);
1996            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1997        }
1998
1999        if (booting) {
2000            mService.finishBooting();
2001        } else if (startingUsers != null) {
2002            for (int i = 0; i < startingUsers.size(); i++) {
2003                mService.finishUserSwitch(startingUsers.get(i));
2004            }
2005        }
2006
2007        mService.trimApplications();
2008        //dump();
2009        //mWindowManager.dump();
2010
2011        if (enableScreen) {
2012            mService.enableScreenAfterBoot();
2013        }
2014
2015        if (activityRemoved) {
2016            resumeTopActivitiesLocked();
2017        }
2018
2019        return r;
2020    }
2021
2022    boolean handleAppDiedLocked(ProcessRecord app) {
2023        boolean hasVisibleActivities = false;
2024        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2025            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2026            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2027                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2028            }
2029        }
2030        return hasVisibleActivities;
2031    }
2032
2033    void closeSystemDialogsLocked() {
2034        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2035            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2036            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2037                stacks.get(stackNdx).closeSystemDialogsLocked();
2038            }
2039        }
2040    }
2041
2042    void removeUserLocked(int userId) {
2043        mUserStackInFront.delete(userId);
2044    }
2045
2046    /**
2047     * @return true if some activity was finished (or would have finished if doit were true).
2048     */
2049    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2050        boolean didSomething = false;
2051        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2052            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2053            final int numStacks = stacks.size();
2054            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2055                final ActivityStack stack = stacks.get(stackNdx);
2056                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2057                    didSomething = true;
2058                }
2059            }
2060        }
2061        return didSomething;
2062    }
2063
2064    void updatePreviousProcessLocked(ActivityRecord r) {
2065        // Now that this process has stopped, we may want to consider
2066        // it to be the previous app to try to keep around in case
2067        // the user wants to return to it.
2068
2069        // First, found out what is currently the foreground app, so that
2070        // we don't blow away the previous app if this activity is being
2071        // hosted by the process that is actually still the foreground.
2072        ProcessRecord fgApp = null;
2073        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2074            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2075            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2076                final ActivityStack stack = stacks.get(stackNdx);
2077                if (isFrontStack(stack)) {
2078                    if (stack.mResumedActivity != null) {
2079                        fgApp = stack.mResumedActivity.app;
2080                    } else if (stack.mPausingActivity != null) {
2081                        fgApp = stack.mPausingActivity.app;
2082                    }
2083                    break;
2084                }
2085            }
2086        }
2087
2088        // Now set this one as the previous process, only if that really
2089        // makes sense to.
2090        if (r.app != null && fgApp != null && r.app != fgApp
2091                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2092                && r.app != mService.mHomeProcess) {
2093            mService.mPreviousProcess = r.app;
2094            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2095        }
2096    }
2097
2098    boolean resumeTopActivitiesLocked() {
2099        return resumeTopActivitiesLocked(null, null, null);
2100    }
2101
2102    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2103            Bundle targetOptions) {
2104        if (targetStack == null) {
2105            targetStack = getFocusedStack();
2106        }
2107        // Do targetStack first.
2108        boolean result = false;
2109        if (isFrontStack(targetStack)) {
2110            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2111        }
2112        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2113            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2114            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2115                final ActivityStack stack = stacks.get(stackNdx);
2116                if (stack == targetStack) {
2117                    // Already started above.
2118                    continue;
2119                }
2120                if (isFrontStack(stack)) {
2121                    stack.resumeTopActivityLocked(null);
2122                }
2123            }
2124        }
2125        return result;
2126    }
2127
2128    void finishTopRunningActivityLocked(ProcessRecord app) {
2129        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2130            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2131            final int numStacks = stacks.size();
2132            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2133                final ActivityStack stack = stacks.get(stackNdx);
2134                stack.finishTopRunningActivityLocked(app);
2135            }
2136        }
2137    }
2138
2139    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2140        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2141            mUserLeaving = true;
2142        }
2143        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2144            // Caller wants the home activity moved with it.  To accomplish this,
2145            // we'll just indicate that this task returns to the home task.
2146            task.mOnTopOfHome = true;
2147        }
2148        task.stack.moveTaskToFrontLocked(task, null, options);
2149        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2150                + task.stack);
2151    }
2152
2153    ActivityStack getStack(int stackId) {
2154        WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2155        if (weakReference != null) {
2156            ActivityContainer activityContainer = weakReference.get();
2157            if (activityContainer != null) {
2158                return activityContainer.mStack;
2159            } else {
2160                mActivityContainers.remove(stackId);
2161            }
2162        }
2163        return null;
2164    }
2165
2166    ArrayList<ActivityStack> getStacks() {
2167        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2168        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2169            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2170        }
2171        return allStacks;
2172    }
2173
2174    IBinder getHomeActivityToken() {
2175        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2176        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2177            final TaskRecord task = tasks.get(taskNdx);
2178            if (task.isHomeTask()) {
2179                final ArrayList<ActivityRecord> activities = task.mActivities;
2180                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2181                    final ActivityRecord r = activities.get(activityNdx);
2182                    if (r.isHomeActivity()) {
2183                        return r.appToken;
2184                    }
2185                }
2186            }
2187        }
2188        return null;
2189    }
2190
2191    ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2192            IActivityContainerCallback callback) {
2193        ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2194                callback);
2195        mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
2196        if (parentActivity != null) {
2197            parentActivity.mChildContainers.add(activityContainer.mStack);
2198        }
2199        return activityContainer;
2200    }
2201
2202    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2203            IActivityContainerCallback callback) {
2204        return createActivityContainer(parentActivity, getNextStackId(), callback);
2205    }
2206
2207    void removeChildActivityContainers(ActivityRecord parentActivity) {
2208        for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2209            final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2210            if (container == null) {
2211                mActivityContainers.removeAt(ndx);
2212                continue;
2213            }
2214            if (container.mParentActivity != parentActivity) {
2215                continue;
2216            }
2217
2218            ActivityStack stack = container.mStack;
2219            ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2220            if (top != null) {
2221                // TODO: Make sure the next activity doesn't start up when top is destroyed.
2222                stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
2223            }
2224            mActivityContainers.removeAt(ndx);
2225            container.detachLocked();
2226        }
2227    }
2228
2229    void deleteActivityContainer(IActivityContainer container) {
2230        ActivityContainer activityContainer = (ActivityContainer)container;
2231        if (activityContainer != null) {
2232            activityContainer.mStack.destroyActivitiesLocked(null, true,
2233                    "deleteActivityContainer");
2234            final ActivityRecord parent = activityContainer.mParentActivity;
2235            if (parent != null) {
2236                parent.mChildContainers.remove(activityContainer);
2237            }
2238            final int stackId = activityContainer.mStackId;
2239            mActivityContainers.remove(stackId);
2240            mWindowManager.removeStack(stackId);
2241        }
2242    }
2243
2244    private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
2245        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2246        if (activityDisplay == null) {
2247            return -1;
2248        }
2249
2250        ActivityContainer activityContainer =
2251                createActivityContainer(parentActivity, stackId, null);
2252        activityContainer.attachToDisplayLocked(activityDisplay);
2253        return stackId;
2254    }
2255
2256    int getNextStackId() {
2257        while (true) {
2258            if (++mLastStackId <= HOME_STACK_ID) {
2259                mLastStackId = HOME_STACK_ID + 1;
2260            }
2261            if (getStack(mLastStackId) == null) {
2262                break;
2263            }
2264        }
2265        return mLastStackId;
2266    }
2267
2268    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2269        final TaskRecord task = anyTaskForIdLocked(taskId);
2270        if (task == null) {
2271            return;
2272        }
2273        final ActivityStack stack = getStack(stackId);
2274        if (stack == null) {
2275            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2276            return;
2277        }
2278        task.stack.removeTask(task);
2279        stack.addTask(task, toTop);
2280        mWindowManager.addTask(taskId, stackId, toTop);
2281        resumeTopActivitiesLocked();
2282    }
2283
2284    ActivityRecord findTaskLocked(ActivityRecord r) {
2285        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2286        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2287            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2288            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2289                final ActivityStack stack = stacks.get(stackNdx);
2290                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2291                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2292                    continue;
2293                }
2294                final ActivityRecord ar = stack.findTaskLocked(r);
2295                if (ar != null) {
2296                    return ar;
2297                }
2298            }
2299        }
2300        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2301        return null;
2302    }
2303
2304    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2305        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2306            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2307            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2308                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2309                if (ar != null) {
2310                    return ar;
2311                }
2312            }
2313        }
2314        return null;
2315    }
2316
2317    void goingToSleepLocked() {
2318        scheduleSleepTimeout();
2319        if (!mGoingToSleep.isHeld()) {
2320            mGoingToSleep.acquire();
2321            if (mLaunchingActivity.isHeld()) {
2322                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2323                    throw new IllegalStateException("Calling must be system uid");
2324                }
2325                mLaunchingActivity.release();
2326                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2327            }
2328        }
2329        checkReadyForSleepLocked();
2330        setLockTaskModeLocked(null);
2331    }
2332
2333    boolean shutdownLocked(int timeout) {
2334        boolean timedout = false;
2335        goingToSleepLocked();
2336
2337        final long endTime = System.currentTimeMillis() + timeout;
2338        while (true) {
2339            boolean cantShutdown = false;
2340            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2341                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2342                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2343                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2344                }
2345            }
2346            if (cantShutdown) {
2347                long timeRemaining = endTime - System.currentTimeMillis();
2348                if (timeRemaining > 0) {
2349                    try {
2350                        mService.wait(timeRemaining);
2351                    } catch (InterruptedException e) {
2352                    }
2353                } else {
2354                    Slog.w(TAG, "Activity manager shutdown timed out");
2355                    timedout = true;
2356                    break;
2357                }
2358            } else {
2359                break;
2360            }
2361        }
2362
2363        // Force checkReadyForSleep to complete.
2364        mSleepTimeout = true;
2365        checkReadyForSleepLocked();
2366
2367        return timedout;
2368    }
2369
2370    void comeOutOfSleepIfNeededLocked() {
2371        removeSleepTimeouts();
2372        if (mGoingToSleep.isHeld()) {
2373            mGoingToSleep.release();
2374        }
2375        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2376            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2377            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2378                final ActivityStack stack = stacks.get(stackNdx);
2379                stack.awakeFromSleepingLocked();
2380                if (isFrontStack(stack)) {
2381                    resumeTopActivitiesLocked();
2382                }
2383            }
2384        }
2385        mGoingToSleepActivities.clear();
2386    }
2387
2388    void activitySleptLocked(ActivityRecord r) {
2389        mGoingToSleepActivities.remove(r);
2390        checkReadyForSleepLocked();
2391    }
2392
2393    void checkReadyForSleepLocked() {
2394        if (!mService.isSleepingOrShuttingDown()) {
2395            // Do not care.
2396            return;
2397        }
2398
2399        if (!mSleepTimeout) {
2400            boolean dontSleep = false;
2401            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2402                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2403                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2404                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2405                }
2406            }
2407
2408            if (mStoppingActivities.size() > 0) {
2409                // Still need to tell some activities to stop; can't sleep yet.
2410                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2411                        + mStoppingActivities.size() + " activities");
2412                scheduleIdleLocked();
2413                dontSleep = true;
2414            }
2415
2416            if (mGoingToSleepActivities.size() > 0) {
2417                // Still need to tell some activities to sleep; can't sleep yet.
2418                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2419                        + mGoingToSleepActivities.size() + " activities");
2420                dontSleep = true;
2421            }
2422
2423            if (dontSleep) {
2424                return;
2425            }
2426        }
2427
2428        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2429            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2430            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2431                stacks.get(stackNdx).goToSleep();
2432            }
2433        }
2434
2435        removeSleepTimeouts();
2436
2437        if (mGoingToSleep.isHeld()) {
2438            mGoingToSleep.release();
2439        }
2440        if (mService.mShuttingDown) {
2441            mService.notifyAll();
2442        }
2443    }
2444
2445    boolean reportResumedActivityLocked(ActivityRecord r) {
2446        final ActivityStack stack = r.task.stack;
2447        if (isFrontStack(stack)) {
2448            mService.updateUsageStats(r, true);
2449        }
2450        if (allResumedActivitiesComplete()) {
2451            ensureActivitiesVisibleLocked(null, 0);
2452            mWindowManager.executeAppTransition();
2453            return true;
2454        }
2455        return false;
2456    }
2457
2458    void handleAppCrashLocked(ProcessRecord app) {
2459        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2460            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2461            final int numStacks = stacks.size();
2462            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2463                final ActivityStack stack = stacks.get(stackNdx);
2464                stack.handleAppCrashLocked(app);
2465            }
2466        }
2467    }
2468
2469    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2470        // First the front stacks. In case any are not fullscreen and are in front of home.
2471        boolean showHomeBehindStack = false;
2472        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2473            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2474            final int topStackNdx = stacks.size() - 1;
2475            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2476                final ActivityStack stack = stacks.get(stackNdx);
2477                if (stackNdx == topStackNdx) {
2478                    // Top stack.
2479                    showHomeBehindStack =
2480                            stack.ensureActivitiesVisibleLocked(starting, configChanges);
2481                } else {
2482                    // Back stack.
2483                    stack.ensureActivitiesVisibleLocked(starting, configChanges,
2484                            showHomeBehindStack);
2485                }
2486            }
2487        }
2488    }
2489
2490    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2491        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2492            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2493            final int numStacks = stacks.size();
2494            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2495                final ActivityStack stack = stacks.get(stackNdx);
2496                stack.scheduleDestroyActivities(app, false, reason);
2497            }
2498        }
2499    }
2500
2501    boolean switchUserLocked(int userId, UserStartedState uss) {
2502        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2503        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2504        mCurrentUser = userId;
2505
2506        mStartingUsers.add(uss);
2507        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2508            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2509            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2510                final ActivityStack stack = stacks.get(stackNdx);
2511                stack.switchUserLocked(userId);
2512                TaskRecord task = stack.topTask();
2513                if (task != null) {
2514                    mWindowManager.moveTaskToTop(task.taskId);
2515                }
2516            }
2517        }
2518
2519        ActivityStack stack = getStack(restoreStackId);
2520        if (stack == null) {
2521            stack = mHomeStack;
2522        }
2523        final boolean homeInFront = stack.isHomeStack();
2524        if (stack.isOnHomeDisplay()) {
2525            moveHomeStack(homeInFront);
2526            TaskRecord task = stack.topTask();
2527            if (task != null) {
2528                mWindowManager.moveTaskToTop(task.taskId);
2529            }
2530        } else {
2531            // Stack was moved to another display while user was swapped out.
2532            resumeHomeActivity(null);
2533        }
2534        return homeInFront;
2535    }
2536
2537    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2538        int N = mStoppingActivities.size();
2539        if (N <= 0) return null;
2540
2541        ArrayList<ActivityRecord> stops = null;
2542
2543        final boolean nowVisible = allResumedActivitiesVisible();
2544        for (int i=0; i<N; i++) {
2545            ActivityRecord s = mStoppingActivities.get(i);
2546            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2547                    + nowVisible + " waitingVisible=" + s.waitingVisible
2548                    + " finishing=" + s.finishing);
2549            if (s.waitingVisible && nowVisible) {
2550                mWaitingVisibleActivities.remove(s);
2551                s.waitingVisible = false;
2552                if (s.finishing) {
2553                    // If this activity is finishing, it is sitting on top of
2554                    // everyone else but we now know it is no longer needed...
2555                    // so get rid of it.  Otherwise, we need to go through the
2556                    // normal flow and hide it once we determine that it is
2557                    // hidden by the activities in front of it.
2558                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2559                    mWindowManager.setAppVisibility(s.appToken, false);
2560                }
2561            }
2562            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2563                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2564                if (stops == null) {
2565                    stops = new ArrayList<ActivityRecord>();
2566                }
2567                stops.add(s);
2568                mStoppingActivities.remove(i);
2569                N--;
2570                i--;
2571            }
2572        }
2573
2574        return stops;
2575    }
2576
2577    void validateTopActivitiesLocked() {
2578        // FIXME
2579/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2580            final ActivityStack stack = stacks.get(stackNdx);
2581            final ActivityRecord r = stack.topRunningActivityLocked(null);
2582            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2583            if (isFrontStack(stack)) {
2584                if (r == null) {
2585                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2586                } else {
2587                    final ActivityRecord pausing = stack.mPausingActivity;
2588                    if (pausing != null && pausing == r) {
2589                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2590                            " state=" + state);
2591                    }
2592                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2593                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2594                                " state=" + state);
2595                    }
2596                }
2597            } else {
2598                final ActivityRecord resumed = stack.mResumedActivity;
2599                if (resumed != null && resumed == r) {
2600                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2601                        " state=" + state);
2602                }
2603                if (r != null && (state == ActivityState.INITIALIZING
2604                        || state == ActivityState.RESUMED)) {
2605                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2606                            " state=" + state);
2607                }
2608            }
2609        }
2610*/
2611    }
2612
2613    public void dump(PrintWriter pw, String prefix) {
2614        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2615                pw.println(mDismissKeyguardOnNextActivity);
2616        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2617                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2618        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2619        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2620        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2621        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2622    }
2623
2624    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2625        return getFocusedStack().getDumpActivitiesLocked(name);
2626    }
2627
2628    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2629            boolean needSep, String prefix) {
2630        if (activity != null) {
2631            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2632                if (needSep) {
2633                    pw.println();
2634                }
2635                pw.print(prefix);
2636                pw.println(activity);
2637                return true;
2638            }
2639        }
2640        return false;
2641    }
2642
2643    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2644            boolean dumpClient, String dumpPackage) {
2645        boolean printed = false;
2646        boolean needSep = false;
2647        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2648            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2649            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2650            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2651            final int numStacks = stacks.size();
2652            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2653                final ActivityStack stack = stacks.get(stackNdx);
2654                StringBuilder stackHeader = new StringBuilder(128);
2655                stackHeader.append("  Stack #");
2656                stackHeader.append(stack.mStackId);
2657                stackHeader.append(":");
2658                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2659                        needSep, stackHeader.toString());
2660                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2661                        !dumpAll, false, dumpPackage, true,
2662                        "    Running activities (most recent first):", null);
2663
2664                needSep = printed;
2665                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2666                        "    mPausingActivity: ");
2667                if (pr) {
2668                    printed = true;
2669                    needSep = false;
2670                }
2671                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2672                        "    mResumedActivity: ");
2673                if (pr) {
2674                    printed = true;
2675                    needSep = false;
2676                }
2677                if (dumpAll) {
2678                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2679                            "    mLastPausedActivity: ");
2680                    if (pr) {
2681                        printed = true;
2682                        needSep = true;
2683                    }
2684                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2685                            needSep, "    mLastNoHistoryActivity: ");
2686                }
2687                needSep = printed;
2688            }
2689        }
2690
2691        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2692                false, dumpPackage, true, "  Activities waiting to finish:", null);
2693        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2694                false, dumpPackage, true, "  Activities waiting to stop:", null);
2695        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2696                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2697                null);
2698        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2699                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2700        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2701                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2702
2703        return printed;
2704    }
2705
2706    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2707            String prefix, String label, boolean complete, boolean brief, boolean client,
2708            String dumpPackage, boolean needNL, String header1, String header2) {
2709        TaskRecord lastTask = null;
2710        String innerPrefix = null;
2711        String[] args = null;
2712        boolean printed = false;
2713        for (int i=list.size()-1; i>=0; i--) {
2714            final ActivityRecord r = list.get(i);
2715            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2716                continue;
2717            }
2718            if (innerPrefix == null) {
2719                innerPrefix = prefix + "      ";
2720                args = new String[0];
2721            }
2722            printed = true;
2723            final boolean full = !brief && (complete || !r.isInHistory());
2724            if (needNL) {
2725                pw.println("");
2726                needNL = false;
2727            }
2728            if (header1 != null) {
2729                pw.println(header1);
2730                header1 = null;
2731            }
2732            if (header2 != null) {
2733                pw.println(header2);
2734                header2 = null;
2735            }
2736            if (lastTask != r.task) {
2737                lastTask = r.task;
2738                pw.print(prefix);
2739                pw.print(full ? "* " : "  ");
2740                pw.println(lastTask);
2741                if (full) {
2742                    lastTask.dump(pw, prefix + "  ");
2743                } else if (complete) {
2744                    // Complete + brief == give a summary.  Isn't that obvious?!?
2745                    if (lastTask.intent != null) {
2746                        pw.print(prefix); pw.print("  ");
2747                                pw.println(lastTask.intent.toInsecureStringWithClip());
2748                    }
2749                }
2750            }
2751            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2752            pw.print(" #"); pw.print(i); pw.print(": ");
2753            pw.println(r);
2754            if (full) {
2755                r.dump(pw, innerPrefix);
2756            } else if (complete) {
2757                // Complete + brief == give a summary.  Isn't that obvious?!?
2758                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2759                if (r.app != null) {
2760                    pw.print(innerPrefix); pw.println(r.app);
2761                }
2762            }
2763            if (client && r.app != null && r.app.thread != null) {
2764                // flush anything that is already in the PrintWriter since the thread is going
2765                // to write to the file descriptor directly
2766                pw.flush();
2767                try {
2768                    TransferPipe tp = new TransferPipe();
2769                    try {
2770                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2771                                r.appToken, innerPrefix, args);
2772                        // Short timeout, since blocking here can
2773                        // deadlock with the application.
2774                        tp.go(fd, 2000);
2775                    } finally {
2776                        tp.kill();
2777                    }
2778                } catch (IOException e) {
2779                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2780                } catch (RemoteException e) {
2781                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2782                }
2783                needNL = true;
2784            }
2785        }
2786        return printed;
2787    }
2788
2789    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2790        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2791        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2792        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2793    }
2794
2795    final void scheduleIdleLocked() {
2796        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2797    }
2798
2799    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2800        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2801        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2802    }
2803
2804    final void scheduleResumeTopActivities() {
2805        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2806            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2807        }
2808    }
2809
2810    void removeSleepTimeouts() {
2811        mSleepTimeout = false;
2812        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2813    }
2814
2815    final void scheduleSleepTimeout() {
2816        removeSleepTimeouts();
2817        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2818    }
2819
2820    @Override
2821    public void onDisplayAdded(int displayId) {
2822        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2823    }
2824
2825    @Override
2826    public void onDisplayRemoved(int displayId) {
2827        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2828    }
2829
2830    @Override
2831    public void onDisplayChanged(int displayId) {
2832        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2833    }
2834
2835    public void handleDisplayAddedLocked(int displayId) {
2836        boolean newDisplay;
2837        synchronized (mService) {
2838            newDisplay = mActivityDisplays.get(displayId) == null;
2839            if (newDisplay) {
2840                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2841                mActivityDisplays.put(displayId, activityDisplay);
2842            }
2843        }
2844        if (newDisplay) {
2845            mWindowManager.onDisplayAdded(displayId);
2846        }
2847    }
2848
2849    public void handleDisplayRemovedLocked(int displayId) {
2850        synchronized (mService) {
2851            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2852            if (activityDisplay != null) {
2853                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2854                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2855                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2856                }
2857                mActivityDisplays.remove(displayId);
2858            }
2859        }
2860        mWindowManager.onDisplayRemoved(displayId);
2861    }
2862
2863    public void handleDisplayChangedLocked(int displayId) {
2864        synchronized (mService) {
2865            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2866            if (activityDisplay != null) {
2867                // TODO: Update the bounds.
2868            }
2869        }
2870        mWindowManager.onDisplayChanged(displayId);
2871    }
2872
2873    StackInfo getStackInfo(ActivityStack stack) {
2874        StackInfo info = new StackInfo();
2875        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2876        info.displayId = Display.DEFAULT_DISPLAY;
2877        info.stackId = stack.mStackId;
2878
2879        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2880        final int numTasks = tasks.size();
2881        int[] taskIds = new int[numTasks];
2882        String[] taskNames = new String[numTasks];
2883        for (int i = 0; i < numTasks; ++i) {
2884            final TaskRecord task = tasks.get(i);
2885            taskIds[i] = task.taskId;
2886            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2887                    : task.realActivity != null ? task.realActivity.flattenToString()
2888                    : task.getTopActivity() != null ? task.getTopActivity().packageName
2889                    : "unknown";
2890        }
2891        info.taskIds = taskIds;
2892        info.taskNames = taskNames;
2893        return info;
2894    }
2895
2896    StackInfo getStackInfoLocked(int stackId) {
2897        ActivityStack stack = getStack(stackId);
2898        if (stack != null) {
2899            return getStackInfo(stack);
2900        }
2901        return null;
2902    }
2903
2904    ArrayList<StackInfo> getAllStackInfosLocked() {
2905        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2906        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2907            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2908            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2909                list.add(getStackInfo(stacks.get(ndx)));
2910            }
2911        }
2912        return list;
2913    }
2914
2915    void setLockTaskModeLocked(TaskRecord task) {
2916        if (task == null) {
2917            // Take out of lock task mode.
2918            mLockTaskModeTask = null;
2919            return;
2920        }
2921        if (isLockTaskModeViolation(task)) {
2922            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2923            return;
2924        }
2925        mLockTaskModeTask = task;
2926        findTaskToMoveToFrontLocked(task, 0, null);
2927        resumeTopActivitiesLocked();
2928    }
2929
2930    boolean isLockTaskModeViolation(TaskRecord task) {
2931        return mLockTaskModeTask != null && mLockTaskModeTask != task;
2932    }
2933
2934    void endLockTaskModeIfTaskEnding(TaskRecord task) {
2935        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
2936            mLockTaskModeTask = null;
2937        }
2938    }
2939
2940    boolean isInLockTaskMode() {
2941        return mLockTaskModeTask != null;
2942    }
2943
2944    private final class ActivityStackSupervisorHandler extends Handler {
2945
2946        public ActivityStackSupervisorHandler(Looper looper) {
2947            super(looper);
2948        }
2949
2950        void activityIdleInternal(ActivityRecord r) {
2951            synchronized (mService) {
2952                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2953            }
2954        }
2955
2956        @Override
2957        public void handleMessage(Message msg) {
2958            switch (msg.what) {
2959                case IDLE_TIMEOUT_MSG: {
2960                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2961                    if (mService.mDidDexOpt) {
2962                        mService.mDidDexOpt = false;
2963                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2964                        nmsg.obj = msg.obj;
2965                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2966                        return;
2967                    }
2968                    // We don't at this point know if the activity is fullscreen,
2969                    // so we need to be conservative and assume it isn't.
2970                    activityIdleInternal((ActivityRecord)msg.obj);
2971                } break;
2972                case IDLE_NOW_MSG: {
2973                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2974                    activityIdleInternal((ActivityRecord)msg.obj);
2975                } break;
2976                case RESUME_TOP_ACTIVITY_MSG: {
2977                    synchronized (mService) {
2978                        resumeTopActivitiesLocked();
2979                    }
2980                } break;
2981                case SLEEP_TIMEOUT_MSG: {
2982                    synchronized (mService) {
2983                        if (mService.isSleepingOrShuttingDown()) {
2984                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2985                            mSleepTimeout = true;
2986                            checkReadyForSleepLocked();
2987                        }
2988                    }
2989                } break;
2990                case LAUNCH_TIMEOUT_MSG: {
2991                    if (mService.mDidDexOpt) {
2992                        mService.mDidDexOpt = false;
2993                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2994                        return;
2995                    }
2996                    synchronized (mService) {
2997                        if (mLaunchingActivity.isHeld()) {
2998                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2999                            if (VALIDATE_WAKE_LOCK_CALLER
3000                                    && Binder.getCallingUid() != Process.myUid()) {
3001                                throw new IllegalStateException("Calling must be system uid");
3002                            }
3003                            mLaunchingActivity.release();
3004                        }
3005                    }
3006                } break;
3007                case HANDLE_DISPLAY_ADDED: {
3008                    handleDisplayAddedLocked(msg.arg1);
3009                } break;
3010                case HANDLE_DISPLAY_CHANGED: {
3011                    handleDisplayChangedLocked(msg.arg1);
3012                } break;
3013                case HANDLE_DISPLAY_REMOVED: {
3014                    handleDisplayRemovedLocked(msg.arg1);
3015                } break;
3016            }
3017        }
3018    }
3019
3020    class ActivityContainer extends IActivityContainer.Stub {
3021        final int mStackId;
3022        final IActivityContainerCallback mCallback;
3023        final ActivityStack mStack;
3024        final ActivityRecord mParentActivity;
3025        final String mIdString;
3026
3027        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
3028        ActivityDisplay mActivityDisplay;
3029
3030        ActivityContainer(ActivityRecord parentActivity, int stackId,
3031                IActivityContainerCallback callback) {
3032            synchronized (mService) {
3033                mStackId = stackId;
3034                mStack = new ActivityStack(this);
3035                mParentActivity = parentActivity;
3036                mCallback = callback;
3037                mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3038                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
3039            }
3040        }
3041
3042        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
3043            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3044                    + " to display=" + activityDisplay);
3045            mActivityDisplay = activityDisplay;
3046            mStack.mDisplayId = activityDisplay.mDisplayId;
3047            mStack.mStacks = activityDisplay.mStacks;
3048
3049            activityDisplay.attachActivities(mStack);
3050            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3051        }
3052
3053        @Override
3054        public void attachToDisplay(int displayId) {
3055            synchronized (mService) {
3056                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3057                if (activityDisplay == null) {
3058                    return;
3059                }
3060                attachToDisplayLocked(activityDisplay);
3061            }
3062        }
3063
3064        @Override
3065        public int getDisplayId() {
3066            if (mActivityDisplay != null) {
3067                return mActivityDisplay.mDisplayId;
3068            }
3069            return -1;
3070        }
3071
3072        @Override
3073        public boolean injectEvent(InputEvent event) {
3074            final long origId = Binder.clearCallingIdentity();
3075            try {
3076                if (mActivityDisplay != null) {
3077                    return mInputManagerInternal.injectInputEvent(event,
3078                            mActivityDisplay.mDisplayId,
3079                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3080                }
3081                return false;
3082            } finally {
3083                Binder.restoreCallingIdentity(origId);
3084            }
3085        }
3086
3087        private void detachLocked() {
3088            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3089                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3090            if (mActivityDisplay != null) {
3091                mActivityDisplay.detachActivitiesLocked(mStack);
3092                mActivityDisplay = null;
3093                mStack.mDisplayId = -1;
3094                mStack.mStacks = null;
3095                mWindowManager.detachStack(mStackId);
3096            }
3097        }
3098
3099        @Override
3100        public void detachFromDisplay() {
3101            synchronized (mService) {
3102                detachLocked();
3103            }
3104        }
3105
3106        @Override
3107        public final int startActivity(Intent intent) {
3108            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3109            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3110                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3111            // TODO: Switch to user app stacks here.
3112            String mimeType = intent.getType();
3113            if (mimeType == null && intent.getData() != null
3114                    && "content".equals(intent.getData().getScheme())) {
3115                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3116            }
3117            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3118                    null, null, null, null, userId, this);
3119        }
3120
3121        @Override
3122        public final int startActivityIntentSender(IIntentSender intentSender) {
3123            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3124
3125            if (!(intentSender instanceof PendingIntentRecord)) {
3126                throw new IllegalArgumentException("Bad PendingIntent object");
3127            }
3128
3129            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3130                    null, 0, 0, 0, null, this);
3131        }
3132
3133        @Override
3134        public IBinder asBinder() {
3135            return this;
3136        }
3137
3138        @Override
3139        public void attachToSurface(Surface surface, int width, int height, int density) {
3140            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3141
3142            final long origId = Binder.clearCallingIdentity();
3143            try {
3144                synchronized (mService) {
3145                    ActivityDisplay activityDisplay =
3146                            new ActivityDisplay(surface, width, height, density);
3147                    mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3148                    attachToDisplayLocked(activityDisplay);
3149                    mStack.resumeTopActivityLocked(null);
3150                }
3151                if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3152                        + mActivityDisplay);
3153            } finally {
3154                Binder.restoreCallingIdentity(origId);
3155            }
3156        }
3157
3158        ActivityStackSupervisor getOuter() {
3159            return ActivityStackSupervisor.this;
3160        }
3161
3162        boolean isAttached() {
3163            return mActivityDisplay != null;
3164        }
3165
3166        void getBounds(Point outBounds) {
3167            if (mActivityDisplay != null) {
3168                mActivityDisplay.getBounds(outBounds);
3169            } else {
3170                outBounds.set(0, 0);
3171            }
3172        }
3173
3174        @Override
3175        public String toString() {
3176            return mIdString + (mActivityDisplay == null ? "N" : "A");
3177        }
3178    }
3179
3180    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3181     * attached {@link ActivityStack}s */
3182    final class ActivityDisplay {
3183        /** Actual Display this object tracks. */
3184        int mDisplayId;
3185        Display mDisplay;
3186        DisplayInfo mDisplayInfo = new DisplayInfo();
3187        Surface mSurface;
3188
3189        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3190         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3191        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3192
3193        /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3194         * here. */
3195        VirtualDisplay mVirtualDisplay;
3196
3197        ActivityDisplay(int displayId) {
3198            init(mDisplayManager.getDisplay(displayId));
3199        }
3200
3201        ActivityDisplay(Surface surface, int width, int height, int density) {
3202            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3203            long ident = Binder.clearCallingIdentity();
3204            try {
3205                mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3206                        VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3207                        DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3208                        DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3209            } finally {
3210                Binder.restoreCallingIdentity(ident);
3211            }
3212
3213            init(mVirtualDisplay.getDisplay());
3214            mSurface = surface;
3215
3216            mWindowManager.handleDisplayAdded(mDisplayId);
3217        }
3218
3219        private void init(Display display) {
3220            mDisplay = display;
3221            mDisplayId = display.getDisplayId();
3222            mDisplay.getDisplayInfo(mDisplayInfo);
3223        }
3224
3225        void attachActivities(ActivityStack stack) {
3226            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3227                    + mDisplayId);
3228            mStacks.add(stack);
3229        }
3230
3231        void detachActivitiesLocked(ActivityStack stack) {
3232            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3233                    + " from displayId=" + mDisplayId);
3234            mStacks.remove(stack);
3235            if (mStacks.isEmpty() && mVirtualDisplay != null) {
3236                mVirtualDisplay.release();
3237                mVirtualDisplay = null;
3238            }
3239            mSurface.release();
3240        }
3241
3242        void getBounds(Point bounds) {
3243            mDisplay.getDisplayInfo(mDisplayInfo);
3244            bounds.x = mDisplayInfo.appWidth;
3245            bounds.y = mDisplayInfo.appHeight;
3246        }
3247
3248        @Override
3249        public String toString() {
3250            return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3251                    + " numStacks=" + mStacks.size() + "}";
3252        }
3253    }
3254}
3255