ActivityStackSupervisor.java revision 14bff9f55eccaf279419cb529711039e13e1e1d7
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        booting = mService.mBooting;
1928        mService.mBooting = false;
1929
1930        if (mStartingUsers.size() > 0) {
1931            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1932            mStartingUsers.clear();
1933        }
1934
1935        // Perform the following actions from unsynchronized state.
1936        final IApplicationThread thumbnailThread = sendThumbnail;
1937        mHandler.post(new Runnable() {
1938            @Override
1939            public void run() {
1940                if (thumbnailThread != null) {
1941                    try {
1942                        thumbnailThread.requestThumbnail(token);
1943                    } catch (Exception e) {
1944                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1945                        mService.sendPendingThumbnail(null, token, null, null, true);
1946                    }
1947                }
1948
1949                // Report back to any thumbnail receivers.
1950                for (int i = 0; i < NT; i++) {
1951                    ActivityRecord r = thumbnails.get(i);
1952                    mService.sendPendingThumbnail(r, null, null, null, true);
1953                }
1954            }
1955        });
1956
1957        // Stop any activities that are scheduled to do so but have been
1958        // waiting for the next one to start.
1959        for (int i = 0; i < NS; i++) {
1960            r = stops.get(i);
1961            final ActivityStack stack = r.task.stack;
1962            if (r.finishing) {
1963                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1964            } else {
1965                stack.stopActivityLocked(r);
1966            }
1967        }
1968
1969        // Finish any activities that are scheduled to do so but have been
1970        // waiting for the next one to start.
1971        for (int i = 0; i < NF; i++) {
1972            r = finishes.get(i);
1973            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1974        }
1975
1976        if (booting) {
1977            mService.finishBooting();
1978        } else if (startingUsers != null) {
1979            for (int i = 0; i < startingUsers.size(); i++) {
1980                mService.finishUserSwitch(startingUsers.get(i));
1981            }
1982        }
1983
1984        mService.trimApplications();
1985        //dump();
1986        //mWindowManager.dump();
1987
1988        if (enableScreen) {
1989            mService.enableScreenAfterBoot();
1990        }
1991
1992        if (activityRemoved) {
1993            resumeTopActivitiesLocked();
1994        }
1995
1996        return r;
1997    }
1998
1999    boolean handleAppDiedLocked(ProcessRecord app) {
2000        boolean hasVisibleActivities = false;
2001        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2002            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2003            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2004                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2005            }
2006        }
2007        return hasVisibleActivities;
2008    }
2009
2010    void closeSystemDialogsLocked() {
2011        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2012            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2013            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2014                stacks.get(stackNdx).closeSystemDialogsLocked();
2015            }
2016        }
2017    }
2018
2019    void removeUserLocked(int userId) {
2020        mUserStackInFront.delete(userId);
2021    }
2022
2023    /**
2024     * @return true if some activity was finished (or would have finished if doit were true).
2025     */
2026    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2027        boolean didSomething = false;
2028        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2029            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2030            final int numStacks = stacks.size();
2031            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2032                final ActivityStack stack = stacks.get(stackNdx);
2033                if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2034                    didSomething = true;
2035                }
2036            }
2037        }
2038        return didSomething;
2039    }
2040
2041    void updatePreviousProcessLocked(ActivityRecord r) {
2042        // Now that this process has stopped, we may want to consider
2043        // it to be the previous app to try to keep around in case
2044        // the user wants to return to it.
2045
2046        // First, found out what is currently the foreground app, so that
2047        // we don't blow away the previous app if this activity is being
2048        // hosted by the process that is actually still the foreground.
2049        ProcessRecord fgApp = null;
2050        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2051            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2052            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2053                final ActivityStack stack = stacks.get(stackNdx);
2054                if (isFrontStack(stack)) {
2055                    if (stack.mResumedActivity != null) {
2056                        fgApp = stack.mResumedActivity.app;
2057                    } else if (stack.mPausingActivity != null) {
2058                        fgApp = stack.mPausingActivity.app;
2059                    }
2060                    break;
2061                }
2062            }
2063        }
2064
2065        // Now set this one as the previous process, only if that really
2066        // makes sense to.
2067        if (r.app != null && fgApp != null && r.app != fgApp
2068                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2069                && r.app != mService.mHomeProcess) {
2070            mService.mPreviousProcess = r.app;
2071            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2072        }
2073    }
2074
2075    boolean resumeTopActivitiesLocked() {
2076        return resumeTopActivitiesLocked(null, null, null);
2077    }
2078
2079    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2080            Bundle targetOptions) {
2081        if (targetStack == null) {
2082            targetStack = getFocusedStack();
2083        }
2084        // Do targetStack first.
2085        boolean result = false;
2086        if (isFrontStack(targetStack)) {
2087            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2088        }
2089        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2090            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2091            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2092                final ActivityStack stack = stacks.get(stackNdx);
2093                if (stack == targetStack) {
2094                    // Already started above.
2095                    continue;
2096                }
2097                if (isFrontStack(stack)) {
2098                    stack.resumeTopActivityLocked(null);
2099                }
2100            }
2101        }
2102        return result;
2103    }
2104
2105    void finishTopRunningActivityLocked(ProcessRecord app) {
2106        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2107            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2108            final int numStacks = stacks.size();
2109            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2110                final ActivityStack stack = stacks.get(stackNdx);
2111                stack.finishTopRunningActivityLocked(app);
2112            }
2113        }
2114    }
2115
2116    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2117        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2118            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2119            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2120                if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2121                    if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2122                            + stacks.get(stackNdx));
2123                    return;
2124                }
2125            }
2126        }
2127    }
2128
2129    ActivityStack getStack(int stackId) {
2130        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2131        if (activityContainer != null) {
2132            return activityContainer.mStack;
2133        }
2134        return null;
2135    }
2136
2137    ArrayList<ActivityStack> getStacks() {
2138        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2139        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2140            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2141        }
2142        return allStacks;
2143    }
2144
2145    IBinder getHomeActivityToken() {
2146        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2147        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2148            final TaskRecord task = tasks.get(taskNdx);
2149            if (task.isHomeTask()) {
2150                final ArrayList<ActivityRecord> activities = task.mActivities;
2151                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2152                    final ActivityRecord r = activities.get(activityNdx);
2153                    if (r.isHomeActivity()) {
2154                        return r.appToken;
2155                    }
2156                }
2157            }
2158        }
2159        return null;
2160    }
2161
2162    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2163            IActivityContainerCallback callback) {
2164        ActivityContainer activityContainer =
2165                new VirtualActivityContainer(parentActivity, callback);
2166        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2167        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
2168        parentActivity.mChildContainers.add(activityContainer);
2169        return activityContainer;
2170    }
2171
2172    void removeChildActivityContainers(ActivityRecord parentActivity) {
2173        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2174        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2175            ActivityContainer container = childStacks.remove(containerNdx);
2176            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
2177                    container);
2178            container.release();
2179        }
2180    }
2181
2182    void deleteActivityContainer(IActivityContainer container) {
2183        ActivityContainer activityContainer = (ActivityContainer)container;
2184        if (activityContainer != null) {
2185            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
2186                    new RuntimeException("here").fillInStackTrace());
2187            final int stackId = activityContainer.mStackId;
2188            mActivityContainers.remove(stackId);
2189            mWindowManager.removeStack(stackId);
2190        }
2191    }
2192
2193    private int createStackOnDisplay(int stackId, int displayId) {
2194        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2195        if (activityDisplay == null) {
2196            return -1;
2197        }
2198
2199        ActivityContainer activityContainer = new ActivityContainer(stackId);
2200        mActivityContainers.put(stackId, activityContainer);
2201        activityContainer.attachToDisplayLocked(activityDisplay);
2202        return stackId;
2203    }
2204
2205    int getNextStackId() {
2206        while (true) {
2207            if (++mLastStackId <= HOME_STACK_ID) {
2208                mLastStackId = HOME_STACK_ID + 1;
2209            }
2210            if (getStack(mLastStackId) == null) {
2211                break;
2212            }
2213        }
2214        return mLastStackId;
2215    }
2216
2217    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2218        final TaskRecord task = anyTaskForIdLocked(taskId);
2219        if (task == null) {
2220            return;
2221        }
2222        final ActivityStack stack = getStack(stackId);
2223        if (stack == null) {
2224            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2225            return;
2226        }
2227        task.stack.removeTask(task);
2228        stack.addTask(task, toTop);
2229        mWindowManager.addTask(taskId, stackId, toTop);
2230        resumeTopActivitiesLocked();
2231    }
2232
2233    ActivityRecord findTaskLocked(ActivityRecord r) {
2234        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2235        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2236            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2237            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2238                final ActivityStack stack = stacks.get(stackNdx);
2239                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2240                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2241                    continue;
2242                }
2243                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2244                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2245                            stack);
2246                    continue;
2247                }
2248                final ActivityRecord ar = stack.findTaskLocked(r);
2249                if (ar != null) {
2250                    return ar;
2251                }
2252            }
2253        }
2254        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2255        return null;
2256    }
2257
2258    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2259        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2260            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2261            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2262                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2263                if (ar != null) {
2264                    return ar;
2265                }
2266            }
2267        }
2268        return null;
2269    }
2270
2271    void goingToSleepLocked() {
2272        scheduleSleepTimeout();
2273        if (!mGoingToSleep.isHeld()) {
2274            mGoingToSleep.acquire();
2275            if (mLaunchingActivity.isHeld()) {
2276                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2277                    throw new IllegalStateException("Calling must be system uid");
2278                }
2279                mLaunchingActivity.release();
2280                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2281            }
2282        }
2283        checkReadyForSleepLocked();
2284    }
2285
2286    boolean shutdownLocked(int timeout) {
2287        goingToSleepLocked();
2288
2289        boolean timedout = false;
2290        final long endTime = System.currentTimeMillis() + timeout;
2291        while (true) {
2292            boolean cantShutdown = false;
2293            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2294                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2295                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2296                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2297                }
2298            }
2299            if (cantShutdown) {
2300                long timeRemaining = endTime - System.currentTimeMillis();
2301                if (timeRemaining > 0) {
2302                    try {
2303                        mService.wait(timeRemaining);
2304                    } catch (InterruptedException e) {
2305                    }
2306                } else {
2307                    Slog.w(TAG, "Activity manager shutdown timed out");
2308                    timedout = true;
2309                    break;
2310                }
2311            } else {
2312                break;
2313            }
2314        }
2315
2316        // Force checkReadyForSleep to complete.
2317        mSleepTimeout = true;
2318        checkReadyForSleepLocked();
2319
2320        return timedout;
2321    }
2322
2323    void comeOutOfSleepIfNeededLocked() {
2324        removeSleepTimeouts();
2325        if (mGoingToSleep.isHeld()) {
2326            mGoingToSleep.release();
2327        }
2328        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2329            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2330            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2331                final ActivityStack stack = stacks.get(stackNdx);
2332                stack.awakeFromSleepingLocked();
2333                if (isFrontStack(stack)) {
2334                    resumeTopActivitiesLocked();
2335                }
2336            }
2337        }
2338        mGoingToSleepActivities.clear();
2339    }
2340
2341    void activitySleptLocked(ActivityRecord r) {
2342        mGoingToSleepActivities.remove(r);
2343        checkReadyForSleepLocked();
2344    }
2345
2346    void checkReadyForSleepLocked() {
2347        if (!mService.isSleepingOrShuttingDown()) {
2348            // Do not care.
2349            return;
2350        }
2351
2352        if (!mSleepTimeout) {
2353            boolean dontSleep = false;
2354            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2355                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2356                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2357                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2358                }
2359            }
2360
2361            if (mStoppingActivities.size() > 0) {
2362                // Still need to tell some activities to stop; can't sleep yet.
2363                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2364                        + mStoppingActivities.size() + " activities");
2365                scheduleIdleLocked();
2366                dontSleep = true;
2367            }
2368
2369            if (mGoingToSleepActivities.size() > 0) {
2370                // Still need to tell some activities to sleep; can't sleep yet.
2371                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2372                        + mGoingToSleepActivities.size() + " activities");
2373                dontSleep = true;
2374            }
2375
2376            if (dontSleep) {
2377                return;
2378            }
2379        }
2380
2381        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2382            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2383            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2384                stacks.get(stackNdx).goToSleep();
2385            }
2386        }
2387
2388        removeSleepTimeouts();
2389
2390        if (mGoingToSleep.isHeld()) {
2391            mGoingToSleep.release();
2392        }
2393        if (mService.mShuttingDown) {
2394            mService.notifyAll();
2395        }
2396    }
2397
2398    boolean reportResumedActivityLocked(ActivityRecord r) {
2399        final ActivityStack stack = r.task.stack;
2400        if (isFrontStack(stack)) {
2401            mService.updateUsageStats(r, true);
2402        }
2403        if (allResumedActivitiesComplete()) {
2404            ensureActivitiesVisibleLocked(null, 0);
2405            mWindowManager.executeAppTransition();
2406            return true;
2407        }
2408        return false;
2409    }
2410
2411    void handleAppCrashLocked(ProcessRecord app) {
2412        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2413            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2414            final int numStacks = stacks.size();
2415            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2416                final ActivityStack stack = stacks.get(stackNdx);
2417                stack.handleAppCrashLocked(app);
2418            }
2419        }
2420    }
2421
2422    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2423        // First the front stacks. In case any are not fullscreen and are in front of home.
2424        boolean showHomeBehindStack = false;
2425        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2426            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2427            final int topStackNdx = stacks.size() - 1;
2428            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2429                final ActivityStack stack = stacks.get(stackNdx);
2430                if (stackNdx == topStackNdx) {
2431                    // Top stack.
2432                    showHomeBehindStack =
2433                            stack.ensureActivitiesVisibleLocked(starting, configChanges);
2434                } else {
2435                    // Back stack.
2436                    stack.ensureActivitiesVisibleLocked(starting, configChanges,
2437                            showHomeBehindStack);
2438                }
2439            }
2440        }
2441    }
2442
2443    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2444        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2445            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2446            final int numStacks = stacks.size();
2447            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2448                final ActivityStack stack = stacks.get(stackNdx);
2449                stack.scheduleDestroyActivities(app, false, reason);
2450            }
2451        }
2452    }
2453
2454    boolean switchUserLocked(int userId, UserStartedState uss) {
2455        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2456        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2457        mCurrentUser = userId;
2458
2459        mStartingUsers.add(uss);
2460        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2461            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2462            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2463                final ActivityStack stack = stacks.get(stackNdx);
2464                stack.switchUserLocked(userId);
2465                mWindowManager.moveTaskToTop(stack.topTask().taskId);
2466            }
2467        }
2468
2469        ActivityStack stack = getStack(restoreStackId);
2470        if (stack == null) {
2471            stack = mHomeStack;
2472        }
2473        final boolean homeInFront = stack.isHomeStack();
2474        if (stack.isOnHomeDisplay()) {
2475            moveHomeStack(homeInFront);
2476            mWindowManager.moveTaskToTop(stack.topTask().taskId);
2477        } else {
2478            // Stack was moved to another display while user was swapped out.
2479            resumeHomeActivity(null);
2480        }
2481        return homeInFront;
2482    }
2483
2484    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2485        int N = mStoppingActivities.size();
2486        if (N <= 0) return null;
2487
2488        ArrayList<ActivityRecord> stops = null;
2489
2490        final boolean nowVisible = allResumedActivitiesVisible();
2491        for (int i=0; i<N; i++) {
2492            ActivityRecord s = mStoppingActivities.get(i);
2493            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2494                    + nowVisible + " waitingVisible=" + s.waitingVisible
2495                    + " finishing=" + s.finishing);
2496            if (s.waitingVisible && nowVisible) {
2497                mWaitingVisibleActivities.remove(s);
2498                s.waitingVisible = false;
2499                if (s.finishing) {
2500                    // If this activity is finishing, it is sitting on top of
2501                    // everyone else but we now know it is no longer needed...
2502                    // so get rid of it.  Otherwise, we need to go through the
2503                    // normal flow and hide it once we determine that it is
2504                    // hidden by the activities in front of it.
2505                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2506                    mWindowManager.setAppVisibility(s.appToken, false);
2507                }
2508            }
2509            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2510                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2511                if (stops == null) {
2512                    stops = new ArrayList<ActivityRecord>();
2513                }
2514                stops.add(s);
2515                mStoppingActivities.remove(i);
2516                N--;
2517                i--;
2518            }
2519        }
2520
2521        return stops;
2522    }
2523
2524    void validateTopActivitiesLocked() {
2525        // FIXME
2526/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2527            final ActivityStack stack = stacks.get(stackNdx);
2528            final ActivityRecord r = stack.topRunningActivityLocked(null);
2529            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2530            if (isFrontStack(stack)) {
2531                if (r == null) {
2532                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2533                } else {
2534                    final ActivityRecord pausing = stack.mPausingActivity;
2535                    if (pausing != null && pausing == r) {
2536                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2537                            " state=" + state);
2538                    }
2539                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2540                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2541                                " state=" + state);
2542                    }
2543                }
2544            } else {
2545                final ActivityRecord resumed = stack.mResumedActivity;
2546                if (resumed != null && resumed == r) {
2547                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2548                        " state=" + state);
2549                }
2550                if (r != null && (state == ActivityState.INITIALIZING
2551                        || state == ActivityState.RESUMED)) {
2552                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2553                            " state=" + state);
2554                }
2555            }
2556        }
2557*/
2558    }
2559
2560    public void dump(PrintWriter pw, String prefix) {
2561        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2562                pw.println(mDismissKeyguardOnNextActivity);
2563        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2564                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2565        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2566        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2567        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2568        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2569    }
2570
2571    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2572        return getFocusedStack().getDumpActivitiesLocked(name);
2573    }
2574
2575    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2576            boolean needSep, String prefix) {
2577        if (activity != null) {
2578            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2579                if (needSep) {
2580                    pw.println();
2581                }
2582                pw.print(prefix);
2583                pw.println(activity);
2584                return true;
2585            }
2586        }
2587        return false;
2588    }
2589
2590    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2591            boolean dumpClient, String dumpPackage) {
2592        boolean printed = false;
2593        boolean needSep = false;
2594        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2595            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2596            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2597            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2598            final int numStacks = stacks.size();
2599            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2600                final ActivityStack stack = stacks.get(stackNdx);
2601                StringBuilder stackHeader = new StringBuilder(128);
2602                stackHeader.append("  Stack #");
2603                stackHeader.append(stack.mStackId);
2604                stackHeader.append(":");
2605                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2606                        needSep, stackHeader.toString());
2607                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2608                        !dumpAll, false, dumpPackage, true,
2609                        "    Running activities (most recent first):", null);
2610
2611                needSep = printed;
2612                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2613                        "    mPausingActivity: ");
2614                if (pr) {
2615                    printed = true;
2616                    needSep = false;
2617                }
2618                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2619                        "    mResumedActivity: ");
2620                if (pr) {
2621                    printed = true;
2622                    needSep = false;
2623                }
2624                if (dumpAll) {
2625                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2626                            "    mLastPausedActivity: ");
2627                    if (pr) {
2628                        printed = true;
2629                        needSep = true;
2630                    }
2631                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2632                            needSep, "    mLastNoHistoryActivity: ");
2633                }
2634                needSep = printed;
2635            }
2636        }
2637
2638        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2639                false, dumpPackage, true, "  Activities waiting to finish:", null);
2640        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2641                false, dumpPackage, true, "  Activities waiting to stop:", null);
2642        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2643                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2644                null);
2645        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2646                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2647        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2648                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2649
2650        return printed;
2651    }
2652
2653    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2654            String prefix, String label, boolean complete, boolean brief, boolean client,
2655            String dumpPackage, boolean needNL, String header1, String header2) {
2656        TaskRecord lastTask = null;
2657        String innerPrefix = null;
2658        String[] args = null;
2659        boolean printed = false;
2660        for (int i=list.size()-1; i>=0; i--) {
2661            final ActivityRecord r = list.get(i);
2662            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2663                continue;
2664            }
2665            if (innerPrefix == null) {
2666                innerPrefix = prefix + "      ";
2667                args = new String[0];
2668            }
2669            printed = true;
2670            final boolean full = !brief && (complete || !r.isInHistory());
2671            if (needNL) {
2672                pw.println("");
2673                needNL = false;
2674            }
2675            if (header1 != null) {
2676                pw.println(header1);
2677                header1 = null;
2678            }
2679            if (header2 != null) {
2680                pw.println(header2);
2681                header2 = null;
2682            }
2683            if (lastTask != r.task) {
2684                lastTask = r.task;
2685                pw.print(prefix);
2686                pw.print(full ? "* " : "  ");
2687                pw.println(lastTask);
2688                if (full) {
2689                    lastTask.dump(pw, prefix + "  ");
2690                } else if (complete) {
2691                    // Complete + brief == give a summary.  Isn't that obvious?!?
2692                    if (lastTask.intent != null) {
2693                        pw.print(prefix); pw.print("  ");
2694                                pw.println(lastTask.intent.toInsecureStringWithClip());
2695                    }
2696                }
2697            }
2698            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2699            pw.print(" #"); pw.print(i); pw.print(": ");
2700            pw.println(r);
2701            if (full) {
2702                r.dump(pw, innerPrefix);
2703            } else if (complete) {
2704                // Complete + brief == give a summary.  Isn't that obvious?!?
2705                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2706                if (r.app != null) {
2707                    pw.print(innerPrefix); pw.println(r.app);
2708                }
2709            }
2710            if (client && r.app != null && r.app.thread != null) {
2711                // flush anything that is already in the PrintWriter since the thread is going
2712                // to write to the file descriptor directly
2713                pw.flush();
2714                try {
2715                    TransferPipe tp = new TransferPipe();
2716                    try {
2717                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2718                                r.appToken, innerPrefix, args);
2719                        // Short timeout, since blocking here can
2720                        // deadlock with the application.
2721                        tp.go(fd, 2000);
2722                    } finally {
2723                        tp.kill();
2724                    }
2725                } catch (IOException e) {
2726                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2727                } catch (RemoteException e) {
2728                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2729                }
2730                needNL = true;
2731            }
2732        }
2733        return printed;
2734    }
2735
2736    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2737        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2738        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2739        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2740    }
2741
2742    final void scheduleIdleLocked() {
2743        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2744    }
2745
2746    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2747        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2748        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2749    }
2750
2751    final void scheduleResumeTopActivities() {
2752        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2753            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2754        }
2755    }
2756
2757    void removeSleepTimeouts() {
2758        mSleepTimeout = false;
2759        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2760    }
2761
2762    final void scheduleSleepTimeout() {
2763        removeSleepTimeouts();
2764        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2765    }
2766
2767    @Override
2768    public void onDisplayAdded(int displayId) {
2769        Slog.v(TAG, "Display added displayId=" + displayId);
2770        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2771    }
2772
2773    @Override
2774    public void onDisplayRemoved(int displayId) {
2775        Slog.v(TAG, "Display removed displayId=" + displayId);
2776        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2777    }
2778
2779    @Override
2780    public void onDisplayChanged(int displayId) {
2781        Slog.v(TAG, "Display changed displayId=" + displayId);
2782        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2783    }
2784
2785    public void handleDisplayAddedLocked(int displayId) {
2786        boolean newDisplay;
2787        synchronized (mService) {
2788            newDisplay = mActivityDisplays.get(displayId) == null;
2789            if (newDisplay) {
2790                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2791                mActivityDisplays.put(displayId, activityDisplay);
2792            }
2793        }
2794        if (newDisplay) {
2795            mWindowManager.onDisplayAdded(displayId);
2796        }
2797    }
2798
2799    public void handleDisplayRemovedLocked(int displayId) {
2800        synchronized (mService) {
2801            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2802            if (activityDisplay != null) {
2803                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2804                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2805                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2806                }
2807                mActivityDisplays.remove(displayId);
2808            }
2809        }
2810        mWindowManager.onDisplayRemoved(displayId);
2811    }
2812
2813    public void handleDisplayChangedLocked(int displayId) {
2814        synchronized (mService) {
2815            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2816            if (activityDisplay != null) {
2817                // TODO: Update the bounds.
2818            }
2819        }
2820        mWindowManager.onDisplayChanged(displayId);
2821    }
2822
2823    StackInfo getStackInfo(ActivityStack stack) {
2824        StackInfo info = new StackInfo();
2825        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2826        info.displayId = Display.DEFAULT_DISPLAY;
2827        info.stackId = stack.mStackId;
2828
2829        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2830        final int numTasks = tasks.size();
2831        int[] taskIds = new int[numTasks];
2832        String[] taskNames = new String[numTasks];
2833        for (int i = 0; i < numTasks; ++i) {
2834            final TaskRecord task = tasks.get(i);
2835            taskIds[i] = task.taskId;
2836            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2837                    : task.realActivity != null ? task.realActivity.flattenToString()
2838                    : task.getTopActivity() != null ? task.getTopActivity().packageName
2839                    : "unknown";
2840        }
2841        info.taskIds = taskIds;
2842        info.taskNames = taskNames;
2843        return info;
2844    }
2845
2846    StackInfo getStackInfoLocked(int stackId) {
2847        ActivityStack stack = getStack(stackId);
2848        if (stack != null) {
2849            return getStackInfo(stack);
2850        }
2851        return null;
2852    }
2853
2854    ArrayList<StackInfo> getAllStackInfosLocked() {
2855        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2856        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2857            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2858            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2859                list.add(getStackInfo(stacks.get(ndx)));
2860            }
2861        }
2862        return list;
2863    }
2864
2865    private final class ActivityStackSupervisorHandler extends Handler {
2866
2867        public ActivityStackSupervisorHandler(Looper looper) {
2868            super(looper);
2869        }
2870
2871        void activityIdleInternal(ActivityRecord r) {
2872            synchronized (mService) {
2873                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2874            }
2875        }
2876
2877        @Override
2878        public void handleMessage(Message msg) {
2879            switch (msg.what) {
2880                case IDLE_TIMEOUT_MSG: {
2881                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2882                    if (mService.mDidDexOpt) {
2883                        mService.mDidDexOpt = false;
2884                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2885                        nmsg.obj = msg.obj;
2886                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2887                        return;
2888                    }
2889                    // We don't at this point know if the activity is fullscreen,
2890                    // so we need to be conservative and assume it isn't.
2891                    activityIdleInternal((ActivityRecord)msg.obj);
2892                } break;
2893                case IDLE_NOW_MSG: {
2894                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2895                    activityIdleInternal((ActivityRecord)msg.obj);
2896                } break;
2897                case RESUME_TOP_ACTIVITY_MSG: {
2898                    synchronized (mService) {
2899                        resumeTopActivitiesLocked();
2900                    }
2901                } break;
2902                case SLEEP_TIMEOUT_MSG: {
2903                    synchronized (mService) {
2904                        if (mService.isSleepingOrShuttingDown()) {
2905                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2906                            mSleepTimeout = true;
2907                            checkReadyForSleepLocked();
2908                        }
2909                    }
2910                } break;
2911                case LAUNCH_TIMEOUT_MSG: {
2912                    if (mService.mDidDexOpt) {
2913                        mService.mDidDexOpt = false;
2914                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2915                        return;
2916                    }
2917                    synchronized (mService) {
2918                        if (mLaunchingActivity.isHeld()) {
2919                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2920                            if (VALIDATE_WAKE_LOCK_CALLER
2921                                    && Binder.getCallingUid() != Process.myUid()) {
2922                                throw new IllegalStateException("Calling must be system uid");
2923                            }
2924                            mLaunchingActivity.release();
2925                        }
2926                    }
2927                } break;
2928                case HANDLE_DISPLAY_ADDED: {
2929                    handleDisplayAddedLocked(msg.arg1);
2930                } break;
2931                case HANDLE_DISPLAY_CHANGED: {
2932                    handleDisplayChangedLocked(msg.arg1);
2933                } break;
2934                case HANDLE_DISPLAY_REMOVED: {
2935                    handleDisplayRemovedLocked(msg.arg1);
2936                } break;
2937                case CONTAINER_CALLBACK_VISIBILITY: {
2938                    final ActivityContainer container = (ActivityContainer) msg.obj;
2939                    final IActivityContainerCallback callback = container.mCallback;
2940                    if (callback != null) {
2941                        try {
2942                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
2943                        } catch (RemoteException e) {
2944                        }
2945                    }
2946                } break;
2947                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
2948                    final ActivityContainer container = (ActivityContainer) msg.obj;
2949                    final IActivityContainerCallback callback = container.mCallback;
2950                    if (callback != null) {
2951                        try {
2952                            callback.onAllActivitiesComplete(container.asBinder());
2953                        } catch (RemoteException e) {
2954                        }
2955                    }
2956                } break;
2957                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
2958                    synchronized (mService) {
2959                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
2960                                msg.obj);
2961                        ((ActivityContainer) msg.obj).onTaskListEmptyLocked();
2962                    }
2963                } break;
2964            }
2965        }
2966    }
2967
2968    class ActivityContainer extends android.app.IActivityContainer.Stub {
2969        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
2970                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
2971        final int mStackId;
2972        IActivityContainerCallback mCallback = null;
2973        final ActivityStack mStack;
2974        ActivityRecord mParentActivity = null;
2975        String mIdString;
2976
2977        boolean mVisible = true;
2978
2979        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
2980        ActivityDisplay mActivityDisplay;
2981
2982        final static int CONTAINER_STATE_HAS_SURFACE = 0;
2983        final static int CONTAINER_STATE_NO_SURFACE = 1;
2984        final static int CONTAINER_STATE_FINISHING = 2;
2985        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
2986
2987        ActivityContainer(int stackId) {
2988            synchronized (mService) {
2989                mStackId = stackId;
2990                mStack = new ActivityStack(this);
2991                mIdString = "ActivtyContainer{" + mStackId + "}";
2992                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
2993            }
2994        }
2995
2996        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
2997            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2998                    + " to display=" + activityDisplay);
2999            mActivityDisplay = activityDisplay;
3000            mStack.mDisplayId = activityDisplay.mDisplayId;
3001            mStack.mStacks = activityDisplay.mStacks;
3002
3003            activityDisplay.attachActivities(mStack);
3004            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3005        }
3006
3007        @Override
3008        public void attachToDisplay(int displayId) {
3009            synchronized (mService) {
3010                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3011                if (activityDisplay == null) {
3012                    return;
3013                }
3014                attachToDisplayLocked(activityDisplay);
3015            }
3016        }
3017
3018        @Override
3019        public int getDisplayId() {
3020            synchronized (mService) {
3021                if (mActivityDisplay != null) {
3022                    return mActivityDisplay.mDisplayId;
3023                }
3024            }
3025            return -1;
3026        }
3027
3028        @Override
3029        public boolean injectEvent(InputEvent event) {
3030            final long origId = Binder.clearCallingIdentity();
3031            try {
3032                synchronized (mService) {
3033                    if (mActivityDisplay != null) {
3034                        return mInputManagerInternal.injectInputEvent(event,
3035                                mActivityDisplay.mDisplayId,
3036                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3037                    }
3038                }
3039                return false;
3040            } finally {
3041                Binder.restoreCallingIdentity(origId);
3042            }
3043        }
3044
3045        @Override
3046        public void release() {
3047            synchronized (mService) {
3048                if (mContainerState == CONTAINER_STATE_FINISHING) {
3049                    return;
3050                }
3051                mContainerState = CONTAINER_STATE_FINISHING;
3052
3053                final Message msg =
3054                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3055                mHandler.sendMessageDelayed(msg, 1000);
3056
3057                long origId = Binder.clearCallingIdentity();
3058                try {
3059                    mStack.finishAllActivitiesLocked();
3060                } finally {
3061                    Binder.restoreCallingIdentity(origId);
3062                }
3063            }
3064        }
3065
3066        private void detachLocked() {
3067            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3068                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3069            if (mActivityDisplay != null) {
3070                mActivityDisplay.detachActivitiesLocked(mStack);
3071                mActivityDisplay = null;
3072                mStack.mDisplayId = -1;
3073                mStack.mStacks = null;
3074                mWindowManager.detachStack(mStackId);
3075            }
3076        }
3077
3078        @Override
3079        public final int startActivity(Intent intent) {
3080            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3081            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3082                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3083            // TODO: Switch to user app stacks here.
3084            intent.addFlags(FORCE_NEW_TASK_FLAGS);
3085            String mimeType = intent.getType();
3086            if (mimeType == null && intent.getData() != null
3087                    && "content".equals(intent.getData().getScheme())) {
3088                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3089            }
3090            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3091                    null, null, null, null, userId, this);
3092        }
3093
3094        @Override
3095        public final int startActivityIntentSender(IIntentSender intentSender) {
3096            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3097
3098            if (!(intentSender instanceof PendingIntentRecord)) {
3099                throw new IllegalArgumentException("Bad PendingIntent object");
3100            }
3101
3102            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3103                    null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
3104        }
3105
3106        private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3107            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3108                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3109            if (resolvedType == null) {
3110                resolvedType = intent.getType();
3111                if (resolvedType == null && intent.getData() != null
3112                        && "content".equals(intent.getData().getScheme())) {
3113                    resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3114                }
3115            }
3116            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
3117            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
3118                throw new SecurityException(
3119                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3120            }
3121        }
3122
3123        /** Throw a SecurityException if allowEmbedded is not true */
3124        @Override
3125        public final void checkEmbeddedAllowed(Intent intent) {
3126            checkEmbeddedAllowedInner(intent, null);
3127        }
3128
3129        /** Throw a SecurityException if allowEmbedded is not true */
3130        @Override
3131        public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3132            if (!(intentSender instanceof PendingIntentRecord)) {
3133                throw new IllegalArgumentException("Bad PendingIntent object");
3134            }
3135            PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3136            checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3137                    pendingIntent.key.requestResolvedType);
3138        }
3139
3140        @Override
3141        public IBinder asBinder() {
3142            return this;
3143        }
3144
3145        @Override
3146        public void setSurface(Surface surface, int width, int height, int density) {
3147            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3148        }
3149
3150        ActivityStackSupervisor getOuter() {
3151            return ActivityStackSupervisor.this;
3152        }
3153
3154        boolean isAttachedLocked() {
3155            return mActivityDisplay != null;
3156        }
3157
3158        void getBounds(Point outBounds) {
3159            synchronized (mService) {
3160                    if (mActivityDisplay != null) {
3161                    mActivityDisplay.getBounds(outBounds);
3162                } else {
3163                    outBounds.set(0, 0);
3164                }
3165            }
3166        }
3167
3168        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
3169        void setVisible(boolean visible) {
3170            if (mVisible != visible) {
3171                mVisible = visible;
3172                if (mCallback != null) {
3173                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3174                            0 /* unused */, this).sendToTarget();
3175                }
3176            }
3177        }
3178
3179        void setDrawn() {
3180        }
3181
3182        // You can always start a new task on a regular ActivityStack.
3183        boolean isEligibleForNewTasks() {
3184            return true;
3185        }
3186
3187        void onTaskListEmptyLocked() {
3188            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3189            if (!mStack.isHomeStack()) {
3190                detachLocked();
3191                deleteActivityContainer(this);
3192            }
3193            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3194        }
3195
3196        @Override
3197        public String toString() {
3198            return mIdString + (mActivityDisplay == null ? "N" : "A");
3199        }
3200    }
3201
3202    private class VirtualActivityContainer extends ActivityContainer {
3203        Surface mSurface;
3204        boolean mDrawn = false;
3205
3206        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3207            super(getNextStackId());
3208            mParentActivity = parent;
3209            mCallback = callback;
3210            mContainerState = CONTAINER_STATE_NO_SURFACE;
3211            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3212        }
3213
3214        @Override
3215        public void setSurface(Surface surface, int width, int height, int density) {
3216            super.setSurface(surface, width, height, density);
3217
3218            synchronized (mService) {
3219                final long origId = Binder.clearCallingIdentity();
3220                try {
3221                    setSurfaceLocked(surface, width, height, density);
3222                } finally {
3223                    Binder.restoreCallingIdentity(origId);
3224                }
3225            }
3226        }
3227
3228        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3229            if (mContainerState == CONTAINER_STATE_FINISHING) {
3230                return;
3231            }
3232            VirtualActivityDisplay virtualActivityDisplay =
3233                    (VirtualActivityDisplay) mActivityDisplay;
3234            if (virtualActivityDisplay == null) {
3235                virtualActivityDisplay =
3236                        new VirtualActivityDisplay(width, height, density);
3237                mActivityDisplay = virtualActivityDisplay;
3238                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3239                attachToDisplayLocked(virtualActivityDisplay);
3240            }
3241
3242            if (mSurface != null) {
3243                mSurface.release();
3244            }
3245
3246            mSurface = surface;
3247            if (surface != null) {
3248                mStack.resumeTopActivityLocked(null);
3249            } else {
3250                mContainerState = CONTAINER_STATE_NO_SURFACE;
3251                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
3252                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3253                    mStack.startPausingLocked(false, true);
3254                }
3255            }
3256
3257            setSurfaceIfReadyLocked();
3258
3259            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3260                    + virtualActivityDisplay);
3261        }
3262
3263        @Override
3264        boolean isAttachedLocked() {
3265            return mSurface != null && super.isAttachedLocked();
3266        }
3267
3268        @Override
3269        void setDrawn() {
3270            synchronized (mService) {
3271                mDrawn = true;
3272                setSurfaceIfReadyLocked();
3273            }
3274        }
3275
3276        // Never start a new task on an ActivityView if it isn't explicitly specified.
3277        @Override
3278        boolean isEligibleForNewTasks() {
3279            return false;
3280        }
3281
3282        private void setSurfaceIfReadyLocked() {
3283            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
3284                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3285            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3286                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3287                mContainerState = CONTAINER_STATE_HAS_SURFACE;
3288            }
3289        }
3290    }
3291
3292    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3293     * attached {@link ActivityStack}s */
3294    class ActivityDisplay {
3295        /** Actual Display this object tracks. */
3296        int mDisplayId;
3297        Display mDisplay;
3298        DisplayInfo mDisplayInfo = new DisplayInfo();
3299
3300        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3301         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3302        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3303
3304        ActivityDisplay() {
3305        }
3306
3307        ActivityDisplay(int displayId) {
3308            init(mDisplayManager.getDisplay(displayId));
3309        }
3310
3311        void init(Display display) {
3312            mDisplay = display;
3313            mDisplayId = display.getDisplayId();
3314            mDisplay.getDisplayInfo(mDisplayInfo);
3315        }
3316
3317        void attachActivities(ActivityStack stack) {
3318            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3319                    + mDisplayId);
3320            mStacks.add(stack);
3321        }
3322
3323        void detachActivitiesLocked(ActivityStack stack) {
3324            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3325                    + " from displayId=" + mDisplayId);
3326            mStacks.remove(stack);
3327        }
3328
3329        void getBounds(Point bounds) {
3330            mDisplay.getDisplayInfo(mDisplayInfo);
3331            bounds.x = mDisplayInfo.appWidth;
3332            bounds.y = mDisplayInfo.appHeight;
3333        }
3334
3335        @Override
3336        public String toString() {
3337            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3338        }
3339    }
3340
3341    class VirtualActivityDisplay extends ActivityDisplay {
3342        VirtualDisplay mVirtualDisplay;
3343
3344        VirtualActivityDisplay(int width, int height, int density) {
3345            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3346            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
3347                    width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3348                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3349
3350            init(mVirtualDisplay.getDisplay());
3351
3352            mWindowManager.handleDisplayAdded(mDisplayId);
3353        }
3354
3355        void setSurface(Surface surface) {
3356            if (mVirtualDisplay != null) {
3357                mVirtualDisplay.setSurface(surface);
3358            }
3359        }
3360
3361        @Override
3362        void detachActivitiesLocked(ActivityStack stack) {
3363            super.detachActivitiesLocked(stack);
3364            if (mVirtualDisplay != null) {
3365                mVirtualDisplay.release();
3366                mVirtualDisplay = null;
3367            }
3368        }
3369
3370        @Override
3371        public String toString() {
3372            return "VirtualActivityDisplay={" + mDisplayId + "}";
3373        }
3374    }
3375}
3376