ActivityStackSupervisor.java revision 1602ec21883f73c5eb2304cf69d2278f70b145ab
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_RESULTS;
26import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
27import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
28import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
29import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
30import static com.android.server.am.ActivityManagerService.TAG;
31
32import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityOptions;
35import android.app.AppGlobals;
36import android.app.IActivityManager;
37import android.app.IApplicationThread;
38import android.app.IThumbnailReceiver;
39import android.app.PendingIntent;
40import android.app.ActivityManager.RunningTaskInfo;
41import android.app.IActivityManager.WaitResult;
42import android.app.ResultInfo;
43import android.content.ComponentName;
44import android.content.Context;
45import android.content.IIntentSender;
46import android.content.Intent;
47import android.content.IntentSender;
48import android.content.pm.ActivityInfo;
49import android.content.pm.ApplicationInfo;
50import android.content.pm.PackageManager;
51import android.content.pm.ResolveInfo;
52import android.content.res.Configuration;
53import android.os.Binder;
54import android.os.Bundle;
55import android.os.Debug;
56import android.os.Handler;
57import android.os.IBinder;
58import android.os.Looper;
59import android.os.Message;
60import android.os.ParcelFileDescriptor;
61import android.os.RemoteException;
62import android.os.SystemClock;
63import android.os.UserHandle;
64import android.util.EventLog;
65import android.util.Slog;
66import android.util.SparseArray;
67
68import com.android.internal.app.HeavyWeightSwitcherActivity;
69import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
70import com.android.server.am.ActivityStack.ActivityState;
71import com.android.server.wm.StackBox;
72import com.android.server.wm.WindowManagerService;
73
74import java.io.FileDescriptor;
75import java.io.IOException;
76import java.io.PrintWriter;
77import java.util.ArrayList;
78import java.util.List;
79
80public class ActivityStackSupervisor {
81    static final boolean DEBUG_STACK = ActivityManagerService.DEBUG_STACK;
82
83    static final boolean DEBUG = ActivityManagerService.DEBUG || false;
84    static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
85    static final boolean DEBUG_APP = DEBUG || false;
86    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
87    static final boolean DEBUG_STATES = DEBUG || false;
88    static final boolean DEBUG_IDLE = DEBUG || false;
89
90    public static final int HOME_STACK_ID = 0;
91
92    /** How long we wait until giving up on the last activity telling us it is idle. */
93    static final int IDLE_TIMEOUT = 10*1000;
94
95    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
96    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
97    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
98
99    final ActivityManagerService mService;
100    final Context mContext;
101    final Looper mLooper;
102
103    final ActivityStackSupervisorHandler mHandler;
104
105    /** Short cut */
106    WindowManagerService mWindowManager;
107
108    /** Dismiss the keyguard after the next activity is displayed? */
109    private boolean mDismissKeyguardOnNextActivity = false;
110
111    /** Identifier counter for all ActivityStacks */
112    private int mLastStackId = HOME_STACK_ID;
113
114    /** Task identifier that activities are currently being started in.  Incremented each time a
115     * new task is created. */
116    private int mCurTaskId = 0;
117
118    /** The current user */
119    private int mCurrentUser;
120
121    /** The stack containing the launcher app */
122    private ActivityStack mHomeStack;
123
124    /** The non-home stack currently receiving input or launching the next activity. If home is
125     * in front then mHomeStack overrides mFocusedStack. */
126    private ActivityStack mFocusedStack;
127
128    /** All the non-launcher stacks */
129    private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
130
131    private static final int STACK_STATE_HOME_IN_FRONT = 0;
132    private static final int STACK_STATE_HOME_TO_BACK = 1;
133    private static final int STACK_STATE_HOME_IN_BACK = 2;
134    private static final int STACK_STATE_HOME_TO_FRONT = 3;
135    private int mStackState = STACK_STATE_HOME_IN_FRONT;
136
137    /** List of activities that are waiting for a new activity to become visible before completing
138     * whatever operation they are supposed to do. */
139    final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
140
141    /** List of processes waiting to find out about the next visible activity. */
142    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
143            new ArrayList<IActivityManager.WaitResult>();
144
145    /** List of processes waiting to find out about the next launched activity. */
146    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
147            new ArrayList<IActivityManager.WaitResult>();
148
149    /** List of activities that are ready to be stopped, but waiting for the next activity to
150     * settle down before doing so. */
151    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
152
153    /** List of activities that are ready to be finished, but waiting for the previous activity to
154     * settle down before doing so.  It contains ActivityRecord objects. */
155    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
156
157    /** List of ActivityRecord objects that have been finished and must still report back to a
158     * pending thumbnail receiver. */
159    final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
160
161    /** Used on user changes */
162    final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
163
164    /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
165     * is being brought in front of us. */
166    boolean mUserLeaving = false;
167
168    /** Stacks belonging to users other than mCurrentUser. Indexed by userId. */
169    final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
170
171    public ActivityStackSupervisor(ActivityManagerService service, Context context,
172            Looper looper) {
173        mService = service;
174        mContext = context;
175        mLooper = looper;
176        mHandler = new ActivityStackSupervisorHandler(looper);
177    }
178
179    void setWindowManager(WindowManagerService wm) {
180        mWindowManager = wm;
181        mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
182        mStacks.add(mHomeStack);
183    }
184
185    void dismissKeyguard() {
186        if (mDismissKeyguardOnNextActivity) {
187            mDismissKeyguardOnNextActivity = false;
188            mWindowManager.dismissKeyguard();
189        }
190    }
191
192    ActivityStack getFocusedStack() {
193        if (mFocusedStack == null) {
194            return mHomeStack;
195        }
196        switch (mStackState) {
197            case STACK_STATE_HOME_IN_FRONT:
198            case STACK_STATE_HOME_TO_FRONT:
199                return mHomeStack;
200            case STACK_STATE_HOME_IN_BACK:
201            case STACK_STATE_HOME_TO_BACK:
202            default:
203                return mFocusedStack;
204        }
205    }
206
207    ActivityStack getLastStack() {
208        switch (mStackState) {
209            case STACK_STATE_HOME_IN_FRONT:
210            case STACK_STATE_HOME_TO_BACK:
211                return mHomeStack;
212            case STACK_STATE_HOME_TO_FRONT:
213            case STACK_STATE_HOME_IN_BACK:
214            default:
215                return mFocusedStack;
216        }
217    }
218
219    boolean isFocusedStack(ActivityStack stack) {
220        return getFocusedStack() == stack;
221    }
222
223    boolean isFrontStack(ActivityStack stack) {
224        if (stack.mCurrentUser != mCurrentUser) {
225            return false;
226        }
227        return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
228    }
229
230    void moveHomeStack(boolean toFront) {
231        final boolean homeInFront = isFrontStack(mHomeStack);
232        if (homeInFront ^ toFront) {
233            mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
234        }
235    }
236
237    boolean resumeHomeActivity(ActivityRecord prev) {
238        moveHomeStack(true);
239        if (prev != null) {
240            prev.mLaunchHomeTaskNext = false;
241        }
242        if (mHomeStack.topRunningActivityLocked(null) != null) {
243            return resumeTopActivitiesLocked(mHomeStack, prev, null);
244        }
245        return mService.startHomeActivityLocked(mCurrentUser);
246    }
247
248    final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r,
249            ActivityStack stack) {
250        if (stack == mHomeStack) {
251            return;
252        }
253        if ((sourceRecord == null && getLastStack() == mHomeStack) ||
254                (sourceRecord != null && sourceRecord.isHomeActivity)) {
255            if (r == null) {
256                r = stack.topRunningActivityLocked(null);
257            }
258            if (r != null && !r.isHomeActivity && r.isRootActivity()) {
259                r.mLaunchHomeTaskNext = true;
260            }
261        }
262    }
263
264    void setDismissKeyguard(boolean dismiss) {
265        mDismissKeyguardOnNextActivity = dismiss;
266    }
267
268    TaskRecord anyTaskForIdLocked(int id) {
269        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
270            ActivityStack stack = mStacks.get(stackNdx);
271            TaskRecord task = stack.taskForIdLocked(id);
272            if (task != null) {
273                return task;
274            }
275        }
276        return null;
277    }
278
279    ActivityRecord isInAnyStackLocked(IBinder token) {
280        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
281            final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
282            if (r != null) {
283                return r;
284            }
285        }
286        return null;
287    }
288
289    int getNextTaskId() {
290        do {
291            mCurTaskId++;
292            if (mCurTaskId <= 0) {
293                mCurTaskId = 1;
294            }
295        } while (anyTaskForIdLocked(mCurTaskId) != null);
296        return mCurTaskId;
297    }
298
299    void removeTask(TaskRecord task) {
300        final ActivityStack stack = task.stack;
301        if (stack.removeTask(task) && !stack.isHomeStack()) {
302            if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
303            mStacks.remove(stack);
304            final int stackId = stack.mStackId;
305            final int nextStackId = mWindowManager.removeStack(stackId);
306            // TODO: Perhaps we need to let the ActivityManager determine the next focus...
307            if (mFocusedStack.mStackId == stackId) {
308                // If this is the last app stack, set mFocusedStack to null.
309                mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
310            }
311        }
312    }
313
314    ActivityRecord resumedAppLocked() {
315        ActivityStack stack = getFocusedStack();
316        if (stack == null) {
317            return null;
318        }
319        ActivityRecord resumedActivity = stack.mResumedActivity;
320        if (resumedActivity == null || resumedActivity.app == null) {
321            resumedActivity = stack.mPausingActivity;
322            if (resumedActivity == null || resumedActivity.app == null) {
323                resumedActivity = stack.topRunningActivityLocked(null);
324            }
325        }
326        return resumedActivity;
327    }
328
329    boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
330        boolean didSomething = false;
331        final String processName = app.processName;
332        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
333            final ActivityStack stack = mStacks.get(stackNdx);
334            if (!isFrontStack(stack)) {
335                continue;
336            }
337            ActivityRecord hr = stack.topRunningActivityLocked(null);
338            if (hr != null) {
339                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
340                        && processName.equals(hr.processName)) {
341                    try {
342                        if (headless) {
343                            Slog.e(TAG, "Starting activities not supported on headless device: "
344                                    + hr);
345                        } else if (realStartActivityLocked(hr, app, true, true)) {
346                            didSomething = true;
347                        }
348                    } catch (Exception e) {
349                        Slog.w(TAG, "Exception in new application when starting activity "
350                              + hr.intent.getComponent().flattenToShortString(), e);
351                        throw e;
352                    }
353                }
354            }
355        }
356        if (!didSomething) {
357            ensureActivitiesVisibleLocked(null, 0);
358        }
359        return didSomething;
360    }
361
362    boolean allResumedActivitiesIdle() {
363        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
364            final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity;
365            if (resumedActivity == null || !resumedActivity.idle) {
366                return false;
367            }
368        }
369        return true;
370    }
371
372    boolean allResumedActivitiesComplete() {
373        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
374            final ActivityStack stack = mStacks.get(stackNdx);
375            if (isFrontStack(stack)) {
376                final ActivityRecord r = stack.mResumedActivity;
377                if (r != null && r.state != ActivityState.RESUMED) {
378                    return false;
379                }
380            }
381        }
382        // TODO: Not sure if this should check if all Paused are complete too.
383        switch (mStackState) {
384            case STACK_STATE_HOME_TO_BACK:
385                mStackState = STACK_STATE_HOME_IN_BACK;
386                break;
387            case STACK_STATE_HOME_TO_FRONT:
388                mStackState = STACK_STATE_HOME_IN_FRONT;
389                break;
390        }
391        return true;
392    }
393
394    boolean allResumedActivitiesVisible() {
395        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
396            final ActivityStack stack = mStacks.get(stackNdx);
397            final ActivityRecord r = stack.mResumedActivity;
398            if (r != null && (!r.nowVisible || r.waitingVisible)) {
399                return false;
400            }
401        }
402        return true;
403    }
404
405    boolean pauseBackStacks(boolean userLeaving) {
406        boolean someActivityPaused = false;
407        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
408            final ActivityStack stack = mStacks.get(stackNdx);
409            if (!isFrontStack(stack) && stack.mResumedActivity != null) {
410                stack.startPausingLocked(userLeaving, false);
411                someActivityPaused = true;
412            }
413        }
414        return someActivityPaused;
415    }
416
417    boolean allPausedActivitiesComplete() {
418        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
419            final ActivityStack stack = mStacks.get(stackNdx);
420            final ActivityRecord r = stack.mPausingActivity;
421            if (r != null && r.state != ActivityState.PAUSED
422                    && r.state != ActivityState.STOPPED
423                    && r.state != ActivityState.STOPPING) {
424                return false;
425            }
426        }
427        return true;
428    }
429
430    void reportActivityVisibleLocked(ActivityRecord r) {
431        for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
432            WaitResult w = mWaitingActivityVisible.get(i);
433            w.timeout = false;
434            if (r != null) {
435                w.who = new ComponentName(r.info.packageName, r.info.name);
436            }
437            w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
438            w.thisTime = w.totalTime;
439        }
440        mService.notifyAll();
441        dismissKeyguard();
442    }
443
444    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
445            long thisTime, long totalTime) {
446        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
447            WaitResult w = mWaitingActivityLaunched.remove(i);
448            w.timeout = timeout;
449            if (r != null) {
450                w.who = new ComponentName(r.info.packageName, r.info.name);
451            }
452            w.thisTime = thisTime;
453            w.totalTime = totalTime;
454        }
455        mService.notifyAll();
456    }
457
458    ActivityRecord topRunningActivityLocked() {
459        final ActivityStack focusedStack = getFocusedStack();
460        ActivityRecord r = focusedStack.topRunningActivityLocked(null);
461        if (r != null) {
462            return r;
463        }
464
465        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
466            final ActivityStack stack = mStacks.get(stackNdx);
467            if (stack.mCurrentUser == mCurrentUser && stack != focusedStack &&
468                    isFrontStack(stack)) {
469                r = stack.topRunningActivityLocked(null);
470                if (r != null) {
471                    return r;
472                }
473            }
474        }
475        return null;
476    }
477
478    ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
479            PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
480        ActivityRecord r = null;
481        final int numStacks = mStacks.size();
482        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
483            final ActivityStack stack = mStacks.get(stackNdx);
484            final ActivityRecord ar =
485                    stack.getTasksLocked(maxNum - list.size(), receiver, pending, list);
486            if (isFrontStack(stack)) {
487                r = ar;
488            }
489        }
490        return r;
491    }
492
493    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
494            String profileFile, ParcelFileDescriptor profileFd, int userId) {
495        // Collect information about the target of the Intent.
496        ActivityInfo aInfo;
497        try {
498            ResolveInfo rInfo =
499                AppGlobals.getPackageManager().resolveIntent(
500                        intent, resolvedType,
501                        PackageManager.MATCH_DEFAULT_ONLY
502                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
503            aInfo = rInfo != null ? rInfo.activityInfo : null;
504        } catch (RemoteException e) {
505            aInfo = null;
506        }
507
508        if (aInfo != null) {
509            // Store the found target back into the intent, because now that
510            // we have it we never want to do this again.  For example, if the
511            // user navigates back to this point in the history, we should
512            // always restart the exact same activity.
513            intent.setComponent(new ComponentName(
514                    aInfo.applicationInfo.packageName, aInfo.name));
515
516            // Don't debug things in the system process
517            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
518                if (!aInfo.processName.equals("system")) {
519                    mService.setDebugApp(aInfo.processName, true, false);
520                }
521            }
522
523            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
524                if (!aInfo.processName.equals("system")) {
525                    mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
526                }
527            }
528
529            if (profileFile != null) {
530                if (!aInfo.processName.equals("system")) {
531                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
532                            profileFile, profileFd,
533                            (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
534                }
535            }
536        }
537        return aInfo;
538    }
539
540    void startHomeActivity(Intent intent, ActivityInfo aInfo) {
541        moveHomeStack(true);
542        startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
543                null, false, null);
544    }
545
546    final int startActivityMayWait(IApplicationThread caller, int callingUid,
547            String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
548            String resultWho, int requestCode, int startFlags, String profileFile,
549            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
550            Bundle options, int userId) {
551        // Refuse possible leaked file descriptors
552        if (intent != null && intent.hasFileDescriptors()) {
553            throw new IllegalArgumentException("File descriptors passed in Intent");
554        }
555        boolean componentSpecified = intent.getComponent() != null;
556
557        // Don't modify the client's object!
558        intent = new Intent(intent);
559
560        // Collect information about the target of the Intent.
561        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
562                profileFile, profileFd, userId);
563
564        synchronized (mService) {
565            int callingPid;
566            if (callingUid >= 0) {
567                callingPid = -1;
568            } else if (caller == null) {
569                callingPid = Binder.getCallingPid();
570                callingUid = Binder.getCallingUid();
571            } else {
572                callingPid = callingUid = -1;
573            }
574
575            final ActivityStack stack = getFocusedStack();
576            stack.mConfigWillChange = config != null
577                    && mService.mConfiguration.diff(config) != 0;
578            if (DEBUG_CONFIGURATION) Slog.v(TAG,
579                    "Starting activity when config will change = " + stack.mConfigWillChange);
580
581            final long origId = Binder.clearCallingIdentity();
582
583            if (aInfo != null &&
584                    (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
585                // This may be a heavy-weight process!  Check to see if we already
586                // have another, different heavy-weight process running.
587                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
588                    if (mService.mHeavyWeightProcess != null &&
589                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
590                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
591                        int realCallingPid = callingPid;
592                        int realCallingUid = callingUid;
593                        if (caller != null) {
594                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
595                            if (callerApp != null) {
596                                realCallingPid = callerApp.pid;
597                                realCallingUid = callerApp.info.uid;
598                            } else {
599                                Slog.w(TAG, "Unable to find app for caller " + caller
600                                      + " (pid=" + realCallingPid + ") when starting: "
601                                      + intent.toString());
602                                ActivityOptions.abort(options);
603                                return ActivityManager.START_PERMISSION_DENIED;
604                            }
605                        }
606
607                        IIntentSender target = mService.getIntentSenderLocked(
608                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
609                                realCallingUid, userId, null, null, 0, new Intent[] { intent },
610                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
611                                | PendingIntent.FLAG_ONE_SHOT, null);
612
613                        Intent newIntent = new Intent();
614                        if (requestCode >= 0) {
615                            // Caller is requesting a result.
616                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
617                        }
618                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
619                                new IntentSender(target));
620                        if (mService.mHeavyWeightProcess.activities.size() > 0) {
621                            ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
622                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
623                                    hist.packageName);
624                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
625                                    hist.task.taskId);
626                        }
627                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
628                                aInfo.packageName);
629                        newIntent.setFlags(intent.getFlags());
630                        newIntent.setClassName("android",
631                                HeavyWeightSwitcherActivity.class.getName());
632                        intent = newIntent;
633                        resolvedType = null;
634                        caller = null;
635                        callingUid = Binder.getCallingUid();
636                        callingPid = Binder.getCallingPid();
637                        componentSpecified = true;
638                        try {
639                            ResolveInfo rInfo =
640                                AppGlobals.getPackageManager().resolveIntent(
641                                        intent, null,
642                                        PackageManager.MATCH_DEFAULT_ONLY
643                                        | ActivityManagerService.STOCK_PM_FLAGS, userId);
644                            aInfo = rInfo != null ? rInfo.activityInfo : null;
645                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
646                        } catch (RemoteException e) {
647                            aInfo = null;
648                        }
649                    }
650                }
651            }
652
653            int res = startActivityLocked(caller, intent, resolvedType,
654                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
655                    callingPackage, startFlags, options, componentSpecified, null);
656
657            if (stack.mConfigWillChange) {
658                // If the caller also wants to switch to a new configuration,
659                // do so now.  This allows a clean switch, as we are waiting
660                // for the current activity to pause (so we will not destroy
661                // it), and have not yet started the next activity.
662                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
663                        "updateConfiguration()");
664                stack.mConfigWillChange = false;
665                if (DEBUG_CONFIGURATION) Slog.v(TAG,
666                        "Updating to new configuration after starting activity.");
667                mService.updateConfigurationLocked(config, null, false, false);
668            }
669
670            Binder.restoreCallingIdentity(origId);
671
672            if (outResult != null) {
673                outResult.result = res;
674                if (res == ActivityManager.START_SUCCESS) {
675                    mWaitingActivityLaunched.add(outResult);
676                    do {
677                        try {
678                            mService.wait();
679                        } catch (InterruptedException e) {
680                        }
681                    } while (!outResult.timeout && outResult.who == null);
682                } else if (res == ActivityManager.START_TASK_TO_FRONT) {
683                    ActivityRecord r = stack.topRunningActivityLocked(null);
684                    if (r.nowVisible) {
685                        outResult.timeout = false;
686                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
687                        outResult.totalTime = 0;
688                        outResult.thisTime = 0;
689                    } else {
690                        outResult.thisTime = SystemClock.uptimeMillis();
691                        mWaitingActivityVisible.add(outResult);
692                        do {
693                            try {
694                                mService.wait();
695                            } catch (InterruptedException e) {
696                            }
697                        } while (!outResult.timeout && outResult.who == null);
698                    }
699                }
700            }
701
702            return res;
703        }
704    }
705
706    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
707            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
708            Bundle options, int userId) {
709        if (intents == null) {
710            throw new NullPointerException("intents is null");
711        }
712        if (resolvedTypes == null) {
713            throw new NullPointerException("resolvedTypes is null");
714        }
715        if (intents.length != resolvedTypes.length) {
716            throw new IllegalArgumentException("intents are length different than resolvedTypes");
717        }
718
719        ActivityRecord[] outActivity = new ActivityRecord[1];
720
721        int callingPid;
722        if (callingUid >= 0) {
723            callingPid = -1;
724        } else if (caller == null) {
725            callingPid = Binder.getCallingPid();
726            callingUid = Binder.getCallingUid();
727        } else {
728            callingPid = callingUid = -1;
729        }
730        final long origId = Binder.clearCallingIdentity();
731        try {
732            synchronized (mService) {
733
734                for (int i=0; i<intents.length; i++) {
735                    Intent intent = intents[i];
736                    if (intent == null) {
737                        continue;
738                    }
739
740                    // Refuse possible leaked file descriptors
741                    if (intent != null && intent.hasFileDescriptors()) {
742                        throw new IllegalArgumentException("File descriptors passed in Intent");
743                    }
744
745                    boolean componentSpecified = intent.getComponent() != null;
746
747                    // Don't modify the client's object!
748                    intent = new Intent(intent);
749
750                    // Collect information about the target of the Intent.
751                    ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
752                            0, null, null, userId);
753                    // TODO: New, check if this is correct
754                    aInfo = mService.getActivityInfoForUser(aInfo, userId);
755
756                    if (aInfo != null &&
757                            (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
758                                    != 0) {
759                        throw new IllegalArgumentException(
760                                "FLAG_CANT_SAVE_STATE not supported here");
761                    }
762
763                    Bundle theseOptions;
764                    if (options != null && i == intents.length-1) {
765                        theseOptions = options;
766                    } else {
767                        theseOptions = null;
768                    }
769                    int res = startActivityLocked(caller, intent, resolvedTypes[i],
770                            aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
771                            0, theseOptions, componentSpecified, outActivity);
772                    if (res < 0) {
773                        return res;
774                    }
775
776                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
777                }
778            }
779        } finally {
780            Binder.restoreCallingIdentity(origId);
781        }
782
783        return ActivityManager.START_SUCCESS;
784    }
785
786    final boolean realStartActivityLocked(ActivityRecord r,
787            ProcessRecord app, boolean andResume, boolean checkConfig)
788            throws RemoteException {
789
790        r.startFreezingScreenLocked(app, 0);
791        mWindowManager.setAppVisibility(r.appToken, true);
792
793        // schedule launch ticks to collect information about slow apps.
794        r.startLaunchTickingLocked();
795
796        // Have the window manager re-evaluate the orientation of
797        // the screen based on the new activity order.  Note that
798        // as a result of this, it can call back into the activity
799        // manager with a new orientation.  We don't care about that,
800        // because the activity is not currently running so we are
801        // just restarting it anyway.
802        if (checkConfig) {
803            Configuration config = mWindowManager.updateOrientationFromAppTokens(
804                    mService.mConfiguration,
805                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
806            mService.updateConfigurationLocked(config, r, false, false);
807        }
808
809        r.app = app;
810        app.waitingToKill = null;
811        r.launchCount++;
812        r.lastLaunchTime = SystemClock.uptimeMillis();
813
814        if (localLOGV) Slog.v(TAG, "Launching: " + r);
815
816        int idx = app.activities.indexOf(r);
817        if (idx < 0) {
818            app.activities.add(r);
819        }
820        mService.updateLruProcessLocked(app, true);
821
822        final ActivityStack stack = r.task.stack;
823        try {
824            if (app.thread == null) {
825                throw new RemoteException();
826            }
827            List<ResultInfo> results = null;
828            List<Intent> newIntents = null;
829            if (andResume) {
830                results = r.results;
831                newIntents = r.newIntents;
832            }
833            if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
834                    + " icicle=" + r.icicle
835                    + " with results=" + results + " newIntents=" + newIntents
836                    + " andResume=" + andResume);
837            if (andResume) {
838                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
839                        r.userId, System.identityHashCode(r),
840                        r.task.taskId, r.shortComponentName);
841            }
842            if (r.isHomeActivity) {
843                mService.mHomeProcess = app;
844            }
845            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
846            r.sleeping = false;
847            r.forceNewConfig = false;
848            mService.showAskCompatModeDialogLocked(r);
849            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
850            String profileFile = null;
851            ParcelFileDescriptor profileFd = null;
852            boolean profileAutoStop = false;
853            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
854                if (mService.mProfileProc == null || mService.mProfileProc == app) {
855                    mService.mProfileProc = app;
856                    profileFile = mService.mProfileFile;
857                    profileFd = mService.mProfileFd;
858                    profileAutoStop = mService.mAutoStopProfiler;
859                }
860            }
861            app.hasShownUi = true;
862            app.pendingUiClean = true;
863            if (profileFd != null) {
864                try {
865                    profileFd = profileFd.dup();
866                } catch (IOException e) {
867                    if (profileFd != null) {
868                        try {
869                            profileFd.close();
870                        } catch (IOException o) {
871                        }
872                        profileFd = null;
873                    }
874                }
875            }
876            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
877                    System.identityHashCode(r), r.info,
878                    new Configuration(mService.mConfiguration),
879                    r.compat, r.icicle, results, newIntents, !andResume,
880                    mService.isNextTransitionForward(), profileFile, profileFd,
881                    profileAutoStop);
882
883            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
884                // This may be a heavy-weight process!  Note that the package
885                // manager will ensure that only activity can run in the main
886                // process of the .apk, which is the only thing that will be
887                // considered heavy-weight.
888                if (app.processName.equals(app.info.packageName)) {
889                    if (mService.mHeavyWeightProcess != null
890                            && mService.mHeavyWeightProcess != app) {
891                        Slog.w(TAG, "Starting new heavy weight process " + app
892                                + " when already running "
893                                + mService.mHeavyWeightProcess);
894                    }
895                    mService.mHeavyWeightProcess = app;
896                    Message msg = mService.mHandler.obtainMessage(
897                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
898                    msg.obj = r;
899                    mService.mHandler.sendMessage(msg);
900                }
901            }
902
903        } catch (RemoteException e) {
904            if (r.launchFailed) {
905                // This is the second time we failed -- finish activity
906                // and give up.
907                Slog.e(TAG, "Second failure launching "
908                      + r.intent.getComponent().flattenToShortString()
909                      + ", giving up", e);
910                mService.appDiedLocked(app, app.pid, app.thread);
911                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
912                        "2nd-crash", false);
913                return false;
914            }
915
916            // This is the first time we failed -- restart process and
917            // retry.
918            app.activities.remove(r);
919            throw e;
920        }
921
922        r.launchFailed = false;
923        if (stack.updateLRUListLocked(r)) {
924            Slog.w(TAG, "Activity " + r
925                  + " being launched, but already in LRU list");
926        }
927
928        if (andResume) {
929            // As part of the process of launching, ActivityThread also performs
930            // a resume.
931            stack.minimalResumeActivityLocked(r);
932        } else {
933            // This activity is not starting in the resumed state... which
934            // should look like we asked it to pause+stop (but remain visible),
935            // and it has done so and reported back the current icicle and
936            // other state.
937            if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
938                    + " (starting in stopped state)");
939            r.state = ActivityState.STOPPED;
940            r.stopped = true;
941        }
942
943        // Launch the new version setup screen if needed.  We do this -after-
944        // launching the initial activity (that is, home), so that it can have
945        // a chance to initialize itself while in the background, making the
946        // switch back to it faster and look better.
947        if (isFrontStack(stack)) {
948            mService.startSetupActivityLocked();
949        }
950
951        return true;
952    }
953
954    void startSpecificActivityLocked(ActivityRecord r,
955            boolean andResume, boolean checkConfig) {
956        // Is this activity's application already running?
957        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
958                r.info.applicationInfo.uid);
959
960        r.task.stack.setLaunchTime(r);
961
962        if (app != null && app.thread != null) {
963            try {
964                app.addPackage(r.info.packageName);
965                realStartActivityLocked(r, app, andResume, checkConfig);
966                return;
967            } catch (RemoteException e) {
968                Slog.w(TAG, "Exception when starting activity "
969                        + r.intent.getComponent().flattenToShortString(), e);
970            }
971
972            // If a dead object exception was thrown -- fall through to
973            // restart the application.
974        }
975
976        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
977                "activity", r.intent.getComponent(), false, false);
978    }
979
980    final int startActivityLocked(IApplicationThread caller,
981            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
982            String resultWho, int requestCode,
983            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
984            boolean componentSpecified, ActivityRecord[] outActivity) {
985        int err = ActivityManager.START_SUCCESS;
986
987        ProcessRecord callerApp = null;
988        if (caller != null) {
989            callerApp = mService.getRecordForAppLocked(caller);
990            if (callerApp != null) {
991                callingPid = callerApp.pid;
992                callingUid = callerApp.info.uid;
993            } else {
994                Slog.w(TAG, "Unable to find app for caller " + caller
995                      + " (pid=" + callingPid + ") when starting: "
996                      + intent.toString());
997                err = ActivityManager.START_PERMISSION_DENIED;
998            }
999        }
1000
1001        if (err == ActivityManager.START_SUCCESS) {
1002            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1003            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1004                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1005        }
1006
1007        ActivityRecord sourceRecord = null;
1008        ActivityRecord resultRecord = null;
1009        if (resultTo != null) {
1010            sourceRecord = isInAnyStackLocked(resultTo);
1011            if (DEBUG_RESULTS) Slog.v(
1012                TAG, "Will send result to " + resultTo + " " + sourceRecord);
1013            if (sourceRecord != null) {
1014                if (requestCode >= 0 && !sourceRecord.finishing) {
1015                    resultRecord = sourceRecord;
1016                }
1017            }
1018        }
1019        ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1020
1021        int launchFlags = intent.getFlags();
1022
1023        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1024                && sourceRecord != null) {
1025            // Transfer the result target from the source activity to the new
1026            // one being started, including any failures.
1027            if (requestCode >= 0) {
1028                ActivityOptions.abort(options);
1029                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1030            }
1031            resultRecord = sourceRecord.resultTo;
1032            resultWho = sourceRecord.resultWho;
1033            requestCode = sourceRecord.requestCode;
1034            sourceRecord.resultTo = null;
1035            if (resultRecord != null) {
1036                resultRecord.removeResultsLocked(
1037                    sourceRecord, resultWho, requestCode);
1038            }
1039        }
1040
1041        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1042            // We couldn't find a class that can handle the given Intent.
1043            // That's the end of that!
1044            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1045        }
1046
1047        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1048            // We couldn't find the specific class specified in the Intent.
1049            // Also the end of the line.
1050            err = ActivityManager.START_CLASS_NOT_FOUND;
1051        }
1052
1053        if (err != ActivityManager.START_SUCCESS) {
1054            if (resultRecord != null) {
1055                resultStack.sendActivityResultLocked(-1,
1056                    resultRecord, resultWho, requestCode,
1057                    Activity.RESULT_CANCELED, null);
1058            }
1059            setDismissKeyguard(false);
1060            ActivityOptions.abort(options);
1061            return err;
1062        }
1063
1064        final int startAnyPerm = mService.checkPermission(
1065                START_ANY_ACTIVITY, callingPid, callingUid);
1066        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1067                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1068        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1069            if (resultRecord != null) {
1070                resultStack.sendActivityResultLocked(-1,
1071                    resultRecord, resultWho, requestCode,
1072                    Activity.RESULT_CANCELED, null);
1073            }
1074            setDismissKeyguard(false);
1075            String msg;
1076            if (!aInfo.exported) {
1077                msg = "Permission Denial: starting " + intent.toString()
1078                        + " from " + callerApp + " (pid=" + callingPid
1079                        + ", uid=" + callingUid + ")"
1080                        + " not exported from uid " + aInfo.applicationInfo.uid;
1081            } else {
1082                msg = "Permission Denial: starting " + intent.toString()
1083                        + " from " + callerApp + " (pid=" + callingPid
1084                        + ", uid=" + callingUid + ")"
1085                        + " requires " + aInfo.permission;
1086            }
1087            Slog.w(TAG, msg);
1088            throw new SecurityException(msg);
1089        }
1090
1091        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent,
1092                callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo);
1093
1094        if (mService.mController != null) {
1095            try {
1096                // The Intent we give to the watcher has the extra data
1097                // stripped off, since it can contain private information.
1098                Intent watchIntent = intent.cloneFilter();
1099                abort |= !mService.mController.activityStarting(watchIntent,
1100                        aInfo.applicationInfo.packageName);
1101            } catch (RemoteException e) {
1102                mService.mController = null;
1103            }
1104        }
1105
1106        if (abort) {
1107            if (resultRecord != null) {
1108                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1109                        Activity.RESULT_CANCELED, null);
1110            }
1111            // We pretend to the caller that it was really started, but
1112            // they will just get a cancel result.
1113            setDismissKeyguard(false);
1114            ActivityOptions.abort(options);
1115            return ActivityManager.START_SUCCESS;
1116        }
1117
1118        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1119                intent, resolvedType, aInfo, mService.mConfiguration,
1120                resultRecord, resultWho, requestCode, componentSpecified, this);
1121        if (outActivity != null) {
1122            outActivity[0] = r;
1123        }
1124
1125        final ActivityStack stack = getFocusedStack();
1126        if (stack.mResumedActivity == null
1127                || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
1128            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1129                PendingActivityLaunch pal =
1130                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1131                mService.mPendingActivityLaunches.add(pal);
1132                setDismissKeyguard(false);
1133                ActivityOptions.abort(options);
1134                return ActivityManager.START_SWITCHES_CANCELED;
1135            }
1136        }
1137
1138        if (mService.mDidAppSwitch) {
1139            // This is the second allowed switch since we stopped switches,
1140            // so now just generally allow switches.  Use case: user presses
1141            // home (switches disabled, switch to home, mDidAppSwitch now true);
1142            // user taps a home icon (coming from home so allowed, we hit here
1143            // and now allow anyone to switch again).
1144            mService.mAppSwitchesAllowedTime = 0;
1145        } else {
1146            mService.mDidAppSwitch = true;
1147        }
1148
1149        mService.doPendingActivityLaunchesLocked(false);
1150
1151        err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
1152        if (stack.mPausingActivity == null) {
1153            // Someone asked to have the keyguard dismissed on the next
1154            // activity start, but we are not actually doing an activity
1155            // switch...  just dismiss the keyguard now, because we
1156            // probably want to see whatever is behind it.
1157            dismissKeyguard();
1158        }
1159        return err;
1160    }
1161
1162    ActivityStack getCorrectStack(ActivityRecord r) {
1163        if (!r.isHomeActivity || (r.task != null && !r.task.isHomeTask())) {
1164            int stackNdx;
1165            for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1166                if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) {
1167                    break;
1168                }
1169            }
1170            if (stackNdx == 0) {
1171                // Time to create the first app stack for this user.
1172                int stackId = mService.createStack(-1, HOME_STACK_ID,
1173                        StackBox.TASK_STACK_GOES_OVER, 1.0f);
1174                mFocusedStack = getStack(stackId);
1175            }
1176            return mFocusedStack;
1177        }
1178        return mHomeStack;
1179    }
1180
1181    void setFocusedStack(ActivityRecord r) {
1182        if (r == null) {
1183            return;
1184        }
1185        if (r.isHomeActivity || (r.task != null && r.task.isHomeTask())) {
1186            if (mStackState != STACK_STATE_HOME_IN_FRONT) {
1187                mStackState = STACK_STATE_HOME_TO_FRONT;
1188            }
1189        } else {
1190            mFocusedStack = r.task.stack;
1191            if (mStackState != STACK_STATE_HOME_IN_BACK) {
1192                mStackState = STACK_STATE_HOME_TO_BACK;
1193            }
1194        }
1195    }
1196
1197    final int startActivityUncheckedLocked(ActivityRecord r,
1198            ActivityRecord sourceRecord, int startFlags, boolean doResume,
1199            Bundle options) {
1200        final Intent intent = r.intent;
1201        final int callingUid = r.launchedFromUid;
1202
1203        int launchFlags = intent.getFlags();
1204
1205        // We'll invoke onUserLeaving before onPause only if the launching
1206        // activity did not explicitly state that this is an automated launch.
1207        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1208        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1209
1210        // If the caller has asked not to resume at this point, we make note
1211        // of this in the record so that we can skip it when trying to find
1212        // the top running activity.
1213        if (!doResume) {
1214            r.delayedResume = true;
1215        }
1216
1217        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1218
1219        // If the onlyIfNeeded flag is set, then we can do this if the activity
1220        // being launched is the same as the one making the call...  or, as
1221        // a special case, if we do not know the caller then we count the
1222        // current top activity as the caller.
1223        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1224            ActivityRecord checkedCaller = sourceRecord;
1225            if (checkedCaller == null) {
1226                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1227            }
1228            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1229                // Caller is not the same as launcher, so always needed.
1230                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1231            }
1232        }
1233
1234        if (sourceRecord == null) {
1235            // This activity is not being started from another...  in this
1236            // case we -always- start a new task.
1237            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1238                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1239                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1240                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1241            }
1242        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1243            // The original activity who is starting us is running as a single
1244            // instance...  this new activity it is starting must go on its
1245            // own task.
1246            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1247        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1248                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1249            // The activity being started is a single instance...  it always
1250            // gets launched into its own task.
1251            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1252        }
1253
1254        final ActivityStack sourceStack;
1255        TaskRecord sourceTask;
1256        if (sourceRecord != null) {
1257            sourceTask = sourceRecord.task;
1258            sourceStack = sourceTask.stack;
1259        } else {
1260            sourceTask = null;
1261            sourceStack = null;
1262        }
1263
1264        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1265            // For whatever reason this activity is being launched into a new
1266            // task...  yet the caller has requested a result back.  Well, that
1267            // is pretty messed up, so instead immediately send back a cancel
1268            // and let the new task continue launched as normal without a
1269            // dependency on its originator.
1270            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1271            r.resultTo.task.stack.sendActivityResultLocked(-1,
1272                    r.resultTo, r.resultWho, r.requestCode,
1273                Activity.RESULT_CANCELED, null);
1274            r.resultTo = null;
1275        }
1276
1277        boolean addingToTask = false;
1278        boolean movedHome = false;
1279        TaskRecord reuseTask = null;
1280        ActivityStack targetStack;
1281        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1282                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1283                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1284                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1285            // If bring to front is requested, and no result is requested, and
1286            // we can find a task that was started with this same
1287            // component, then instead of launching bring that one to the front.
1288            if (r.resultTo == null) {
1289                // See if there is a task to bring to the front.  If this is
1290                // a SINGLE_INSTANCE activity, there can be one and only one
1291                // instance of it in the history, and it is always in its own
1292                // unique task, so we do a special search.
1293                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1294                        ? findTaskLocked(intent, r.info)
1295                        : findActivityLocked(intent, r.info);
1296                if (intentActivity != null) {
1297                    if (r.task == null) {
1298                        r.task = intentActivity.task;
1299                    }
1300                    targetStack = intentActivity.task.stack;
1301                    moveHomeStack(targetStack.isHomeStack());
1302                    if (intentActivity.task.intent == null) {
1303                        // This task was started because of movement of
1304                        // the activity based on affinity...  now that we
1305                        // are actually launching it, we can assign the
1306                        // base intent.
1307                        intentActivity.task.setIntent(intent, r.info);
1308                    }
1309                    // If the target task is not in the front, then we need
1310                    // to bring it to the front...  except...  well, with
1311                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1312                    // to have the same behavior as if a new instance was
1313                    // being started, which means not bringing it to the front
1314                    // if the caller is not itself in the front.
1315                    final ActivityStack lastStack = getLastStack();
1316                    ActivityRecord curTop = lastStack == null?
1317                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1318                    if (curTop != null && curTop.task != intentActivity.task) {
1319                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1320                        if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) {
1321                            // We really do want to push this one into the
1322                            // user's face, right now.
1323                            movedHome = true;
1324                            if ((launchFlags &
1325                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1326                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1327                                // Caller wants to appear on home activity, so before starting
1328                                // their own activity we will bring home to the front.
1329                                r.mLaunchHomeTaskNext = true;
1330                            }
1331                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1332                            options = null;
1333                        }
1334                    }
1335                    // If the caller has requested that the target task be
1336                    // reset, then do so.
1337                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1338                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1339                    }
1340                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1341                        // We don't need to start a new activity, and
1342                        // the client said not to do anything if that
1343                        // is the case, so this is it!  And for paranoia, make
1344                        // sure we have correctly resumed the top activity.
1345                        if (doResume) {
1346                            setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
1347                            resumeTopActivitiesLocked(targetStack, null, options);
1348                        } else {
1349                            ActivityOptions.abort(options);
1350                        }
1351                        if (r.task == null)  Slog.v(TAG,
1352                                "startActivityUncheckedLocked: task left null",
1353                                new RuntimeException("here").fillInStackTrace());
1354                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1355                    }
1356                    if ((launchFlags &
1357                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1358                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1359                        // The caller has requested to completely replace any
1360                        // existing task with its new activity.  Well that should
1361                        // not be too hard...
1362                        reuseTask = intentActivity.task;
1363                        reuseTask.performClearTaskLocked();
1364                        reuseTask.setIntent(r.intent, r.info);
1365                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1366                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1367                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1368                        // In this situation we want to remove all activities
1369                        // from the task up to the one being started.  In most
1370                        // cases this means we are resetting the task to its
1371                        // initial state.
1372                        ActivityRecord top =
1373                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1374                        if (top != null) {
1375                            if (top.frontOfTask) {
1376                                // Activity aliases may mean we use different
1377                                // intents for the top activity, so make sure
1378                                // the task now has the identity of the new
1379                                // intent.
1380                                top.task.setIntent(r.intent, r.info);
1381                            }
1382                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1383                                    r, top.task);
1384                            top.deliverNewIntentLocked(callingUid, r.intent);
1385                        } else {
1386                            // A special case: we need to
1387                            // start the activity because it is not currently
1388                            // running, and the caller has asked to clear the
1389                            // current task to have this activity at the top.
1390                            addingToTask = true;
1391                            // Now pretend like this activity is being started
1392                            // by the top of its task, so it is put in the
1393                            // right place.
1394                            sourceRecord = intentActivity;
1395                        }
1396                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1397                        // In this case the top activity on the task is the
1398                        // same as the one being launched, so we take that
1399                        // as a request to bring the task to the foreground.
1400                        // If the top activity in the task is the root
1401                        // activity, deliver this new intent to it if it
1402                        // desires.
1403                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1404                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1405                                && intentActivity.realActivity.equals(r.realActivity)) {
1406                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1407                                    intentActivity.task);
1408                            if (intentActivity.frontOfTask) {
1409                                intentActivity.task.setIntent(r.intent, r.info);
1410                            }
1411                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1412                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1413                            // In this case we are launching the root activity
1414                            // of the task, but with a different intent.  We
1415                            // should start a new instance on top.
1416                            addingToTask = true;
1417                            sourceRecord = intentActivity;
1418                        }
1419                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1420                        // In this case an activity is being launched in to an
1421                        // existing task, without resetting that task.  This
1422                        // is typically the situation of launching an activity
1423                        // from a notification or shortcut.  We want to place
1424                        // the new activity on top of the current task.
1425                        addingToTask = true;
1426                        sourceRecord = intentActivity;
1427                    } else if (!intentActivity.task.rootWasReset) {
1428                        // In this case we are launching in to an existing task
1429                        // that has not yet been started from its front door.
1430                        // The current task has been brought to the front.
1431                        // Ideally, we'd probably like to place this new task
1432                        // at the bottom of its stack, but that's a little hard
1433                        // to do with the current organization of the code so
1434                        // for now we'll just drop it.
1435                        intentActivity.task.setIntent(r.intent, r.info);
1436                    }
1437                    if (!addingToTask && reuseTask == null) {
1438                        // We didn't do anything...  but it was needed (a.k.a., client
1439                        // don't use that intent!)  And for paranoia, make
1440                        // sure we have correctly resumed the top activity.
1441                        if (doResume) {
1442                            setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1443                            targetStack.resumeTopActivityLocked(null, options);
1444                        } else {
1445                            ActivityOptions.abort(options);
1446                        }
1447                        if (r.task == null)  Slog.v(TAG,
1448                            "startActivityUncheckedLocked: task left null",
1449                            new RuntimeException("here").fillInStackTrace());
1450                        return ActivityManager.START_TASK_TO_FRONT;
1451                    }
1452                }
1453            }
1454        }
1455
1456        //String uri = r.intent.toURI();
1457        //Intent intent2 = new Intent(uri);
1458        //Slog.i(TAG, "Given intent: " + r.intent);
1459        //Slog.i(TAG, "URI is: " + uri);
1460        //Slog.i(TAG, "To intent: " + intent2);
1461
1462        if (r.packageName != null) {
1463            // If the activity being launched is the same as the one currently
1464            // at the top, then we need to check if it should only be launched
1465            // once.
1466            ActivityStack topStack = getFocusedStack();
1467            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1468            if (top != null && r.resultTo == null) {
1469                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1470                    if (top.app != null && top.app.thread != null) {
1471                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1472                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1473                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1474                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1475                                    top.task);
1476                            // For paranoia, make sure we have correctly
1477                            // resumed the top activity.
1478                            if (doResume) {
1479                                setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
1480                                resumeTopActivitiesLocked();
1481                            }
1482                            ActivityOptions.abort(options);
1483                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1484                                // We don't need to start a new activity, and
1485                                // the client said not to do anything if that
1486                                // is the case, so this is it!
1487                                if (r.task == null)  Slog.v(TAG,
1488                                    "startActivityUncheckedLocked: task left null",
1489                                    new RuntimeException("here").fillInStackTrace());
1490                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1491                            }
1492                            top.deliverNewIntentLocked(callingUid, r.intent);
1493                            if (r.task == null)  Slog.v(TAG,
1494                                "startActivityUncheckedLocked: task left null",
1495                                new RuntimeException("here").fillInStackTrace());
1496                            return ActivityManager.START_DELIVERED_TO_TOP;
1497                        }
1498                    }
1499                }
1500            }
1501
1502        } else {
1503            if (r.resultTo != null) {
1504                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1505                        r.requestCode, Activity.RESULT_CANCELED, null);
1506            }
1507            ActivityOptions.abort(options);
1508            if (r.task == null)  Slog.v(TAG,
1509                "startActivityUncheckedLocked: task left null",
1510                new RuntimeException("here").fillInStackTrace());
1511            return ActivityManager.START_CLASS_NOT_FOUND;
1512        }
1513
1514        boolean newTask = false;
1515        boolean keepCurTransition = false;
1516
1517        // Should this be considered a new task?
1518        if (r.resultTo == null && !addingToTask
1519                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1520            targetStack = getCorrectStack(r);
1521            moveHomeStack(targetStack.isHomeStack());
1522            if (reuseTask == null) {
1523                r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1524                        null, true);
1525                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1526                        r.task);
1527            } else {
1528                r.setTask(reuseTask, reuseTask, true);
1529            }
1530            newTask = true;
1531            if (!movedHome) {
1532                if ((launchFlags &
1533                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1534                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1535                    // Caller wants to appear on home activity, so before starting
1536                    // their own activity we will bring home to the front.
1537                    r.mLaunchHomeTaskNext = true;
1538                }
1539            }
1540        } else if (sourceRecord != null) {
1541            sourceTask = sourceRecord.task;
1542            targetStack = sourceTask.stack;
1543            moveHomeStack(targetStack.isHomeStack());
1544            if (!addingToTask &&
1545                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1546                // In this case, we are adding the activity to an existing
1547                // task, but the caller has asked to clear that task if the
1548                // activity is already running.
1549                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1550                keepCurTransition = true;
1551                if (top != null) {
1552                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1553                    top.deliverNewIntentLocked(callingUid, r.intent);
1554                    // For paranoia, make sure we have correctly
1555                    // resumed the top activity.
1556                    if (doResume) {
1557                        setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
1558                        targetStack.resumeTopActivityLocked(null);
1559                    }
1560                    ActivityOptions.abort(options);
1561                    if (r.task == null)  Slog.v(TAG,
1562                        "startActivityUncheckedLocked: task left null",
1563                        new RuntimeException("here").fillInStackTrace());
1564                    return ActivityManager.START_DELIVERED_TO_TOP;
1565                }
1566            } else if (!addingToTask &&
1567                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1568                // In this case, we are launching an activity in our own task
1569                // that may already be running somewhere in the history, and
1570                // we want to shuffle it to the front of the stack if so.
1571                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1572                if (top != null) {
1573                    final TaskRecord task = top.task;
1574                    task.moveActivityToFrontLocked(top);
1575                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1576                    top.updateOptionsLocked(options);
1577                    top.deliverNewIntentLocked(callingUid, r.intent);
1578                    if (doResume) {
1579                        setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
1580                        targetStack.resumeTopActivityLocked(null);
1581                    }
1582                    if (r.task == null)  Slog.v(TAG,
1583                        "startActivityUncheckedLocked: task left null",
1584                        new RuntimeException("here").fillInStackTrace());
1585                    return ActivityManager.START_DELIVERED_TO_TOP;
1586                }
1587            }
1588            // An existing activity is starting this new activity, so we want
1589            // to keep the new one in the same task as the one that is starting
1590            // it.
1591            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
1592            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1593                    + " in existing task " + r.task);
1594
1595        } else {
1596            // This not being started from an existing activity, and not part
1597            // of a new task...  just put it in the top task, though these days
1598            // this case should never happen.
1599            targetStack = getCorrectStack(r);
1600            moveHomeStack(targetStack.isHomeStack());
1601            ActivityRecord prev = targetStack.topActivity();
1602            r.setTask(prev != null ? prev.task
1603                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1604                    null, true);
1605            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1606                    + " in new guessed " + r.task);
1607        }
1608
1609        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1610                intent, r.getUriPermissionsLocked());
1611
1612        if (newTask) {
1613            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1614        }
1615        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1616        setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
1617        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1618        return ActivityManager.START_SUCCESS;
1619    }
1620
1621    // Checked.
1622    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1623            Configuration config) {
1624        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1625
1626        ActivityRecord res = null;
1627
1628        ArrayList<ActivityRecord> stops = null;
1629        ArrayList<ActivityRecord> finishes = null;
1630        ArrayList<UserStartedState> startingUsers = null;
1631        int NS = 0;
1632        int NF = 0;
1633        IApplicationThread sendThumbnail = null;
1634        boolean booting = false;
1635        boolean enableScreen = false;
1636        boolean activityRemoved = false;
1637
1638        ActivityRecord r = ActivityRecord.forToken(token);
1639        if (r != null) {
1640            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1641                    Debug.getCallers(4));
1642            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1643            r.finishLaunchTickingLocked();
1644            res = r.task.stack.activityIdleInternalLocked(token);
1645            if (res != null) {
1646                if (fromTimeout) {
1647                    reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1648                }
1649
1650                // This is a hack to semi-deal with a race condition
1651                // in the client where it can be constructed with a
1652                // newer configuration from when we asked it to launch.
1653                // We'll update with whatever configuration it now says
1654                // it used to launch.
1655                if (config != null) {
1656                    r.configuration = config;
1657                }
1658
1659                // We are now idle.  If someone is waiting for a thumbnail from
1660                // us, we can now deliver.
1661                r.idle = true;
1662                if (allResumedActivitiesIdle()) {
1663                    mService.scheduleAppGcsLocked();
1664                }
1665                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1666                    sendThumbnail = r.app.thread;
1667                    r.thumbnailNeeded = false;
1668                }
1669
1670                //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1671                if (!mService.mBooted && isFrontStack(r.task.stack)) {
1672                    mService.mBooted = true;
1673                    enableScreen = true;
1674                }
1675            } else if (fromTimeout) {
1676                reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
1677            }
1678        }
1679
1680        // Atomically retrieve all of the other things to do.
1681        stops = processStoppingActivitiesLocked(true);
1682        NS = stops != null ? stops.size() : 0;
1683        if ((NF=mFinishingActivities.size()) > 0) {
1684            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1685            mFinishingActivities.clear();
1686        }
1687
1688        final ArrayList<ActivityRecord> thumbnails;
1689        final int NT = mCancelledThumbnails.size();
1690        if (NT > 0) {
1691            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1692            mCancelledThumbnails.clear();
1693        } else {
1694            thumbnails = null;
1695        }
1696
1697        if (isFrontStack(mHomeStack)) {
1698            booting = mService.mBooting;
1699            mService.mBooting = false;
1700        }
1701
1702        if (mStartingUsers.size() > 0) {
1703            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1704            mStartingUsers.clear();
1705        }
1706
1707        // Perform the following actions from unsynchronized state.
1708        final IApplicationThread thumbnailThread = sendThumbnail;
1709        mHandler.post(new Runnable() {
1710            @Override
1711            public void run() {
1712                if (thumbnailThread != null) {
1713                    try {
1714                        thumbnailThread.requestThumbnail(token);
1715                    } catch (Exception e) {
1716                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1717                        mService.sendPendingThumbnail(null, token, null, null, true);
1718                    }
1719                }
1720
1721                // Report back to any thumbnail receivers.
1722                for (int i = 0; i < NT; i++) {
1723                    ActivityRecord r = thumbnails.get(i);
1724                    mService.sendPendingThumbnail(r, null, null, null, true);
1725                }
1726            }
1727        });
1728
1729        // Stop any activities that are scheduled to do so but have been
1730        // waiting for the next one to start.
1731        for (int i = 0; i < NS; i++) {
1732            r = stops.get(i);
1733            final ActivityStack stack = r.task.stack;
1734            if (r.finishing) {
1735                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1736            } else {
1737                stack.stopActivityLocked(r);
1738            }
1739        }
1740
1741        // Finish any activities that are scheduled to do so but have been
1742        // waiting for the next one to start.
1743        for (int i = 0; i < NF; i++) {
1744            r = finishes.get(i);
1745            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1746        }
1747
1748        if (booting) {
1749            mService.finishBooting();
1750        } else if (startingUsers != null) {
1751            for (int i = 0; i < startingUsers.size(); i++) {
1752                mService.finishUserSwitch(startingUsers.get(i));
1753            }
1754        }
1755
1756        mService.trimApplications();
1757        //dump();
1758        //mWindowManager.dump();
1759
1760        if (enableScreen) {
1761            mService.enableScreenAfterBoot();
1762        }
1763
1764        if (activityRemoved) {
1765            resumeTopActivitiesLocked();
1766        }
1767
1768        return res;
1769    }
1770
1771    void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1772        // Just in case.
1773        final int numStacks = mStacks.size();
1774        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1775            mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
1776        }
1777    }
1778
1779    void closeSystemDialogsLocked() {
1780        final int numStacks = mStacks.size();
1781        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1782            final ActivityStack stack = mStacks.get(stackNdx);
1783            stack.closeSystemDialogsLocked();
1784        }
1785    }
1786
1787    /**
1788     * @return true if some activity was finished (or would have finished if doit were true).
1789     */
1790    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1791        boolean didSomething = false;
1792        final int numStacks = mStacks.size();
1793        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1794            final ActivityStack stack = mStacks.get(stackNdx);
1795            if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1796                didSomething = true;
1797            }
1798        }
1799        return didSomething;
1800    }
1801
1802    boolean resumeTopActivitiesLocked() {
1803        return resumeTopActivitiesLocked(null, null, null);
1804    }
1805
1806    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1807            Bundle targetOptions) {
1808        if (targetStack == null) {
1809            targetStack = getFocusedStack();
1810        }
1811        boolean result = false;
1812        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1813            final ActivityStack stack = mStacks.get(stackNdx);
1814            if (isFrontStack(stack)) {
1815                if (stack == targetStack) {
1816                    result = stack.resumeTopActivityLocked(target, targetOptions);
1817                } else {
1818                    stack.resumeTopActivityLocked(null);
1819                }
1820            }
1821        }
1822        return result;
1823    }
1824
1825    void finishTopRunningActivityLocked(ProcessRecord app) {
1826        final int numStacks = mStacks.size();
1827        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1828            final ActivityStack stack = mStacks.get(stackNdx);
1829            stack.finishTopRunningActivityLocked(app);
1830        }
1831    }
1832
1833    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
1834        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1835            if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
1836                return;
1837            }
1838        }
1839    }
1840
1841    ActivityStack getStack(int stackId) {
1842        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1843            final ActivityStack stack = mStacks.get(stackNdx);
1844            if (stack.getStackId() == stackId) {
1845                return stack;
1846            }
1847        }
1848        return null;
1849    }
1850
1851    ArrayList<ActivityStack> getStacks() {
1852        return new ArrayList<ActivityStack>(mStacks);
1853    }
1854
1855    int createStack() {
1856        while (true) {
1857            if (++mLastStackId <= HOME_STACK_ID) {
1858                mLastStackId = HOME_STACK_ID + 1;
1859            }
1860            if (getStack(mLastStackId) == null) {
1861                break;
1862            }
1863        }
1864        mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
1865        return mLastStackId;
1866    }
1867
1868    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
1869        final ActivityStack stack = getStack(stackId);
1870        if (stack == null) {
1871            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
1872            return;
1873        }
1874        stack.moveTask(taskId, toTop);
1875        resumeTopActivitiesLocked();
1876    }
1877
1878    ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
1879        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1880            final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info);
1881            if (ar != null) {
1882                return ar;
1883            }
1884        }
1885        return null;
1886    }
1887
1888    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
1889        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1890            final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
1891            if (ar != null) {
1892                return ar;
1893            }
1894        }
1895        return null;
1896    }
1897
1898    void goingToSleepLocked() {
1899        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1900            mStacks.get(stackNdx).stopIfSleepingLocked();
1901        }
1902    }
1903
1904    boolean shutdownLocked(int timeout) {
1905        boolean timedout = false;
1906        final int numStacks = mStacks.size();
1907        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1908            final ActivityStack stack = mStacks.get(stackNdx);
1909            if (stack.mResumedActivity != null) {
1910                stack.stopIfSleepingLocked();
1911                final long endTime = System.currentTimeMillis() + timeout;
1912                while (stack.mResumedActivity != null || stack.mPausingActivity != null) {
1913                    long delay = endTime - System.currentTimeMillis();
1914                    if (delay <= 0) {
1915                        Slog.w(TAG, "Activity manager shutdown timed out");
1916                        timedout = true;
1917                        break;
1918                    }
1919                    try {
1920                        mService.wait();
1921                    } catch (InterruptedException e) {
1922                    }
1923                }
1924            }
1925        }
1926        return timedout;
1927    }
1928
1929    void comeOutOfSleepIfNeededLocked() {
1930        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1931            final ActivityStack stack = mStacks.get(stackNdx);
1932            stack.awakeFromSleepingLocked();
1933            if (isFrontStack(stack)) {
1934                resumeTopActivitiesLocked();
1935            }
1936        }
1937    }
1938
1939    boolean reportResumedActivityLocked(ActivityRecord r) {
1940        final ActivityStack stack = r.task.stack;
1941        if (isFrontStack(stack)) {
1942            mService.updateUsageStats(r, true);
1943            mService.setFocusedActivityLocked(r);
1944        }
1945        if (allResumedActivitiesComplete()) {
1946            ensureActivitiesVisibleLocked(null, 0);
1947            mWindowManager.executeAppTransition();
1948            return true;
1949        }
1950        return false;
1951    }
1952
1953    void handleAppCrashLocked(ProcessRecord app) {
1954        final int numStacks = mStacks.size();
1955        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1956            final ActivityStack stack = mStacks.get(stackNdx);
1957            stack.handleAppCrashLocked(app);
1958        }
1959    }
1960
1961    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
1962        // First the front stacks. In case any are not fullscreen and are in front of home.
1963        boolean showHomeBehindStack = false;
1964        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1965            final ActivityStack stack = mStacks.get(stackNdx);
1966            if (isFrontStack(stack)) {
1967                showHomeBehindStack =
1968                        stack.ensureActivitiesVisibleLocked(starting, configChanges);
1969            }
1970        }
1971        // Now do back stacks.
1972        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1973            final ActivityStack stack = mStacks.get(stackNdx);
1974            if (!isFrontStack(stack)) {
1975                stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
1976            }
1977        }
1978    }
1979
1980    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
1981        final int numStacks = mStacks.size();
1982        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1983            final ActivityStack stack = mStacks.get(stackNdx);
1984            stack.scheduleDestroyActivities(app, false, reason);
1985        }
1986    }
1987
1988    boolean switchUserLocked(int userId, UserStartedState uss) {
1989        mUserStates.put(mCurrentUser, new UserState());
1990        mCurrentUser = userId;
1991        UserState userState = mUserStates.get(userId);
1992        if (userState != null) {
1993            userState.restore();
1994            mUserStates.delete(userId);
1995        } else {
1996            mFocusedStack = null;
1997            mStackState = STACK_STATE_HOME_IN_FRONT;
1998        }
1999
2000        mStartingUsers.add(uss);
2001        boolean haveActivities = mHomeStack.switchUserLocked(userId);
2002
2003        resumeTopActivitiesLocked();
2004
2005        return haveActivities;
2006    }
2007
2008    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2009        int N = mStoppingActivities.size();
2010        if (N <= 0) return null;
2011
2012        ArrayList<ActivityRecord> stops = null;
2013
2014        final boolean nowVisible = allResumedActivitiesVisible();
2015        for (int i=0; i<N; i++) {
2016            ActivityRecord s = mStoppingActivities.get(i);
2017            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2018                    + nowVisible + " waitingVisible=" + s.waitingVisible
2019                    + " finishing=" + s.finishing);
2020            if (s.waitingVisible && nowVisible) {
2021                mWaitingVisibleActivities.remove(s);
2022                s.waitingVisible = false;
2023                if (s.finishing) {
2024                    // If this activity is finishing, it is sitting on top of
2025                    // everyone else but we now know it is no longer needed...
2026                    // so get rid of it.  Otherwise, we need to go through the
2027                    // normal flow and hide it once we determine that it is
2028                    // hidden by the activities in front of it.
2029                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2030                    mWindowManager.setAppVisibility(s.appToken, false);
2031                }
2032            }
2033            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2034                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2035                if (stops == null) {
2036                    stops = new ArrayList<ActivityRecord>();
2037                }
2038                stops.add(s);
2039                mStoppingActivities.remove(i);
2040                N--;
2041                i--;
2042            }
2043        }
2044
2045        return stops;
2046    }
2047
2048    void validateTopActivitiesLocked() {
2049        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2050            final ActivityStack stack = mStacks.get(stackNdx);
2051            final ActivityRecord r = stack.topRunningActivityLocked(null);
2052            if (isFrontStack(stack)) {
2053                if (r == null) {
2054                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2055                } else {
2056                    if (stack.mPausingActivity != null) {
2057                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2058                            " state=" + r.state);
2059                    }
2060                    if (r.state != ActivityState.INITIALIZING &&
2061                            r.state != ActivityState.RESUMED) {
2062                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2063                                " state=" + r.state);
2064                    }
2065                }
2066            } else {
2067                if (stack.mResumedActivity != null) {
2068                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2069                        " state=" + r.state);
2070                }
2071                if (r != null && (r.state == ActivityState.INITIALIZING
2072                        || r.state == ActivityState.RESUMED)) {
2073                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2074                            " state=" + r.state);
2075                }
2076            }
2077        }
2078    }
2079
2080    public void dump(PrintWriter pw, String prefix) {
2081        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2082                pw.println(mDismissKeyguardOnNextActivity);
2083    }
2084
2085    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2086        return getFocusedStack().getDumpActivitiesLocked(name);
2087    }
2088
2089    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2090            boolean dumpClient, String dumpPackage) {
2091        final int numStacks = mStacks.size();
2092        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2093            final ActivityStack stack = mStacks.get(stackNdx);
2094            pw.print("  Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":");
2095            stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
2096            pw.println(" ");
2097            pw.println("  Running activities (most recent first):");
2098            dumpHistoryList(fd, pw, stack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
2099                    dumpPackage);
2100            if (stack.mGoingToSleepActivities.size() > 0) {
2101                pw.println(" ");
2102                pw.println("  Activities waiting to sleep:");
2103                dumpHistoryList(fd, pw, stack.mGoingToSleepActivities, "  ", "Sleep", false,
2104                        !dumpAll, false, dumpPackage);
2105            }
2106
2107            pw.print("  Stack #"); pw.println(mStacks.indexOf(stack));
2108            if (stack.mPausingActivity != null) {
2109                pw.println("  mPausingActivity: " + stack.mPausingActivity);
2110            }
2111            pw.println("  mResumedActivity: " + stack.mResumedActivity);
2112            if (dumpAll) {
2113                pw.println("  mLastPausedActivity: " + stack.mLastPausedActivity);
2114                pw.println("  mSleepTimeout: " + stack.mSleepTimeout);
2115            }
2116        }
2117
2118        if (mFinishingActivities.size() > 0) {
2119            pw.println(" ");
2120            pw.println("  Activities waiting to finish:");
2121            dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll, false,
2122                    dumpPackage);
2123        }
2124
2125        if (mStoppingActivities.size() > 0) {
2126            pw.println(" ");
2127            pw.println("  Activities waiting to stop:");
2128            dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll, false,
2129                    dumpPackage);
2130        }
2131
2132        if (mWaitingVisibleActivities.size() > 0) {
2133            pw.println(" ");
2134            pw.println("  Activities waiting for another to become visible:");
2135            dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2136                    false, dumpPackage);
2137        }
2138
2139        if (dumpAll) {
2140            pw.println(" ");
2141            pw.println("  mCurTaskId: " + mCurTaskId);
2142        }
2143        return true;
2144    }
2145
2146    static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2147            String prefix, String label, boolean complete, boolean brief, boolean client,
2148            String dumpPackage) {
2149        TaskRecord lastTask = null;
2150        boolean needNL = false;
2151        final String innerPrefix = prefix + "      ";
2152        final String[] args = new String[0];
2153        for (int i=list.size()-1; i>=0; i--) {
2154            final ActivityRecord r = list.get(i);
2155            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2156                continue;
2157            }
2158            final boolean full = !brief && (complete || !r.isInHistory());
2159            if (needNL) {
2160                pw.println(" ");
2161                needNL = false;
2162            }
2163            if (lastTask != r.task) {
2164                lastTask = r.task;
2165                pw.print(prefix);
2166                pw.print(full ? "* " : "  ");
2167                pw.println(lastTask);
2168                if (full) {
2169                    lastTask.dump(pw, prefix + "  ");
2170                } else if (complete) {
2171                    // Complete + brief == give a summary.  Isn't that obvious?!?
2172                    if (lastTask.intent != null) {
2173                        pw.print(prefix); pw.print("  ");
2174                                pw.println(lastTask.intent.toInsecureStringWithClip());
2175                    }
2176                }
2177            }
2178            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2179            pw.print(" #"); pw.print(i); pw.print(": ");
2180            pw.println(r);
2181            if (full) {
2182                r.dump(pw, innerPrefix);
2183            } else if (complete) {
2184                // Complete + brief == give a summary.  Isn't that obvious?!?
2185                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2186                if (r.app != null) {
2187                    pw.print(innerPrefix); pw.println(r.app);
2188                }
2189            }
2190            if (client && r.app != null && r.app.thread != null) {
2191                // flush anything that is already in the PrintWriter since the thread is going
2192                // to write to the file descriptor directly
2193                pw.flush();
2194                try {
2195                    TransferPipe tp = new TransferPipe();
2196                    try {
2197                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2198                                r.appToken, innerPrefix, args);
2199                        // Short timeout, since blocking here can
2200                        // deadlock with the application.
2201                        tp.go(fd, 2000);
2202                    } finally {
2203                        tp.kill();
2204                    }
2205                } catch (IOException e) {
2206                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2207                } catch (RemoteException e) {
2208                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2209                }
2210                needNL = true;
2211            }
2212        }
2213    }
2214
2215    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2216        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2217        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2218        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2219    }
2220
2221    final void scheduleIdleLocked() {
2222        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2223    }
2224
2225    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2226        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2227        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2228    }
2229
2230    final void scheduleResumeTopActivities() {
2231        mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2232    }
2233
2234    private final class ActivityStackSupervisorHandler extends Handler {
2235
2236        public ActivityStackSupervisorHandler(Looper looper) {
2237            super(looper);
2238        }
2239
2240        void activityIdleInternal(ActivityRecord r) {
2241            synchronized (mService) {
2242                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2243            }
2244        }
2245
2246        @Override
2247        public void handleMessage(Message msg) {
2248            switch (msg.what) {
2249                case IDLE_TIMEOUT_MSG: {
2250                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" +
2251                            Debug.getCallers(4));
2252                    if (mService.mDidDexOpt) {
2253                        mService.mDidDexOpt = false;
2254                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2255                        nmsg.obj = msg.obj;
2256                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2257                        return;
2258                    }
2259                    // We don't at this point know if the activity is fullscreen,
2260                    // so we need to be conservative and assume it isn't.
2261                    activityIdleInternal((ActivityRecord)msg.obj);
2262                } break;
2263                case IDLE_NOW_MSG: {
2264                    activityIdleInternal((ActivityRecord)msg.obj);
2265                } break;
2266                case RESUME_TOP_ACTIVITY_MSG: {
2267                    synchronized (mService) {
2268                        resumeTopActivitiesLocked();
2269                    }
2270                } break;
2271            }
2272        }
2273    }
2274
2275    private final class UserState {
2276        final ActivityStack mSavedFocusedStack;
2277        final int mSavedStackState;
2278
2279        public UserState() {
2280            ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2281            mSavedFocusedStack = supervisor.mFocusedStack;
2282            mSavedStackState = supervisor.mStackState;
2283        }
2284
2285        void restore() {
2286            ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2287            supervisor.mFocusedStack = mSavedFocusedStack;
2288            supervisor.mStackState = mSavedStackState;
2289        }
2290    }
2291}
2292