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