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