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