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