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