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