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.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
21import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
22import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
23import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
24import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
25import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
26import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
27import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
28import static android.content.pm.PackageManager.PERMISSION_GRANTED;
29import static com.android.server.am.ActivityManagerDebugConfig.*;
30import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
31import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
32import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
33import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
34import static com.android.server.am.ActivityStack.ActivityState.*;
35import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
36import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
37import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
38import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
39import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
40
41import android.Manifest;
42import android.app.Activity;
43import android.app.ActivityManager;
44import android.app.ActivityManager.StackInfo;
45import android.app.ActivityOptions;
46import android.app.AppGlobals;
47import android.app.AppOpsManager;
48import android.app.IActivityContainer;
49import android.app.IActivityContainerCallback;
50import android.app.IActivityManager;
51import android.app.IApplicationThread;
52import android.app.PendingIntent;
53import android.app.ProfilerInfo;
54import android.app.ActivityManager.RunningTaskInfo;
55import android.app.IActivityManager.WaitResult;
56import android.app.ResultInfo;
57import android.app.StatusBarManager;
58import android.app.admin.IDevicePolicyManager;
59import android.content.ComponentName;
60import android.content.Context;
61import android.content.IIntentSender;
62import android.content.Intent;
63import android.content.IntentSender;
64import android.content.pm.ActivityInfo;
65import android.content.pm.ApplicationInfo;
66import android.content.pm.PackageInfo;
67import android.content.pm.PackageManager;
68import android.content.pm.ResolveInfo;
69import android.content.res.Configuration;
70import android.graphics.Point;
71import android.graphics.Rect;
72import android.hardware.display.DisplayManager;
73import android.hardware.display.DisplayManager.DisplayListener;
74import android.hardware.display.DisplayManagerGlobal;
75import android.hardware.display.VirtualDisplay;
76import android.hardware.input.InputManager;
77import android.hardware.input.InputManagerInternal;
78import android.net.Uri;
79import android.os.Binder;
80import android.os.Bundle;
81import android.os.Debug;
82import android.os.Handler;
83import android.os.IBinder;
84import android.os.Looper;
85import android.os.Message;
86import android.os.ParcelFileDescriptor;
87import android.os.PowerManager;
88import android.os.Process;
89import android.os.RemoteException;
90import android.os.ServiceManager;
91import android.os.SystemClock;
92import android.os.TransactionTooLargeException;
93import android.os.UserHandle;
94import android.os.WorkSource;
95import android.provider.MediaStore;
96import android.provider.Settings;
97import android.provider.Settings.SettingNotFoundException;
98import android.service.voice.IVoiceInteractionSession;
99import android.util.ArrayMap;
100import android.util.ArraySet;
101import android.util.EventLog;
102import android.util.Slog;
103import android.util.SparseArray;
104
105import android.util.SparseIntArray;
106import android.view.Display;
107import android.view.DisplayInfo;
108import android.view.InputEvent;
109import android.view.Surface;
110import com.android.internal.app.HeavyWeightSwitcherActivity;
111import com.android.internal.app.IVoiceInteractor;
112import com.android.internal.content.ReferrerIntent;
113import com.android.internal.os.TransferPipe;
114import com.android.internal.statusbar.IStatusBarService;
115import com.android.internal.util.ArrayUtils;
116import com.android.internal.widget.LockPatternUtils;
117import com.android.server.LocalServices;
118import com.android.server.am.ActivityStack.ActivityState;
119import com.android.server.wm.WindowManagerService;
120
121
122import java.io.FileDescriptor;
123import java.io.IOException;
124import java.io.PrintWriter;
125import java.util.ArrayList;
126import java.util.Arrays;
127import java.util.List;
128import java.util.Set;
129
130public final class ActivityStackSupervisor implements DisplayListener {
131    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
132    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
133    private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
134    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
135    private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
136    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
137    private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
138    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
139    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
140    private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
141    private static final String TAG_STACK = TAG + POSTFIX_STACK;
142    private static final String TAG_STATES = TAG + POSTFIX_STATES;
143    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
144    private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
145    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
146    private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
147
148    public static final int HOME_STACK_ID = 0;
149
150    /** How long we wait until giving up on the last activity telling us it is idle. */
151    static final int IDLE_TIMEOUT = 10 * 1000;
152
153    /** How long we can hold the sleep wake lock before giving up. */
154    static final int SLEEP_TIMEOUT = 5 * 1000;
155
156    // How long we can hold the launch wake lock before giving up.
157    static final int LAUNCH_TIMEOUT = 10 * 1000;
158
159    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
160    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
161    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
162    static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
163    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
164    static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
165    static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
166    static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
167    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
168    static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
169    static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
170    static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
171    static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
172    static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
173
174    private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
175
176    private static final String LOCK_TASK_TAG = "Lock-to-App";
177
178    // Activity actions an app cannot start if it uses a permission which is not granted.
179    private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
180            new ArrayMap<>();
181    static {
182        ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE,
183                Manifest.permission.CAMERA);
184        ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE,
185                Manifest.permission.CAMERA);
186        ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL,
187                Manifest.permission.CALL_PHONE);
188    }
189
190    /** Action restriction: launching the activity is not restricted. */
191    private static final int ACTIVITY_RESTRICTION_NONE = 0;
192    /** Action restriction: launching the activity is restricted by a permission. */
193    private static final int ACTIVITY_RESTRICTION_PERMISSION = 1;
194    /** Action restriction: launching the activity is restricted by an app op. */
195    private static final int ACTIVITY_RESTRICTION_APPOP = 2;
196
197    /** Status Bar Service **/
198    private IBinder mToken = new Binder();
199    private IStatusBarService mStatusBarService;
200    private IDevicePolicyManager mDevicePolicyManager;
201
202    // For debugging to make sure the caller when acquiring/releasing our
203    // wake lock is the system process.
204    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
205
206    final ActivityManagerService mService;
207
208    private final RecentTasks mRecentTasks;
209
210    final ActivityStackSupervisorHandler mHandler;
211
212    /** Short cut */
213    WindowManagerService mWindowManager;
214    DisplayManager mDisplayManager;
215
216    /** Identifier counter for all ActivityStacks */
217    private int mLastStackId = HOME_STACK_ID;
218
219    /** Task identifier that activities are currently being started in.  Incremented each time a
220     * new task is created. */
221    private int mCurTaskId = 0;
222
223    /** The current user */
224    private int mCurrentUser;
225
226    /** The stack containing the launcher app. Assumed to always be attached to
227     * Display.DEFAULT_DISPLAY. */
228    private ActivityStack mHomeStack;
229
230    /** The stack currently receiving input or launching the next activity. */
231    private ActivityStack mFocusedStack;
232
233    /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
234     * been resumed. If stacks are changing position this will hold the old stack until the new
235     * stack becomes resumed after which it will be set to mFocusedStack. */
236    private ActivityStack mLastFocusedStack;
237
238    /** List of activities that are waiting for a new activity to become visible before completing
239     * whatever operation they are supposed to do. */
240    final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
241
242    /** List of processes waiting to find out about the next visible activity. */
243    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>();
244
245    /** List of processes waiting to find out about the next launched activity. */
246    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>();
247
248    /** List of activities that are ready to be stopped, but waiting for the next activity to
249     * settle down before doing so. */
250    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
251
252    /** List of activities that are ready to be finished, but waiting for the previous activity to
253     * settle down before doing so.  It contains ActivityRecord objects. */
254    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
255
256    /** List of activities that are in the process of going to sleep. */
257    final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
258
259    /** Used on user changes */
260    final ArrayList<UserState> mStartingUsers = new ArrayList<>();
261
262    /** Used to queue up any background users being started */
263    final ArrayList<UserState> mStartingBackgroundUsers = new ArrayList<>();
264
265    /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
266     * is being brought in front of us. */
267    boolean mUserLeaving = false;
268
269    /** Set when we have taken too long waiting to go to sleep. */
270    boolean mSleepTimeout = false;
271
272    /** Indicates if we are running on a Leanback-only (TV) device. Only initialized after
273     * setWindowManager is called. **/
274    private boolean mLeanbackOnlyDevice;
275
276    /**
277     * We don't want to allow the device to go to sleep while in the process
278     * of launching an activity.  This is primarily to allow alarm intent
279     * receivers to launch an activity and get that to run before the device
280     * goes back to sleep.
281     */
282    PowerManager.WakeLock mLaunchingActivity;
283
284    /**
285     * Set when the system is going to sleep, until we have
286     * successfully paused the current activity and released our wake lock.
287     * At that point the system is allowed to actually sleep.
288     */
289    PowerManager.WakeLock mGoingToSleep;
290
291    /** Stack id of the front stack when user switched, indexed by userId. */
292    SparseIntArray mUserStackInFront = new SparseIntArray(2);
293
294    // TODO: Add listener for removal of references.
295    /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
296    private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>();
297
298    /** Mapping from displayId to display current state */
299    private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>();
300
301    InputManagerInternal mInputManagerInternal;
302
303    /** The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks
304     * may be finished until there is only one entry left. If this is empty the system is not
305     * in lockTask mode. */
306    ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>();
307    /** Store the current lock task mode. Possible values:
308     * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
309     * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
310     */
311    private int mLockTaskModeState;
312    /**
313     * Notifies the user when entering/exiting lock-task.
314     */
315    private LockTaskNotify mLockTaskNotify;
316
317    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<>();
318
319    /** Used to keep resumeTopActivityLocked() from being entered recursively */
320    boolean inResumeTopActivity;
321
322    /**
323     * Description of a request to start a new activity, which has been held
324     * due to app switches being disabled.
325     */
326    static class PendingActivityLaunch {
327        final ActivityRecord r;
328        final ActivityRecord sourceRecord;
329        final int startFlags;
330        final ActivityStack stack;
331
332        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
333                int _startFlags, ActivityStack _stack) {
334            r = _r;
335            sourceRecord = _sourceRecord;
336            startFlags = _startFlags;
337            stack = _stack;
338        }
339    }
340
341    public ActivityStackSupervisor(ActivityManagerService service, RecentTasks recentTasks) {
342        mService = service;
343        mRecentTasks = recentTasks;
344        mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
345    }
346
347    /**
348     * At the time when the constructor runs, the power manager has not yet been
349     * initialized.  So we initialize our wakelocks afterwards.
350     */
351    void initPowerManagement() {
352        PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
353        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
354        mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*launch*");
355        mLaunchingActivity.setReferenceCounted(false);
356    }
357
358    // This function returns a IStatusBarService. The value is from ServiceManager.
359    // getService and is cached.
360    private IStatusBarService getStatusBarService() {
361        synchronized (mService) {
362            if (mStatusBarService == null) {
363                mStatusBarService = IStatusBarService.Stub.asInterface(
364                    ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
365                if (mStatusBarService == null) {
366                    Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
367                }
368            }
369            return mStatusBarService;
370        }
371    }
372
373    private IDevicePolicyManager getDevicePolicyManager() {
374        synchronized (mService) {
375            if (mDevicePolicyManager == null) {
376                mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
377                    ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE));
378                if (mDevicePolicyManager == null) {
379                    Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
380                }
381            }
382            return mDevicePolicyManager;
383        }
384    }
385
386    void setWindowManager(WindowManagerService wm) {
387        synchronized (mService) {
388            mWindowManager = wm;
389
390            mDisplayManager =
391                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
392            mDisplayManager.registerDisplayListener(this, null);
393
394            Display[] displays = mDisplayManager.getDisplays();
395            for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
396                final int displayId = displays[displayNdx].getDisplayId();
397                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
398                if (activityDisplay.mDisplay == null) {
399                    throw new IllegalStateException("Default Display does not exist");
400                }
401                mActivityDisplays.put(displayId, activityDisplay);
402            }
403
404            createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
405            mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
406
407            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
408
409            // Initialize this here, now that we can get a valid reference to PackageManager.
410            mLeanbackOnlyDevice = isLeanbackOnlyDevice();
411        }
412    }
413
414    void notifyActivityDrawnForKeyguard() {
415        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
416        mWindowManager.notifyActivityDrawnForKeyguard();
417    }
418
419    ActivityStack getFocusedStack() {
420        return mFocusedStack;
421    }
422
423    ActivityStack getLastStack() {
424        return mLastFocusedStack;
425    }
426
427    /** Top of all visible stacks is/should always be equal to the focused stack.
428     * Use {@link ActivityStack#isStackVisibleLocked} to determine if a specific
429     * stack is visible or not. */
430    boolean isFrontStack(ActivityStack stack) {
431        if (stack == null) {
432            return false;
433        }
434
435        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
436        if (parent != null) {
437            stack = parent.task.stack;
438        }
439        return stack == mFocusedStack;
440    }
441
442    void moveHomeStack(boolean toFront, String reason) {
443        moveHomeStack(toFront, reason, null);
444    }
445
446    void moveHomeStack(boolean toFront, String reason, ActivityStack lastFocusedStack) {
447        ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
448        final int topNdx = stacks.size() - 1;
449        if (topNdx <= 0) {
450            return;
451        }
452
453        // The home stack should either be at the top or bottom of the stack list.
454        if ((toFront && (stacks.get(topNdx) != mHomeStack))
455                || (!toFront && (stacks.get(0) != mHomeStack))) {
456            if (DEBUG_STACK) Slog.d(TAG_STACK, "moveHomeTask: topStack old="
457                    + ((lastFocusedStack != null) ? lastFocusedStack : stacks.get(topNdx))
458                    + " new=" + mFocusedStack);
459            stacks.remove(mHomeStack);
460            stacks.add(toFront ? topNdx : 0, mHomeStack);
461        }
462
463        if (lastFocusedStack != null) {
464            mLastFocusedStack = lastFocusedStack;
465        }
466        mFocusedStack = stacks.get(topNdx);
467
468        EventLog.writeEvent(EventLogTags.AM_HOME_STACK_MOVED,
469                mCurrentUser, toFront ? 1 : 0, stacks.get(topNdx).getStackId(),
470                mFocusedStack == null ? -1 : mFocusedStack.getStackId(), reason);
471
472        if (mService.mBooting || !mService.mBooted) {
473            final ActivityRecord r = topRunningActivityLocked();
474            if (r != null && r.idle) {
475                checkFinishBootingLocked();
476            }
477        }
478    }
479
480    /** Returns true if the focus activity was adjusted to the home stack top activity. */
481    boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
482        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
483            mWindowManager.showRecentApps();
484            return false;
485        }
486
487        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
488
489        final ActivityRecord top = getHomeActivity();
490        if (top == null) {
491            return false;
492        }
493        mService.setFocusedActivityLocked(top, reason);
494        return true;
495    }
496
497    boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
498        if (!mService.mBooting && !mService.mBooted) {
499            // Not ready yet!
500            return false;
501        }
502
503        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
504            mWindowManager.showRecentApps();
505            return false;
506        }
507
508        if (prev != null) {
509            prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
510        }
511
512        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
513        ActivityRecord r = getHomeActivity();
514        if (r != null) {
515            mService.setFocusedActivityLocked(r, reason);
516            return resumeTopActivitiesLocked(mHomeStack, prev, null);
517        }
518        return mService.startHomeActivityLocked(mCurrentUser, reason);
519    }
520
521    TaskRecord anyTaskForIdLocked(int id) {
522        return anyTaskForIdLocked(id, true);
523    }
524
525    /**
526     * Returns a {@link TaskRecord} for the input id if available. Null otherwise.
527     * @param id Id of the task we would like returned.
528     * @param restoreFromRecents If the id was not in the active list, but was found in recents,
529     *                           restore the task from recents to the active list.
530     */
531    TaskRecord anyTaskForIdLocked(int id, boolean restoreFromRecents) {
532        int numDisplays = mActivityDisplays.size();
533        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
534            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
535            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
536                ActivityStack stack = stacks.get(stackNdx);
537                TaskRecord task = stack.taskForIdLocked(id);
538                if (task != null) {
539                    return task;
540                }
541            }
542        }
543
544        // Don't give up! Look in recents.
545        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
546        TaskRecord task = mRecentTasks.taskForIdLocked(id);
547        if (task == null) {
548            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
549            return null;
550        }
551
552        if (!restoreFromRecents) {
553            return task;
554        }
555
556        if (!restoreRecentTaskLocked(task)) {
557            if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
558                    "Couldn't restore task id=" + id + " found in recents");
559            return null;
560        }
561        if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
562        return task;
563    }
564
565    ActivityRecord isInAnyStackLocked(IBinder token) {
566        int numDisplays = mActivityDisplays.size();
567        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
568            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
569            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
570                final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
571                if (r != null) {
572                    return r;
573                }
574            }
575        }
576        return null;
577    }
578
579    void setNextTaskId(int taskId) {
580        if (taskId > mCurTaskId) {
581            mCurTaskId = taskId;
582        }
583    }
584
585    int getNextTaskId() {
586        do {
587            mCurTaskId++;
588            if (mCurTaskId <= 0) {
589                mCurTaskId = 1;
590            }
591        } while (anyTaskForIdLocked(mCurTaskId, false) != null);
592        return mCurTaskId;
593    }
594
595    ActivityRecord resumedAppLocked() {
596        ActivityStack stack = mFocusedStack;
597        if (stack == null) {
598            return null;
599        }
600        ActivityRecord resumedActivity = stack.mResumedActivity;
601        if (resumedActivity == null || resumedActivity.app == null) {
602            resumedActivity = stack.mPausingActivity;
603            if (resumedActivity == null || resumedActivity.app == null) {
604                resumedActivity = stack.topRunningActivityLocked(null);
605            }
606        }
607        return resumedActivity;
608    }
609
610    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
611        final String processName = app.processName;
612        boolean didSomething = false;
613        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
614            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
615            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
616                final ActivityStack stack = stacks.get(stackNdx);
617                if (!isFrontStack(stack)) {
618                    continue;
619                }
620                ActivityRecord hr = stack.topRunningActivityLocked(null);
621                if (hr != null) {
622                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
623                            && processName.equals(hr.processName)) {
624                        try {
625                            if (realStartActivityLocked(hr, app, true, true)) {
626                                didSomething = true;
627                            }
628                        } catch (RemoteException e) {
629                            Slog.w(TAG, "Exception in new application when starting activity "
630                                  + hr.intent.getComponent().flattenToShortString(), e);
631                            throw e;
632                        }
633                    }
634                }
635            }
636        }
637        if (!didSomething) {
638            ensureActivitiesVisibleLocked(null, 0);
639        }
640        return didSomething;
641    }
642
643    boolean allResumedActivitiesIdle() {
644        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
645            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
646            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
647                final ActivityStack stack = stacks.get(stackNdx);
648                if (!isFrontStack(stack) || stack.numActivities() == 0) {
649                    continue;
650                }
651                final ActivityRecord resumedActivity = stack.mResumedActivity;
652                if (resumedActivity == null || !resumedActivity.idle) {
653                    if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
654                             + stack.mStackId + " " + resumedActivity + " not idle");
655                    return false;
656                }
657            }
658        }
659        return true;
660    }
661
662    boolean allResumedActivitiesComplete() {
663        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
664            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
665            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
666                final ActivityStack stack = stacks.get(stackNdx);
667                if (isFrontStack(stack)) {
668                    final ActivityRecord r = stack.mResumedActivity;
669                    if (r != null && r.state != RESUMED) {
670                        return false;
671                    }
672                }
673            }
674        }
675        // TODO: Not sure if this should check if all Paused are complete too.
676        if (DEBUG_STACK) Slog.d(TAG_STACK,
677                "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
678                mLastFocusedStack + " to=" + mFocusedStack);
679        mLastFocusedStack = mFocusedStack;
680        return true;
681    }
682
683    boolean allResumedActivitiesVisible() {
684        boolean foundResumed = false;
685        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
686            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
687            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
688                final ActivityStack stack = stacks.get(stackNdx);
689                final ActivityRecord r = stack.mResumedActivity;
690                if (r != null) {
691                    if (!r.nowVisible || mWaitingVisibleActivities.contains(r)) {
692                        return false;
693                    }
694                    foundResumed = true;
695                }
696            }
697        }
698        return foundResumed;
699    }
700
701    /**
702     * Pause all activities in either all of the stacks or just the back stacks.
703     * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
704     * @return true if any activity was paused as a result of this call.
705     */
706    boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
707        boolean someActivityPaused = false;
708        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
709            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
710            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
711                final ActivityStack stack = stacks.get(stackNdx);
712                if (!isFrontStack(stack) && stack.mResumedActivity != null) {
713                    if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
714                            " mResumedActivity=" + stack.mResumedActivity);
715                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
716                            dontWait);
717                }
718            }
719        }
720        return someActivityPaused;
721    }
722
723    boolean allPausedActivitiesComplete() {
724        boolean pausing = true;
725        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
726            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
727            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
728                final ActivityStack stack = stacks.get(stackNdx);
729                final ActivityRecord r = stack.mPausingActivity;
730                if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) {
731                    if (DEBUG_STATES) {
732                        Slog.d(TAG_STATES,
733                                "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
734                        pausing = false;
735                    } else {
736                        return false;
737                    }
738                }
739            }
740        }
741        return pausing;
742    }
743
744    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
745            boolean resuming, boolean dontWait) {
746        // TODO: Put all stacks in supervisor and iterate through them instead.
747        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
748            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
749            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
750                final ActivityStack stack = stacks.get(stackNdx);
751                if (stack.mResumedActivity != null &&
752                        stack.mActivityContainer.mParentActivity == parent) {
753                    stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
754                }
755            }
756        }
757    }
758
759    void reportActivityVisibleLocked(ActivityRecord r) {
760        sendWaitingVisibleReportLocked(r);
761    }
762
763    void sendWaitingVisibleReportLocked(ActivityRecord r) {
764        boolean changed = false;
765        for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
766            WaitResult w = mWaitingActivityVisible.get(i);
767            if (w.who == null) {
768                changed = true;
769                w.timeout = false;
770                if (r != null) {
771                    w.who = new ComponentName(r.info.packageName, r.info.name);
772                }
773                w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
774                w.thisTime = w.totalTime;
775            }
776        }
777        if (changed) {
778            mService.notifyAll();
779        }
780    }
781
782    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
783            long thisTime, long totalTime) {
784        boolean changed = false;
785        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
786            WaitResult w = mWaitingActivityLaunched.remove(i);
787            if (w.who == null) {
788                changed = true;
789                w.timeout = timeout;
790                if (r != null) {
791                    w.who = new ComponentName(r.info.packageName, r.info.name);
792                }
793                w.thisTime = thisTime;
794                w.totalTime = totalTime;
795            }
796        }
797        if (changed) {
798            mService.notifyAll();
799        }
800    }
801
802    ActivityRecord topRunningActivityLocked() {
803        final ActivityStack focusedStack = mFocusedStack;
804        ActivityRecord r = focusedStack.topRunningActivityLocked(null);
805        if (r != null) {
806            return r;
807        }
808
809        // Return to the home stack.
810        final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
811        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
812            final ActivityStack stack = stacks.get(stackNdx);
813            if (stack != focusedStack && isFrontStack(stack)) {
814                r = stack.topRunningActivityLocked(null);
815                if (r != null) {
816                    return r;
817                }
818            }
819        }
820        return null;
821    }
822
823    void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) {
824        // Gather all of the running tasks for each stack into runningTaskLists.
825        ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
826                new ArrayList<ArrayList<RunningTaskInfo>>();
827        final int numDisplays = mActivityDisplays.size();
828        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
829            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
830            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
831                final ActivityStack stack = stacks.get(stackNdx);
832                ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>();
833                runningTaskLists.add(stackTaskList);
834                stack.getTasksLocked(stackTaskList, callingUid, allowed);
835            }
836        }
837
838        // The lists are already sorted from most recent to oldest. Just pull the most recent off
839        // each list and add it to list. Stop when all lists are empty or maxNum reached.
840        while (maxNum > 0) {
841            long mostRecentActiveTime = Long.MIN_VALUE;
842            ArrayList<RunningTaskInfo> selectedStackList = null;
843            final int numTaskLists = runningTaskLists.size();
844            for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
845                ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
846                if (!stackTaskList.isEmpty()) {
847                    final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
848                    if (lastActiveTime > mostRecentActiveTime) {
849                        mostRecentActiveTime = lastActiveTime;
850                        selectedStackList = stackTaskList;
851                    }
852                }
853            }
854            if (selectedStackList != null) {
855                list.add(selectedStackList.remove(0));
856                --maxNum;
857            } else {
858                break;
859            }
860        }
861    }
862
863    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
864            ProfilerInfo profilerInfo, int userId) {
865        // Collect information about the target of the Intent.
866        ActivityInfo aInfo;
867        try {
868            ResolveInfo rInfo =
869                AppGlobals.getPackageManager().resolveIntent(
870                        intent, resolvedType,
871                        PackageManager.MATCH_DEFAULT_ONLY
872                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
873            aInfo = rInfo != null ? rInfo.activityInfo : null;
874        } catch (RemoteException e) {
875            aInfo = null;
876        }
877
878        if (aInfo != null) {
879            // Store the found target back into the intent, because now that
880            // we have it we never want to do this again.  For example, if the
881            // user navigates back to this point in the history, we should
882            // always restart the exact same activity.
883            intent.setComponent(new ComponentName(
884                    aInfo.applicationInfo.packageName, aInfo.name));
885
886            // Don't debug things in the system process
887            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
888                if (!aInfo.processName.equals("system")) {
889                    mService.setDebugApp(aInfo.processName, true, false);
890                }
891            }
892
893            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
894                if (!aInfo.processName.equals("system")) {
895                    mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
896                }
897            }
898
899            if (profilerInfo != null) {
900                if (!aInfo.processName.equals("system")) {
901                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
902                }
903            }
904        }
905        return aInfo;
906    }
907
908    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
909        moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
910        startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
911                null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
912                null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
913                null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
914                0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */,
915                false /* componentSpecified */,
916                null /* outActivity */, null /* container */,  null /* inTask */);
917        if (inResumeTopActivity) {
918            // If we are in resume section already, home activity will be initialized, but not
919            // resumed (to avoid recursive resume) and will stay that way until something pokes it
920            // again. We need to schedule another resume.
921            scheduleResumeTopActivities();
922        }
923    }
924
925    final int startActivityMayWait(IApplicationThread caller, int callingUid,
926            String callingPackage, Intent intent, String resolvedType,
927            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
928            IBinder resultTo, String resultWho, int requestCode, int startFlags,
929            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
930            Bundle options, boolean ignoreTargetSecurity, int userId,
931            IActivityContainer iContainer, TaskRecord inTask) {
932        // Refuse possible leaked file descriptors
933        if (intent != null && intent.hasFileDescriptors()) {
934            throw new IllegalArgumentException("File descriptors passed in Intent");
935        }
936        boolean componentSpecified = intent.getComponent() != null;
937
938        // Don't modify the client's object!
939        intent = new Intent(intent);
940
941        // Collect information about the target of the Intent.
942        ActivityInfo aInfo =
943                resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
944
945        ActivityContainer container = (ActivityContainer)iContainer;
946        synchronized (mService) {
947            if (container != null && container.mParentActivity != null &&
948                    container.mParentActivity.state != RESUMED) {
949                // Cannot start a child activity if the parent is not resumed.
950                return ActivityManager.START_CANCELED;
951            }
952            final int realCallingPid = Binder.getCallingPid();
953            final int realCallingUid = Binder.getCallingUid();
954            int callingPid;
955            if (callingUid >= 0) {
956                callingPid = -1;
957            } else if (caller == null) {
958                callingPid = realCallingPid;
959                callingUid = realCallingUid;
960            } else {
961                callingPid = callingUid = -1;
962            }
963
964            final ActivityStack stack;
965            if (container == null || container.mStack.isOnHomeDisplay()) {
966                stack = mFocusedStack;
967            } else {
968                stack = container.mStack;
969            }
970            stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
971            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
972                    "Starting activity when config will change = " + stack.mConfigWillChange);
973
974            final long origId = Binder.clearCallingIdentity();
975
976            if (aInfo != null &&
977                    (aInfo.applicationInfo.privateFlags
978                            &ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
979                // This may be a heavy-weight process!  Check to see if we already
980                // have another, different heavy-weight process running.
981                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
982                    if (mService.mHeavyWeightProcess != null &&
983                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
984                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
985                        int appCallingUid = callingUid;
986                        if (caller != null) {
987                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
988                            if (callerApp != null) {
989                                appCallingUid = callerApp.info.uid;
990                            } else {
991                                Slog.w(TAG, "Unable to find app for caller " + caller
992                                      + " (pid=" + callingPid + ") when starting: "
993                                      + intent.toString());
994                                ActivityOptions.abort(options);
995                                return ActivityManager.START_PERMISSION_DENIED;
996                            }
997                        }
998
999                        IIntentSender target = mService.getIntentSenderLocked(
1000                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1001                                appCallingUid, userId, null, null, 0, new Intent[] { intent },
1002                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1003                                | PendingIntent.FLAG_ONE_SHOT, null);
1004
1005                        Intent newIntent = new Intent();
1006                        if (requestCode >= 0) {
1007                            // Caller is requesting a result.
1008                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1009                        }
1010                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1011                                new IntentSender(target));
1012                        if (mService.mHeavyWeightProcess.activities.size() > 0) {
1013                            ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
1014                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
1015                                    hist.packageName);
1016                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
1017                                    hist.task.taskId);
1018                        }
1019                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1020                                aInfo.packageName);
1021                        newIntent.setFlags(intent.getFlags());
1022                        newIntent.setClassName("android",
1023                                HeavyWeightSwitcherActivity.class.getName());
1024                        intent = newIntent;
1025                        resolvedType = null;
1026                        caller = null;
1027                        callingUid = Binder.getCallingUid();
1028                        callingPid = Binder.getCallingPid();
1029                        componentSpecified = true;
1030                        try {
1031                            ResolveInfo rInfo =
1032                                AppGlobals.getPackageManager().resolveIntent(
1033                                        intent, null,
1034                                        PackageManager.MATCH_DEFAULT_ONLY
1035                                        | ActivityManagerService.STOCK_PM_FLAGS, userId);
1036                            aInfo = rInfo != null ? rInfo.activityInfo : null;
1037                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
1038                        } catch (RemoteException e) {
1039                            aInfo = null;
1040                        }
1041                    }
1042                }
1043            }
1044
1045            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
1046                    voiceSession, voiceInteractor, resultTo, resultWho,
1047                    requestCode, callingPid, callingUid, callingPackage,
1048                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
1049                    componentSpecified, null, container, inTask);
1050
1051            Binder.restoreCallingIdentity(origId);
1052
1053            if (stack.mConfigWillChange) {
1054                // If the caller also wants to switch to a new configuration,
1055                // do so now.  This allows a clean switch, as we are waiting
1056                // for the current activity to pause (so we will not destroy
1057                // it), and have not yet started the next activity.
1058                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
1059                        "updateConfiguration()");
1060                stack.mConfigWillChange = false;
1061                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1062                        "Updating to new configuration after starting activity.");
1063                mService.updateConfigurationLocked(config, null, false, false);
1064            }
1065
1066            if (outResult != null) {
1067                outResult.result = res;
1068                if (res == ActivityManager.START_SUCCESS) {
1069                    mWaitingActivityLaunched.add(outResult);
1070                    do {
1071                        try {
1072                            mService.wait();
1073                        } catch (InterruptedException e) {
1074                        }
1075                    } while (!outResult.timeout && outResult.who == null);
1076                } else if (res == ActivityManager.START_TASK_TO_FRONT) {
1077                    ActivityRecord r = stack.topRunningActivityLocked(null);
1078                    if (r.nowVisible && r.state == RESUMED) {
1079                        outResult.timeout = false;
1080                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
1081                        outResult.totalTime = 0;
1082                        outResult.thisTime = 0;
1083                    } else {
1084                        outResult.thisTime = SystemClock.uptimeMillis();
1085                        mWaitingActivityVisible.add(outResult);
1086                        do {
1087                            try {
1088                                mService.wait();
1089                            } catch (InterruptedException e) {
1090                            }
1091                        } while (!outResult.timeout && outResult.who == null);
1092                    }
1093                }
1094            }
1095
1096            return res;
1097        }
1098    }
1099
1100    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
1101            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
1102            Bundle options, int userId) {
1103        if (intents == null) {
1104            throw new NullPointerException("intents is null");
1105        }
1106        if (resolvedTypes == null) {
1107            throw new NullPointerException("resolvedTypes is null");
1108        }
1109        if (intents.length != resolvedTypes.length) {
1110            throw new IllegalArgumentException("intents are length different than resolvedTypes");
1111        }
1112
1113
1114        int callingPid;
1115        if (callingUid >= 0) {
1116            callingPid = -1;
1117        } else if (caller == null) {
1118            callingPid = Binder.getCallingPid();
1119            callingUid = Binder.getCallingUid();
1120        } else {
1121            callingPid = callingUid = -1;
1122        }
1123        final long origId = Binder.clearCallingIdentity();
1124        try {
1125            synchronized (mService) {
1126                ActivityRecord[] outActivity = new ActivityRecord[1];
1127                for (int i=0; i<intents.length; i++) {
1128                    Intent intent = intents[i];
1129                    if (intent == null) {
1130                        continue;
1131                    }
1132
1133                    // Refuse possible leaked file descriptors
1134                    if (intent != null && intent.hasFileDescriptors()) {
1135                        throw new IllegalArgumentException("File descriptors passed in Intent");
1136                    }
1137
1138                    boolean componentSpecified = intent.getComponent() != null;
1139
1140                    // Don't modify the client's object!
1141                    intent = new Intent(intent);
1142
1143                    // Collect information about the target of the Intent.
1144                    ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 0, null, userId);
1145                    // TODO: New, check if this is correct
1146                    aInfo = mService.getActivityInfoForUser(aInfo, userId);
1147
1148                    if (aInfo != null &&
1149                            (aInfo.applicationInfo.privateFlags
1150                                    & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)  != 0) {
1151                        throw new IllegalArgumentException(
1152                                "FLAG_CANT_SAVE_STATE not supported here");
1153                    }
1154
1155                    Bundle theseOptions;
1156                    if (options != null && i == intents.length-1) {
1157                        theseOptions = options;
1158                    } else {
1159                        theseOptions = null;
1160                    }
1161                    int res = startActivityLocked(caller, intent, resolvedTypes[i],
1162                            aInfo, null, null, resultTo, null, -1, callingPid, callingUid,
1163                            callingPackage, callingPid, callingUid,
1164                            0, theseOptions, false, componentSpecified, outActivity, null, null);
1165                    if (res < 0) {
1166                        return res;
1167                    }
1168
1169                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
1170                }
1171            }
1172        } finally {
1173            Binder.restoreCallingIdentity(origId);
1174        }
1175
1176        return ActivityManager.START_SUCCESS;
1177    }
1178
1179    final boolean realStartActivityLocked(ActivityRecord r,
1180            ProcessRecord app, boolean andResume, boolean checkConfig)
1181            throws RemoteException {
1182
1183        if (andResume) {
1184            r.startFreezingScreenLocked(app, 0);
1185            mWindowManager.setAppVisibility(r.appToken, true);
1186
1187            // schedule launch ticks to collect information about slow apps.
1188            r.startLaunchTickingLocked();
1189        }
1190
1191        // Have the window manager re-evaluate the orientation of
1192        // the screen based on the new activity order.  Note that
1193        // as a result of this, it can call back into the activity
1194        // manager with a new orientation.  We don't care about that,
1195        // because the activity is not currently running so we are
1196        // just restarting it anyway.
1197        if (checkConfig) {
1198            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1199                    mService.mConfiguration,
1200                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
1201            mService.updateConfigurationLocked(config, r, false, false);
1202        }
1203
1204        r.app = app;
1205        app.waitingToKill = null;
1206        r.launchCount++;
1207        r.lastLaunchTime = SystemClock.uptimeMillis();
1208
1209        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
1210
1211        int idx = app.activities.indexOf(r);
1212        if (idx < 0) {
1213            app.activities.add(r);
1214        }
1215        mService.updateLruProcessLocked(app, true, null);
1216        mService.updateOomAdjLocked();
1217
1218        final TaskRecord task = r.task;
1219        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
1220                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
1221            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
1222        }
1223
1224        final ActivityStack stack = task.stack;
1225        try {
1226            if (app.thread == null) {
1227                throw new RemoteException();
1228            }
1229            List<ResultInfo> results = null;
1230            List<ReferrerIntent> newIntents = null;
1231            if (andResume) {
1232                results = r.results;
1233                newIntents = r.newIntents;
1234            }
1235            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1236                    "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
1237                    + " newIntents=" + newIntents + " andResume=" + andResume);
1238            if (andResume) {
1239                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
1240                        r.userId, System.identityHashCode(r),
1241                        task.taskId, r.shortComponentName);
1242            }
1243            if (r.isHomeActivity() && r.isNotResolverActivity()) {
1244                // Home process is the root process of the task.
1245                mService.mHomeProcess = task.mActivities.get(0).app;
1246            }
1247            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1248            r.sleeping = false;
1249            r.forceNewConfig = false;
1250            mService.showAskCompatModeDialogLocked(r);
1251            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1252            ProfilerInfo profilerInfo = null;
1253            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1254                if (mService.mProfileProc == null || mService.mProfileProc == app) {
1255                    mService.mProfileProc = app;
1256                    final String profileFile = mService.mProfileFile;
1257                    if (profileFile != null) {
1258                        ParcelFileDescriptor profileFd = mService.mProfileFd;
1259                        if (profileFd != null) {
1260                            try {
1261                                profileFd = profileFd.dup();
1262                            } catch (IOException e) {
1263                                if (profileFd != null) {
1264                                    try {
1265                                        profileFd.close();
1266                                    } catch (IOException o) {
1267                                    }
1268                                    profileFd = null;
1269                                }
1270                            }
1271                        }
1272
1273                        profilerInfo = new ProfilerInfo(profileFile, profileFd,
1274                                mService.mSamplingInterval, mService.mAutoStopProfiler);
1275                    }
1276                }
1277            }
1278
1279            if (andResume) {
1280                app.hasShownUi = true;
1281                app.pendingUiClean = true;
1282            }
1283            app.forceProcessStateUpTo(mService.mTopProcessState);
1284            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1285                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
1286                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
1287                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
1288                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
1289
1290            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
1291                // This may be a heavy-weight process!  Note that the package
1292                // manager will ensure that only activity can run in the main
1293                // process of the .apk, which is the only thing that will be
1294                // considered heavy-weight.
1295                if (app.processName.equals(app.info.packageName)) {
1296                    if (mService.mHeavyWeightProcess != null
1297                            && mService.mHeavyWeightProcess != app) {
1298                        Slog.w(TAG, "Starting new heavy weight process " + app
1299                                + " when already running "
1300                                + mService.mHeavyWeightProcess);
1301                    }
1302                    mService.mHeavyWeightProcess = app;
1303                    Message msg = mService.mHandler.obtainMessage(
1304                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1305                    msg.obj = r;
1306                    mService.mHandler.sendMessage(msg);
1307                }
1308            }
1309
1310        } catch (RemoteException e) {
1311            if (r.launchFailed) {
1312                // This is the second time we failed -- finish activity
1313                // and give up.
1314                Slog.e(TAG, "Second failure launching "
1315                      + r.intent.getComponent().flattenToShortString()
1316                      + ", giving up", e);
1317                mService.appDiedLocked(app);
1318                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1319                        "2nd-crash", false);
1320                return false;
1321            }
1322
1323            // This is the first time we failed -- restart process and
1324            // retry.
1325            app.activities.remove(r);
1326            throw e;
1327        }
1328
1329        r.launchFailed = false;
1330        if (stack.updateLRUListLocked(r)) {
1331            Slog.w(TAG, "Activity " + r
1332                  + " being launched, but already in LRU list");
1333        }
1334
1335        if (andResume) {
1336            // As part of the process of launching, ActivityThread also performs
1337            // a resume.
1338            stack.minimalResumeActivityLocked(r);
1339        } else {
1340            // This activity is not starting in the resumed state... which
1341            // should look like we asked it to pause+stop (but remain visible),
1342            // and it has done so and reported back the current icicle and
1343            // other state.
1344            if (DEBUG_STATES) Slog.v(TAG_STATES,
1345                    "Moving to STOPPED: " + r + " (starting in stopped state)");
1346            r.state = STOPPED;
1347            r.stopped = true;
1348        }
1349
1350        // Launch the new version setup screen if needed.  We do this -after-
1351        // launching the initial activity (that is, home), so that it can have
1352        // a chance to initialize itself while in the background, making the
1353        // switch back to it faster and look better.
1354        if (isFrontStack(stack)) {
1355            mService.startSetupActivityLocked();
1356        }
1357
1358        // Update any services we are bound to that might care about whether
1359        // their client may have activities.
1360        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
1361
1362        return true;
1363    }
1364
1365    void startSpecificActivityLocked(ActivityRecord r,
1366            boolean andResume, boolean checkConfig) {
1367        // Is this activity's application already running?
1368        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1369                r.info.applicationInfo.uid, true);
1370
1371        r.task.stack.setLaunchTime(r);
1372
1373        if (app != null && app.thread != null) {
1374            try {
1375                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1376                        || !"android".equals(r.info.packageName)) {
1377                    // Don't add this if it is a platform component that is marked
1378                    // to run in multiple processes, because this is actually
1379                    // part of the framework so doesn't make sense to track as a
1380                    // separate apk in the process.
1381                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
1382                            mService.mProcessStats);
1383                }
1384                realStartActivityLocked(r, app, andResume, checkConfig);
1385                return;
1386            } catch (RemoteException e) {
1387                Slog.w(TAG, "Exception when starting activity "
1388                        + r.intent.getComponent().flattenToShortString(), e);
1389            }
1390
1391            // If a dead object exception was thrown -- fall through to
1392            // restart the application.
1393        }
1394
1395        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1396                "activity", r.intent.getComponent(), false, false, true);
1397    }
1398
1399    final int startActivityLocked(IApplicationThread caller,
1400            Intent intent, String resolvedType, ActivityInfo aInfo,
1401            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1402            IBinder resultTo, String resultWho, int requestCode,
1403            int callingPid, int callingUid, String callingPackage,
1404            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
1405            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
1406            ActivityContainer container, TaskRecord inTask) {
1407        int err = ActivityManager.START_SUCCESS;
1408
1409        ProcessRecord callerApp = null;
1410        if (caller != null) {
1411            callerApp = mService.getRecordForAppLocked(caller);
1412            if (callerApp != null) {
1413                callingPid = callerApp.pid;
1414                callingUid = callerApp.info.uid;
1415            } else {
1416                Slog.w(TAG, "Unable to find app for caller " + caller
1417                      + " (pid=" + callingPid + ") when starting: "
1418                      + intent.toString());
1419                err = ActivityManager.START_PERMISSION_DENIED;
1420            }
1421        }
1422
1423        final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1424
1425        if (err == ActivityManager.START_SUCCESS) {
1426            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1427                    + "} from uid " + callingUid
1428                    + " on display " + (container == null ? (mFocusedStack == null ?
1429                            Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1430                            (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1431                                    container.mActivityDisplay.mDisplayId)));
1432        }
1433
1434        ActivityRecord sourceRecord = null;
1435        ActivityRecord resultRecord = null;
1436        if (resultTo != null) {
1437            sourceRecord = isInAnyStackLocked(resultTo);
1438            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
1439                    "Will send result to " + resultTo + " " + sourceRecord);
1440            if (sourceRecord != null) {
1441                if (requestCode >= 0 && !sourceRecord.finishing) {
1442                    resultRecord = sourceRecord;
1443                }
1444            }
1445        }
1446
1447        final int launchFlags = intent.getFlags();
1448
1449        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
1450            // Transfer the result target from the source activity to the new
1451            // one being started, including any failures.
1452            if (requestCode >= 0) {
1453                ActivityOptions.abort(options);
1454                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1455            }
1456            resultRecord = sourceRecord.resultTo;
1457            if (resultRecord != null && !resultRecord.isInStackLocked()) {
1458                resultRecord = null;
1459            }
1460            resultWho = sourceRecord.resultWho;
1461            requestCode = sourceRecord.requestCode;
1462            sourceRecord.resultTo = null;
1463            if (resultRecord != null) {
1464                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
1465            }
1466            if (sourceRecord.launchedFromUid == callingUid) {
1467                // The new activity is being launched from the same uid as the previous
1468                // activity in the flow, and asking to forward its result back to the
1469                // previous.  In this case the activity is serving as a trampoline between
1470                // the two, so we also want to update its launchedFromPackage to be the
1471                // same as the previous activity.  Note that this is safe, since we know
1472                // these two packages come from the same uid; the caller could just as
1473                // well have supplied that same package name itself.  This specifially
1474                // deals with the case of an intent picker/chooser being launched in the app
1475                // flow to redirect to an activity picked by the user, where we want the final
1476                // activity to consider it to have been launched by the previous app activity.
1477                callingPackage = sourceRecord.launchedFromPackage;
1478            }
1479        }
1480
1481        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1482            // We couldn't find a class that can handle the given Intent.
1483            // That's the end of that!
1484            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1485        }
1486
1487        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1488            // We couldn't find the specific class specified in the Intent.
1489            // Also the end of the line.
1490            err = ActivityManager.START_CLASS_NOT_FOUND;
1491        }
1492
1493        if (err == ActivityManager.START_SUCCESS
1494                && !isCurrentProfileLocked(userId)
1495                && (aInfo.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
1496            // Trying to launch a background activity that doesn't show for all users.
1497            err = ActivityManager.START_NOT_CURRENT_USER_ACTIVITY;
1498        }
1499
1500        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
1501                && sourceRecord.task.voiceSession != null) {
1502            // If this activity is being launched as part of a voice session, we need
1503            // to ensure that it is safe to do so.  If the upcoming activity will also
1504            // be part of the voice session, we can only launch it if it has explicitly
1505            // said it supports the VOICE category, or it is a part of the calling app.
1506            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
1507                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
1508                try {
1509                    intent.addCategory(Intent.CATEGORY_VOICE);
1510                    if (!AppGlobals.getPackageManager().activitySupportsIntent(
1511                            intent.getComponent(), intent, resolvedType)) {
1512                        Slog.w(TAG,
1513                                "Activity being started in current voice task does not support voice: "
1514                                + intent);
1515                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1516                    }
1517                } catch (RemoteException e) {
1518                    Slog.w(TAG, "Failure checking voice capabilities", e);
1519                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1520                }
1521            }
1522        }
1523
1524        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
1525            // If the caller is starting a new voice session, just make sure the target
1526            // is actually allowing it to run this way.
1527            try {
1528                if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1529                        intent, resolvedType)) {
1530                    Slog.w(TAG,
1531                            "Activity being started in new voice task does not support: "
1532                            + intent);
1533                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1534                }
1535            } catch (RemoteException e) {
1536                Slog.w(TAG, "Failure checking voice capabilities", e);
1537                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1538            }
1539        }
1540
1541        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1542
1543        if (err != ActivityManager.START_SUCCESS) {
1544            if (resultRecord != null) {
1545                resultStack.sendActivityResultLocked(-1,
1546                    resultRecord, resultWho, requestCode,
1547                    Activity.RESULT_CANCELED, null);
1548            }
1549            ActivityOptions.abort(options);
1550            return err;
1551        }
1552
1553        boolean abort = false;
1554
1555        final int startAnyPerm = mService.checkPermission(
1556                START_ANY_ACTIVITY, callingPid, callingUid);
1557
1558        if (startAnyPerm != PERMISSION_GRANTED) {
1559            final int componentRestriction = getComponentRestrictionForCallingPackage(
1560                    aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity);
1561            final int actionRestriction = getActionRestrictionForCallingPackage(
1562                    intent.getAction(), callingPackage, callingPid, callingUid);
1563
1564            if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
1565                    || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1566                if (resultRecord != null) {
1567                    resultStack.sendActivityResultLocked(-1,
1568                            resultRecord, resultWho, requestCode,
1569                            Activity.RESULT_CANCELED, null);
1570                }
1571                String msg;
1572                if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1573                    msg = "Permission Denial: starting " + intent.toString()
1574                            + " from " + callerApp + " (pid=" + callingPid
1575                            + ", uid=" + callingUid + ")" + " with revoked permission "
1576                            + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
1577                } else if (!aInfo.exported) {
1578                    msg = "Permission Denial: starting " + intent.toString()
1579                            + " from " + callerApp + " (pid=" + callingPid
1580                            + ", uid=" + callingUid + ")"
1581                            + " not exported from uid " + aInfo.applicationInfo.uid;
1582                } else {
1583                    msg = "Permission Denial: starting " + intent.toString()
1584                            + " from " + callerApp + " (pid=" + callingPid
1585                            + ", uid=" + callingUid + ")"
1586                            + " requires " + aInfo.permission;
1587                }
1588                Slog.w(TAG, msg);
1589                throw new SecurityException(msg);
1590            }
1591
1592            if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
1593                String message = "Appop Denial: starting " + intent.toString()
1594                        + " from " + callerApp + " (pid=" + callingPid
1595                        + ", uid=" + callingUid + ")"
1596                        + " requires " + AppOpsManager.permissionToOp(
1597                                ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
1598                Slog.w(TAG, message);
1599                abort = true;
1600            } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
1601                String message = "Appop Denial: starting " + intent.toString()
1602                        + " from " + callerApp + " (pid=" + callingPid
1603                        + ", uid=" + callingUid + ")"
1604                        + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
1605                Slog.w(TAG, message);
1606                abort = true;
1607            }
1608        }
1609
1610        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1611                callingPid, resolvedType, aInfo.applicationInfo);
1612
1613        if (mService.mController != null) {
1614            try {
1615                // The Intent we give to the watcher has the extra data
1616                // stripped off, since it can contain private information.
1617                Intent watchIntent = intent.cloneFilter();
1618                abort |= !mService.mController.activityStarting(watchIntent,
1619                        aInfo.applicationInfo.packageName);
1620            } catch (RemoteException e) {
1621                mService.mController = null;
1622            }
1623        }
1624
1625        if (abort) {
1626            if (resultRecord != null) {
1627                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1628                        Activity.RESULT_CANCELED, null);
1629            }
1630            // We pretend to the caller that it was really started, but
1631            // they will just get a cancel result.
1632            ActivityOptions.abort(options);
1633            return ActivityManager.START_SUCCESS;
1634        }
1635
1636        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1637                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1638                requestCode, componentSpecified, voiceSession != null, this, container, options);
1639        if (outActivity != null) {
1640            outActivity[0] = r;
1641        }
1642
1643        if (r.appTimeTracker == null && sourceRecord != null) {
1644            // If the caller didn't specify an explicit time tracker, we want to continue
1645            // tracking under any it has.
1646            r.appTimeTracker = sourceRecord.appTimeTracker;
1647        }
1648
1649        final ActivityStack stack = mFocusedStack;
1650        if (voiceSession == null && (stack.mResumedActivity == null
1651                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
1652            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
1653                    realCallingPid, realCallingUid, "Activity start")) {
1654                PendingActivityLaunch pal =
1655                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1656                mPendingActivityLaunches.add(pal);
1657                ActivityOptions.abort(options);
1658                return ActivityManager.START_SWITCHES_CANCELED;
1659            }
1660        }
1661
1662        if (mService.mDidAppSwitch) {
1663            // This is the second allowed switch since we stopped switches,
1664            // so now just generally allow switches.  Use case: user presses
1665            // home (switches disabled, switch to home, mDidAppSwitch now true);
1666            // user taps a home icon (coming from home so allowed, we hit here
1667            // and now allow anyone to switch again).
1668            mService.mAppSwitchesAllowedTime = 0;
1669        } else {
1670            mService.mDidAppSwitch = true;
1671        }
1672
1673        doPendingActivityLaunchesLocked(false);
1674
1675        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
1676                startFlags, true, options, inTask);
1677
1678        if (err < 0) {
1679            // If someone asked to have the keyguard dismissed on the next
1680            // activity start, but we are not actually doing an activity
1681            // switch...  just dismiss the keyguard now, because we
1682            // probably want to see whatever is behind it.
1683            notifyActivityDrawnForKeyguard();
1684        }
1685        return err;
1686    }
1687
1688    private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
1689            String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
1690        if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
1691                callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
1692                == PackageManager.PERMISSION_DENIED) {
1693            return ACTIVITY_RESTRICTION_PERMISSION;
1694        }
1695
1696        if (activityInfo.permission == null) {
1697            return ACTIVITY_RESTRICTION_NONE;
1698        }
1699
1700        final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
1701        if (opCode == AppOpsManager.OP_NONE) {
1702            return ACTIVITY_RESTRICTION_NONE;
1703        }
1704
1705        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1706                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1707            if (!ignoreTargetSecurity) {
1708                return ACTIVITY_RESTRICTION_APPOP;
1709            }
1710        }
1711
1712        return ACTIVITY_RESTRICTION_NONE;
1713    }
1714
1715    private int getActionRestrictionForCallingPackage(String action,
1716            String callingPackage, int callingPid, int callingUid) {
1717        if (action == null) {
1718            return ACTIVITY_RESTRICTION_NONE;
1719        }
1720
1721        String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
1722        if (permission == null) {
1723            return ACTIVITY_RESTRICTION_NONE;
1724        }
1725
1726        final PackageInfo packageInfo;
1727        try {
1728            packageInfo = mService.mContext.getPackageManager()
1729                    .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
1730        } catch (PackageManager.NameNotFoundException e) {
1731            Slog.i(TAG, "Cannot find package info for " + callingPackage);
1732            return ACTIVITY_RESTRICTION_NONE;
1733        }
1734
1735        if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
1736            return ACTIVITY_RESTRICTION_NONE;
1737        }
1738
1739        if (mService.checkPermission(permission, callingPid, callingUid) ==
1740                PackageManager.PERMISSION_DENIED) {
1741            return ACTIVITY_RESTRICTION_PERMISSION;
1742        }
1743
1744        final int opCode = AppOpsManager.permissionToOpCode(permission);
1745        if (opCode == AppOpsManager.OP_NONE) {
1746            return ACTIVITY_RESTRICTION_NONE;
1747        }
1748
1749        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1750                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1751            return ACTIVITY_RESTRICTION_APPOP;
1752        }
1753
1754        return ACTIVITY_RESTRICTION_NONE;
1755    }
1756
1757    ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
1758        final TaskRecord task = r.task;
1759
1760        // On leanback only devices we should keep all activities in the same stack.
1761        if (!mLeanbackOnlyDevice &&
1762                (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
1763
1764            ActivityStack stack;
1765
1766            if (task != null && task.stack != null) {
1767                stack = task.stack;
1768                if (stack.isOnHomeDisplay()) {
1769                    if (mFocusedStack != stack) {
1770                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1771                                "computeStackFocus: Setting " + "focused stack to r=" + r
1772                                + " task=" + task);
1773                    } else {
1774                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1775                            "computeStackFocus: Focused stack already=" + mFocusedStack);
1776                    }
1777                }
1778                return stack;
1779            }
1780
1781            final ActivityContainer container = r.mInitialActivityContainer;
1782            if (container != null) {
1783                // The first time put it on the desired stack, after this put on task stack.
1784                r.mInitialActivityContainer = null;
1785                return container.mStack;
1786            }
1787
1788            if (mFocusedStack != mHomeStack && (!newTask ||
1789                    mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
1790                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1791                        "computeStackFocus: Have a focused stack=" + mFocusedStack);
1792                return mFocusedStack;
1793            }
1794
1795            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1796            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1797                stack = homeDisplayStacks.get(stackNdx);
1798                if (!stack.isHomeStack()) {
1799                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1800                            "computeStackFocus: Setting focused stack=" + stack);
1801                    return stack;
1802                }
1803            }
1804
1805            // Need to create an app stack for this user.
1806            stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
1807            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
1808                    + r + " stackId=" + stack.mStackId);
1809            return stack;
1810        }
1811        return mHomeStack;
1812    }
1813
1814    boolean setFocusedStack(ActivityRecord r, String reason) {
1815        if (r == null) {
1816            // Not sure what you are trying to do, but it is not going to work...
1817            return false;
1818        }
1819        final TaskRecord task = r.task;
1820        if (task == null || task.stack == null) {
1821            Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task);
1822            return false;
1823        }
1824        task.stack.moveToFront(reason);
1825        return true;
1826    }
1827
1828    final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
1829            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
1830            boolean doResume, Bundle options, TaskRecord inTask) {
1831        final Intent intent = r.intent;
1832        final int callingUid = r.launchedFromUid;
1833
1834        // In some flows in to this function, we retrieve the task record and hold on to it
1835        // without a lock before calling back in to here...  so the task at this point may
1836        // not actually be in recents.  Check for that, and if it isn't in recents just
1837        // consider it invalid.
1838        if (inTask != null && !inTask.inRecents) {
1839            Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1840            inTask = null;
1841        }
1842
1843        final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
1844        final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
1845        final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
1846
1847        int launchFlags = intent.getFlags();
1848        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1849                (launchSingleInstance || launchSingleTask)) {
1850            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1851            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1852                    "\"singleInstance\" or \"singleTask\"");
1853            launchFlags &=
1854                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
1855        } else {
1856            switch (r.info.documentLaunchMode) {
1857                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1858                    break;
1859                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1860                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1861                    break;
1862                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1863                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1864                    break;
1865                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1866                    launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1867                    break;
1868            }
1869        }
1870
1871        final boolean launchTaskBehind = r.mLaunchTaskBehind
1872                && !launchSingleTask && !launchSingleInstance
1873                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1874
1875        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0
1876                && r.resultTo.task.stack != null) {
1877            // For whatever reason this activity is being launched into a new
1878            // task...  yet the caller has requested a result back.  Well, that
1879            // is pretty messed up, so instead immediately send back a cancel
1880            // and let the new task continue launched as normal without a
1881            // dependency on its originator.
1882            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1883            r.resultTo.task.stack.sendActivityResultLocked(-1,
1884                    r.resultTo, r.resultWho, r.requestCode,
1885                    Activity.RESULT_CANCELED, null);
1886            r.resultTo = null;
1887        }
1888
1889        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1890            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1891        }
1892
1893        // If we are actually going to launch in to a new task, there are some cases where
1894        // we further want to do multiple task.
1895        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1896            if (launchTaskBehind
1897                    || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
1898                launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1899            }
1900        }
1901
1902        // We'll invoke onUserLeaving before onPause only if the launching
1903        // activity did not explicitly state that this is an automated launch.
1904        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1905        if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1906                "startActivity() => mUserLeaving=" + mUserLeaving);
1907
1908        // If the caller has asked not to resume at this point, we make note
1909        // of this in the record so that we can skip it when trying to find
1910        // the top running activity.
1911        if (!doResume) {
1912            r.delayedResume = true;
1913        }
1914
1915        ActivityRecord notTop =
1916                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1917
1918        // If the onlyIfNeeded flag is set, then we can do this if the activity
1919        // being launched is the same as the one making the call...  or, as
1920        // a special case, if we do not know the caller then we count the
1921        // current top activity as the caller.
1922        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1923            ActivityRecord checkedCaller = sourceRecord;
1924            if (checkedCaller == null) {
1925                checkedCaller = mFocusedStack.topRunningNonDelayedActivityLocked(notTop);
1926            }
1927            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1928                // Caller is not the same as launcher, so always needed.
1929                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1930            }
1931        }
1932
1933        boolean addingToTask = false;
1934        TaskRecord reuseTask = null;
1935
1936        // If the caller is not coming from another activity, but has given us an
1937        // explicit task into which they would like us to launch the new activity,
1938        // then let's see about doing that.
1939        if (sourceRecord == null && inTask != null && inTask.stack != null) {
1940            final Intent baseIntent = inTask.getBaseIntent();
1941            final ActivityRecord root = inTask.getRootActivity();
1942            if (baseIntent == null) {
1943                ActivityOptions.abort(options);
1944                throw new IllegalArgumentException("Launching into task without base intent: "
1945                        + inTask);
1946            }
1947
1948            // If this task is empty, then we are adding the first activity -- it
1949            // determines the root, and must be launching as a NEW_TASK.
1950            if (launchSingleInstance || launchSingleTask) {
1951                if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
1952                    ActivityOptions.abort(options);
1953                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1954                            + r + " into different task " + inTask);
1955                }
1956                if (root != null) {
1957                    ActivityOptions.abort(options);
1958                    throw new IllegalArgumentException("Caller with inTask " + inTask
1959                            + " has root " + root + " but target is singleInstance/Task");
1960                }
1961            }
1962
1963            // If task is empty, then adopt the interesting intent launch flags in to the
1964            // activity being started.
1965            if (root == null) {
1966                final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
1967                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
1968                        | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1969                launchFlags = (launchFlags&~flagsOfInterest)
1970                        | (baseIntent.getFlags()&flagsOfInterest);
1971                intent.setFlags(launchFlags);
1972                inTask.setIntent(r);
1973                addingToTask = true;
1974
1975            // If the task is not empty and the caller is asking to start it as the root
1976            // of a new task, then we don't actually want to start this on the task.  We
1977            // will bring the task to the front, and possibly give it a new intent.
1978            } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1979                addingToTask = false;
1980
1981            } else {
1982                addingToTask = true;
1983            }
1984
1985            reuseTask = inTask;
1986        } else {
1987            inTask = null;
1988        }
1989
1990        if (inTask == null) {
1991            if (sourceRecord == null) {
1992                // This activity is not being started from another...  in this
1993                // case we -always- start a new task.
1994                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
1995                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1996                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1997                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1998                }
1999            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
2000                // The original activity who is starting us is running as a single
2001                // instance...  this new activity it is starting must go on its
2002                // own task.
2003                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2004            } else if (launchSingleInstance || launchSingleTask) {
2005                // The activity being started is a single instance...  it always
2006                // gets launched into its own task.
2007                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2008            }
2009        }
2010
2011        ActivityInfo newTaskInfo = null;
2012        Intent newTaskIntent = null;
2013        ActivityStack sourceStack;
2014        if (sourceRecord != null) {
2015            if (sourceRecord.finishing) {
2016                // If the source is finishing, we can't further count it as our source.  This
2017                // is because the task it is associated with may now be empty and on its way out,
2018                // so we don't want to blindly throw it in to that task.  Instead we will take
2019                // the NEW_TASK flow and try to find a task for it. But save the task information
2020                // so it can be used when creating the new task.
2021                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
2022                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
2023                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
2024                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2025                    newTaskInfo = sourceRecord.info;
2026                    newTaskIntent = sourceRecord.task.intent;
2027                }
2028                sourceRecord = null;
2029                sourceStack = null;
2030            } else {
2031                sourceStack = sourceRecord.task.stack;
2032            }
2033        } else {
2034            sourceStack = null;
2035        }
2036
2037        boolean movedHome = false;
2038        ActivityStack targetStack;
2039
2040        intent.setFlags(launchFlags);
2041        final boolean noAnimation = (launchFlags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0;
2042
2043        // We may want to try to place the new activity in to an existing task.  We always
2044        // do this if the target activity is singleTask or singleInstance; we will also do
2045        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2046        // us to still place it in a new task: multi task, always doc mode, or being asked to
2047        // launch this as a new task behind the current one.
2048        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
2049                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
2050                || launchSingleInstance || launchSingleTask) {
2051            // If bring to front is requested, and no result is requested and we have not
2052            // been given an explicit task to launch in to, and
2053            // we can find a task that was started with this same
2054            // component, then instead of launching bring that one to the front.
2055            if (inTask == null && r.resultTo == null) {
2056                // See if there is a task to bring to the front.  If this is
2057                // a SINGLE_INSTANCE activity, there can be one and only one
2058                // instance of it in the history, and it is always in its own
2059                // unique task, so we do a special search.
2060                ActivityRecord intentActivity = !launchSingleInstance ?
2061                        findTaskLocked(r) : findActivityLocked(intent, r.info);
2062                if (intentActivity != null) {
2063                    // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused
2064                    // but still needs to be a lock task mode violation since the task gets
2065                    // cleared out and the device would otherwise leave the locked task.
2066                    if (isLockTaskModeViolation(intentActivity.task,
2067                            (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2068                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
2069                        showLockTaskToast();
2070                        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
2071                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2072                    }
2073                    if (r.task == null) {
2074                        r.task = intentActivity.task;
2075                    }
2076                    if (intentActivity.task.intent == null) {
2077                        // This task was started because of movement of
2078                        // the activity based on affinity...  now that we
2079                        // are actually launching it, we can assign the
2080                        // base intent.
2081                        intentActivity.task.setIntent(r);
2082                    }
2083                    targetStack = intentActivity.task.stack;
2084                    targetStack.mLastPausedActivity = null;
2085                    // If the target task is not in the front, then we need
2086                    // to bring it to the front...  except...  well, with
2087                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
2088                    // to have the same behavior as if a new instance was
2089                    // being started, which means not bringing it to the front
2090                    // if the caller is not itself in the front.
2091                    final ActivityStack focusStack = getFocusedStack();
2092                    ActivityRecord curTop = (focusStack == null)
2093                            ? null : focusStack.topRunningNonDelayedActivityLocked(notTop);
2094                    boolean movedToFront = false;
2095                    if (curTop != null && (curTop.task != intentActivity.task ||
2096                            curTop.task != focusStack.topTask())) {
2097                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
2098                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
2099                                sourceStack.topActivity().task == sourceRecord.task)) {
2100                            // We really do want to push this one into the user's face, right now.
2101                            if (launchTaskBehind && sourceRecord != null) {
2102                                intentActivity.setTaskToAffiliateWith(sourceRecord.task);
2103                            }
2104                            movedHome = true;
2105                            targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
2106                                    options, r.appTimeTracker, "bringingFoundTaskToFront");
2107                            movedToFront = true;
2108                            if ((launchFlags &
2109                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
2110                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
2111                                // Caller wants to appear on home activity.
2112                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2113                            }
2114                            options = null;
2115                        }
2116                    }
2117                    if (!movedToFront) {
2118                        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + targetStack
2119                                + " from " + intentActivity);
2120                        targetStack.moveToFront("intentActivityFound");
2121                    }
2122
2123                    // If the caller has requested that the target task be
2124                    // reset, then do so.
2125                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2126                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
2127                    }
2128                    if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2129                        // We don't need to start a new activity, and
2130                        // the client said not to do anything if that
2131                        // is the case, so this is it!  And for paranoia, make
2132                        // sure we have correctly resumed the top activity.
2133                        if (doResume) {
2134                            resumeTopActivitiesLocked(targetStack, null, options);
2135
2136                            // Make sure to notify Keyguard as well if we are not running an app
2137                            // transition later.
2138                            if (!movedToFront) {
2139                                notifyActivityDrawnForKeyguard();
2140                            }
2141                        } else {
2142                            ActivityOptions.abort(options);
2143                        }
2144                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2145                    }
2146                    if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2147                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2148                        // The caller has requested to completely replace any
2149                        // existing task with its new activity.  Well that should
2150                        // not be too hard...
2151                        reuseTask = intentActivity.task;
2152                        reuseTask.performClearTaskLocked();
2153                        reuseTask.setIntent(r);
2154                    } else if ((launchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2155                            || launchSingleInstance || launchSingleTask) {
2156                        // In this situation we want to remove all activities
2157                        // from the task up to the one being started.  In most
2158                        // cases this means we are resetting the task to its
2159                        // initial state.
2160                        ActivityRecord top =
2161                                intentActivity.task.performClearTaskLocked(r, launchFlags);
2162                        if (top != null) {
2163                            if (top.frontOfTask) {
2164                                // Activity aliases may mean we use different
2165                                // intents for the top activity, so make sure
2166                                // the task now has the identity of the new
2167                                // intent.
2168                                top.task.setIntent(r);
2169                            }
2170                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
2171                                    r, top.task);
2172                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2173                        } else {
2174                            // A special case: we need to start the activity because it is not
2175                            // currently running, and the caller has asked to clear the current
2176                            // task to have this activity at the top.
2177                            addingToTask = true;
2178                            // Now pretend like this activity is being started by the top of its
2179                            // task, so it is put in the right place.
2180                            sourceRecord = intentActivity;
2181                            TaskRecord task = sourceRecord.task;
2182                            if (task != null && task.stack == null) {
2183                                // Target stack got cleared when we all activities were removed
2184                                // above. Go ahead and reset it.
2185                                targetStack = computeStackFocus(sourceRecord, false /* newTask */);
2186                                targetStack.addTask(
2187                                        task, !launchTaskBehind /* toTop */, false /* moving */);
2188                            }
2189
2190                        }
2191                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
2192                        // In this case the top activity on the task is the
2193                        // same as the one being launched, so we take that
2194                        // as a request to bring the task to the foreground.
2195                        // If the top activity in the task is the root
2196                        // activity, deliver this new intent to it if it
2197                        // desires.
2198                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
2199                                && intentActivity.realActivity.equals(r.realActivity)) {
2200                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
2201                                    intentActivity.task);
2202                            if (intentActivity.frontOfTask) {
2203                                intentActivity.task.setIntent(r);
2204                            }
2205                            intentActivity.deliverNewIntentLocked(callingUid, r.intent,
2206                                    r.launchedFromPackage);
2207                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
2208                            // In this case we are launching the root activity
2209                            // of the task, but with a different intent.  We
2210                            // should start a new instance on top.
2211                            addingToTask = true;
2212                            sourceRecord = intentActivity;
2213                        }
2214                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2215                        // In this case an activity is being launched in to an
2216                        // existing task, without resetting that task.  This
2217                        // is typically the situation of launching an activity
2218                        // from a notification or shortcut.  We want to place
2219                        // the new activity on top of the current task.
2220                        addingToTask = true;
2221                        sourceRecord = intentActivity;
2222                    } else if (!intentActivity.task.rootWasReset) {
2223                        // In this case we are launching in to an existing task
2224                        // that has not yet been started from its front door.
2225                        // The current task has been brought to the front.
2226                        // Ideally, we'd probably like to place this new task
2227                        // at the bottom of its stack, but that's a little hard
2228                        // to do with the current organization of the code so
2229                        // for now we'll just drop it.
2230                        intentActivity.task.setIntent(r);
2231                    }
2232                    if (!addingToTask && reuseTask == null) {
2233                        // We didn't do anything...  but it was needed (a.k.a., client
2234                        // don't use that intent!)  And for paranoia, make
2235                        // sure we have correctly resumed the top activity.
2236                        if (doResume) {
2237                            targetStack.resumeTopActivityLocked(null, options);
2238                            if (!movedToFront) {
2239                                // Make sure to notify Keyguard as well if we are not running an app
2240                                // transition later.
2241                                notifyActivityDrawnForKeyguard();
2242                            }
2243                        } else {
2244                            ActivityOptions.abort(options);
2245                        }
2246                        return ActivityManager.START_TASK_TO_FRONT;
2247                    }
2248                }
2249            }
2250        }
2251
2252        //String uri = r.intent.toURI();
2253        //Intent intent2 = new Intent(uri);
2254        //Slog.i(TAG, "Given intent: " + r.intent);
2255        //Slog.i(TAG, "URI is: " + uri);
2256        //Slog.i(TAG, "To intent: " + intent2);
2257
2258        if (r.packageName != null) {
2259            // If the activity being launched is the same as the one currently
2260            // at the top, then we need to check if it should only be launched
2261            // once.
2262            ActivityStack topStack = mFocusedStack;
2263            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
2264            if (top != null && r.resultTo == null) {
2265                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2266                    if (top.app != null && top.app.thread != null) {
2267                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2268                            || launchSingleTop || launchSingleTask) {
2269                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
2270                                    top.task);
2271                            // For paranoia, make sure we have correctly
2272                            // resumed the top activity.
2273                            topStack.mLastPausedActivity = null;
2274                            if (doResume) {
2275                                resumeTopActivitiesLocked();
2276                            }
2277                            ActivityOptions.abort(options);
2278                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2279                                // We don't need to start a new activity, and
2280                                // the client said not to do anything if that
2281                                // is the case, so this is it!
2282                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2283                            }
2284                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2285                            return ActivityManager.START_DELIVERED_TO_TOP;
2286                        }
2287                    }
2288                }
2289            }
2290
2291        } else {
2292            if (r.resultTo != null && r.resultTo.task.stack != null) {
2293                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
2294                        r.requestCode, Activity.RESULT_CANCELED, null);
2295            }
2296            ActivityOptions.abort(options);
2297            return ActivityManager.START_CLASS_NOT_FOUND;
2298        }
2299
2300        boolean newTask = false;
2301        boolean keepCurTransition = false;
2302
2303        TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
2304                sourceRecord.task : null;
2305
2306        // Should this be considered a new task?
2307        if (r.resultTo == null && inTask == null && !addingToTask
2308                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
2309            newTask = true;
2310            targetStack = computeStackFocus(r, newTask);
2311            targetStack.moveToFront("startingNewTask");
2312
2313            if (reuseTask == null) {
2314                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
2315                        newTaskInfo != null ? newTaskInfo : r.info,
2316                        newTaskIntent != null ? newTaskIntent : intent,
2317                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
2318                        taskToAffiliate);
2319                if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2320                        "Starting new activity " + r + " in new task " + r.task);
2321            } else {
2322                r.setTask(reuseTask, taskToAffiliate);
2323            }
2324            if (isLockTaskModeViolation(r.task)) {
2325                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2326                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2327            }
2328            if (!movedHome) {
2329                if ((launchFlags &
2330                        (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
2331                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
2332                    // Caller wants to appear on home activity, so before starting
2333                    // their own activity we will bring home to the front.
2334                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2335                }
2336            }
2337        } else if (sourceRecord != null) {
2338            final TaskRecord sourceTask = sourceRecord.task;
2339            if (isLockTaskModeViolation(sourceTask)) {
2340                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2341                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2342            }
2343            targetStack = sourceTask.stack;
2344            targetStack.moveToFront("sourceStackToFront");
2345            final TaskRecord topTask = targetStack.topTask();
2346            if (topTask != sourceTask) {
2347                targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
2348                        r.appTimeTracker, "sourceTaskToFront");
2349            }
2350            if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2351                // In this case, we are adding the activity to an existing
2352                // task, but the caller has asked to clear that task if the
2353                // activity is already running.
2354                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
2355                keepCurTransition = true;
2356                if (top != null) {
2357                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
2358                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2359                    // For paranoia, make sure we have correctly
2360                    // resumed the top activity.
2361                    targetStack.mLastPausedActivity = null;
2362                    if (doResume) {
2363                        targetStack.resumeTopActivityLocked(null);
2364                    }
2365                    ActivityOptions.abort(options);
2366                    return ActivityManager.START_DELIVERED_TO_TOP;
2367                }
2368            } else if (!addingToTask &&
2369                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2370                // In this case, we are launching an activity in our own task
2371                // that may already be running somewhere in the history, and
2372                // we want to shuffle it to the front of the stack if so.
2373                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
2374                if (top != null) {
2375                    final TaskRecord task = top.task;
2376                    task.moveActivityToFrontLocked(top);
2377                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
2378                    top.updateOptionsLocked(options);
2379                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2380                    targetStack.mLastPausedActivity = null;
2381                    if (doResume) {
2382                        targetStack.resumeTopActivityLocked(null);
2383                    }
2384                    return ActivityManager.START_DELIVERED_TO_TOP;
2385                }
2386            }
2387            // An existing activity is starting this new activity, so we want
2388            // to keep the new one in the same task as the one that is starting
2389            // it.
2390            r.setTask(sourceTask, null);
2391            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2392                    + " in existing task " + r.task + " from source " + sourceRecord);
2393
2394        } else if (inTask != null) {
2395            // The caller is asking that the new activity be started in an explicit
2396            // task it has provided to us.
2397            if (isLockTaskModeViolation(inTask)) {
2398                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2399                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2400            }
2401            targetStack = inTask.stack;
2402            targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker,
2403                    "inTaskToFront");
2404
2405            // Check whether we should actually launch the new activity in to the task,
2406            // or just reuse the current activity on top.
2407            ActivityRecord top = inTask.getTopActivity();
2408            if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2409                if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2410                        || launchSingleTop || launchSingleTask) {
2411                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
2412                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2413                        // We don't need to start a new activity, and
2414                        // the client said not to do anything if that
2415                        // is the case, so this is it!
2416                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2417                    }
2418                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2419                    return ActivityManager.START_DELIVERED_TO_TOP;
2420                }
2421            }
2422
2423            if (!addingToTask) {
2424                // We don't actually want to have this activity added to the task, so just
2425                // stop here but still tell the caller that we consumed the intent.
2426                ActivityOptions.abort(options);
2427                return ActivityManager.START_TASK_TO_FRONT;
2428            }
2429
2430            r.setTask(inTask, null);
2431            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2432                    + " in explicit task " + r.task);
2433
2434        } else {
2435            // This not being started from an existing activity, and not part
2436            // of a new task...  just put it in the top task, though these days
2437            // this case should never happen.
2438            targetStack = computeStackFocus(r, newTask);
2439            targetStack.moveToFront("addingToTopTask");
2440            ActivityRecord prev = targetStack.topActivity();
2441            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
2442                            r.info, intent, null, null, true), null);
2443            mWindowManager.moveTaskToTop(r.task.taskId);
2444            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2445                    + " in new guessed " + r.task);
2446        }
2447
2448        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2449                intent, r.getUriPermissionsLocked(), r.userId);
2450
2451        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
2452            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
2453        }
2454        if (newTask) {
2455            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
2456        }
2457        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
2458        targetStack.mLastPausedActivity = null;
2459        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
2460        if (!launchTaskBehind) {
2461            // Don't set focus on an activity that's going to the back.
2462            mService.setFocusedActivityLocked(r, "startedActivity");
2463        }
2464        return ActivityManager.START_SUCCESS;
2465    }
2466
2467    final void doPendingActivityLaunchesLocked(boolean doResume) {
2468        while (!mPendingActivityLaunches.isEmpty()) {
2469            PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
2470
2471            try {
2472                startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
2473                                             doResume && mPendingActivityLaunches.isEmpty(), null, null);
2474            } catch (Exception e) {
2475                Slog.w(TAG, "Exception during pending activity launch pal=" + pal, e);
2476            }
2477        }
2478    }
2479
2480    void removePendingActivityLaunchesLocked(ActivityStack stack) {
2481        for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
2482            PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
2483            if (pal.stack == stack) {
2484                mPendingActivityLaunches.remove(palNdx);
2485            }
2486        }
2487    }
2488
2489    void setLaunchSource(int uid) {
2490        mLaunchingActivity.setWorkSource(new WorkSource(uid));
2491    }
2492
2493    void acquireLaunchWakelock() {
2494        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2495            throw new IllegalStateException("Calling must be system uid");
2496        }
2497        mLaunchingActivity.acquire();
2498        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2499            // To be safe, don't allow the wake lock to be held for too long.
2500            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2501        }
2502    }
2503
2504    /**
2505     * Called when the frontmost task is idle.
2506     * @return the state of mService.mBooting before this was called.
2507     */
2508    private boolean checkFinishBootingLocked() {
2509        final boolean booting = mService.mBooting;
2510        boolean enableScreen = false;
2511        mService.mBooting = false;
2512        if (!mService.mBooted) {
2513            mService.mBooted = true;
2514            enableScreen = true;
2515        }
2516        if (booting || enableScreen) {
2517            mService.postFinishBooting(booting, enableScreen);
2518        }
2519        return booting;
2520    }
2521
2522    // Checked.
2523    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2524            Configuration config) {
2525        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
2526
2527        ArrayList<ActivityRecord> stops = null;
2528        ArrayList<ActivityRecord> finishes = null;
2529        ArrayList<UserState> startingUsers = null;
2530        int NS = 0;
2531        int NF = 0;
2532        boolean booting = false;
2533        boolean activityRemoved = false;
2534
2535        ActivityRecord r = ActivityRecord.forTokenLocked(token);
2536        if (r != null) {
2537            if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
2538                    + Debug.getCallers(4));
2539            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2540            r.finishLaunchTickingLocked();
2541            if (fromTimeout) {
2542                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2543            }
2544
2545            // This is a hack to semi-deal with a race condition
2546            // in the client where it can be constructed with a
2547            // newer configuration from when we asked it to launch.
2548            // We'll update with whatever configuration it now says
2549            // it used to launch.
2550            if (config != null) {
2551                r.configuration = config;
2552            }
2553
2554            // We are now idle.  If someone is waiting for a thumbnail from
2555            // us, we can now deliver.
2556            r.idle = true;
2557
2558            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2559            if (isFrontStack(r.task.stack) || fromTimeout) {
2560                booting = checkFinishBootingLocked();
2561            }
2562        }
2563
2564        if (allResumedActivitiesIdle()) {
2565            if (r != null) {
2566                mService.scheduleAppGcsLocked();
2567            }
2568
2569            if (mLaunchingActivity.isHeld()) {
2570                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2571                if (VALIDATE_WAKE_LOCK_CALLER &&
2572                        Binder.getCallingUid() != Process.myUid()) {
2573                    throw new IllegalStateException("Calling must be system uid");
2574                }
2575                mLaunchingActivity.release();
2576            }
2577            ensureActivitiesVisibleLocked(null, 0);
2578        }
2579
2580        // Atomically retrieve all of the other things to do.
2581        stops = processStoppingActivitiesLocked(true);
2582        NS = stops != null ? stops.size() : 0;
2583        if ((NF = mFinishingActivities.size()) > 0) {
2584            finishes = new ArrayList<>(mFinishingActivities);
2585            mFinishingActivities.clear();
2586        }
2587
2588        if (mStartingUsers.size() > 0) {
2589            startingUsers = new ArrayList<>(mStartingUsers);
2590            mStartingUsers.clear();
2591        }
2592
2593        // Stop any activities that are scheduled to do so but have been
2594        // waiting for the next one to start.
2595        for (int i = 0; i < NS; i++) {
2596            r = stops.get(i);
2597            final ActivityStack stack = r.task.stack;
2598            if (stack != null) {
2599                if (r.finishing) {
2600                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2601                } else {
2602                    stack.stopActivityLocked(r);
2603                }
2604            }
2605        }
2606
2607        // Finish any activities that are scheduled to do so but have been
2608        // waiting for the next one to start.
2609        for (int i = 0; i < NF; i++) {
2610            r = finishes.get(i);
2611            final ActivityStack stack = r.task.stack;
2612            if (stack != null) {
2613                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
2614            }
2615        }
2616
2617        if (!booting) {
2618            // Complete user switch
2619            if (startingUsers != null) {
2620                for (int i = 0; i < startingUsers.size(); i++) {
2621                    mService.finishUserSwitch(startingUsers.get(i));
2622                }
2623            }
2624            // Complete starting up of background users
2625            if (mStartingBackgroundUsers.size() > 0) {
2626                startingUsers = new ArrayList<UserState>(mStartingBackgroundUsers);
2627                mStartingBackgroundUsers.clear();
2628                for (int i = 0; i < startingUsers.size(); i++) {
2629                    mService.finishUserBoot(startingUsers.get(i));
2630                }
2631            }
2632        }
2633
2634        mService.trimApplications();
2635        //dump();
2636        //mWindowManager.dump();
2637
2638        if (activityRemoved) {
2639            resumeTopActivitiesLocked();
2640        }
2641
2642        return r;
2643    }
2644
2645    boolean handleAppDiedLocked(ProcessRecord app) {
2646        boolean hasVisibleActivities = false;
2647        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2648            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2649            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2650                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2651            }
2652        }
2653        return hasVisibleActivities;
2654    }
2655
2656    void closeSystemDialogsLocked() {
2657        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2658            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2659            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2660                stacks.get(stackNdx).closeSystemDialogsLocked();
2661            }
2662        }
2663    }
2664
2665    void removeUserLocked(int userId) {
2666        mUserStackInFront.delete(userId);
2667    }
2668
2669    /**
2670     * @return true if some activity was finished (or would have finished if doit were true).
2671     */
2672    boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
2673            boolean doit, boolean evenPersistent, int userId) {
2674        boolean didSomething = false;
2675        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2676            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2677            final int numStacks = stacks.size();
2678            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2679                final ActivityStack stack = stacks.get(stackNdx);
2680                if (stack.finishDisabledPackageActivitiesLocked(
2681                        packageName, filterByClasses, doit, evenPersistent, userId)) {
2682                    didSomething = true;
2683                }
2684            }
2685        }
2686        return didSomething;
2687    }
2688
2689    void updatePreviousProcessLocked(ActivityRecord r) {
2690        // Now that this process has stopped, we may want to consider
2691        // it to be the previous app to try to keep around in case
2692        // the user wants to return to it.
2693
2694        // First, found out what is currently the foreground app, so that
2695        // we don't blow away the previous app if this activity is being
2696        // hosted by the process that is actually still the foreground.
2697        ProcessRecord fgApp = null;
2698        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2699            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2700            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2701                final ActivityStack stack = stacks.get(stackNdx);
2702                if (isFrontStack(stack)) {
2703                    if (stack.mResumedActivity != null) {
2704                        fgApp = stack.mResumedActivity.app;
2705                    } else if (stack.mPausingActivity != null) {
2706                        fgApp = stack.mPausingActivity.app;
2707                    }
2708                    break;
2709                }
2710            }
2711        }
2712
2713        // Now set this one as the previous process, only if that really
2714        // makes sense to.
2715        if (r.app != null && fgApp != null && r.app != fgApp
2716                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2717                && r.app != mService.mHomeProcess) {
2718            mService.mPreviousProcess = r.app;
2719            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2720        }
2721    }
2722
2723    boolean resumeTopActivitiesLocked() {
2724        return resumeTopActivitiesLocked(null, null, null);
2725    }
2726
2727    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2728            Bundle targetOptions) {
2729        if (targetStack == null) {
2730            targetStack = mFocusedStack;
2731        }
2732        // Do targetStack first.
2733        boolean result = false;
2734        if (isFrontStack(targetStack)) {
2735            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2736        }
2737
2738        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2739            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2740            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2741                final ActivityStack stack = stacks.get(stackNdx);
2742                if (stack == targetStack) {
2743                    // Already started above.
2744                    continue;
2745                }
2746                if (isFrontStack(stack)) {
2747                    stack.resumeTopActivityLocked(null);
2748                }
2749            }
2750        }
2751        return result;
2752    }
2753
2754    void finishTopRunningActivityLocked(ProcessRecord app, String reason) {
2755        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2756            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2757            final int numStacks = stacks.size();
2758            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2759                final ActivityStack stack = stacks.get(stackNdx);
2760                stack.finishTopRunningActivityLocked(app, reason);
2761            }
2762        }
2763    }
2764
2765    void finishVoiceTask(IVoiceInteractionSession session) {
2766        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2767            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2768            final int numStacks = stacks.size();
2769            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2770                final ActivityStack stack = stacks.get(stackNdx);
2771                stack.finishVoiceTask(session);
2772            }
2773        }
2774    }
2775
2776    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options, String reason) {
2777        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2778            mUserLeaving = true;
2779        }
2780        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2781            // Caller wants the home activity moved with it.  To accomplish this,
2782            // we'll just indicate that this task returns to the home task.
2783            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2784        }
2785        if (task.stack == null) {
2786            Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
2787                    + task + " to front. Stack is null");
2788            return;
2789        }
2790        task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
2791                task.getTopActivity() == null ? null : task.getTopActivity().appTimeTracker,
2792                reason);
2793        if (DEBUG_STACK) Slog.d(TAG_STACK,
2794                "findTaskToMoveToFront: moved to front of stack=" + task.stack);
2795    }
2796
2797    ActivityStack getStack(int stackId) {
2798        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2799        if (activityContainer != null) {
2800            return activityContainer.mStack;
2801        }
2802        return null;
2803    }
2804
2805    ArrayList<ActivityStack> getStacks() {
2806        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2807        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2808            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2809        }
2810        return allStacks;
2811    }
2812
2813    IBinder getHomeActivityToken() {
2814        ActivityRecord homeActivity = getHomeActivity();
2815        if (homeActivity != null) {
2816            return homeActivity.appToken;
2817        }
2818        return null;
2819    }
2820
2821    ActivityRecord getHomeActivity() {
2822        return getHomeActivityForUser(mCurrentUser);
2823    }
2824
2825    ActivityRecord getHomeActivityForUser(int userId) {
2826        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2827        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2828            final TaskRecord task = tasks.get(taskNdx);
2829            if (task.isHomeTask()) {
2830                final ArrayList<ActivityRecord> activities = task.mActivities;
2831                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2832                    final ActivityRecord r = activities.get(activityNdx);
2833                    if (r.isHomeActivity()
2834                            && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
2835                        return r;
2836                    }
2837                }
2838            }
2839        }
2840        return null;
2841    }
2842
2843    ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
2844            IActivityContainerCallback callback) {
2845        ActivityContainer activityContainer =
2846                new VirtualActivityContainer(parentActivity, callback);
2847        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2848        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
2849                "createActivityContainer: " + activityContainer);
2850        parentActivity.mChildContainers.add(activityContainer);
2851        return activityContainer;
2852    }
2853
2854    void removeChildActivityContainers(ActivityRecord parentActivity) {
2855        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2856        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2857            ActivityContainer container = childStacks.remove(containerNdx);
2858            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
2859                    + container);
2860            container.release();
2861        }
2862    }
2863
2864    void deleteActivityContainer(IActivityContainer container) {
2865        ActivityContainer activityContainer = (ActivityContainer)container;
2866        if (activityContainer != null) {
2867            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
2868                    "deleteActivityContainer: callers=" + Debug.getCallers(4));
2869            final int stackId = activityContainer.mStackId;
2870            mActivityContainers.remove(stackId);
2871            mWindowManager.removeStack(stackId);
2872        }
2873    }
2874
2875    void resizeStackLocked(int stackId, Rect bounds) {
2876        final ActivityStack stack = getStack(stackId);
2877        if (stack == null) {
2878            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2879            return;
2880        }
2881
2882        final ActivityRecord r = stack.topRunningActivityLocked(null);
2883        if (r != null && !r.task.mResizeable) {
2884            Slog.w(TAG, "resizeStack: top task " + r.task + " not resizeable.");
2885            return;
2886        }
2887
2888        final Configuration overrideConfig = mWindowManager.resizeStack(stackId, bounds);
2889        if (stack.updateOverrideConfiguration(overrideConfig)) {
2890            if (r != null) {
2891                final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
2892                // And we need to make sure at this point that all other activities
2893                // are made visible with the correct configuration.
2894                ensureActivitiesVisibleLocked(r, 0);
2895                if (!updated) {
2896                    resumeTopActivitiesLocked(stack, null, null);
2897                }
2898            }
2899        }
2900    }
2901
2902    /** Makes sure the input task is in a stack with the specified bounds by either resizing the
2903     * current task stack if it only has one entry, moving the task to a stack that matches the
2904     * bounds, or creating a new stack with the required bounds. Also, makes the task resizeable.*/
2905    void resizeTaskLocked(TaskRecord task, Rect bounds) {
2906        task.mResizeable = true;
2907        final ActivityStack currentStack = task.stack;
2908        if (currentStack.isHomeStack()) {
2909            // Can't move task off the home stack. Sorry!
2910            return;
2911        }
2912
2913        final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds);
2914        if (matchingStackId != -1) {
2915            // There is already a stack with the right bounds!
2916            if (currentStack != null && currentStack.mStackId == matchingStackId) {
2917                // Nothing to do here. Already in the right stack...
2918                return;
2919            }
2920            // Move task to stack with matching bounds.
2921            moveTaskToStackLocked(task.taskId, matchingStackId, true);
2922            return;
2923        }
2924
2925        if (currentStack != null && currentStack.numTasks() == 1) {
2926            // Just resize the current stack since this is the task in it.
2927            resizeStackLocked(currentStack.mStackId, bounds);
2928            return;
2929        }
2930
2931        // Create new stack and move the task to it.
2932        final int displayId = (currentStack != null && currentStack.mDisplayId != -1)
2933                ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY;
2934        ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId);
2935
2936        if (newStack == null) {
2937            Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task);
2938            return;
2939        }
2940        moveTaskToStackLocked(task.taskId, newStack.mStackId, true);
2941        resizeStackLocked(newStack.mStackId, bounds);
2942    }
2943
2944    ActivityStack createStackOnDisplay(int stackId, int displayId) {
2945        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2946        if (activityDisplay == null) {
2947            return null;
2948        }
2949
2950        ActivityContainer activityContainer = new ActivityContainer(stackId);
2951        mActivityContainers.put(stackId, activityContainer);
2952        activityContainer.attachToDisplayLocked(activityDisplay);
2953        return activityContainer.mStack;
2954    }
2955
2956    int getNextStackId() {
2957        while (true) {
2958            if (++mLastStackId <= HOME_STACK_ID) {
2959                mLastStackId = HOME_STACK_ID + 1;
2960            }
2961            if (getStack(mLastStackId) == null) {
2962                break;
2963            }
2964        }
2965        return mLastStackId;
2966    }
2967
2968    private boolean restoreRecentTaskLocked(TaskRecord task) {
2969        ActivityStack stack = null;
2970        // Determine stack to restore task to.
2971        if (mLeanbackOnlyDevice) {
2972            // There is only one stack for lean back devices.
2973            stack = mHomeStack;
2974        } else {
2975            // Look for the top stack on the home display that isn't the home stack.
2976            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
2977            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2978                final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx);
2979                if (!tmpStack.isHomeStack() && tmpStack.mFullscreen) {
2980                    stack = tmpStack;
2981                    break;
2982                }
2983            }
2984        }
2985
2986        if (stack == null) {
2987            // We couldn't find a stack to restore the task to. Possible if are restoring recents
2988            // before an application stack is created...Go ahead and create one on the default
2989            // display.
2990            stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2991            // Restore home stack to top.
2992            moveHomeStack(true, "restoreRecentTask");
2993            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2994                    "Created stack=" + stack + " for recents restoration.");
2995        }
2996
2997        if (stack == null) {
2998            // What does this mean??? Not sure how we would get here...
2999            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
3000                    "Unable to find/create stack to restore recent task=" + task);
3001            return false;
3002        }
3003
3004        stack.addTask(task, false, false);
3005        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
3006                "Added restored task=" + task + " to stack=" + stack);
3007        final ArrayList<ActivityRecord> activities = task.mActivities;
3008        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3009            final ActivityRecord r = activities.get(activityNdx);
3010            mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
3011                    r.info.screenOrientation, r.fullscreen,
3012                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
3013                    r.userId, r.info.configChanges, task.voiceSession != null,
3014                    r.mLaunchTaskBehind);
3015        }
3016        return true;
3017    }
3018
3019    void moveTaskToStackLocked(int taskId, int stackId, boolean toTop) {
3020        final TaskRecord task = anyTaskForIdLocked(taskId);
3021        if (task == null) {
3022            Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
3023            return;
3024        }
3025        final ActivityStack stack = getStack(stackId);
3026        if (stack == null) {
3027            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
3028            return;
3029        }
3030        mWindowManager.moveTaskToStack(taskId, stackId, toTop);
3031        if (task.stack != null) {
3032            task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */);
3033        }
3034        stack.addTask(task, toTop, true);
3035        // The task might have already been running and its visibility needs to be synchronized with
3036        // the visibility of the stack / windows.
3037        stack.ensureActivitiesVisibleLocked(null, 0);
3038        resumeTopActivitiesLocked();
3039    }
3040
3041    ActivityRecord findTaskLocked(ActivityRecord r) {
3042        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
3043        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3044            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3045            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3046                final ActivityStack stack = stacks.get(stackNdx);
3047                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
3048                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
3049                    continue;
3050                }
3051                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
3052                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
3053                            "Skipping stack: (new task not allowed) " + stack);
3054                    continue;
3055                }
3056                final ActivityRecord ar = stack.findTaskLocked(r);
3057                if (ar != null) {
3058                    return ar;
3059                }
3060            }
3061        }
3062        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "No task found");
3063        return null;
3064    }
3065
3066    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
3067        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3068            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3069            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3070                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
3071                if (ar != null) {
3072                    return ar;
3073                }
3074            }
3075        }
3076        return null;
3077    }
3078
3079    void goingToSleepLocked() {
3080        scheduleSleepTimeout();
3081        if (!mGoingToSleep.isHeld()) {
3082            mGoingToSleep.acquire();
3083            if (mLaunchingActivity.isHeld()) {
3084                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
3085                    throw new IllegalStateException("Calling must be system uid");
3086                }
3087                mLaunchingActivity.release();
3088                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
3089            }
3090        }
3091        checkReadyForSleepLocked();
3092    }
3093
3094    boolean shutdownLocked(int timeout) {
3095        goingToSleepLocked();
3096
3097        boolean timedout = false;
3098        final long endTime = System.currentTimeMillis() + timeout;
3099        while (true) {
3100            boolean cantShutdown = false;
3101            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3102                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3103                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3104                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
3105                }
3106            }
3107            if (cantShutdown) {
3108                long timeRemaining = endTime - System.currentTimeMillis();
3109                if (timeRemaining > 0) {
3110                    try {
3111                        mService.wait(timeRemaining);
3112                    } catch (InterruptedException e) {
3113                    }
3114                } else {
3115                    Slog.w(TAG, "Activity manager shutdown timed out");
3116                    timedout = true;
3117                    break;
3118                }
3119            } else {
3120                break;
3121            }
3122        }
3123
3124        // Force checkReadyForSleep to complete.
3125        mSleepTimeout = true;
3126        checkReadyForSleepLocked();
3127
3128        return timedout;
3129    }
3130
3131    void comeOutOfSleepIfNeededLocked() {
3132        removeSleepTimeouts();
3133        if (mGoingToSleep.isHeld()) {
3134            mGoingToSleep.release();
3135        }
3136        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3137            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3138            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3139                final ActivityStack stack = stacks.get(stackNdx);
3140                stack.awakeFromSleepingLocked();
3141                if (isFrontStack(stack)) {
3142                    resumeTopActivitiesLocked();
3143                }
3144            }
3145        }
3146        mGoingToSleepActivities.clear();
3147    }
3148
3149    void activitySleptLocked(ActivityRecord r) {
3150        mGoingToSleepActivities.remove(r);
3151        checkReadyForSleepLocked();
3152    }
3153
3154    void checkReadyForSleepLocked() {
3155        if (!mService.isSleepingOrShuttingDown()) {
3156            // Do not care.
3157            return;
3158        }
3159
3160        if (!mSleepTimeout) {
3161            boolean dontSleep = false;
3162            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3163                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3164                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3165                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
3166                }
3167            }
3168
3169            if (mStoppingActivities.size() > 0) {
3170                // Still need to tell some activities to stop; can't sleep yet.
3171                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
3172                        + mStoppingActivities.size() + " activities");
3173                scheduleIdleLocked();
3174                dontSleep = true;
3175            }
3176
3177            if (mGoingToSleepActivities.size() > 0) {
3178                // Still need to tell some activities to sleep; can't sleep yet.
3179                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
3180                        + mGoingToSleepActivities.size() + " activities");
3181                dontSleep = true;
3182            }
3183
3184            if (dontSleep) {
3185                return;
3186            }
3187        }
3188
3189        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3190            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3191            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3192                stacks.get(stackNdx).goToSleep();
3193            }
3194        }
3195
3196        removeSleepTimeouts();
3197
3198        if (mGoingToSleep.isHeld()) {
3199            mGoingToSleep.release();
3200        }
3201        if (mService.mShuttingDown) {
3202            mService.notifyAll();
3203        }
3204    }
3205
3206    boolean reportResumedActivityLocked(ActivityRecord r) {
3207        final ActivityStack stack = r.task.stack;
3208        if (isFrontStack(stack)) {
3209            mService.updateUsageStats(r, true);
3210        }
3211        if (allResumedActivitiesComplete()) {
3212            ensureActivitiesVisibleLocked(null, 0);
3213            mWindowManager.executeAppTransition();
3214            return true;
3215        }
3216        return false;
3217    }
3218
3219    void handleAppCrashLocked(ProcessRecord app) {
3220        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3221            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3222            int stackNdx = stacks.size() - 1;
3223            while (stackNdx >= 0) {
3224                stacks.get(stackNdx).handleAppCrashLocked(app);
3225                stackNdx--;
3226            }
3227        }
3228    }
3229
3230    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
3231        final ActivityStack stack = r.task.stack;
3232        if (stack == null) {
3233            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3234                    "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
3235            return false;
3236        }
3237        final boolean isVisible = stack.hasVisibleBehindActivity();
3238        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3239                "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
3240
3241        final ActivityRecord top = topRunningActivityLocked();
3242        if (top == null || top == r || (visible == isVisible)) {
3243            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
3244            stack.setVisibleBehindActivity(visible ? r : null);
3245            return true;
3246        }
3247
3248        // A non-top activity is reporting a visibility change.
3249        if (visible && top.fullscreen) {
3250            // Let the caller know that it can't be seen.
3251            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3252                    "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
3253                    + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
3254                    + top.app.thread);
3255            return false;
3256        } else if (!visible && stack.getVisibleBehindActivity() != r) {
3257            // Only the activity set as currently visible behind should actively reset its
3258            // visible behind state.
3259            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3260                    "requestVisibleBehind: returning visible=" + visible
3261                    + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
3262                    + " r=" + r);
3263            return false;
3264        }
3265
3266        stack.setVisibleBehindActivity(visible ? r : null);
3267        if (!visible) {
3268            // Make the activity immediately above r opaque.
3269            final ActivityRecord next = stack.findNextTranslucentActivity(r);
3270            if (next != null) {
3271                mService.convertFromTranslucent(next.appToken);
3272            }
3273        }
3274        if (top.app != null && top.app.thread != null) {
3275            // Notify the top app of the change.
3276            try {
3277                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
3278            } catch (RemoteException e) {
3279            }
3280        }
3281        return true;
3282    }
3283
3284    // Called when WindowManager has finished animating the launchingBehind activity to the back.
3285    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
3286        r.mLaunchTaskBehind = false;
3287        final TaskRecord task = r.task;
3288        task.setLastThumbnail(task.stack.screenshotActivities(r));
3289        mRecentTasks.addLocked(task);
3290        mService.notifyTaskStackChangedLocked();
3291        mWindowManager.setAppVisibility(r.appToken, false);
3292    }
3293
3294    void scheduleLaunchTaskBehindComplete(IBinder token) {
3295        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
3296    }
3297
3298    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
3299        // First the front stacks. In case any are not fullscreen and are in front of home.
3300        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3301            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3302            final int topStackNdx = stacks.size() - 1;
3303            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
3304                final ActivityStack stack = stacks.get(stackNdx);
3305                stack.ensureActivitiesVisibleLocked(starting, configChanges);
3306            }
3307        }
3308    }
3309
3310    void clearOtherAppTimeTrackers(AppTimeTracker except) {
3311        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3312            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3313            final int topStackNdx = stacks.size() - 1;
3314            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
3315                final ActivityStack stack = stacks.get(stackNdx);
3316                stack.clearOtherAppTimeTrackers(except);
3317            }
3318        }
3319    }
3320
3321    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
3322        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3323            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3324            final int numStacks = stacks.size();
3325            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
3326                final ActivityStack stack = stacks.get(stackNdx);
3327                stack.scheduleDestroyActivities(app, reason);
3328            }
3329        }
3330    }
3331
3332    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
3333        // Examine all activities currently running in the process.
3334        TaskRecord firstTask = null;
3335        // Tasks is non-null only if two or more tasks are found.
3336        ArraySet<TaskRecord> tasks = null;
3337        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
3338        for (int i = 0; i < app.activities.size(); i++) {
3339            ActivityRecord r = app.activities.get(i);
3340            // First, if we find an activity that is in the process of being destroyed,
3341            // then we just aren't going to do anything for now; we want things to settle
3342            // down before we try to prune more activities.
3343            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
3344                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
3345                return;
3346            }
3347            // Don't consider any activies that are currently not in a state where they
3348            // can be destroyed.
3349            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
3350                    || r.state == PAUSED || r.state == STOPPING) {
3351                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
3352                continue;
3353            }
3354            if (r.task != null) {
3355                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task
3356                        + " from " + r);
3357                if (firstTask == null) {
3358                    firstTask = r.task;
3359                } else if (firstTask != r.task) {
3360                    if (tasks == null) {
3361                        tasks = new ArraySet<>();
3362                        tasks.add(firstTask);
3363                    }
3364                    tasks.add(r.task);
3365                }
3366            }
3367        }
3368        if (tasks == null) {
3369            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
3370            return;
3371        }
3372        // If we have activities in multiple tasks that are in a position to be destroyed,
3373        // let's iterate through the tasks and release the oldest one.
3374        final int numDisplays = mActivityDisplays.size();
3375        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
3376            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3377            // Step through all stacks starting from behind, to hit the oldest things first.
3378            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
3379                final ActivityStack stack = stacks.get(stackNdx);
3380                // Try to release activities in this stack; if we manage to, we are done.
3381                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
3382                    return;
3383                }
3384            }
3385        }
3386    }
3387
3388    boolean switchUserLocked(int userId, UserState uss) {
3389        mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
3390        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
3391        mCurrentUser = userId;
3392
3393        mStartingUsers.add(uss);
3394        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3395            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3396            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3397                final ActivityStack stack = stacks.get(stackNdx);
3398                stack.switchUserLocked(userId);
3399                TaskRecord task = stack.topTask();
3400                if (task != null) {
3401                    mWindowManager.moveTaskToTop(task.taskId);
3402                }
3403            }
3404        }
3405
3406        ActivityStack stack = getStack(restoreStackId);
3407        if (stack == null) {
3408            stack = mHomeStack;
3409        }
3410        final boolean homeInFront = stack.isHomeStack();
3411        if (stack.isOnHomeDisplay()) {
3412            moveHomeStack(homeInFront, "switchUserOnHomeDisplay");
3413            TaskRecord task = stack.topTask();
3414            if (task != null) {
3415                mWindowManager.moveTaskToTop(task.taskId);
3416            }
3417        } else {
3418            // Stack was moved to another display while user was swapped out.
3419            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
3420        }
3421        return homeInFront;
3422    }
3423
3424    /**
3425     * Add background users to send boot completed events to.
3426     * @param userId The user being started in the background
3427     * @param uss The state object for the user.
3428     */
3429    public void startBackgroundUserLocked(int userId, UserState uss) {
3430        mStartingBackgroundUsers.add(uss);
3431    }
3432
3433    /** Checks whether the userid is a profile of the current user. */
3434    boolean isCurrentProfileLocked(int userId) {
3435        if (userId == mCurrentUser) return true;
3436        for (int i = 0; i < mService.mCurrentProfileIds.length; i++) {
3437            if (mService.mCurrentProfileIds[i] == userId) return true;
3438        }
3439        return false;
3440    }
3441
3442    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
3443        ArrayList<ActivityRecord> stops = null;
3444
3445        final boolean nowVisible = allResumedActivitiesVisible();
3446        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3447            ActivityRecord s = mStoppingActivities.get(activityNdx);
3448            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
3449            if (DEBUG_ALL) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
3450                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
3451            if (waitingVisible && nowVisible) {
3452                mWaitingVisibleActivities.remove(s);
3453                if (s.finishing) {
3454                    // If this activity is finishing, it is sitting on top of
3455                    // everyone else but we now know it is no longer needed...
3456                    // so get rid of it.  Otherwise, we need to go through the
3457                    // normal flow and hide it once we determine that it is
3458                    // hidden by the activities in front of it.
3459                    if (DEBUG_ALL) Slog.v(TAG, "Before stopping, can hide: " + s);
3460                    mWindowManager.setAppVisibility(s.appToken, false);
3461                }
3462            }
3463            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
3464                if (DEBUG_ALL) Slog.v(TAG, "Ready to stop: " + s);
3465                if (stops == null) {
3466                    stops = new ArrayList<>();
3467                }
3468                stops.add(s);
3469                mStoppingActivities.remove(activityNdx);
3470            }
3471        }
3472
3473        return stops;
3474    }
3475
3476    void validateTopActivitiesLocked() {
3477        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3478            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3479            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3480                final ActivityStack stack = stacks.get(stackNdx);
3481                final ActivityRecord r = stack.topRunningActivityLocked(null);
3482                final ActivityState state = r == null ? DESTROYED : r.state;
3483                if (isFrontStack(stack)) {
3484                    if (r == null) Slog.e(TAG,
3485                            "validateTop...: null top activity, stack=" + stack);
3486                    else {
3487                        final ActivityRecord pausing = stack.mPausingActivity;
3488                        if (pausing != null && pausing == r) Slog.e(TAG,
3489                                "validateTop...: top stack has pausing activity r=" + r
3490                                + " state=" + state);
3491                        if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
3492                                "validateTop...: activity in front not resumed r=" + r
3493                                + " state=" + state);
3494                    }
3495                } else {
3496                    final ActivityRecord resumed = stack.mResumedActivity;
3497                    if (resumed != null && resumed == r) Slog.e(TAG,
3498                            "validateTop...: back stack has resumed activity r=" + r
3499                            + " state=" + state);
3500                    if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
3501                            "validateTop...: activity in back resumed r=" + r + " state=" + state);
3502                }
3503            }
3504        }
3505    }
3506
3507    private String lockTaskModeToString() {
3508        switch (mLockTaskModeState) {
3509            case LOCK_TASK_MODE_LOCKED:
3510                return "LOCKED";
3511            case LOCK_TASK_MODE_PINNED:
3512                return "PINNED";
3513            case LOCK_TASK_MODE_NONE:
3514                return "NONE";
3515            default: return "unknown=" + mLockTaskModeState;
3516        }
3517    }
3518
3519    public void dump(PrintWriter pw, String prefix) {
3520        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3521                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3522        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3523        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
3524        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3525        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3526        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
3527                final SparseArray<String[]> packages = mService.mLockTaskPackages;
3528                if (packages.size() > 0) {
3529                    pw.println(" mLockTaskPackages (userId:packages)=");
3530                    for (int i = 0; i < packages.size(); ++i) {
3531                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
3532                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
3533                    }
3534                }
3535                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
3536    }
3537
3538    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3539        return mFocusedStack.getDumpActivitiesLocked(name);
3540    }
3541
3542    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3543            boolean needSep, String prefix) {
3544        if (activity != null) {
3545            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3546                if (needSep) {
3547                    pw.println();
3548                }
3549                pw.print(prefix);
3550                pw.println(activity);
3551                return true;
3552            }
3553        }
3554        return false;
3555    }
3556
3557    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3558            boolean dumpClient, String dumpPackage) {
3559        boolean printed = false;
3560        boolean needSep = false;
3561        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3562            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3563            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3564                    pw.println(" (activities from top to bottom):");
3565            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3566            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3567                final ActivityStack stack = stacks.get(stackNdx);
3568                StringBuilder stackHeader = new StringBuilder(128);
3569                stackHeader.append("  Stack #");
3570                stackHeader.append(stack.mStackId);
3571                stackHeader.append(":");
3572                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3573                        needSep, stackHeader.toString());
3574                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3575                        !dumpAll, false, dumpPackage, true,
3576                        "    Running activities (most recent first):", null);
3577
3578                needSep = printed;
3579                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3580                        "    mPausingActivity: ");
3581                if (pr) {
3582                    printed = true;
3583                    needSep = false;
3584                }
3585                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3586                        "    mResumedActivity: ");
3587                if (pr) {
3588                    printed = true;
3589                    needSep = false;
3590                }
3591                if (dumpAll) {
3592                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3593                            "    mLastPausedActivity: ");
3594                    if (pr) {
3595                        printed = true;
3596                        needSep = true;
3597                    }
3598                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3599                            needSep, "    mLastNoHistoryActivity: ");
3600                }
3601                needSep = printed;
3602            }
3603        }
3604
3605        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3606                false, dumpPackage, true, "  Activities waiting to finish:", null);
3607        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3608                false, dumpPackage, true, "  Activities waiting to stop:", null);
3609        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3610                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3611                null);
3612        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3613                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3614        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3615                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3616
3617        return printed;
3618    }
3619
3620    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3621            String prefix, String label, boolean complete, boolean brief, boolean client,
3622            String dumpPackage, boolean needNL, String header1, String header2) {
3623        TaskRecord lastTask = null;
3624        String innerPrefix = null;
3625        String[] args = null;
3626        boolean printed = false;
3627        for (int i=list.size()-1; i>=0; i--) {
3628            final ActivityRecord r = list.get(i);
3629            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3630                continue;
3631            }
3632            if (innerPrefix == null) {
3633                innerPrefix = prefix + "      ";
3634                args = new String[0];
3635            }
3636            printed = true;
3637            final boolean full = !brief && (complete || !r.isInHistory());
3638            if (needNL) {
3639                pw.println("");
3640                needNL = false;
3641            }
3642            if (header1 != null) {
3643                pw.println(header1);
3644                header1 = null;
3645            }
3646            if (header2 != null) {
3647                pw.println(header2);
3648                header2 = null;
3649            }
3650            if (lastTask != r.task) {
3651                lastTask = r.task;
3652                pw.print(prefix);
3653                pw.print(full ? "* " : "  ");
3654                pw.println(lastTask);
3655                if (full) {
3656                    lastTask.dump(pw, prefix + "  ");
3657                } else if (complete) {
3658                    // Complete + brief == give a summary.  Isn't that obvious?!?
3659                    if (lastTask.intent != null) {
3660                        pw.print(prefix); pw.print("  ");
3661                                pw.println(lastTask.intent.toInsecureStringWithClip());
3662                    }
3663                }
3664            }
3665            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3666            pw.print(" #"); pw.print(i); pw.print(": ");
3667            pw.println(r);
3668            if (full) {
3669                r.dump(pw, innerPrefix);
3670            } else if (complete) {
3671                // Complete + brief == give a summary.  Isn't that obvious?!?
3672                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3673                if (r.app != null) {
3674                    pw.print(innerPrefix); pw.println(r.app);
3675                }
3676            }
3677            if (client && r.app != null && r.app.thread != null) {
3678                // flush anything that is already in the PrintWriter since the thread is going
3679                // to write to the file descriptor directly
3680                pw.flush();
3681                try {
3682                    TransferPipe tp = new TransferPipe();
3683                    try {
3684                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3685                                r.appToken, innerPrefix, args);
3686                        // Short timeout, since blocking here can
3687                        // deadlock with the application.
3688                        tp.go(fd, 2000);
3689                    } finally {
3690                        tp.kill();
3691                    }
3692                } catch (IOException e) {
3693                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3694                } catch (RemoteException e) {
3695                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3696                }
3697                needNL = true;
3698            }
3699        }
3700        return printed;
3701    }
3702
3703    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3704        if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3705                "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3706        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3707        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3708    }
3709
3710    final void scheduleIdleLocked() {
3711        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3712    }
3713
3714    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3715        if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
3716                + Debug.getCallers(4));
3717        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3718    }
3719
3720    final void scheduleResumeTopActivities() {
3721        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3722            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3723        }
3724    }
3725
3726    void removeSleepTimeouts() {
3727        mSleepTimeout = false;
3728        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3729    }
3730
3731    final void scheduleSleepTimeout() {
3732        removeSleepTimeouts();
3733        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3734    }
3735
3736    @Override
3737    public void onDisplayAdded(int displayId) {
3738        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
3739        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3740    }
3741
3742    @Override
3743    public void onDisplayRemoved(int displayId) {
3744        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
3745        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3746    }
3747
3748    @Override
3749    public void onDisplayChanged(int displayId) {
3750        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
3751        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3752    }
3753
3754    private void handleDisplayAdded(int displayId) {
3755        boolean newDisplay;
3756        synchronized (mService) {
3757            newDisplay = mActivityDisplays.get(displayId) == null;
3758            if (newDisplay) {
3759                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3760                if (activityDisplay.mDisplay == null) {
3761                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3762                    return;
3763                }
3764                mActivityDisplays.put(displayId, activityDisplay);
3765            }
3766        }
3767        if (newDisplay) {
3768            mWindowManager.onDisplayAdded(displayId);
3769        }
3770    }
3771
3772    private void handleDisplayRemoved(int displayId) {
3773        synchronized (mService) {
3774            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3775            if (activityDisplay != null) {
3776                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3777                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3778                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3779                }
3780                mActivityDisplays.remove(displayId);
3781            }
3782        }
3783        mWindowManager.onDisplayRemoved(displayId);
3784    }
3785
3786    private void handleDisplayChanged(int displayId) {
3787        synchronized (mService) {
3788            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3789            if (activityDisplay != null) {
3790                // TODO: Update the bounds.
3791            }
3792        }
3793        mWindowManager.onDisplayChanged(displayId);
3794    }
3795
3796    private StackInfo getStackInfoLocked(ActivityStack stack) {
3797        StackInfo info = new StackInfo();
3798        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3799        info.displayId = Display.DEFAULT_DISPLAY;
3800        info.stackId = stack.mStackId;
3801
3802        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3803        final int numTasks = tasks.size();
3804        int[] taskIds = new int[numTasks];
3805        String[] taskNames = new String[numTasks];
3806        for (int i = 0; i < numTasks; ++i) {
3807            final TaskRecord task = tasks.get(i);
3808            taskIds[i] = task.taskId;
3809            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3810                    : task.realActivity != null ? task.realActivity.flattenToString()
3811                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3812                    : "unknown";
3813        }
3814        info.taskIds = taskIds;
3815        info.taskNames = taskNames;
3816        return info;
3817    }
3818
3819    StackInfo getStackInfoLocked(int stackId) {
3820        ActivityStack stack = getStack(stackId);
3821        if (stack != null) {
3822            return getStackInfoLocked(stack);
3823        }
3824        return null;
3825    }
3826
3827    ArrayList<StackInfo> getAllStackInfosLocked() {
3828        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3829        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3830            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3831            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3832                list.add(getStackInfoLocked(stacks.get(ndx)));
3833            }
3834        }
3835        return list;
3836    }
3837
3838    TaskRecord getLockedTaskLocked() {
3839        final int top = mLockTaskModeTasks.size() - 1;
3840        if (top >= 0) {
3841            return mLockTaskModeTasks.get(top);
3842        }
3843        return null;
3844    }
3845
3846    boolean isLockedTask(TaskRecord task) {
3847        return mLockTaskModeTasks.contains(task);
3848    }
3849
3850    boolean isLastLockedTask(TaskRecord task) {
3851        return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
3852    }
3853
3854    void removeLockedTaskLocked(final TaskRecord task) {
3855        if (!mLockTaskModeTasks.remove(task)) {
3856            return;
3857        }
3858        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
3859        if (mLockTaskModeTasks.isEmpty()) {
3860            // Last one.
3861            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
3862                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
3863            final Message lockTaskMsg = Message.obtain();
3864            lockTaskMsg.arg1 = task.userId;
3865            lockTaskMsg.what = LOCK_TASK_END_MSG;
3866            mHandler.sendMessage(lockTaskMsg);
3867        }
3868    }
3869
3870    void showLockTaskToast() {
3871        mLockTaskNotify.showToast(mLockTaskModeState);
3872    }
3873
3874    void showLockTaskEscapeMessageLocked(TaskRecord task) {
3875        if (mLockTaskModeTasks.contains(task)) {
3876            mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
3877        }
3878    }
3879
3880    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
3881            boolean andResume) {
3882        if (task == null) {
3883            // Take out of lock task mode if necessary
3884            final TaskRecord lockedTask = getLockedTaskLocked();
3885            if (lockedTask != null) {
3886                removeLockedTaskLocked(lockedTask);
3887                if (!mLockTaskModeTasks.isEmpty()) {
3888                    // There are locked tasks remaining, can only finish this task, not unlock it.
3889                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3890                            "setLockTaskModeLocked: Tasks remaining, can't unlock");
3891                    lockedTask.performClearTaskLocked();
3892                    resumeTopActivitiesLocked();
3893                    return;
3894                }
3895            }
3896            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3897                    "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
3898            return;
3899        }
3900
3901        // Should have already been checked, but do it again.
3902        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
3903            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3904                    "setLockTaskModeLocked: Can't lock due to auth");
3905            return;
3906        }
3907        if (isLockTaskModeViolation(task)) {
3908            Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
3909            return;
3910        }
3911
3912        if (mLockTaskModeTasks.isEmpty()) {
3913            // First locktask.
3914            final Message lockTaskMsg = Message.obtain();
3915            lockTaskMsg.obj = task.intent.getComponent().getPackageName();
3916            lockTaskMsg.arg1 = task.userId;
3917            lockTaskMsg.what = LOCK_TASK_START_MSG;
3918            lockTaskMsg.arg2 = lockTaskModeState;
3919            mHandler.sendMessage(lockTaskMsg);
3920        }
3921        // Add it or move it to the top.
3922        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
3923                " Callers=" + Debug.getCallers(4));
3924        mLockTaskModeTasks.remove(task);
3925        mLockTaskModeTasks.add(task);
3926
3927        if (task.mLockTaskUid == -1) {
3928            task.mLockTaskUid = task.effectiveUid;
3929        }
3930
3931        if (andResume) {
3932            findTaskToMoveToFrontLocked(task, 0, null, reason);
3933            resumeTopActivitiesLocked();
3934        }
3935    }
3936
3937    boolean isLockTaskModeViolation(TaskRecord task) {
3938        return isLockTaskModeViolation(task, false);
3939    }
3940
3941    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
3942        if (getLockedTaskLocked() == task && !isNewClearTask) {
3943            return false;
3944        }
3945        final int lockTaskAuth = task.mLockTaskAuth;
3946        switch (lockTaskAuth) {
3947            case LOCK_TASK_AUTH_DONT_LOCK:
3948                return !mLockTaskModeTasks.isEmpty();
3949            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
3950            case LOCK_TASK_AUTH_LAUNCHABLE:
3951            case LOCK_TASK_AUTH_WHITELISTED:
3952                return false;
3953            case LOCK_TASK_AUTH_PINNABLE:
3954                // Pinnable tasks can't be launched on top of locktask tasks.
3955                return !mLockTaskModeTasks.isEmpty();
3956            default:
3957                Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
3958                return true;
3959        }
3960    }
3961
3962    void onLockTaskPackagesUpdatedLocked() {
3963        boolean didSomething = false;
3964        for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
3965            final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
3966            final boolean wasWhitelisted =
3967                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3968                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3969            lockedTask.setLockTaskAuth();
3970            final boolean isWhitelisted =
3971                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3972                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3973            if (wasWhitelisted && !isWhitelisted) {
3974                // Lost whitelisting authorization. End it now.
3975                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
3976                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
3977                removeLockedTaskLocked(lockedTask);
3978                lockedTask.performClearTaskLocked();
3979                didSomething = true;
3980            }
3981        }
3982        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3983            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3984            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3985                final ActivityStack stack = stacks.get(stackNdx);
3986                stack.onLockTaskPackagesUpdatedLocked();
3987            }
3988        }
3989        final ActivityRecord r = topRunningActivityLocked();
3990        final TaskRecord task = r != null ? r.task : null;
3991        if (mLockTaskModeTasks.isEmpty() && task != null
3992                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
3993            // This task must have just been authorized.
3994            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
3995                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
3996            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
3997                    false);
3998            didSomething = true;
3999        }
4000        if (didSomething) {
4001            resumeTopActivitiesLocked();
4002        }
4003    }
4004
4005    int getLockTaskModeState() {
4006        return mLockTaskModeState;
4007    }
4008
4009    private final class ActivityStackSupervisorHandler extends Handler {
4010
4011        public ActivityStackSupervisorHandler(Looper looper) {
4012            super(looper);
4013        }
4014
4015        void activityIdleInternal(ActivityRecord r) {
4016            synchronized (mService) {
4017                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
4018            }
4019        }
4020
4021        @Override
4022        public void handleMessage(Message msg) {
4023            switch (msg.what) {
4024                case IDLE_TIMEOUT_MSG: {
4025                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
4026                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
4027                    if (mService.mDidDexOpt) {
4028                        mService.mDidDexOpt = false;
4029                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
4030                        nmsg.obj = msg.obj;
4031                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
4032                        return;
4033                    }
4034                    // We don't at this point know if the activity is fullscreen,
4035                    // so we need to be conservative and assume it isn't.
4036                    activityIdleInternal((ActivityRecord)msg.obj);
4037                } break;
4038                case IDLE_NOW_MSG: {
4039                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
4040                    activityIdleInternal((ActivityRecord)msg.obj);
4041                } break;
4042                case RESUME_TOP_ACTIVITY_MSG: {
4043                    synchronized (mService) {
4044                        resumeTopActivitiesLocked();
4045                    }
4046                } break;
4047                case SLEEP_TIMEOUT_MSG: {
4048                    synchronized (mService) {
4049                        if (mService.isSleepingOrShuttingDown()) {
4050                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
4051                            mSleepTimeout = true;
4052                            checkReadyForSleepLocked();
4053                        }
4054                    }
4055                } break;
4056                case LAUNCH_TIMEOUT_MSG: {
4057                    if (mService.mDidDexOpt) {
4058                        mService.mDidDexOpt = false;
4059                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
4060                        return;
4061                    }
4062                    synchronized (mService) {
4063                        if (mLaunchingActivity.isHeld()) {
4064                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
4065                            if (VALIDATE_WAKE_LOCK_CALLER
4066                                    && Binder.getCallingUid() != Process.myUid()) {
4067                                throw new IllegalStateException("Calling must be system uid");
4068                            }
4069                            mLaunchingActivity.release();
4070                        }
4071                    }
4072                } break;
4073                case HANDLE_DISPLAY_ADDED: {
4074                    handleDisplayAdded(msg.arg1);
4075                } break;
4076                case HANDLE_DISPLAY_CHANGED: {
4077                    handleDisplayChanged(msg.arg1);
4078                } break;
4079                case HANDLE_DISPLAY_REMOVED: {
4080                    handleDisplayRemoved(msg.arg1);
4081                } break;
4082                case CONTAINER_CALLBACK_VISIBILITY: {
4083                    final ActivityContainer container = (ActivityContainer) msg.obj;
4084                    final IActivityContainerCallback callback = container.mCallback;
4085                    if (callback != null) {
4086                        try {
4087                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
4088                        } catch (RemoteException e) {
4089                        }
4090                    }
4091                } break;
4092                case LOCK_TASK_START_MSG: {
4093                    // When lock task starts, we disable the status bars.
4094                    try {
4095                        if (mLockTaskNotify == null) {
4096                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
4097                        }
4098                        mLockTaskNotify.show(true);
4099                        mLockTaskModeState = msg.arg2;
4100                        if (getStatusBarService() != null) {
4101                            int flags = 0;
4102                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
4103                                flags = StatusBarManager.DISABLE_MASK
4104                                        & (~StatusBarManager.DISABLE_BACK);
4105                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
4106                                flags = StatusBarManager.DISABLE_MASK
4107                                        & (~StatusBarManager.DISABLE_BACK)
4108                                        & (~StatusBarManager.DISABLE_HOME)
4109                                        & (~StatusBarManager.DISABLE_RECENT);
4110                            }
4111                            getStatusBarService().disable(flags, mToken,
4112                                    mService.mContext.getPackageName());
4113                        }
4114                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
4115                        if (getDevicePolicyManager() != null) {
4116                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
4117                                    (String)msg.obj, msg.arg1);
4118                        }
4119                    } catch (RemoteException ex) {
4120                        throw new RuntimeException(ex);
4121                    }
4122                } break;
4123                case LOCK_TASK_END_MSG: {
4124                    // When lock task ends, we enable the status bars.
4125                    try {
4126                        if (getStatusBarService() != null) {
4127                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
4128                                    mService.mContext.getPackageName());
4129                        }
4130                        mWindowManager.reenableKeyguard(mToken);
4131                        if (getDevicePolicyManager() != null) {
4132                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
4133                                    msg.arg1);
4134                        }
4135                        if (mLockTaskNotify == null) {
4136                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
4137                        }
4138                        mLockTaskNotify.show(false);
4139                        try {
4140                            boolean shouldLockKeyguard = Settings.Secure.getInt(
4141                                    mService.mContext.getContentResolver(),
4142                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
4143                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
4144                                mWindowManager.lockNow(null);
4145                                mWindowManager.dismissKeyguard();
4146                                new LockPatternUtils(mService.mContext)
4147                                        .requireCredentialEntry(UserHandle.USER_ALL);
4148                            }
4149                        } catch (SettingNotFoundException e) {
4150                            // No setting, don't lock.
4151                        }
4152                    } catch (RemoteException ex) {
4153                        throw new RuntimeException(ex);
4154                    } finally {
4155                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
4156                    }
4157                } break;
4158                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
4159                    if (mLockTaskNotify == null) {
4160                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
4161                    }
4162                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
4163                } break;
4164                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
4165                    final ActivityContainer container = (ActivityContainer) msg.obj;
4166                    final IActivityContainerCallback callback = container.mCallback;
4167                    if (callback != null) {
4168                        try {
4169                            callback.onAllActivitiesComplete(container.asBinder());
4170                        } catch (RemoteException e) {
4171                        }
4172                    }
4173                } break;
4174                case LAUNCH_TASK_BEHIND_COMPLETE: {
4175                    synchronized (mService) {
4176                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
4177                        if (r != null) {
4178                            handleLaunchTaskBehindCompleteLocked(r);
4179                        }
4180                    }
4181                } break;
4182            }
4183        }
4184    }
4185
4186    class ActivityContainer extends android.app.IActivityContainer.Stub {
4187        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
4188                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
4189        final int mStackId;
4190        IActivityContainerCallback mCallback = null;
4191        final ActivityStack mStack;
4192        ActivityRecord mParentActivity = null;
4193        String mIdString;
4194
4195        boolean mVisible = true;
4196
4197        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
4198        ActivityDisplay mActivityDisplay;
4199
4200        final static int CONTAINER_STATE_HAS_SURFACE = 0;
4201        final static int CONTAINER_STATE_NO_SURFACE = 1;
4202        final static int CONTAINER_STATE_FINISHING = 2;
4203        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
4204
4205        ActivityContainer(int stackId) {
4206            synchronized (mService) {
4207                mStackId = stackId;
4208                mStack = new ActivityStack(this, mRecentTasks);
4209                mIdString = "ActivtyContainer{" + mStackId + "}";
4210                if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
4211            }
4212        }
4213
4214        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
4215            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
4216                    + " to display=" + activityDisplay);
4217            mActivityDisplay = activityDisplay;
4218            mStack.mDisplayId = activityDisplay.mDisplayId;
4219            mStack.mStacks = activityDisplay.mStacks;
4220
4221            activityDisplay.attachActivities(mStack);
4222            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
4223        }
4224
4225        @Override
4226        public void attachToDisplay(int displayId) {
4227            synchronized (mService) {
4228                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
4229                if (activityDisplay == null) {
4230                    return;
4231                }
4232                attachToDisplayLocked(activityDisplay);
4233            }
4234        }
4235
4236        @Override
4237        public int getDisplayId() {
4238            synchronized (mService) {
4239                if (mActivityDisplay != null) {
4240                    return mActivityDisplay.mDisplayId;
4241                }
4242            }
4243            return -1;
4244        }
4245
4246        @Override
4247        public int getStackId() {
4248            synchronized (mService) {
4249                return mStackId;
4250            }
4251        }
4252
4253        @Override
4254        public boolean injectEvent(InputEvent event) {
4255            final long origId = Binder.clearCallingIdentity();
4256            try {
4257                synchronized (mService) {
4258                    if (mActivityDisplay != null) {
4259                        return mInputManagerInternal.injectInputEvent(event,
4260                                mActivityDisplay.mDisplayId,
4261                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
4262                    }
4263                }
4264                return false;
4265            } finally {
4266                Binder.restoreCallingIdentity(origId);
4267            }
4268        }
4269
4270        @Override
4271        public void release() {
4272            synchronized (mService) {
4273                if (mContainerState == CONTAINER_STATE_FINISHING) {
4274                    return;
4275                }
4276                mContainerState = CONTAINER_STATE_FINISHING;
4277
4278                long origId = Binder.clearCallingIdentity();
4279                try {
4280                    mStack.finishAllActivitiesLocked(false);
4281                    removePendingActivityLaunchesLocked(mStack);
4282                } finally {
4283                    Binder.restoreCallingIdentity(origId);
4284                }
4285            }
4286        }
4287
4288        protected void detachLocked() {
4289            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
4290                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
4291            if (mActivityDisplay != null) {
4292                mActivityDisplay.detachActivitiesLocked(mStack);
4293                mActivityDisplay = null;
4294                mStack.mDisplayId = -1;
4295                mStack.mStacks = null;
4296                mWindowManager.detachStack(mStackId);
4297            }
4298        }
4299
4300        @Override
4301        public final int startActivity(Intent intent) {
4302            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
4303            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
4304                    Binder.getCallingUid(), mCurrentUser, false,
4305                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4306
4307            // TODO: Switch to user app stacks here.
4308            String mimeType = intent.getType();
4309            final Uri data = intent.getData();
4310            if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4311                mimeType = mService.getProviderMimeType(data, userId);
4312            }
4313            checkEmbeddedAllowedInner(userId, intent, mimeType);
4314
4315            intent.addFlags(FORCE_NEW_TASK_FLAGS);
4316            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null,
4317                    0, 0, null, null, null, null, false, userId, this, null);
4318        }
4319
4320        @Override
4321        public final int startActivityIntentSender(IIntentSender intentSender)
4322                throws TransactionTooLargeException {
4323            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
4324
4325            if (!(intentSender instanceof PendingIntentRecord)) {
4326                throw new IllegalArgumentException("Bad PendingIntent object");
4327            }
4328
4329            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
4330                    Binder.getCallingUid(), mCurrentUser, false,
4331                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4332
4333            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
4334            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
4335                    pendingIntent.key.requestResolvedType);
4336
4337            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
4338                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
4339        }
4340
4341        private void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
4342            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
4343            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
4344                throw new SecurityException(
4345                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
4346            }
4347        }
4348
4349        @Override
4350        public IBinder asBinder() {
4351            return this;
4352        }
4353
4354        @Override
4355        public void setSurface(Surface surface, int width, int height, int density) {
4356            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
4357        }
4358
4359        ActivityStackSupervisor getOuter() {
4360            return ActivityStackSupervisor.this;
4361        }
4362
4363        boolean isAttachedLocked() {
4364            return mActivityDisplay != null;
4365        }
4366
4367        void getBounds(Point outBounds) {
4368            synchronized (mService) {
4369                    if (mActivityDisplay != null) {
4370                    mActivityDisplay.getBounds(outBounds);
4371                } else {
4372                    outBounds.set(0, 0);
4373                }
4374            }
4375        }
4376
4377        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
4378        void setVisible(boolean visible) {
4379            if (mVisible != visible) {
4380                mVisible = visible;
4381                if (mCallback != null) {
4382                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
4383                            0 /* unused */, this).sendToTarget();
4384                }
4385            }
4386        }
4387
4388        void setDrawn() {
4389        }
4390
4391        // You can always start a new task on a regular ActivityStack.
4392        boolean isEligibleForNewTasks() {
4393            return true;
4394        }
4395
4396        void onTaskListEmptyLocked() {
4397            detachLocked();
4398            deleteActivityContainer(this);
4399            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
4400        }
4401
4402        @Override
4403        public String toString() {
4404            return mIdString + (mActivityDisplay == null ? "N" : "A");
4405        }
4406    }
4407
4408    private class VirtualActivityContainer extends ActivityContainer {
4409        Surface mSurface;
4410        boolean mDrawn = false;
4411
4412        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
4413            super(getNextStackId());
4414            mParentActivity = parent;
4415            mCallback = callback;
4416            mContainerState = CONTAINER_STATE_NO_SURFACE;
4417            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
4418        }
4419
4420        @Override
4421        public void setSurface(Surface surface, int width, int height, int density) {
4422            super.setSurface(surface, width, height, density);
4423
4424            synchronized (mService) {
4425                final long origId = Binder.clearCallingIdentity();
4426                try {
4427                    setSurfaceLocked(surface, width, height, density);
4428                } finally {
4429                    Binder.restoreCallingIdentity(origId);
4430                }
4431            }
4432        }
4433
4434        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
4435            if (mContainerState == CONTAINER_STATE_FINISHING) {
4436                return;
4437            }
4438            VirtualActivityDisplay virtualActivityDisplay =
4439                    (VirtualActivityDisplay) mActivityDisplay;
4440            if (virtualActivityDisplay == null) {
4441                virtualActivityDisplay =
4442                        new VirtualActivityDisplay(width, height, density);
4443                mActivityDisplay = virtualActivityDisplay;
4444                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
4445                attachToDisplayLocked(virtualActivityDisplay);
4446            }
4447
4448            if (mSurface != null) {
4449                mSurface.release();
4450            }
4451
4452            mSurface = surface;
4453            if (surface != null) {
4454                mStack.resumeTopActivityLocked(null);
4455            } else {
4456                mContainerState = CONTAINER_STATE_NO_SURFACE;
4457                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
4458                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
4459                    mStack.startPausingLocked(false, true, false, false);
4460                }
4461            }
4462
4463            setSurfaceIfReadyLocked();
4464
4465            if (DEBUG_STACK) Slog.d(TAG_STACK,
4466                    "setSurface: " + this + " to display=" + virtualActivityDisplay);
4467        }
4468
4469        @Override
4470        boolean isAttachedLocked() {
4471            return mSurface != null && super.isAttachedLocked();
4472        }
4473
4474        @Override
4475        void setDrawn() {
4476            synchronized (mService) {
4477                mDrawn = true;
4478                setSurfaceIfReadyLocked();
4479            }
4480        }
4481
4482        // Never start a new task on an ActivityView if it isn't explicitly specified.
4483        @Override
4484        boolean isEligibleForNewTasks() {
4485            return false;
4486        }
4487
4488        private void setSurfaceIfReadyLocked() {
4489            if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
4490                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
4491            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
4492                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
4493                mContainerState = CONTAINER_STATE_HAS_SURFACE;
4494            }
4495        }
4496    }
4497
4498    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
4499     * attached {@link ActivityStack}s */
4500    class ActivityDisplay {
4501        /** Actual Display this object tracks. */
4502        int mDisplayId;
4503        Display mDisplay;
4504        DisplayInfo mDisplayInfo = new DisplayInfo();
4505
4506        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
4507         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
4508        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
4509
4510        ActivityRecord mVisibleBehindActivity;
4511
4512        ActivityDisplay() {
4513        }
4514
4515        // After instantiation, check that mDisplay is not null before using this. The alternative
4516        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
4517        ActivityDisplay(int displayId) {
4518            final Display display = mDisplayManager.getDisplay(displayId);
4519            if (display == null) {
4520                return;
4521            }
4522            init(display);
4523        }
4524
4525        void init(Display display) {
4526            mDisplay = display;
4527            mDisplayId = display.getDisplayId();
4528            mDisplay.getDisplayInfo(mDisplayInfo);
4529        }
4530
4531        void attachActivities(ActivityStack stack) {
4532            if (DEBUG_STACK) Slog.v(TAG_STACK,
4533                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId);
4534            mStacks.add(stack);
4535        }
4536
4537        void detachActivitiesLocked(ActivityStack stack) {
4538            if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
4539                    + " from displayId=" + mDisplayId);
4540            mStacks.remove(stack);
4541        }
4542
4543        void getBounds(Point bounds) {
4544            mDisplay.getDisplayInfo(mDisplayInfo);
4545            bounds.x = mDisplayInfo.appWidth;
4546            bounds.y = mDisplayInfo.appHeight;
4547        }
4548
4549        void setVisibleBehindActivity(ActivityRecord r) {
4550            mVisibleBehindActivity = r;
4551        }
4552
4553        boolean hasVisibleBehindActivity() {
4554            return mVisibleBehindActivity != null;
4555        }
4556
4557        @Override
4558        public String toString() {
4559            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4560        }
4561    }
4562
4563    class VirtualActivityDisplay extends ActivityDisplay {
4564        VirtualDisplay mVirtualDisplay;
4565
4566        VirtualActivityDisplay(int width, int height, int density) {
4567            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4568            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4569                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4570                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4571                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4572
4573            init(mVirtualDisplay.getDisplay());
4574
4575            mWindowManager.handleDisplayAdded(mDisplayId);
4576        }
4577
4578        void setSurface(Surface surface) {
4579            if (mVirtualDisplay != null) {
4580                mVirtualDisplay.setSurface(surface);
4581            }
4582        }
4583
4584        @Override
4585        void detachActivitiesLocked(ActivityStack stack) {
4586            super.detachActivitiesLocked(stack);
4587            if (mVirtualDisplay != null) {
4588                mVirtualDisplay.release();
4589                mVirtualDisplay = null;
4590            }
4591        }
4592
4593        @Override
4594        public String toString() {
4595            return "VirtualActivityDisplay={" + mDisplayId + "}";
4596        }
4597    }
4598
4599    private boolean isLeanbackOnlyDevice() {
4600        boolean onLeanbackOnly = false;
4601        try {
4602            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
4603                    PackageManager.FEATURE_LEANBACK_ONLY);
4604        } catch (RemoteException e) {
4605            // noop
4606        }
4607
4608        return onLeanbackOnly;
4609    }
4610}
4611