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