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