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