ActivityStack.java revision 92fe44e966b9622c24a6810aaf9c2d8e2b1f9d92
175f0d3110b04346b901771f96ce15cdbe907278fYang Ni/*
275f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Copyright (C) 2010 The Android Open Source Project
375f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
475f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
575f0d3110b04346b901771f96ce15cdbe907278fYang Ni * you may not use this file except in compliance with the License.
675f0d3110b04346b901771f96ce15cdbe907278fYang Ni * You may obtain a copy of the License at
775f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
875f0d3110b04346b901771f96ce15cdbe907278fYang Ni *      http://www.apache.org/licenses/LICENSE-2.0
975f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
1075f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Unless required by applicable law or agreed to in writing, software
1175f0d3110b04346b901771f96ce15cdbe907278fYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
1275f0d3110b04346b901771f96ce15cdbe907278fYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375f0d3110b04346b901771f96ce15cdbe907278fYang Ni * See the License for the specific language governing permissions and
1475f0d3110b04346b901771f96ce15cdbe907278fYang Ni * limitations under the License.
1575f0d3110b04346b901771f96ce15cdbe907278fYang Ni */
1675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
1775f0d3110b04346b901771f96ce15cdbe907278fYang Nipackage com.android.server.am;
1875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
1975f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
2075f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
2175f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
2275f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static android.app.ActivityManager.StackId.HOME_STACK_ID;
2375f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static android.app.ActivityManager.StackId.PINNED_STACK_ID;
2475f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
2575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
2675f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static com.android.server.am.ActivityManagerDebugConfig.*;
2775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
2875f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
2975f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
3075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
3175f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static com.android.server.am.ActivityStackSupervisor.MOVING;
3275f0d3110b04346b901771f96ce15cdbe907278fYang Niimport static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
3375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
3475f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.graphics.Rect;
3575f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.util.ArraySet;
3675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
3775f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.internal.app.IVoiceInteractor;
3875f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.internal.content.ReferrerIntent;
3975f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.internal.os.BatteryStatsImpl;
4075f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.server.Watchdog;
4175f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.server.am.ActivityManagerService.ItemMatcher;
4275f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.server.am.ActivityStackSupervisor.ActivityContainer;
4375f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.server.wm.AppTransition;
4475f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.server.wm.TaskGroup;
4575f0d3110b04346b901771f96ce15cdbe907278fYang Niimport com.android.server.wm.WindowManagerService;
4675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
4775f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.Activity;
4875f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.ActivityManager;
4975f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.ActivityManager.StackId;
5075f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.ActivityOptions;
5175f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.AppGlobals;
5275f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.IActivityController;
5375f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.ResultInfo;
5475f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.app.ActivityManager.RunningTaskInfo;
5575f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.content.ComponentName;
5675f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.content.Intent;
5775f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.content.pm.ActivityInfo;
5875f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.content.pm.PackageManager;
5975f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.content.res.Configuration;
6075f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.graphics.Bitmap;
6175f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.net.Uri;
6275f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.Binder;
6375f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.Bundle;
6475f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.Debug;
6575f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.Handler;
6675f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.IBinder;
6775f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.Looper;
6875f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.Message;
6975f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.PersistableBundle;
7075f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.RemoteException;
7175f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.SystemClock;
7275f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.Trace;
7375f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.os.UserHandle;
7475f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.service.voice.IVoiceInteractionSession;
7575f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.util.EventLog;
7675f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.util.Slog;
7775f0d3110b04346b901771f96ce15cdbe907278fYang Niimport android.view.Display;
7875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
7975f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.io.FileDescriptor;
8075f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.io.PrintWriter;
8175f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.lang.ref.WeakReference;
8275f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.util.ArrayList;
8375f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.util.Iterator;
8475f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.util.List;
8575f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.util.Objects;
8675f0d3110b04346b901771f96ce15cdbe907278fYang Niimport java.util.Set;
8775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
8875f0d3110b04346b901771f96ce15cdbe907278fYang Ni/**
8975f0d3110b04346b901771f96ce15cdbe907278fYang Ni * State and management of a single stack of activities.
9075f0d3110b04346b901771f96ce15cdbe907278fYang Ni */
9175f0d3110b04346b901771f96ce15cdbe907278fYang Nifinal class ActivityStack {
9275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
9375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM;
9475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
9575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_APP = TAG + POSTFIX_APP;
9675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
9775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
9875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
9975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
10075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
10175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
10275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
10375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_SCREENSHOTS = TAG + POSTFIX_SCREENSHOTS;
10475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_STACK = TAG + POSTFIX_STACK;
10575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_STATES = TAG + POSTFIX_STATES;
10675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
10775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
10875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
10975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
11075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
11175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
11275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private static final boolean VALIDATE_TOKENS = false;
11375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
11475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Ticks during which we check progress while waiting for an app to launch.
11575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int LAUNCH_TICK = 500;
11675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
11775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // How long we wait until giving up on the last activity to pause.  This
11875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // is short because it directly impacts the responsiveness of starting the
11975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // next activity.
12075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int PAUSE_TIMEOUT = 500;
12175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
12275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // How long we wait for the activity to tell us it has stopped before
12375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // giving up.  This is a good amount of time because we really need this
12475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // from the application in order to get its saved state.
12575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int STOP_TIMEOUT = 10 * 1000;
12675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
12775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // How long we wait until giving up on an activity telling us it has
12875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // finished destroying itself.
12975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int DESTROY_TIMEOUT = 10 * 1000;
13075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
13175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // How long until we reset a task when the user returns to it.  Currently
13275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // disabled.
13375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final long ACTIVITY_INACTIVE_RESET_TIME = 0;
13475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
13575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // How long between activity launches that we consider safe to not warn
13675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // the user about an unexpected activity being launched on top.
13775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final long START_WARN_TIME = 5 * 1000;
13875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
13975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Set to false to disable the preview that is shown while a new activity
14075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // is being started.
14175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final boolean SHOW_APP_STARTING_PREVIEW = true;
14275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
14375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // How long to wait for all background Activities to redraw following a call to
14475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // convertToTranslucent().
14575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
14675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
14775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    enum ActivityState {
14875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        INITIALIZING,
14975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        RESUMED,
15075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        PAUSING,
15175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        PAUSED,
15275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        STOPPING,
15375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        STOPPED,
15475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        FINISHING,
15575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        DESTROYING,
15675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        DESTROYED
15775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
15875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
15975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ActivityManagerService mService;
16075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final WindowManagerService mWindowManager;
16175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private final RecentTasks mRecentTasks;
16275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
16375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
16475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * The back history of all previous (and possibly still
16575f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * running) activities.  It contains #TaskRecord objects.
16675f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
16775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
16875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
16975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
17075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Used for validating app tokens with window manager.
17175f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
17275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<>();
17375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
17475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
17575f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * List of running activities, sorted by recent usage.
17675f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * The first entry in the list is the least recently used.
17775f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * It contains HistoryRecord objects.
17875f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
17975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
18075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
18175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
18275f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Animations that for the current transition have requested not to
18375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * be considered for the transition animation.
18475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
18575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>();
18675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
18775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
18875f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * When we are in the process of pausing an activity, before starting the
18975f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * next one, this variable holds the activity that is currently being paused.
19075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
19175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord mPausingActivity = null;
19275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
19375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
19475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * This is the last activity that we put into the paused state.  This is
19575f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * used to determine if we need to do an activity transition while sleeping,
19675f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * when we normally hold the top activity paused.
19775f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
19875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord mLastPausedActivity = null;
19975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
20075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
20175f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Activities that specify No History must be removed once the user navigates away from them.
20275f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * If the device goes to sleep with such an activity in the paused state then we save it here
20375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * and finish it later if another activity replaces it on wakeup.
20475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
20575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord mLastNoHistoryActivity = null;
20675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
20775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
20875f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Current activity that is resumed, or null if there is none.
20975f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
21075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord mResumedActivity = null;
21175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
21275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
21375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * This is the last activity that has been started.  It is only used to
21475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * identify when multiple activities are started at once so that the user
21575f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * can be warned they may not be in the activity they think they are.
21675f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
21775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord mLastStartedActivity = null;
21875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
21975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
22075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
22175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
22275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Activity in mTranslucentActivityWaiting is notified via
22375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
22475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // background activity being drawn then the same call will be made with a true value.
22575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord mTranslucentActivityWaiting = null;
22675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>();
22775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
22875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
22975f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Set when we know we are going to be calling updateConfiguration()
23075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * soon, so want to skip intermediate config checks.
23175f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
23275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    boolean mConfigWillChange;
23375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
23475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Whether or not this stack covers the entire screen; by default stacks are fullscreen
23575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    boolean mFullscreen = true;
23675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Current bounds of the stack or null if fullscreen.
23775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    Rect mBounds = null;
23875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
23975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    long mLaunchStartTime = 0;
24075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    long mFullyDrawnStartTime = 0;
24175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
24275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    int mCurrentUser;
24375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
24475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final int mStackId;
24575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ActivityContainer mActivityContainer;
24675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /** The other stacks, in order, on the attached display. Updated at attach/detach time. */
24775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ArrayList<ActivityStack> mStacks;
24875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /** The attached Display's unique identifier, or -1 if detached */
24975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    int mDisplayId;
25075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
25175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /** Run all ActivityStacks through this */
25275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ActivityStackSupervisor mStackSupervisor;
25375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
25475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private final LaunchingTaskPositioner mTaskPositioner;
25575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
25675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
25775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
25875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
25975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
26075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
26175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
26275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static final int RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG =
26375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7;
26475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
26575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    static class ScheduleDestroyArgs {
26675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final ProcessRecord mOwner;
26775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final String mReason;
26875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ScheduleDestroyArgs(ProcessRecord owner, String reason) {
26975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mOwner = owner;
27075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mReason = reason;
27175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
27275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
27375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
27475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final Handler mHandler;
27575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
27675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final class ActivityStackHandler extends Handler {
27775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
27875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ActivityStackHandler(Looper looper) {
27975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            super(looper);
28075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
28175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
28275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        @Override
28375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        public void handleMessage(Message msg) {
28475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            switch (msg.what) {
28575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                case PAUSE_TIMEOUT_MSG: {
28675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    ActivityRecord r = (ActivityRecord)msg.obj;
28775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // We don't at this point know if the activity is fullscreen,
28875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // so we need to be conservative and assume it isn't.
28975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    Slog.w(TAG, "Activity pause timeout for " + r);
29075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (mService) {
29175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        if (r.app != null) {
29275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
29375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        }
29475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        activityPausedLocked(r.appToken, true);
29575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
29675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } break;
29775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                case LAUNCH_TICK_MSG: {
29875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    ActivityRecord r = (ActivityRecord)msg.obj;
29975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (mService) {
30075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        if (r.continueLaunchTickingLocked()) {
30175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
30275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        }
30375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
30475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } break;
30575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                case DESTROY_TIMEOUT_MSG: {
30675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    ActivityRecord r = (ActivityRecord)msg.obj;
30775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // We don't at this point know if the activity is fullscreen,
30875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // so we need to be conservative and assume it isn't.
30975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    Slog.w(TAG, "Activity destroy timeout for " + r);
31075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (mService) {
31175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        activityDestroyedLocked(r != null ? r.appToken : null, "destroyTimeout");
31275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
31375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } break;
31475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                case STOP_TIMEOUT_MSG: {
31575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    ActivityRecord r = (ActivityRecord)msg.obj;
31675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // We don't at this point know if the activity is fullscreen,
31775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // so we need to be conservative and assume it isn't.
31875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    Slog.w(TAG, "Activity stop timeout for " + r);
31975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (mService) {
32075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        if (r.isInHistory()) {
32175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            activityStoppedLocked(r, null, null, null);
32275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        }
32375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
32475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } break;
32575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                case DESTROY_ACTIVITIES_MSG: {
32675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj;
32775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (mService) {
32875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        destroyActivitiesLocked(args.mOwner, args.mReason);
32975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
33075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } break;
33175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                case TRANSLUCENT_TIMEOUT_MSG: {
33275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (mService) {
33375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        notifyActivityDrawnLocked(null);
33475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
33575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } break;
33675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                case RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG: {
33775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (mService) {
33875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        final ActivityRecord r = getVisibleBehindActivity();
33975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        Slog.e(TAG, "Timeout waiting for cancelVisibleBehind player=" + r);
34075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        if (r != null) {
34175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            mService.killAppAtUsersRequest(r.app, null);
34275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        }
34375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
34475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } break;
34575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
34675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
34775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
34875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
34975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    int numActivities() {
35075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        int count = 0;
35175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
35275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            count += mTaskHistory.get(taskNdx).mActivities.size();
35375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
35475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return count;
35575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
35675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
35775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer,
35875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            RecentTasks recentTasks) {
35975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mActivityContainer = activityContainer;
36075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mStackSupervisor = activityContainer.getOuter();
36175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mService = mStackSupervisor.mService;
36275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
36375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mWindowManager = mService.mWindowManager;
36475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mStackId = activityContainer.mStackId;
36575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mCurrentUser = mService.mUserController.getCurrentUserIdLocked();
36675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mRecentTasks = recentTasks;
36775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID
36875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                ? new LaunchingTaskPositioner() : null;
36975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
37075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
37175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void attachDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) {
37275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mDisplayId = activityDisplay.mDisplayId;
37375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mStacks = activityDisplay.mStacks;
37475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mBounds = mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop);
37575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mFullscreen = mBounds == null;
37675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mTaskPositioner != null) {
37775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mTaskPositioner.setDisplay(activityDisplay.mDisplay);
37875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mTaskPositioner.configure(mBounds);
37975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
38075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
38175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
38275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void detachDisplay() {
38375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mDisplayId = Display.INVALID_DISPLAY;
38475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mStacks = null;
38575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mTaskPositioner != null) {
38675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mTaskPositioner.reset();
38775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
38875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mWindowManager.detachStack(mStackId);
38975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
39075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
39175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void setBounds(Rect bounds) {
39275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mBounds = mFullscreen ? null : new Rect(bounds);
39375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mTaskPositioner != null) {
39475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mTaskPositioner.configure(bounds);
39575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
39675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
39775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
39875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    boolean okToShowLocked(ActivityRecord r) {
39975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return mStackSupervisor.okToShowLocked(r);
40075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
40175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
40275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ActivityRecord topRunningActivityLocked() {
40375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
40475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
40575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (r != null) {
40675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                return r;
40775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
40875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
40975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
41075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
41175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
41275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
41375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
41475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final TaskRecord task = mTaskHistory.get(taskNdx);
41575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ArrayList<ActivityRecord> activities = task.mActivities;
41675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
41775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                ActivityRecord r = activities.get(activityNdx);
41875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (!r.finishing && !r.delayedResume && r != notTop && okToShowLocked(r)) {
41975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    return r;
42075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
42175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
42275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
42375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
42475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
42575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
42675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
42775f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * This is a simplified version of topRunningActivityLocked that provides a number of
42875f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * optional skip-over modes.  It is intended for use with the ActivityController hook only.
42975f0d3110b04346b901771f96ce15cdbe907278fYang Ni     *
43075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param token If non-null, any history records matching this token will be skipped.
43175f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
43275f0d3110b04346b901771f96ce15cdbe907278fYang Ni     *
43375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @return Returns the HistoryRecord of the next activity on the stack.
43475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
43575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
43675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
43775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            TaskRecord task = mTaskHistory.get(taskNdx);
43875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (task.taskId == taskId) {
43975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                continue;
44075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
44175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            ArrayList<ActivityRecord> activities = task.mActivities;
44275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            for (int i = activities.size() - 1; i >= 0; --i) {
44375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                final ActivityRecord r = activities.get(i);
44475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // Note: the taskId check depends on real taskId fields being non-zero
44575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) {
44675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    return r;
44775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
44875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
44975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
45075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
45175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
45275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
45375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final ActivityRecord topActivity() {
45475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
45575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
45675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
45775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                final ActivityRecord r = activities.get(activityNdx);
45875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (!r.finishing) {
45975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    return r;
46075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
46175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
46275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
46375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
46475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
46575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
46675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final TaskRecord topTask() {
46775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final int size = mTaskHistory.size();
46875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (size > 0) {
46975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return mTaskHistory.get(size - 1);
47075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
47175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
47275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
47375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
47475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    TaskRecord taskForIdLocked(int id) {
47575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
47675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final TaskRecord task = mTaskHistory.get(taskNdx);
47775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (task.taskId == id) {
47875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                return task;
47975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
48075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
48175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
48275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
48375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
48475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord isInStackLocked(IBinder token) {
48575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
48675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return isInStackLocked(r);
48775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
48875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
48975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord isInStackLocked(ActivityRecord r) {
49075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (r == null) {
49175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return null;
49275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
49375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final TaskRecord task = r.task;
49475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (task != null && task.stack != null
49575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                && task.mActivities.contains(r) && mTaskHistory.contains(task)) {
49675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (task.stack != this) Slog.w(TAG,
49775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    "Illegal state! task does not point to stack it is in.");
49875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return r;
49975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
50075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
50175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
50275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
50375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final boolean updateLRUListLocked(ActivityRecord r) {
50475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final boolean hadit = mLRUActivities.remove(r);
50575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mLRUActivities.add(r);
50675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return hadit;
50775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
50875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
50975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final boolean isHomeStack() {
51075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return mStackId == HOME_STACK_ID;
51175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
51275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
51375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final boolean isOnHomeDisplay() {
51475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return isAttached() &&
51575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mActivityContainer.mActivityDisplay.mDisplayId == Display.DEFAULT_DISPLAY;
51675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
51775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
51875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void moveToFront(String reason) {
51975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        moveToFront(reason, null);
52075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
52175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
52275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
52375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param reason The reason for moving the stack to the front.
52475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param task If non-null, the task will be moved to the top of the stack.
52575f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * */
52675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void moveToFront(String reason, TaskRecord task) {
52775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (!isAttached()) {
52875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return;
52975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
53075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
53175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mStacks.remove(this);
53275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        int addIndex = mStacks.size();
53375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
53475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (addIndex > 0) {
53575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ActivityStack topStack = mStacks.get(addIndex - 1);
53675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (topStack.mStackId == PINNED_STACK_ID && topStack != this) {
53775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // The pinned stack is always the top most stack (always-on-top).
53875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // So, stack is moved just below the pinned stack.
53975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                addIndex--;
54075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
54175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
54275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
54375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mStacks.add(addIndex, this);
54475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
54575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // TODO(multi-display): Needs to also work if focus is moving to the non-home display.
54675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (isOnHomeDisplay()) {
54775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mStackSupervisor.setFocusStack(reason, this);
54875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
54975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (task != null) {
55075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            insertTaskAtTop(task, null);
55175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        } else {
55275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            task = topTask();
55375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
55475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (task != null) {
55575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mWindowManager.moveTaskToTop(task.taskId);
55675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
55775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
55875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
55975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final boolean isAttached() {
56075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return mStacks != null;
56175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
56275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
56375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
56475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Returns the top activity in any existing task matching the given
56575f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Intent.  Returns null if no such task is found.
56675f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
56775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord findTaskLocked(ActivityRecord target) {
56875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        Intent intent = target.intent;
56975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ActivityInfo info = target.info;
57075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ComponentName cls = intent.getComponent();
57175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (info.targetActivity != null) {
57275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            cls = new ComponentName(info.packageName, info.targetActivity);
57375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
57475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
57575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        boolean isDocument = intent != null & intent.isDocument();
57675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // If documentData is non-null then it must match the existing task data.
57775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        Uri documentData = isDocument ? intent.getData() : null;
57875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
57975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + this);
58075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
58175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final TaskRecord task = mTaskHistory.get(taskNdx);
58275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (task.voiceSession != null) {
58375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // We never match voice sessions; those always run independently.
58475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
58575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                continue;
58675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
58775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (task.userId != userId) {
58875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // Looking for a different task.
58975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
59075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                continue;
59175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
59275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ActivityRecord r = task.getTopActivity();
59375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (r == null || r.finishing || r.userId != userId ||
59475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
59575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
59675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                continue;
59775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
59875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (r.mActivityType != target.mActivityType) {
59975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
60075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                continue;
60175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
60275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
60375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final Intent taskIntent = task.intent;
60475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final Intent affinityIntent = task.affinityIntent;
60575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final boolean taskIsDocument;
60675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final Uri taskDocumentData;
60775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (taskIntent != null && taskIntent.isDocument()) {
60875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                taskIsDocument = true;
60975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                taskDocumentData = taskIntent.getData();
61075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else if (affinityIntent != null && affinityIntent.isDocument()) {
61175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                taskIsDocument = true;
61275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                taskDocumentData = affinityIntent.getData();
61375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else {
61475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                taskIsDocument = false;
61575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                taskDocumentData = null;
61675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
61775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
61875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
61975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    + taskIntent.getComponent().flattenToShortString()
62075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    + "/aff=" + r.task.rootAffinity + " to new cls="
62175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
62275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (!isDocument && !taskIsDocument && task.rootAffinity != null) {
62375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (task.rootAffinity.equals(target.taskAffinity)) {
62475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity!");
62575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    return r;
62675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
62775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else if (taskIntent != null && taskIntent.getComponent() != null &&
62875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    taskIntent.getComponent().compareTo(cls) == 0 &&
62975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    Objects.equals(documentData, taskDocumentData)) {
63075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
63175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                //dump();
63275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
63375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        "For Intent " + intent + " bringing to top: " + r.intent);
63475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                return r;
63575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
63675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    affinityIntent.getComponent().compareTo(cls) == 0 &&
63775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    Objects.equals(documentData, taskDocumentData)) {
63875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
63975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                //dump();
64075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
64175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        "For Intent " + intent + " bringing to top: " + r.intent);
64275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                return r;
64375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
64475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
64575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
64675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
64775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
64875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
64975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
65075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Returns the first activity (starting from the top of the stack) that
65175f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * is the same as the given activity.  Returns null if no such activity
65275f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * is found.
65375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
65475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
65575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ComponentName cls = intent.getComponent();
65675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (info.targetActivity != null) {
65775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            cls = new ComponentName(info.packageName, info.targetActivity);
65875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
65975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
66075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
66175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
66275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final TaskRecord task = mTaskHistory.get(taskNdx);
66375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final boolean notCurrentUserTask =
66475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    !mStackSupervisor.isCurrentProfileLocked(task.userId);
66575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ArrayList<ActivityRecord> activities = task.mActivities;
66675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
66775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
66875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                ActivityRecord r = activities.get(activityNdx);
66975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (notCurrentUserTask && (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
67075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    continue;
67175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
67275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
67375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    return r;
67475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
67575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
67675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
67775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
67875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
67975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
68075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
68175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /*
68275f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Move the activities around in the stack to bring a user to the foreground.
68375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
68475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final void switchUserLocked(int userId) {
68575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mCurrentUser == userId) {
68675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return;
68775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
68875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mCurrentUser = userId;
68975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
69075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // Move userId's tasks to the top.
69175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        int index = mTaskHistory.size();
69275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int i = 0; i < index; ) {
69375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final TaskRecord task = mTaskHistory.get(i);
69475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
69575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
69675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // okay to show the activity when locked.
69775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (mStackSupervisor.isCurrentProfileLocked(task.userId)
69875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    || task.topRunningActivityLocked() != null) {
69975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "switchUserLocked: stack=" + getStackId() +
70075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        " moving " + task + " to top");
70175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mTaskHistory.remove(i);
70275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mTaskHistory.add(task);
70375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                --index;
70475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // Use same value for i.
70575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else {
70675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                ++i;
70775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
70875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
70975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (VALIDATE_TOKENS) {
71075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            validateAppTokensLocked();
71175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
71275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
71375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
71475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void minimalResumeActivityLocked(ActivityRecord r) {
71575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        r.state = ActivityState.RESUMED;
71675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_STATES) Slog.v(TAG_STATES,
71775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                "Moving to RESUMED: " + r + " (starting new instance)");
71875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        r.stopped = false;
71975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mResumedActivity = r;
72075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        r.task.touchActiveTime();
72175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mRecentTasks.addLocked(r.task);
72275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        completeResumeLocked(r);
72375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mStackSupervisor.checkReadyForSleepLocked();
72475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        setLaunchTime(r);
72575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
72675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                "Launch completed; removing icicle of " + r.icicle);
72775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
72875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
72975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private void addRecentActivityLocked(ActivityRecord r) {
73075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (r != null) {
73175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mRecentTasks.addLocked(r.task);
73275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.task.touchActiveTime();
73375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
73475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
73575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
73675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private void startLaunchTraces(String packageName) {
73775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mFullyDrawnStartTime != 0)  {
73875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
73975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
74075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
74175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
74275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
74375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
74475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private void stopFullyDrawnTraceIfNeeded() {
74575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
74675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
74775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mFullyDrawnStartTime = 0;
74875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
74975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
75075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
75175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void setLaunchTime(ActivityRecord r) {
75275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (r.displayStartTime == 0) {
75375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
75475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (mLaunchStartTime == 0) {
75575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                startLaunchTraces(r.packageName);
75675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
75775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
75875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        } else if (mLaunchStartTime == 0) {
75975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            startLaunchTraces(r.packageName);
76075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
76175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
76275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
76375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
76475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void clearLaunchTime(ActivityRecord r) {
76575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // Make sure that there is no activity waiting for this to launch.
76675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
76775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.displayStartTime = r.fullyDrawnStartTime = 0;
76875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        } else {
76975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mStackSupervisor.removeTimeoutsForActivityLocked(r);
77075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mStackSupervisor.scheduleIdleTimeoutLocked(r);
77175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
77275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
77375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
77475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void awakeFromSleepingLocked() {
77575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // Ensure activities are no longer sleeping.
77675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
77775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
77875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
77975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                activities.get(activityNdx).setSleeping(false);
78075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
78175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
78275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mPausingActivity != null) {
78375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
78475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            activityPausedLocked(mPausingActivity.appToken, true);
78575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
78675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
78775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
78875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
78975f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @return true if something must be done before going to sleep.
79075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
79175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    boolean checkReadyForSleepLocked() {
79275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mResumedActivity != null) {
79375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // Still have something resumed; can't sleep until it is paused.
79475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
79575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
79675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    "Sleep => pause with userLeaving=false");
79775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            startPausingLocked(false, true, false, false);
79875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return true;
79975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
80075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mPausingActivity != null) {
80175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // Still waiting for something to pause; can't sleep yet.
80275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
80375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return true;
80475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
80575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
80675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (hasVisibleBehindActivity()) {
80775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // Stop visible behind activity before going to sleep.
80875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ActivityRecord r = mActivityContainer.mActivityDisplay.mVisibleBehindActivity;
80975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mStackSupervisor.mStoppingActivities.add(r);
81075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_STATES) Slog.v(TAG_STATES,
81175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    "Sleep still waiting to stop visible behind " + r);
81275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return true;
81375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
81475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
81575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return false;
81675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
81775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
81875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    void goToSleep() {
81975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
82075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
82175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // Make sure any stopped but visible activities are now sleeping.
82275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // This ensures that the activity's onStop() is called.
82375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
82475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
82575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
82675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                final ActivityRecord r = activities.get(activityNdx);
82775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) {
82875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    r.setSleeping(true);
82975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
83075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
83175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
83275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
83375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
83475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    public final Bitmap screenshotActivities(ActivityRecord who) {
83575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "screenshotActivities: " + who);
83675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (who.noDisplay) {
83775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tNo display");
83875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return null;
83975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
84075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
84175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (isHomeStack()) {
84275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // This is an optimization -- since we never show Home or Recents within Recents itself,
84375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // we can just go ahead and skip taking the screenshot if this is the home stack.
84475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tHome stack");
84575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return null;
84675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
84775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
84875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        int w = mService.mThumbnailWidth;
84975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        int h = mService.mThumbnailHeight;
85075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (w > 0) {
85175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tTaking screenshot");
85275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return mWindowManager.screenshotApplications(who.appToken, Display.DEFAULT_DISPLAY,
85375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    w, h);
85475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
85575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        Slog.e(TAG, "Invalid thumbnail dimensions: " + w + "x" + h);
85675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return null;
85775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
85875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
85975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
86075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Start pausing the currently resumed activity.  It is an error to call this if there
86175f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * is already an activity being paused or there is no resumed activity.
86275f0d3110b04346b901771f96ce15cdbe907278fYang Ni     *
86375f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param userLeaving True if this should result in an onUserLeaving to the current activity.
86475f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param uiSleeping True if this is happening with the user interface going to sleep (the
86575f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * screen turning off).
86675f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param resuming True if this is being called as part of resuming the top activity, so
86775f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * we shouldn't try to instigate a resume here.
86875f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @param dontWait True if the caller does not want to wait for the pause to complete.  If
86975f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * set to true, we will immediately complete the pause here before returning.
87075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
87175f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * it to tell us when it is done.
87275f0d3110b04346b901771f96ce15cdbe907278fYang Ni     */
87375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
87475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            boolean dontWait) {
87575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mPausingActivity != null) {
87675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
87775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    + " state=" + mPausingActivity.state);
87875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (!mService.isSleeping()) {
87975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // Avoid recursion among check for sleep and complete pause during sleeping.
88075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // Because activity will be paused immediately after resume, just let pause
88175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // be completed by the order of activity paused from clients.
88275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                completePauseLocked(false);
88375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
88475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
88575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ActivityRecord prev = mResumedActivity;
88675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (prev == null) {
88775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (!resuming) {
88875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
88975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mStackSupervisor.resumeTopActivitiesLocked();
89075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
89175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return false;
89275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
89375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
89475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mActivityContainer.mParentActivity == null) {
89575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // Top level stack, not a child. Look for child stacks.
89675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
89775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
89875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
89975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
90075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
90175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mResumedActivity = null;
90275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mPausingActivity = prev;
90375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mLastPausedActivity = prev;
90475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
90575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
90675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        prev.state = ActivityState.PAUSING;
90775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        prev.task.touchActiveTime();
90875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        clearLaunchTime(prev);
90975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
91075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mService.mHasRecents
91175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
91275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            prev.updateThumbnailLocked(screenshotActivities(prev), null);
91375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
91475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        stopFullyDrawnTraceIfNeeded();
91575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
91675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mService.updateCpuStats();
91775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
91875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (prev.app != null && prev.app.thread != null) {
91975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
92075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            try {
92175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
92275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        prev.userId, System.identityHashCode(prev),
92375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        prev.shortComponentName);
92475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mService.updateUsageStats(prev, false);
92575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
92675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        userLeaving, prev.configChangeFlags, dontWait);
92775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } catch (Exception e) {
92875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // Ignore exception, if process died other code will cleanup.
92975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                Slog.w(TAG, "Exception thrown during pause", e);
93075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mPausingActivity = null;
93175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mLastPausedActivity = null;
93275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mLastNoHistoryActivity = null;
93375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
93475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        } else {
93575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mPausingActivity = null;
93675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mLastPausedActivity = null;
93775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mLastNoHistoryActivity = null;
93875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
93975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
94075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // If we are not going to sleep, we want to ensure the device is
94175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // awake until the next activity is started.
94275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
94375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mStackSupervisor.acquireLaunchWakelock();
94475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
94575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
94675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (mPausingActivity != null) {
94775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // Have the window manager pause its key dispatching until the new
94875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // activity has started.  If we're pausing the activity just because
94975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // the screen is being turned off and the UI is sleeping, don't interrupt
95075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // key dispatch; the same activity will pick it up again on wakeup.
95175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (!uiSleeping) {
95275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                prev.pauseKeyDispatchingLocked();
95375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else if (DEBUG_PAUSE) {
95475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
95575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
95675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
95775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (dontWait) {
95875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // If the caller said they don't want to wait for the pause, then complete
95975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // the pause now.
96075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                completePauseLocked(false);
96175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                return false;
96275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
96375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else {
96475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // Schedule a pause timeout in case the app doesn't respond.
96575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // We don't give it much time because this directly impacts the
96675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                // responsiveness seen by the user.
96775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
96875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                msg.obj = prev;
96975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                prev.pauseTime = SystemClock.uptimeMillis();
97075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
97175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
97275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                return true;
97375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
97475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
97575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        } else {
97675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // This activity failed to schedule the
97775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // pause, so just treat it as being paused now.
97875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
97975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (!resuming) {
98075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
98175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
98275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return false;
98375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
98475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
98575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
98675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final void activityPausedLocked(IBinder token, boolean timeout) {
98775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
98875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            "Activity paused: token=" + token + ", timeout=" + timeout);
98975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
99075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        final ActivityRecord r = isInStackLocked(token);
99175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (r != null) {
99275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
99375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (mPausingActivity == r) {
99475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
99575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        + (timeout ? " (due to timeout)" : " (pause complete)"));
99675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                completePauseLocked(true);
99775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else {
99875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
99975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        r.userId, System.identityHashCode(r), r.shortComponentName,
100075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        mPausingActivity != null
100175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            ? mPausingActivity.shortComponentName : "(none)");
100275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (r.state == ActivityState.PAUSING) {
100375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    r.state = ActivityState.PAUSED;
100475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    if (r.finishing) {
100575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        if (DEBUG_PAUSE) Slog.v(TAG,
100675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                "Executing finish of failed to pause activity: " + r);
100775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
100875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
100975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
101075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
101175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
101275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
101375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
101475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    final void activityStoppedLocked(ActivityRecord r, Bundle icicle,
101575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            PersistableBundle persistentState, CharSequence description) {
101675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (r.state != ActivityState.STOPPING) {
101775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            Slog.i(TAG, "Activity reported stop, but no longer stopping: " + r);
101875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
101975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            return;
102075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
102175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (persistentState != null) {
102275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.persistentState = persistentState;
102375f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mService.notifyTaskPersisterLocked(r.task, false);
102475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
102575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + r + ": " + icicle);
102675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (icicle != null) {
102775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // If icicle is null, this is happening due to a timeout, so we
102875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // haven't really saved the state.
102975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.icicle = icicle;
103075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.haveState = true;
103175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.launchCount = 0;
103275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.updateThumbnailLocked(null, description);
103375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
103475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (!r.stopped) {
103575f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + r + " (stop complete)");
103675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
103775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.stopped = true;
103875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            r.state = ActivityState.STOPPED;
103975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == r) {
104075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mStackSupervisor.requestVisibleBehindLocked(r, false);
104175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
104275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (r.finishing) {
104375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                r.clearOptionsLocked();
104475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else {
104575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (r.configDestroy) {
104675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    destroyActivityLocked(r, true, "stop-config");
104775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    mStackSupervisor.resumeTopActivitiesLocked();
104875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } else {
104975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    mStackSupervisor.updatePreviousProcessLocked(r);
105075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
105175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
105275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
105375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
105475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
105575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    private void completePauseLocked(boolean resumeNext) {
105675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        ActivityRecord prev = mPausingActivity;
105775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
105875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
105975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (prev != null) {
106075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            prev.state = ActivityState.PAUSED;
106175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (prev.finishing) {
106275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
106375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
106475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else if (prev.app != null) {
106575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending stop: " + prev);
106675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
106775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
106875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            "Complete pause, no longer waiting: " + prev);
106975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
107075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (prev.configDestroy) {
107175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // The previous is being paused because the configuration
107275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // is changing, which means it is actually stopping...
107375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // To juggle the fact that we are also starting a new
107475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // instance right now, we need to first completely stop
107575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // the current instance before starting the new one.
107675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev);
107775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    destroyActivityLocked(prev, true, "pause-config");
107875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
107975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // If we were visible then resumeTopActivities will release resources before
108075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // stopping.
108175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    mStackSupervisor.mStoppingActivities.add(prev);
108275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    if (mStackSupervisor.mStoppingActivities.size() > 3 ||
108375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            prev.frontOfTask && mTaskHistory.size() <= 1) {
108475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        // If we already have a few activities waiting to stop,
108575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        // then give up on things going idle and start clearing
108675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        // them out. Or if r is the last of activity of the last task the stack
108775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        // will be empty and must be cleared immediately.
108875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "To many pending stops, forcing idle");
108975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        mStackSupervisor.scheduleIdleLocked();
109075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    } else {
109175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        mStackSupervisor.checkReadyForSleepLocked();
109275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
109375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
109475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else {
109575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
109675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                prev = null;
109775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
109875f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // It is possible the activity was freezing the screen before it was paused.
109975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // In that case go ahead and remove the freeze this activity has on the screen
110075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            // since it is no longer visible.
110175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            prev.stopFreezingScreenLocked(true /*force*/);
110275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            mPausingActivity = null;
110375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
110475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
110575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (resumeNext) {
110675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
110775f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (!mService.isSleepingOrShuttingDown()) {
110875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
110975f0d3110b04346b901771f96ce15cdbe907278fYang Ni            } else {
111075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                mStackSupervisor.checkReadyForSleepLocked();
111175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                ActivityRecord top = topStack.topRunningActivityLocked();
111275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (top == null || (prev != null && top != prev)) {
111375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // If there are no more activities available to run,
111475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // do resume anyway to start something.  Also if the top
111575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // activity on the stack is not the just paused activity,
111675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // we need to go ahead and resume it to ensure we complete
111775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    // an in-flight app switch.
111875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
111975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
112075f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
112175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
112275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
112375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (prev != null) {
112475f0d3110b04346b901771f96ce15cdbe907278fYang Ni            prev.resumeKeyDispatchingLocked();
112575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
112675f0d3110b04346b901771f96ce15cdbe907278fYang Ni            if (prev.app != null && prev.cpuTimeAtResume > 0
112775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    && mService.mBatteryStatsService.isOnBattery()) {
112875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
112975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        - prev.cpuTimeAtResume;
113075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                if (diff > 0) {
113175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
113275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    synchronized (bsi) {
113375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        BatteryStatsImpl.Uid.Proc ps =
113475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
113575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                        prev.info.packageName);
113675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        if (ps != null) {
113775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                            ps.addForegroundTimeLocked(diff);
113875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                        }
113975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                    }
114075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                }
114175f0d3110b04346b901771f96ce15cdbe907278fYang Ni            }
114275f0d3110b04346b901771f96ce15cdbe907278fYang Ni            prev.cpuTimeAtResume = 0; // reset it
114375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
114475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
114575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // Notfiy when the task stack has changed
114675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        mService.notifyTaskStackChangedLocked();
114775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
114875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
114975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    /**
115075f0d3110b04346b901771f96ce15cdbe907278fYang Ni     * Once we know that we have asked an application to put an activity in
1151     * the resumed state (either by launching it or explicitly telling it),
1152     * this function updates the rest of our state to match that fact.
1153     */
1154    private void completeResumeLocked(ActivityRecord next) {
1155        next.idle = false;
1156        next.results = null;
1157        next.newIntents = null;
1158
1159        if (next.isHomeActivity()) {
1160            ProcessRecord app = next.task.mActivities.get(0).app;
1161            if (app != null && app != mService.mHomeProcess) {
1162                mService.mHomeProcess = app;
1163            }
1164        }
1165
1166        if (next.nowVisible) {
1167            // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
1168            mStackSupervisor.notifyActivityDrawnForKeyguard();
1169        }
1170
1171        // schedule an idle timeout in case the app doesn't do it for us.
1172        mStackSupervisor.scheduleIdleTimeoutLocked(next);
1173
1174        mStackSupervisor.reportResumedActivityLocked(next);
1175
1176        next.resumeKeyDispatchingLocked();
1177        mNoAnimActivities.clear();
1178
1179        // Mark the point when the activity is resuming
1180        // TODO: To be more accurate, the mark should be before the onCreate,
1181        //       not after the onResume. But for subsequent starts, onResume is fine.
1182        if (next.app != null) {
1183            next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid);
1184        } else {
1185            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
1186        }
1187
1188        next.returningOptions = null;
1189
1190        if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == next) {
1191            // When resuming an activity, require it to call requestVisibleBehind() again.
1192            mActivityContainer.mActivityDisplay.setVisibleBehindActivity(null);
1193        }
1194    }
1195
1196    private void setVisible(ActivityRecord r, boolean visible) {
1197        r.visible = visible;
1198        mWindowManager.setAppVisibility(r.appToken, visible);
1199        final ArrayList<ActivityContainer> containers = r.mChildContainers;
1200        for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
1201            ActivityContainer container = containers.get(containerNdx);
1202            container.setVisible(visible);
1203        }
1204    }
1205
1206    // Find the first visible activity above the passed activity and if it is translucent return it
1207    // otherwise return null;
1208    ActivityRecord findNextTranslucentActivity(ActivityRecord r) {
1209        TaskRecord task = r.task;
1210        if (task == null) {
1211            return null;
1212        }
1213
1214        ActivityStack stack = task.stack;
1215        if (stack == null) {
1216            return null;
1217        }
1218
1219        int stackNdx = mStacks.indexOf(stack);
1220
1221        ArrayList<TaskRecord> tasks = stack.mTaskHistory;
1222        int taskNdx = tasks.indexOf(task);
1223
1224        ArrayList<ActivityRecord> activities = task.mActivities;
1225        int activityNdx = activities.indexOf(r) + 1;
1226
1227        final int numStacks = mStacks.size();
1228        while (stackNdx < numStacks) {
1229            final ActivityStack historyStack = mStacks.get(stackNdx);
1230            tasks = historyStack.mTaskHistory;
1231            final int numTasks = tasks.size();
1232            while (taskNdx < numTasks) {
1233                final TaskRecord currentTask = tasks.get(taskNdx);
1234                activities = currentTask.mActivities;
1235                final int numActivities = activities.size();
1236                while (activityNdx < numActivities) {
1237                    final ActivityRecord activity = activities.get(activityNdx);
1238                    if (!activity.finishing) {
1239                        return historyStack.mFullscreen
1240                                && currentTask.mFullscreen && activity.fullscreen ? null : activity;
1241                    }
1242                    ++activityNdx;
1243                }
1244                activityNdx = 0;
1245                ++taskNdx;
1246            }
1247            taskNdx = 0;
1248            ++stackNdx;
1249        }
1250
1251        return null;
1252    }
1253
1254    private ActivityStack getNextVisibleStackLocked() {
1255        ArrayList<ActivityStack> stacks = mStacks;
1256        final ActivityRecord parent = mActivityContainer.mParentActivity;
1257        if (parent != null) {
1258            stacks = parent.task.stack.mStacks;
1259        }
1260        if (stacks != null) {
1261            for (int i = stacks.size() - 1; i >= 0; --i) {
1262                ActivityStack stack = stacks.get(i);
1263                if (stack != this && stack.isStackVisibleLocked()) {
1264                    return stack;
1265                }
1266            }
1267        }
1268        return null;
1269    }
1270
1271    /** Returns true if the stack contains a fullscreen task. */
1272    private boolean hasFullscreenTask() {
1273        for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
1274            final TaskRecord task = mTaskHistory.get(i);
1275            if (task.mFullscreen) {
1276                return true;
1277            }
1278        }
1279        return false;
1280    }
1281
1282    private boolean hasTranslucentActivity(ActivityStack stack) {
1283        final ArrayList<TaskRecord> tasks = stack.getAllTasks();
1284        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1285            final TaskRecord task = tasks.get(taskNdx);
1286            final ArrayList<ActivityRecord> activities = task.mActivities;
1287            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1288                final ActivityRecord r = activities.get(activityNdx);
1289
1290                // Conditions for an activity to obscure the stack we're
1291                // examining:
1292                // 1. Not Finishing AND Visible AND:
1293                // 2. Either:
1294                // - Full Screen Activity OR
1295                // - On top of Home and our stack is NOT home
1296                if (!r.finishing && r.visible && (r.fullscreen ||
1297                        (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()))) {
1298                    return false;
1299                }
1300            }
1301        }
1302        return true;
1303    }
1304
1305    /** Returns true if the stack is considered visible. */
1306    private boolean isStackVisibleLocked() {
1307        if (!isAttached()) {
1308            return false;
1309        }
1310
1311        if (mStackSupervisor.isFrontStack(this) || mStackSupervisor.isFocusedStack(this)) {
1312            return true;
1313        }
1314
1315        final int stackIndex = mStacks.indexOf(this);
1316
1317        if (stackIndex == mStacks.size() - 1) {
1318            Slog.wtf(TAG,
1319                    "Stack=" + this + " isn't front stack but is at the top of the stack list");
1320            return false;
1321        }
1322
1323        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
1324        final int focusedStackId = focusedStack.mStackId;
1325
1326        if (mStackId == DOCKED_STACK_ID) {
1327            // Docked stack is always visible, except in the case where the home activity
1328            // is the top running activity in the focused home stack.
1329            if (focusedStackId != HOME_STACK_ID) {
1330                return true;
1331            }
1332            ActivityRecord topHomeActivity = focusedStack.topRunningActivityLocked();
1333            return topHomeActivity == null || !topHomeActivity.isHomeActivity();
1334        }
1335
1336        final int belowFocusedIndex = mStacks.indexOf(focusedStack) - 1;
1337        if ((focusedStackId == DOCKED_STACK_ID || focusedStackId == PINNED_STACK_ID)
1338                && stackIndex == belowFocusedIndex) {
1339            // Stacks directly behind the docked or pinned stack are always visible.
1340            return true;
1341        }
1342
1343        if (focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
1344                && hasTranslucentActivity(focusedStack)) {
1345            // Stacks behind the fullscreen stack with a translucent activity are always
1346            // visible so they can act as a backdrop to the translucent activity.
1347            // For example, dialog activities
1348            if (stackIndex == belowFocusedIndex) {
1349                return true;
1350            }
1351            if (belowFocusedIndex >= 0) {
1352                final ActivityStack stack = mStacks.get(belowFocusedIndex);
1353                if ((stack.mStackId == DOCKED_STACK_ID || stack.mStackId == PINNED_STACK_ID)
1354                        && stackIndex == (belowFocusedIndex - 1)) {
1355                    // The stack behind the docked or pinned stack is also visible so we can have a
1356                    // complete backdrop to the translucent activity when the docked stack is up.
1357                    return true;
1358                }
1359            }
1360        }
1361
1362        if (StackId.isStaticStack(mStackId)) {
1363            // Visibility of any static stack should have been determined by the conditions above.
1364            return false;
1365        }
1366
1367        for (int i = stackIndex + 1; i < mStacks.size(); i++) {
1368            final ActivityStack stack = mStacks.get(i);
1369
1370            if (!stack.mFullscreen && !stack.hasFullscreenTask()) {
1371                continue;
1372            }
1373
1374            if (!StackId.isDynamicStacksVisibleBehindAllowed(stack.mStackId)) {
1375                // These stacks can't have any dynamic stacks visible behind them.
1376                return false;
1377            }
1378
1379            if (!hasTranslucentActivity(stack)) {
1380                return false;
1381            }
1382        }
1383
1384        return true;
1385    }
1386
1387    final int rankTaskLayers(int baseLayer) {
1388        int layer = 0;
1389        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1390            final TaskRecord task = mTaskHistory.get(taskNdx);
1391            ActivityRecord r = task.topRunningActivityLocked();
1392            if (r == null || r.finishing || !r.visible) {
1393                task.mLayerRank = -1;
1394            } else {
1395                task.mLayerRank = baseLayer + layer++;
1396            }
1397        }
1398        return layer;
1399    }
1400
1401    /**
1402     * Make sure that all activities that need to be visible (that is, they
1403     * currently can be seen by the user) actually are.
1404     */
1405    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
1406            boolean preserveWindows) {
1407        ActivityRecord top = topRunningActivityLocked();
1408        if (top == null) {
1409            return;
1410        }
1411        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1412                "ensureActivitiesVisible behind " + top
1413                + " configChanges=0x" + Integer.toHexString(configChanges));
1414
1415        if (mTranslucentActivityWaiting != top) {
1416            mUndrawnActivitiesBelowTopTranslucent.clear();
1417            if (mTranslucentActivityWaiting != null) {
1418                // Call the callback with a timeout indication.
1419                notifyActivityDrawnLocked(null);
1420                mTranslucentActivityWaiting = null;
1421            }
1422            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1423        }
1424
1425        // If the top activity is not fullscreen, then we need to
1426        // make sure any activities under it are now visible.
1427        boolean aboveTop = true;
1428        final boolean stackInvisible = !isStackVisibleLocked();
1429        boolean behindFullscreenActivity = stackInvisible;
1430        boolean noStackActivityResumed = (isInStackLocked(starting) == null);
1431
1432        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1433            final TaskRecord task = mTaskHistory.get(taskNdx);
1434            final ArrayList<ActivityRecord> activities = task.mActivities;
1435
1436            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1437                final ActivityRecord r = activities.get(activityNdx);
1438                if (r.finishing) {
1439                    continue;
1440                }
1441                if (aboveTop && r != top) {
1442                    continue;
1443                }
1444                aboveTop = false;
1445                // mLaunchingBehind: Activities launching behind are at the back of the task stack
1446                // but must be drawn initially for the animation as though they were visible.
1447                if (!behindFullscreenActivity || r.mLaunchTaskBehind) {
1448                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1449                            "Make visible? " + r + " finishing=" + r.finishing
1450                            + " state=" + r.state);
1451
1452                    // First: if this is not the current activity being started, make
1453                    // sure it matches the current configuration.
1454                    if (r != starting) {
1455                        ensureActivityConfigurationLocked(r, 0, preserveWindows);
1456                    }
1457
1458                    if (r.app == null || r.app.thread == null) {
1459                        // This activity needs to be visible, but isn't even running...
1460                        // get it started and resume if no other stack in this stack is resumed.
1461                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1462                                "Start and freeze screen for " + r);
1463                        if (r != starting) {
1464                            r.startFreezingScreenLocked(r.app, configChanges);
1465                        }
1466                        if (!r.visible || r.mLaunchTaskBehind) {
1467                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1468                                    "Starting and making visible: " + r);
1469                            setVisible(r, true);
1470                        }
1471                        if (r != starting) {
1472                            mStackSupervisor.startSpecificActivityLocked(
1473                                    r, noStackActivityResumed, false);
1474                            if (activityNdx >= activities.size()) {
1475                                // Record may be removed if its process needs to restart.
1476                                activityNdx = activities.size() - 1;
1477                            } else {
1478                                noStackActivityResumed = false;
1479                            }
1480                        }
1481
1482                    } else if (r.visible) {
1483                        // If this activity is already visible, then there is nothing
1484                        // else to do here.
1485                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1486                                "Skipping: already visible at " + r);
1487                        r.stopFreezingScreenLocked(false);
1488                        try {
1489                            if (r.returningOptions != null) {
1490                                r.app.thread.scheduleOnNewActivityOptions(r.appToken,
1491                                        r.returningOptions);
1492                            }
1493                        } catch(RemoteException e) {
1494                        }
1495                        if (r.state == ActivityState.RESUMED) {
1496                            noStackActivityResumed = false;
1497                        }
1498                    } else {
1499                        // This activity is not currently visible, but is running.
1500                        // Tell it to become visible.
1501                        r.visible = true;
1502                        if (r.state != ActivityState.RESUMED && r != starting) {
1503                            // If this activity is paused, tell it
1504                            // to now show its window.
1505                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1506                                    "Making visible and scheduling visibility: " + r);
1507                            try {
1508                                if (mTranslucentActivityWaiting != null) {
1509                                    r.updateOptionsLocked(r.returningOptions);
1510                                    mUndrawnActivitiesBelowTopTranslucent.add(r);
1511                                }
1512                                setVisible(r, true);
1513                                r.sleeping = false;
1514                                r.app.pendingUiClean = true;
1515                                r.app.thread.scheduleWindowVisibility(r.appToken, true);
1516                                r.stopFreezingScreenLocked(false);
1517                            } catch (Exception e) {
1518                                // Just skip on any failure; we'll make it
1519                                // visible when it next restarts.
1520                                Slog.w(TAG, "Exception thrown making visibile: "
1521                                        + r.intent.getComponent(), e);
1522                            }
1523                        }
1524                    }
1525
1526                    // Aggregate current change flags.
1527                    configChanges |= r.configChangeFlags;
1528
1529                    if (r.fullscreen) {
1530                        // At this point, nothing else needs to be shown in this task.
1531                        behindFullscreenActivity = true;
1532                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
1533                                + " stackInvisible=" + stackInvisible
1534                                + " behindFullscreenActivity=" + behindFullscreenActivity);
1535                    } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
1536                        behindFullscreenActivity = true;
1537                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
1538                                + " stackInvisible=" + stackInvisible
1539                                + " behindFullscreenActivity=" + behindFullscreenActivity);
1540                    }
1541                } else {
1542                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1543                            "Make invisible? " + r + " finishing=" + r.finishing
1544                            + " state=" + r.state + " stackInvisible=" + stackInvisible
1545                            + " behindFullscreenActivity=" + behindFullscreenActivity);
1546                    // Now for any activities that aren't visible to the user, make
1547                    // sure they no longer are keeping the screen frozen.
1548                    if (r.visible) {
1549                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r);
1550                        try {
1551                            setVisible(r, false);
1552                            switch (r.state) {
1553                                case STOPPING:
1554                                case STOPPED:
1555                                    if (r.app != null && r.app.thread != null) {
1556                                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1557                                                "Scheduling invisibility: " + r);
1558                                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
1559                                    }
1560                                    break;
1561
1562                                case INITIALIZING:
1563                                case RESUMED:
1564                                case PAUSING:
1565                                case PAUSED:
1566                                    // This case created for transitioning activities from
1567                                    // translucent to opaque {@link Activity#convertToOpaque}.
1568                                    if (getVisibleBehindActivity() == r) {
1569                                        releaseBackgroundResources(r);
1570                                    } else {
1571                                        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
1572                                            mStackSupervisor.mStoppingActivities.add(r);
1573                                        }
1574                                        mStackSupervisor.scheduleIdleLocked();
1575                                    }
1576                                    break;
1577
1578                                default:
1579                                    break;
1580                            }
1581                        } catch (Exception e) {
1582                            // Just skip on any failure; we'll make it
1583                            // visible when it next restarts.
1584                            Slog.w(TAG, "Exception thrown making hidden: "
1585                                    + r.intent.getComponent(), e);
1586                        }
1587                    } else {
1588                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
1589                    }
1590                }
1591            }
1592            if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
1593                // The visibility of tasks and the activities they contain in freeform stack are
1594                // determined individually unlike other stacks where the visibility or fullscreen
1595                // status of an activity in a previous task affects other.
1596                behindFullscreenActivity = stackInvisible;
1597            }
1598        }
1599
1600        if (mTranslucentActivityWaiting != null &&
1601                mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
1602            // Nothing is getting drawn or everything was already visible, don't wait for timeout.
1603            notifyActivityDrawnLocked(null);
1604        }
1605    }
1606
1607    void convertActivityToTranslucent(ActivityRecord r) {
1608        mTranslucentActivityWaiting = r;
1609        mUndrawnActivitiesBelowTopTranslucent.clear();
1610        mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
1611    }
1612
1613    void clearOtherAppTimeTrackers(AppTimeTracker except) {
1614        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1615            final TaskRecord task = mTaskHistory.get(taskNdx);
1616            final ArrayList<ActivityRecord> activities = task.mActivities;
1617            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1618                final ActivityRecord r = activities.get(activityNdx);
1619                if ( r.appTimeTracker != except) {
1620                    r.appTimeTracker = null;
1621                }
1622            }
1623        }
1624    }
1625
1626    /**
1627     * Called as activities below the top translucent activity are redrawn. When the last one is
1628     * redrawn notify the top activity by calling
1629     * {@link Activity#onTranslucentConversionComplete}.
1630     *
1631     * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
1632     * occurred and the activity will be notified immediately.
1633     */
1634    void notifyActivityDrawnLocked(ActivityRecord r) {
1635        mActivityContainer.setDrawn();
1636        if ((r == null)
1637                || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
1638                        mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
1639            // The last undrawn activity below the top has just been drawn. If there is an
1640            // opaque activity at the top, notify it that it can become translucent safely now.
1641            final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
1642            mTranslucentActivityWaiting = null;
1643            mUndrawnActivitiesBelowTopTranslucent.clear();
1644            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1645
1646            if (waitingActivity != null) {
1647                mWindowManager.setWindowOpaque(waitingActivity.appToken, false);
1648                if (waitingActivity.app != null && waitingActivity.app.thread != null) {
1649                    try {
1650                        waitingActivity.app.thread.scheduleTranslucentConversionComplete(
1651                                waitingActivity.appToken, r != null);
1652                    } catch (RemoteException e) {
1653                    }
1654                }
1655            }
1656        }
1657    }
1658
1659    /** If any activities below the top running one are in the INITIALIZING state and they have a
1660     * starting window displayed then remove that starting window. It is possible that the activity
1661     * in this state will never resumed in which case that starting window will be orphaned. */
1662    void cancelInitializingActivities() {
1663        final ActivityRecord topActivity = topRunningActivityLocked();
1664        boolean aboveTop = true;
1665        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1666            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1667            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1668                final ActivityRecord r = activities.get(activityNdx);
1669                if (aboveTop) {
1670                    if (r == topActivity) {
1671                        aboveTop = false;
1672                    }
1673                    continue;
1674                }
1675
1676                if (r.state == ActivityState.INITIALIZING && r.mStartingWindowShown) {
1677                    if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY,
1678                            "Found orphaned starting window " + r);
1679                    r.mStartingWindowShown = false;
1680                    mWindowManager.removeAppStartingWindow(r.appToken);
1681                }
1682            }
1683        }
1684    }
1685
1686    /**
1687     * Ensure that the top activity in the stack is resumed.
1688     *
1689     * @param prev The previously resumed activity, for when in the process
1690     * of pausing; can be null to call from elsewhere.
1691     *
1692     * @return Returns true if something is being resumed, or false if
1693     * nothing happened.
1694     */
1695    final boolean resumeTopActivityLocked(ActivityRecord prev) {
1696        return resumeTopActivityLocked(prev, null);
1697    }
1698
1699    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
1700        if (mStackSupervisor.inResumeTopActivity) {
1701            // Don't even start recursing.
1702            return false;
1703        }
1704
1705        boolean result = false;
1706        try {
1707            // Protect against recursion.
1708            mStackSupervisor.inResumeTopActivity = true;
1709            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
1710                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
1711                mService.updateSleepIfNeededLocked();
1712            }
1713            result = resumeTopActivityInnerLocked(prev, options);
1714        } finally {
1715            mStackSupervisor.inResumeTopActivity = false;
1716        }
1717        return result;
1718    }
1719
1720    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
1721        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
1722
1723        if (!mService.mBooting && !mService.mBooted) {
1724            // Not ready yet!
1725            return false;
1726        }
1727
1728        ActivityRecord parent = mActivityContainer.mParentActivity;
1729        if ((parent != null && parent.state != ActivityState.RESUMED) ||
1730                !mActivityContainer.isAttachedLocked()) {
1731            // Do not resume this stack if its parent is not resumed.
1732            // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
1733            return false;
1734        }
1735
1736        cancelInitializingActivities();
1737
1738        // Find the first activity that is not finishing.
1739        final ActivityRecord next = topRunningActivityLocked();
1740
1741        // Remember how we'll process this pause/resume situation, and ensure
1742        // that the state is reset however we wind up proceeding.
1743        final boolean userLeaving = mStackSupervisor.mUserLeaving;
1744        mStackSupervisor.mUserLeaving = false;
1745
1746        final TaskRecord prevTask = prev != null ? prev.task : null;
1747        if (next == null) {
1748            // There are no more activities!
1749            final String reason = "noMoreActivities";
1750            if (!mFullscreen) {
1751                // Try to move focus to the next visible stack with a running activity if this
1752                // stack is not covering the entire screen.
1753                final ActivityStack stack = getNextVisibleStackLocked();
1754                if (adjustFocusToNextVisibleStackLocked(stack, reason)) {
1755                    return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
1756                }
1757            }
1758            // Let's just start up the Launcher...
1759            ActivityOptions.abort(options);
1760            if (DEBUG_STATES) Slog.d(TAG_STATES,
1761                    "resumeTopActivityLocked: No more activities go home");
1762            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1763            // Only resume home if on home display
1764            final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
1765                    HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
1766            return isOnHomeDisplay() &&
1767                    mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
1768        }
1769
1770        next.delayedResume = false;
1771
1772        // If the top activity is the resumed one, nothing to do.
1773        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
1774                    mStackSupervisor.allResumedActivitiesComplete()) {
1775            // Make sure we have executed any pending transitions, since there
1776            // should be nothing left to do at this point.
1777            mWindowManager.executeAppTransition();
1778            mNoAnimActivities.clear();
1779            ActivityOptions.abort(options);
1780            if (DEBUG_STATES) Slog.d(TAG_STATES,
1781                    "resumeTopActivityLocked: Top activity resumed " + next);
1782            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1783            return false;
1784        }
1785
1786        final TaskRecord nextTask = next.task;
1787        if (prevTask != null && prevTask.stack == this &&
1788                prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
1789            if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
1790            if (prevTask == nextTask) {
1791                prevTask.setFrontOfTask();
1792            } else if (prevTask != topTask()) {
1793                // This task is going away but it was supposed to return to the home stack.
1794                // Now the task above it has to return to the home task instead.
1795                final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
1796                mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1797            } else if (!isOnHomeDisplay()) {
1798                return false;
1799            } else if (!isHomeStack()){
1800                if (DEBUG_STATES) Slog.d(TAG_STATES,
1801                        "resumeTopActivityLocked: Launching home next");
1802                final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
1803                        HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
1804                return isOnHomeDisplay() &&
1805                        mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
1806            }
1807        }
1808
1809        // If we are sleeping, and there is no resumed activity, and the top
1810        // activity is paused, well that is the state we want.
1811        if (mService.isSleepingOrShuttingDown()
1812                && mLastPausedActivity == next
1813                && mStackSupervisor.allPausedActivitiesComplete()) {
1814            // Make sure we have executed any pending transitions, since there
1815            // should be nothing left to do at this point.
1816            mWindowManager.executeAppTransition();
1817            mNoAnimActivities.clear();
1818            ActivityOptions.abort(options);
1819            if (DEBUG_STATES) Slog.d(TAG_STATES,
1820                    "resumeTopActivityLocked: Going to sleep and all paused");
1821            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1822            return false;
1823        }
1824
1825        // Make sure that the user who owns this activity is started.  If not,
1826        // we will just leave it as is because someone should be bringing
1827        // another user's activities to the top of the stack.
1828        if (!mService.mUserController.hasStartedUserState(next.userId)) {
1829            Slog.w(TAG, "Skipping resume of top activity " + next
1830                    + ": user " + next.userId + " is stopped");
1831            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1832            return false;
1833        }
1834
1835        // The activity may be waiting for stop, but that is no longer
1836        // appropriate for it.
1837        mStackSupervisor.mStoppingActivities.remove(next);
1838        mStackSupervisor.mGoingToSleepActivities.remove(next);
1839        next.sleeping = false;
1840        mStackSupervisor.mWaitingVisibleActivities.remove(next);
1841
1842        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
1843
1844        // If we are currently pausing an activity, then don't do anything
1845        // until that is done.
1846        if (!mStackSupervisor.allPausedActivitiesComplete()) {
1847            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
1848                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
1849            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1850            return false;
1851        }
1852
1853        // Okay we are now going to start a switch, to 'next'.  We may first
1854        // have to pause the current activity, but this is an important point
1855        // where we have decided to go to 'next' so keep track of that.
1856        // XXX "App Redirected" dialog is getting too many false positives
1857        // at this point, so turn off for now.
1858        if (false) {
1859            if (mLastStartedActivity != null && !mLastStartedActivity.finishing) {
1860                long now = SystemClock.uptimeMillis();
1861                final boolean inTime = mLastStartedActivity.startTime != 0
1862                        && (mLastStartedActivity.startTime + START_WARN_TIME) >= now;
1863                final int lastUid = mLastStartedActivity.info.applicationInfo.uid;
1864                final int nextUid = next.info.applicationInfo.uid;
1865                if (inTime && lastUid != nextUid
1866                        && lastUid != next.launchedFromUid
1867                        && mService.checkPermission(
1868                                android.Manifest.permission.STOP_APP_SWITCHES,
1869                                -1, next.launchedFromUid)
1870                        != PackageManager.PERMISSION_GRANTED) {
1871                    mService.showLaunchWarningLocked(mLastStartedActivity, next);
1872                } else {
1873                    next.startTime = now;
1874                    mLastStartedActivity = next;
1875                }
1876            } else {
1877                next.startTime = SystemClock.uptimeMillis();
1878                mLastStartedActivity = next;
1879            }
1880        }
1881
1882        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
1883
1884        // We need to start pausing the current activity so the top one
1885        // can be resumed...
1886        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
1887        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
1888        if (mResumedActivity != null) {
1889            if (DEBUG_STATES) Slog.d(TAG_STATES,
1890                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
1891            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
1892        }
1893        if (pausing) {
1894            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
1895                    "resumeTopActivityLocked: Skip resume: need to start pausing");
1896            // At this point we want to put the upcoming activity's process
1897            // at the top of the LRU list, since we know we will be needing it
1898            // very soon and it would be a waste to let it get killed if it
1899            // happens to be sitting towards the end.
1900            if (next.app != null && next.app.thread != null) {
1901                mService.updateLruProcessLocked(next.app, true, null);
1902            }
1903            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1904            return true;
1905        }
1906
1907        // If the most recent activity was noHistory but was only stopped rather
1908        // than stopped+finished because the device went to sleep, we need to make
1909        // sure to finish it as we're making a new activity topmost.
1910        if (mService.isSleeping() && mLastNoHistoryActivity != null &&
1911                !mLastNoHistoryActivity.finishing) {
1912            if (DEBUG_STATES) Slog.d(TAG_STATES,
1913                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
1914            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
1915                    null, "resume-no-history", false);
1916            mLastNoHistoryActivity = null;
1917        }
1918
1919        if (prev != null && prev != next) {
1920            if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
1921                    && next != null && !next.nowVisible) {
1922                mStackSupervisor.mWaitingVisibleActivities.add(prev);
1923                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1924                        "Resuming top, waiting visible to hide: " + prev);
1925            } else {
1926                // The next activity is already visible, so hide the previous
1927                // activity's windows right now so we can show the new one ASAP.
1928                // We only do this if the previous is finishing, which should mean
1929                // it is on top of the one being resumed so hiding it quickly
1930                // is good.  Otherwise, we want to do the normal route of allowing
1931                // the resumed activity to be shown so we can decide if the
1932                // previous should actually be hidden depending on whether the
1933                // new one is found to be full-screen or not.
1934                if (prev.finishing) {
1935                    mWindowManager.setAppVisibility(prev.appToken, false);
1936                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1937                            "Not waiting for visible to hide: " + prev + ", waitingVisible="
1938                            + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
1939                            + ", nowVisible=" + next.nowVisible);
1940                } else {
1941                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1942                            "Previous already visible but still waiting to hide: " + prev
1943                            + ", waitingVisible="
1944                            + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
1945                            + ", nowVisible=" + next.nowVisible);
1946                }
1947            }
1948        }
1949
1950        // Launching this app's activity, make sure the app is no longer
1951        // considered stopped.
1952        try {
1953            AppGlobals.getPackageManager().setPackageStoppedState(
1954                    next.packageName, false, next.userId); /* TODO: Verify if correct userid */
1955        } catch (RemoteException e1) {
1956        } catch (IllegalArgumentException e) {
1957            Slog.w(TAG, "Failed trying to unstop package "
1958                    + next.packageName + ": " + e);
1959        }
1960
1961        // We are starting up the next activity, so tell the window manager
1962        // that the previous one will be hidden soon.  This way it can know
1963        // to ignore it when computing the desired screen orientation.
1964        boolean anim = true;
1965        if (prev != null) {
1966            if (prev.finishing) {
1967                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
1968                        "Prepare close transition: prev=" + prev);
1969                if (mNoAnimActivities.contains(prev)) {
1970                    anim = false;
1971                    mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
1972                } else {
1973                    mWindowManager.prepareAppTransition(prev.task == next.task
1974                            ? AppTransition.TRANSIT_ACTIVITY_CLOSE
1975                            : AppTransition.TRANSIT_TASK_CLOSE, false);
1976                }
1977                mWindowManager.setAppVisibility(prev.appToken, false);
1978            } else {
1979                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
1980                        "Prepare open transition: prev=" + prev);
1981                if (mNoAnimActivities.contains(next)) {
1982                    anim = false;
1983                    mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
1984                } else {
1985                    mWindowManager.prepareAppTransition(prev.task == next.task
1986                            ? AppTransition.TRANSIT_ACTIVITY_OPEN
1987                            : next.mLaunchTaskBehind
1988                                    ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
1989                                    : AppTransition.TRANSIT_TASK_OPEN, false);
1990                }
1991            }
1992        } else {
1993            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
1994            if (mNoAnimActivities.contains(next)) {
1995                anim = false;
1996                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
1997            } else {
1998                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
1999            }
2000        }
2001
2002        Bundle resumeAnimOptions = null;
2003        if (anim) {
2004            ActivityOptions opts = next.getOptionsForTargetActivityLocked();
2005            if (opts != null) {
2006                resumeAnimOptions = opts.toBundle();
2007            }
2008            next.applyOptionsLocked();
2009        } else {
2010            next.clearOptionsLocked();
2011        }
2012
2013        ActivityStack lastStack = mStackSupervisor.getLastStack();
2014        if (next.app != null && next.app.thread != null) {
2015            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);
2016
2017            // This activity is now becoming visible.
2018            mWindowManager.setAppVisibility(next.appToken, true);
2019
2020            // schedule launch ticks to collect information about slow apps.
2021            next.startLaunchTickingLocked();
2022
2023            ActivityRecord lastResumedActivity =
2024                    lastStack == null ? null :lastStack.mResumedActivity;
2025            ActivityState lastState = next.state;
2026
2027            mService.updateCpuStats();
2028
2029            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
2030            next.state = ActivityState.RESUMED;
2031            mResumedActivity = next;
2032            next.task.touchActiveTime();
2033            mRecentTasks.addLocked(next.task);
2034            mService.updateLruProcessLocked(next.app, true, null);
2035            updateLRUListLocked(next);
2036            mService.updateOomAdjLocked();
2037
2038            // Have the window manager re-evaluate the orientation of
2039            // the screen based on the new activity order.
2040            boolean notUpdated = true;
2041            if (mStackSupervisor.isFocusedStack(this)) {
2042                Configuration config = mWindowManager.updateOrientationFromAppTokens(
2043                        mService.mConfiguration,
2044                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
2045                if (config != null) {
2046                    next.frozenBeforeDestroy = true;
2047                }
2048                notUpdated = !mService.updateConfigurationLocked(config, next, false);
2049            }
2050
2051            if (notUpdated) {
2052                // The configuration update wasn't able to keep the existing
2053                // instance of the activity, and instead started a new one.
2054                // We should be all done, but let's just make sure our activity
2055                // is still at the top and schedule another run if something
2056                // weird happened.
2057                ActivityRecord nextNext = topRunningActivityLocked();
2058                if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
2059                        "Activity config changed during resume: " + next
2060                        + ", new next: " + nextNext);
2061                if (nextNext != next) {
2062                    // Do over!
2063                    mStackSupervisor.scheduleResumeTopActivities();
2064                }
2065                if (mStackSupervisor.reportResumedActivityLocked(next)) {
2066                    mNoAnimActivities.clear();
2067                    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2068                    return true;
2069                }
2070                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2071                return false;
2072            }
2073
2074            try {
2075                // Deliver all pending results.
2076                ArrayList<ResultInfo> a = next.results;
2077                if (a != null) {
2078                    final int N = a.size();
2079                    if (!next.finishing && N > 0) {
2080                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
2081                                "Delivering results to " + next + ": " + a);
2082                        next.app.thread.scheduleSendResult(next.appToken, a);
2083                    }
2084                }
2085
2086                if (next.newIntents != null) {
2087                    next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
2088                }
2089
2090                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
2091                        System.identityHashCode(next), next.task.taskId, next.shortComponentName);
2092
2093                next.sleeping = false;
2094                mService.showAskCompatModeDialogLocked(next);
2095                next.app.pendingUiClean = true;
2096                next.app.forceProcessStateUpTo(mService.mTopProcessState);
2097                next.clearOptionsLocked();
2098                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
2099                        mService.isNextTransitionForward(), resumeAnimOptions);
2100
2101                mStackSupervisor.checkReadyForSleepLocked();
2102
2103                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
2104            } catch (Exception e) {
2105                // Whoops, need to restart this activity!
2106                if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
2107                        + lastState + ": " + next);
2108                next.state = lastState;
2109                if (lastStack != null) {
2110                    lastStack.mResumedActivity = lastResumedActivity;
2111                }
2112                Slog.i(TAG, "Restarting because process died: " + next);
2113                if (!next.hasBeenLaunched) {
2114                    next.hasBeenLaunched = true;
2115                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
2116                        mStackSupervisor.isFrontStack(lastStack)) {
2117                    mWindowManager.setAppStartingWindow(
2118                            next.appToken, next.packageName, next.theme,
2119                            mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
2120                            next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
2121                            next.windowFlags, null, true);
2122                }
2123                mStackSupervisor.startSpecificActivityLocked(next, true, false);
2124                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2125                return true;
2126            }
2127
2128            // From this point on, if something goes wrong there is no way
2129            // to recover the activity.
2130            try {
2131                next.visible = true;
2132                completeResumeLocked(next);
2133            } catch (Exception e) {
2134                // If any exception gets thrown, toss away this
2135                // activity and try the next one.
2136                Slog.w(TAG, "Exception thrown during resume of " + next, e);
2137                requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
2138                        "resume-exception", true);
2139                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2140                return true;
2141            }
2142            next.stopped = false;
2143
2144        } else {
2145            // Whoops, need to restart this activity!
2146            if (!next.hasBeenLaunched) {
2147                next.hasBeenLaunched = true;
2148            } else {
2149                if (SHOW_APP_STARTING_PREVIEW) {
2150                    mWindowManager.setAppStartingWindow(
2151                            next.appToken, next.packageName, next.theme,
2152                            mService.compatibilityInfoForPackageLocked(
2153                                    next.info.applicationInfo),
2154                            next.nonLocalizedLabel,
2155                            next.labelRes, next.icon, next.logo, next.windowFlags,
2156                            null, true);
2157                }
2158                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
2159            }
2160            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
2161            mStackSupervisor.startSpecificActivityLocked(next, true, true);
2162        }
2163
2164        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2165        return true;
2166    }
2167
2168    private TaskRecord getNextTask(TaskRecord targetTask) {
2169        final int index = mTaskHistory.indexOf(targetTask);
2170        if (index >= 0) {
2171            final int numTasks = mTaskHistory.size();
2172            for (int i = index + 1; i < numTasks; ++i) {
2173                TaskRecord task = mTaskHistory.get(i);
2174                if (task.userId == targetTask.userId) {
2175                    return task;
2176                }
2177            }
2178        }
2179        return null;
2180    }
2181
2182    private void insertTaskAtPosition(TaskRecord task, int position) {
2183        if (position >= mTaskHistory.size()) {
2184            insertTaskAtTop(task, null);
2185            return;
2186        }
2187        // Calculate maximum possible position for this task.
2188        int maxPosition = mTaskHistory.size();
2189        if (!mStackSupervisor.isCurrentProfileLocked(task.userId)
2190                && task.topRunningActivityLocked() == null) {
2191            // Put non-current user tasks below current user tasks.
2192            while (maxPosition > 0) {
2193                final TaskRecord tmpTask = mTaskHistory.get(maxPosition - 1);
2194                if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId)
2195                        || tmpTask.topRunningActivityLocked() == null) {
2196                    break;
2197                }
2198                maxPosition--;
2199            }
2200        }
2201        position = Math.min(position, maxPosition);
2202        mTaskHistory.remove(task);
2203        mTaskHistory.add(position, task);
2204        updateTaskMovement(task, true);
2205    }
2206
2207    private void insertTaskAtTop(TaskRecord task, ActivityRecord newActivity) {
2208        // If the moving task is over home stack, transfer its return type to next task
2209        if (task.isOverHomeStack()) {
2210            final TaskRecord nextTask = getNextTask(task);
2211            if (nextTask != null) {
2212                nextTask.setTaskToReturnTo(task.getTaskToReturnTo());
2213            }
2214        }
2215
2216        // If this is being moved to the top by another activity or being launched from the home
2217        // activity, set mTaskToReturnTo accordingly.
2218        if (isOnHomeDisplay()) {
2219            ActivityStack lastStack = mStackSupervisor.getLastStack();
2220            final boolean fromHome = lastStack.isHomeStack();
2221            if (!isHomeStack() && (fromHome || topTask() != task)) {
2222                task.setTaskToReturnTo(fromHome
2223                        ? lastStack.topTask() == null
2224                                ? HOME_ACTIVITY_TYPE
2225                                : lastStack.topTask().taskType
2226                        : APPLICATION_ACTIVITY_TYPE);
2227            }
2228        } else {
2229            task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
2230        }
2231
2232        mTaskHistory.remove(task);
2233        // Now put task at top.
2234        int taskNdx = mTaskHistory.size();
2235        final boolean notShownWhenLocked =
2236                (newActivity != null && (newActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0)
2237                || (newActivity == null && task.topRunningActivityLocked() == null);
2238        if (!mStackSupervisor.isCurrentProfileLocked(task.userId) && notShownWhenLocked) {
2239            // Put non-current user tasks below current user tasks.
2240            while (--taskNdx >= 0) {
2241                final TaskRecord tmpTask = mTaskHistory.get(taskNdx);
2242                if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId)
2243                        || tmpTask.topRunningActivityLocked() == null) {
2244                    break;
2245                }
2246            }
2247            ++taskNdx;
2248        }
2249        mTaskHistory.add(taskNdx, task);
2250        updateTaskMovement(task, true);
2251    }
2252
2253    final void startActivityLocked(ActivityRecord r, boolean newTask,
2254            boolean doResume, boolean keepCurTransition, Bundle options) {
2255        TaskRecord rTask = r.task;
2256        final int taskId = rTask.taskId;
2257        // mLaunchTaskBehind tasks get placed at the back of the task stack.
2258        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
2259            // Last activity in task had been removed or ActivityManagerService is reusing task.
2260            // Insert or replace.
2261            // Might not even be in.
2262            insertTaskAtTop(rTask, r);
2263            mWindowManager.moveTaskToTop(taskId);
2264        }
2265        TaskRecord task = null;
2266        if (!newTask) {
2267            // If starting in an existing task, find where that is...
2268            boolean startIt = true;
2269            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2270                task = mTaskHistory.get(taskNdx);
2271                if (task.getTopActivity() == null) {
2272                    // All activities in task are finishing.
2273                    continue;
2274                }
2275                if (task == r.task) {
2276                    // Here it is!  Now, if this is not yet visible to the
2277                    // user, then just add it without starting; it will
2278                    // get started when the user navigates back to it.
2279                    if (!startIt) {
2280                        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
2281                                + task, new RuntimeException("here").fillInStackTrace());
2282                        task.addActivityToTop(r);
2283                        r.putInHistory();
2284                        addConfigOverride(r, task);
2285                        if (VALIDATE_TOKENS) {
2286                            validateAppTokensLocked();
2287                        }
2288                        ActivityOptions.abort(options);
2289                        return;
2290                    }
2291                    break;
2292                } else if (task.numFullscreen > 0) {
2293                    startIt = false;
2294                }
2295            }
2296        }
2297
2298        // Place a new activity at top of stack, so it is next to interact
2299        // with the user.
2300
2301        // If we are not placing the new activity frontmost, we do not want
2302        // to deliver the onUserLeaving callback to the actual frontmost
2303        // activity
2304        if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
2305            mStackSupervisor.mUserLeaving = false;
2306            if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2307                    "startActivity() behind front, mUserLeaving=false");
2308        }
2309
2310        task = r.task;
2311
2312        // Slot the activity into the history stack and proceed
2313        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
2314                new RuntimeException("here").fillInStackTrace());
2315        task.addActivityToTop(r);
2316        task.setFrontOfTask();
2317
2318        r.putInHistory();
2319        if (!isHomeStack() || numActivities() > 0) {
2320            // We want to show the starting preview window if we are
2321            // switching to a new task, or the next activity's process is
2322            // not currently running.
2323            boolean showStartingIcon = newTask;
2324            ProcessRecord proc = r.app;
2325            if (proc == null) {
2326                proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2327            }
2328            if (proc == null || proc.thread == null) {
2329                showStartingIcon = true;
2330            }
2331            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2332                    "Prepare open transition: starting " + r);
2333            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2334                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
2335                mNoAnimActivities.add(r);
2336            } else {
2337                mWindowManager.prepareAppTransition(newTask
2338                        ? r.mLaunchTaskBehind
2339                                ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
2340                                : AppTransition.TRANSIT_TASK_OPEN
2341                        : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
2342                mNoAnimActivities.remove(r);
2343            }
2344            addConfigOverride(r, task);
2345            boolean doShow = true;
2346            if (newTask) {
2347                // Even though this activity is starting fresh, we still need
2348                // to reset it to make sure we apply affinities to move any
2349                // existing activities from other tasks in to it.
2350                // If the caller has requested that the target task be
2351                // reset, then do so.
2352                if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2353                    resetTaskIfNeededLocked(r, r);
2354                    doShow = topRunningNonDelayedActivityLocked(null) == r;
2355                }
2356            } else if (options != null && new ActivityOptions(options).getAnimationType()
2357                    == ActivityOptions.ANIM_SCENE_TRANSITION) {
2358                doShow = false;
2359            }
2360            if (r.mLaunchTaskBehind) {
2361                // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
2362                // tell WindowManager that r is visible even though it is at the back of the stack.
2363                mWindowManager.setAppVisibility(r.appToken, true);
2364                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2365            } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
2366                // Figure out if we are transitioning from another activity that is
2367                // "has the same starting icon" as the next one.  This allows the
2368                // window manager to keep the previous window it had previously
2369                // created, if it still had one.
2370                ActivityRecord prev = mResumedActivity;
2371                if (prev != null) {
2372                    // We don't want to reuse the previous starting preview if:
2373                    // (1) The current activity is in a different task.
2374                    if (prev.task != r.task) {
2375                        prev = null;
2376                    }
2377                    // (2) The current activity is already displayed.
2378                    else if (prev.nowVisible) {
2379                        prev = null;
2380                    }
2381                }
2382                mWindowManager.setAppStartingWindow(
2383                        r.appToken, r.packageName, r.theme,
2384                        mService.compatibilityInfoForPackageLocked(
2385                                r.info.applicationInfo), r.nonLocalizedLabel,
2386                        r.labelRes, r.icon, r.logo, r.windowFlags,
2387                        prev != null ? prev.appToken : null, showStartingIcon);
2388                r.mStartingWindowShown = true;
2389            }
2390        } else {
2391            // If this is the first activity, don't do any fancy animations,
2392            // because there is nothing for it to animate on top of.
2393            addConfigOverride(r, task);
2394            ActivityOptions.abort(options);
2395            options = null;
2396        }
2397        if (VALIDATE_TOKENS) {
2398            validateAppTokensLocked();
2399        }
2400
2401        if (doResume) {
2402            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
2403        } else {
2404            addRecentActivityLocked(r);
2405        }
2406    }
2407
2408    final void validateAppTokensLocked() {
2409        mValidateAppTokens.clear();
2410        mValidateAppTokens.ensureCapacity(numActivities());
2411        final int numTasks = mTaskHistory.size();
2412        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
2413            TaskRecord task = mTaskHistory.get(taskNdx);
2414            final ArrayList<ActivityRecord> activities = task.mActivities;
2415            if (activities.isEmpty()) {
2416                continue;
2417            }
2418            TaskGroup group = new TaskGroup();
2419            group.taskId = task.taskId;
2420            mValidateAppTokens.add(group);
2421            final int numActivities = activities.size();
2422            for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2423                final ActivityRecord r = activities.get(activityNdx);
2424                group.tokens.add(r.appToken);
2425            }
2426        }
2427        mWindowManager.validateAppTokens(mStackId, mValidateAppTokens);
2428    }
2429
2430    /**
2431     * Perform a reset of the given task, if needed as part of launching it.
2432     * Returns the new HistoryRecord at the top of the task.
2433     */
2434    /**
2435     * Helper method for #resetTaskIfNeededLocked.
2436     * We are inside of the task being reset...  we'll either finish this activity, push it out
2437     * for another task, or leave it as-is.
2438     * @param task The task containing the Activity (taskTop) that might be reset.
2439     * @param forceReset
2440     * @return An ActivityOptions that needs to be processed.
2441     */
2442    final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
2443        ActivityOptions topOptions = null;
2444
2445        int replyChainEnd = -1;
2446        boolean canMoveOptions = true;
2447
2448        // We only do this for activities that are not the root of the task (since if we finish
2449        // the root, we may no longer have the task!).
2450        final ArrayList<ActivityRecord> activities = task.mActivities;
2451        final int numActivities = activities.size();
2452        final int rootActivityNdx = task.findEffectiveRootIndex();
2453        for (int i = numActivities - 1; i > rootActivityNdx; --i ) {
2454            ActivityRecord target = activities.get(i);
2455            if (target.frontOfTask)
2456                break;
2457
2458            final int flags = target.info.flags;
2459            final boolean finishOnTaskLaunch =
2460                    (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
2461            final boolean allowTaskReparenting =
2462                    (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
2463            final boolean clearWhenTaskReset =
2464                    (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
2465
2466            if (!finishOnTaskLaunch
2467                    && !clearWhenTaskReset
2468                    && target.resultTo != null) {
2469                // If this activity is sending a reply to a previous
2470                // activity, we can't do anything with it now until
2471                // we reach the start of the reply chain.
2472                // XXX note that we are assuming the result is always
2473                // to the previous activity, which is almost always
2474                // the case but we really shouldn't count on.
2475                if (replyChainEnd < 0) {
2476                    replyChainEnd = i;
2477                }
2478            } else if (!finishOnTaskLaunch
2479                    && !clearWhenTaskReset
2480                    && allowTaskReparenting
2481                    && target.taskAffinity != null
2482                    && !target.taskAffinity.equals(task.affinity)) {
2483                // If this activity has an affinity for another
2484                // task, then we need to move it out of here.  We will
2485                // move it as far out of the way as possible, to the
2486                // bottom of the activity stack.  This also keeps it
2487                // correctly ordered with any activities we previously
2488                // moved.
2489                final TaskRecord targetTask;
2490                final ActivityRecord bottom =
2491                        !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
2492                                mTaskHistory.get(0).mActivities.get(0) : null;
2493                if (bottom != null && target.taskAffinity != null
2494                        && target.taskAffinity.equals(bottom.task.affinity)) {
2495                    // If the activity currently at the bottom has the
2496                    // same task affinity as the one we are moving,
2497                    // then merge it into the same task.
2498                    targetTask = bottom.task;
2499                    if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
2500                            + " out to bottom task " + bottom.task);
2501                } else {
2502                    targetTask = createTaskRecord(mStackSupervisor.getNextTaskId(), target.info,
2503                            null, null, null, false);
2504                    targetTask.affinityIntent = target.intent;
2505                    if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
2506                            + " out to new task " + target.task);
2507                }
2508
2509                setAppTask(target, targetTask);
2510
2511                boolean noOptions = canMoveOptions;
2512                final int start = replyChainEnd < 0 ? i : replyChainEnd;
2513                for (int srcPos = start; srcPos >= i; --srcPos) {
2514                    final ActivityRecord p = activities.get(srcPos);
2515                    if (p.finishing) {
2516                        continue;
2517                    }
2518
2519                    canMoveOptions = false;
2520                    if (noOptions && topOptions == null) {
2521                        topOptions = p.takeOptionsLocked();
2522                        if (topOptions != null) {
2523                            noOptions = false;
2524                        }
2525                    }
2526                    if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
2527                            "Removing activity " + p + " from task=" + task + " adding to task="
2528                            + targetTask + " Callers=" + Debug.getCallers(4));
2529                    if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2530                            "Pushing next activity " + p + " out to target's task " + target.task);
2531                    p.setTask(targetTask, null);
2532                    targetTask.addActivityAtBottom(p);
2533
2534                    setAppTask(p, targetTask);
2535                }
2536
2537                mWindowManager.moveTaskToBottom(targetTask.taskId);
2538                if (VALIDATE_TOKENS) {
2539                    validateAppTokensLocked();
2540                }
2541
2542                replyChainEnd = -1;
2543            } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) {
2544                // If the activity should just be removed -- either
2545                // because it asks for it, or the task should be
2546                // cleared -- then finish it and anything that is
2547                // part of its reply chain.
2548                int end;
2549                if (clearWhenTaskReset) {
2550                    // In this case, we want to finish this activity
2551                    // and everything above it, so be sneaky and pretend
2552                    // like these are all in the reply chain.
2553                    end = activities.size() - 1;
2554                } else if (replyChainEnd < 0) {
2555                    end = i;
2556                } else {
2557                    end = replyChainEnd;
2558                }
2559                boolean noOptions = canMoveOptions;
2560                for (int srcPos = i; srcPos <= end; srcPos++) {
2561                    ActivityRecord p = activities.get(srcPos);
2562                    if (p.finishing) {
2563                        continue;
2564                    }
2565                    canMoveOptions = false;
2566                    if (noOptions && topOptions == null) {
2567                        topOptions = p.takeOptionsLocked();
2568                        if (topOptions != null) {
2569                            noOptions = false;
2570                        }
2571                    }
2572                    if (DEBUG_TASKS) Slog.w(TAG_TASKS,
2573                            "resetTaskIntendedTask: calling finishActivity on " + p);
2574                    if (finishActivityLocked(
2575                            p, Activity.RESULT_CANCELED, null, "reset-task", false)) {
2576                        end--;
2577                        srcPos--;
2578                    }
2579                }
2580                replyChainEnd = -1;
2581            } else {
2582                // If we were in the middle of a chain, well the
2583                // activity that started it all doesn't want anything
2584                // special, so leave it all as-is.
2585                replyChainEnd = -1;
2586            }
2587        }
2588
2589        return topOptions;
2590    }
2591
2592    /**
2593     * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given
2594     * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop.
2595     * @param affinityTask The task we are looking for an affinity to.
2596     * @param task Task that resetTaskIfNeededLocked.taskTop belongs to.
2597     * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked.
2598     * @param forceReset Flag passed in to resetTaskIfNeededLocked.
2599     */
2600    private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task,
2601            boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) {
2602        int replyChainEnd = -1;
2603        final int taskId = task.taskId;
2604        final String taskAffinity = task.affinity;
2605
2606        final ArrayList<ActivityRecord> activities = affinityTask.mActivities;
2607        final int numActivities = activities.size();
2608        final int rootActivityNdx = affinityTask.findEffectiveRootIndex();
2609
2610        // Do not operate on or below the effective root Activity.
2611        for (int i = numActivities - 1; i > rootActivityNdx; --i) {
2612            ActivityRecord target = activities.get(i);
2613            if (target.frontOfTask)
2614                break;
2615
2616            final int flags = target.info.flags;
2617            boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
2618            boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
2619
2620            if (target.resultTo != null) {
2621                // If this activity is sending a reply to a previous
2622                // activity, we can't do anything with it now until
2623                // we reach the start of the reply chain.
2624                // XXX note that we are assuming the result is always
2625                // to the previous activity, which is almost always
2626                // the case but we really shouldn't count on.
2627                if (replyChainEnd < 0) {
2628                    replyChainEnd = i;
2629                }
2630            } else if (topTaskIsHigher
2631                    && allowTaskReparenting
2632                    && taskAffinity != null
2633                    && taskAffinity.equals(target.taskAffinity)) {
2634                // This activity has an affinity for our task. Either remove it if we are
2635                // clearing or move it over to our task.  Note that
2636                // we currently punt on the case where we are resetting a
2637                // task that is not at the top but who has activities above
2638                // with an affinity to it...  this is really not a normal
2639                // case, and we will need to later pull that task to the front
2640                // and usually at that point we will do the reset and pick
2641                // up those remaining activities.  (This only happens if
2642                // someone starts an activity in a new task from an activity
2643                // in a task that is not currently on top.)
2644                if (forceReset || finishOnTaskLaunch) {
2645                    final int start = replyChainEnd >= 0 ? replyChainEnd : i;
2646                    if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2647                            "Finishing task at index " + start + " to " + i);
2648                    for (int srcPos = start; srcPos >= i; --srcPos) {
2649                        final ActivityRecord p = activities.get(srcPos);
2650                        if (p.finishing) {
2651                            continue;
2652                        }
2653                        finishActivityLocked(
2654                                p, Activity.RESULT_CANCELED, null, "move-affinity", false);
2655                    }
2656                } else {
2657                    if (taskInsertionPoint < 0) {
2658                        taskInsertionPoint = task.mActivities.size();
2659
2660                    }
2661
2662                    final int start = replyChainEnd >= 0 ? replyChainEnd : i;
2663                    if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2664                            "Reparenting from task=" + affinityTask + ":" + start + "-" + i
2665                            + " to task=" + task + ":" + taskInsertionPoint);
2666                    for (int srcPos = start; srcPos >= i; --srcPos) {
2667                        final ActivityRecord p = activities.get(srcPos);
2668                        p.setTask(task, null);
2669                        task.addActivityAtIndex(taskInsertionPoint, p);
2670
2671                        if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
2672                                "Removing and adding activity " + p + " to stack at " + task
2673                                + " callers=" + Debug.getCallers(3));
2674                        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Pulling activity " + p
2675                                + " from " + srcPos + " in to resetting task " + task);
2676                        setAppTask(p, task);
2677                    }
2678                    mWindowManager.moveTaskToTop(taskId);
2679                    if (VALIDATE_TOKENS) {
2680                        validateAppTokensLocked();
2681                    }
2682
2683                    // Now we've moved it in to place...  but what if this is
2684                    // a singleTop activity and we have put it on top of another
2685                    // instance of the same activity?  Then we drop the instance
2686                    // below so it remains singleTop.
2687                    if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
2688                        ArrayList<ActivityRecord> taskActivities = task.mActivities;
2689                        int targetNdx = taskActivities.indexOf(target);
2690                        if (targetNdx > 0) {
2691                            ActivityRecord p = taskActivities.get(targetNdx - 1);
2692                            if (p.intent.getComponent().equals(target.intent.getComponent())) {
2693                                finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
2694                                        false);
2695                            }
2696                        }
2697                    }
2698                }
2699
2700                replyChainEnd = -1;
2701            }
2702        }
2703        return taskInsertionPoint;
2704    }
2705
2706    final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
2707            ActivityRecord newActivity) {
2708        boolean forceReset =
2709                (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
2710        if (ACTIVITY_INACTIVE_RESET_TIME > 0
2711                && taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
2712            if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
2713                forceReset = true;
2714            }
2715        }
2716
2717        final TaskRecord task = taskTop.task;
2718
2719        /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
2720         * for remaining tasks. Used for later tasks to reparent to task. */
2721        boolean taskFound = false;
2722
2723        /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */
2724        ActivityOptions topOptions = null;
2725
2726        // Preserve the location for reparenting in the new task.
2727        int reparentInsertionPoint = -1;
2728
2729        for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
2730            final TaskRecord targetTask = mTaskHistory.get(i);
2731
2732            if (targetTask == task) {
2733                topOptions = resetTargetTaskIfNeededLocked(task, forceReset);
2734                taskFound = true;
2735            } else {
2736                reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task,
2737                        taskFound, forceReset, reparentInsertionPoint);
2738            }
2739        }
2740
2741        int taskNdx = mTaskHistory.indexOf(task);
2742        if (taskNdx >= 0) {
2743            do {
2744                taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
2745            } while (taskTop == null && taskNdx >= 0);
2746        }
2747
2748        if (topOptions != null) {
2749            // If we got some ActivityOptions from an activity on top that
2750            // was removed from the task, propagate them to the new real top.
2751            if (taskTop != null) {
2752                taskTop.updateOptionsLocked(topOptions);
2753            } else {
2754                topOptions.abort();
2755            }
2756        }
2757
2758        return taskTop;
2759    }
2760
2761    void sendActivityResultLocked(int callingUid, ActivityRecord r,
2762            String resultWho, int requestCode, int resultCode, Intent data) {
2763
2764        if (callingUid > 0) {
2765            mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2766                    data, r.getUriPermissionsLocked(), r.userId);
2767        }
2768
2769        if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
2770                + " : who=" + resultWho + " req=" + requestCode
2771                + " res=" + resultCode + " data=" + data);
2772        if (mResumedActivity == r && r.app != null && r.app.thread != null) {
2773            try {
2774                ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2775                list.add(new ResultInfo(resultWho, requestCode,
2776                        resultCode, data));
2777                r.app.thread.scheduleSendResult(r.appToken, list);
2778                return;
2779            } catch (Exception e) {
2780                Slog.w(TAG, "Exception thrown sending result to " + r, e);
2781            }
2782        }
2783
2784        r.addResultLocked(null, resultWho, requestCode, resultCode, data);
2785    }
2786
2787    private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {
2788        if (mStackSupervisor.isFocusedStack(this) && mService.mFocusedActivity == r) {
2789            ActivityRecord next = topRunningActivityLocked();
2790            final String myReason = reason + " adjustFocus";
2791            if (next != r) {
2792                if (next != null && StackId.keepFocusInStackIfPossible(mStackId)) {
2793                    // For freeform, docked, and pinned stacks we always keep the focus within the
2794                    // stack as long as there is a running activity in the stack that we can adjust
2795                    // focus to.
2796                    mService.setFocusedActivityLocked(next, myReason);
2797                    return;
2798                } else {
2799                    final TaskRecord task = r.task;
2800                    if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
2801                        // For non-fullscreen stack, we want to move the focus to the next visible
2802                        // stack to prevent the home screen from moving to the top and obscuring
2803                        // other visible stacks.
2804                        if (!mFullscreen
2805                                && adjustFocusToNextVisibleStackLocked(null, myReason)) {
2806                            return;
2807                        }
2808                        // Move the home stack to the top if this stack is fullscreen or there is no
2809                        // other visible stack.
2810                        if (mStackSupervisor.moveHomeStackTaskToTop(
2811                                task.getTaskToReturnTo(), myReason)) {
2812                            // Activity focus was already adjusted. Nothing else to do...
2813                            return;
2814                        }
2815                    }
2816                }
2817            }
2818
2819            final ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
2820            if (top != null) {
2821                mService.setFocusedActivityLocked(top, myReason);
2822            }
2823        }
2824    }
2825
2826    private boolean adjustFocusToNextVisibleStackLocked(ActivityStack inStack, String reason) {
2827        final ActivityStack stack = (inStack != null) ? inStack : getNextVisibleStackLocked();
2828        final String myReason = reason + " adjustFocusToNextVisibleStack";
2829        if (stack == null) {
2830            return false;
2831        }
2832        final ActivityRecord top = stack.topRunningActivityLocked();
2833        if (top == null) {
2834            return false;
2835        }
2836        mService.setFocusedActivityLocked(top, myReason);
2837        return true;
2838    }
2839
2840    final void stopActivityLocked(ActivityRecord r) {
2841        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
2842        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
2843                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
2844            if (!r.finishing) {
2845                if (!mService.isSleeping()) {
2846                    if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
2847                    if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
2848                            "stop-no-history", false)) {
2849                        // Activity was finished, no need to continue trying to schedule stop.
2850                        adjustFocusedActivityLocked(r, "stopActivityFinished");
2851                        r.resumeKeyDispatchingLocked();
2852                        return;
2853                    }
2854                } else {
2855                    if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
2856                            + " on stop because we're just sleeping");
2857                }
2858            }
2859        }
2860
2861        if (r.app != null && r.app.thread != null) {
2862            adjustFocusedActivityLocked(r, "stopActivity");
2863            r.resumeKeyDispatchingLocked();
2864            try {
2865                r.stopped = false;
2866                if (DEBUG_STATES) Slog.v(TAG_STATES,
2867                        "Moving to STOPPING: " + r + " (stop requested)");
2868                r.state = ActivityState.STOPPING;
2869                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
2870                        "Stopping visible=" + r.visible + " for " + r);
2871                if (!r.visible) {
2872                    mWindowManager.setAppVisibility(r.appToken, false);
2873                }
2874                r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
2875                if (mService.isSleepingOrShuttingDown()) {
2876                    r.setSleeping(true);
2877                }
2878                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
2879                mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
2880            } catch (Exception e) {
2881                // Maybe just ignore exceptions here...  if the process
2882                // has crashed, our death notification will clean things
2883                // up.
2884                Slog.w(TAG, "Exception thrown during pause", e);
2885                // Just in case, assume it to be stopped.
2886                r.stopped = true;
2887                if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
2888                r.state = ActivityState.STOPPED;
2889                if (r.configDestroy) {
2890                    destroyActivityLocked(r, true, "stop-except");
2891                }
2892            }
2893        }
2894    }
2895
2896    /**
2897     * @return Returns true if the activity is being finished, false if for
2898     * some reason it is being left as-is.
2899     */
2900    final boolean requestFinishActivityLocked(IBinder token, int resultCode,
2901            Intent resultData, String reason, boolean oomAdj) {
2902        ActivityRecord r = isInStackLocked(token);
2903        if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
2904                "Finishing activity token=" + token + " r="
2905                + ", result=" + resultCode + ", data=" + resultData
2906                + ", reason=" + reason);
2907        if (r == null) {
2908            return false;
2909        }
2910
2911        finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
2912        return true;
2913    }
2914
2915    final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
2916        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2917            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2918            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2919                ActivityRecord r = activities.get(activityNdx);
2920                if (r.resultTo == self && r.requestCode == requestCode) {
2921                    if ((r.resultWho == null && resultWho == null) ||
2922                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
2923                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
2924                                false);
2925                    }
2926                }
2927            }
2928        }
2929        mService.updateOomAdjLocked();
2930    }
2931
2932    final void finishTopRunningActivityLocked(ProcessRecord app, String reason) {
2933        ActivityRecord r = topRunningActivityLocked();
2934        if (r != null && r.app == app) {
2935            // If the top running activity is from this crashing
2936            // process, then terminate it to avoid getting in a loop.
2937            Slog.w(TAG, "  Force finishing activity "
2938                    + r.intent.getComponent().flattenToShortString());
2939            int taskNdx = mTaskHistory.indexOf(r.task);
2940            int activityNdx = r.task.mActivities.indexOf(r);
2941            finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
2942            // Also terminate any activities below it that aren't yet
2943            // stopped, to avoid a situation where one will get
2944            // re-start our crashing activity once it gets resumed again.
2945            --activityNdx;
2946            if (activityNdx < 0) {
2947                do {
2948                    --taskNdx;
2949                    if (taskNdx < 0) {
2950                        break;
2951                    }
2952                    activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
2953                } while (activityNdx < 0);
2954            }
2955            if (activityNdx >= 0) {
2956                r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
2957                if (r.state == ActivityState.RESUMED
2958                        || r.state == ActivityState.PAUSING
2959                        || r.state == ActivityState.PAUSED) {
2960                    if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
2961                        Slog.w(TAG, "  Force finishing activity "
2962                                + r.intent.getComponent().flattenToShortString());
2963                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
2964                    }
2965                }
2966            }
2967        }
2968    }
2969
2970    final void finishVoiceTask(IVoiceInteractionSession session) {
2971        IBinder sessionBinder = session.asBinder();
2972        boolean didOne = false;
2973        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2974            TaskRecord tr = mTaskHistory.get(taskNdx);
2975            if (tr.voiceSession != null && tr.voiceSession.asBinder() == sessionBinder) {
2976                for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2977                    ActivityRecord r = tr.mActivities.get(activityNdx);
2978                    if (!r.finishing) {
2979                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice",
2980                                false);
2981                        didOne = true;
2982                    }
2983                }
2984            }
2985        }
2986        if (didOne) {
2987            mService.updateOomAdjLocked();
2988        }
2989    }
2990
2991    final boolean finishActivityAffinityLocked(ActivityRecord r) {
2992        ArrayList<ActivityRecord> activities = r.task.mActivities;
2993        for (int index = activities.indexOf(r); index >= 0; --index) {
2994            ActivityRecord cur = activities.get(index);
2995            if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) {
2996                break;
2997            }
2998            finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
2999        }
3000        return true;
3001    }
3002
3003    final void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
3004        // send the result
3005        ActivityRecord resultTo = r.resultTo;
3006        if (resultTo != null) {
3007            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
3008                    + " who=" + r.resultWho + " req=" + r.requestCode
3009                    + " res=" + resultCode + " data=" + resultData);
3010            if (resultTo.userId != r.userId) {
3011                if (resultData != null) {
3012                    resultData.prepareToLeaveUser(r.userId);
3013                }
3014            }
3015            if (r.info.applicationInfo.uid > 0) {
3016                mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
3017                        resultTo.packageName, resultData,
3018                        resultTo.getUriPermissionsLocked(), resultTo.userId);
3019            }
3020            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
3021                                     resultData);
3022            r.resultTo = null;
3023        }
3024        else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
3025
3026        // Make sure this HistoryRecord is not holding on to other resources,
3027        // because clients have remote IPC references to this object so we
3028        // can't assume that will go away and want to avoid circular IPC refs.
3029        r.results = null;
3030        r.pendingResults = null;
3031        r.newIntents = null;
3032        r.icicle = null;
3033    }
3034
3035    /**
3036     * @return Returns true if this activity has been removed from the history
3037     * list, or false if it is still in the list and will be removed later.
3038     */
3039    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
3040            String reason, boolean oomAdj) {
3041        if (r.finishing) {
3042            Slog.w(TAG, "Duplicate finish request for " + r);
3043            return false;
3044        }
3045
3046        r.makeFinishingLocked();
3047        final TaskRecord task = r.task;
3048        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3049                r.userId, System.identityHashCode(r),
3050                task.taskId, r.shortComponentName, reason);
3051        final ArrayList<ActivityRecord> activities = task.mActivities;
3052        final int index = activities.indexOf(r);
3053        if (index < (activities.size() - 1)) {
3054            task.setFrontOfTask();
3055            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
3056                // If the caller asked that this activity (and all above it)
3057                // be cleared when the task is reset, don't lose that information,
3058                // but propagate it up to the next activity.
3059                ActivityRecord next = activities.get(index+1);
3060                next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
3061            }
3062        }
3063
3064        r.pauseKeyDispatchingLocked();
3065
3066        adjustFocusedActivityLocked(r, "finishActivity");
3067
3068        finishActivityResultsLocked(r, resultCode, resultData);
3069
3070        if (mResumedActivity == r) {
3071            boolean endTask = index <= 0;
3072            if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
3073                    "Prepare close transition: finishing " + r);
3074            mWindowManager.prepareAppTransition(endTask
3075                    ? AppTransition.TRANSIT_TASK_CLOSE
3076                    : AppTransition.TRANSIT_ACTIVITY_CLOSE, false);
3077
3078            // Tell window manager to prepare for this one to be removed.
3079            mWindowManager.setAppVisibility(r.appToken, false);
3080
3081            if (mPausingActivity == null) {
3082                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
3083                if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
3084                        "finish() => pause with userLeaving=false");
3085                startPausingLocked(false, false, false, false);
3086            }
3087
3088            if (endTask) {
3089                mStackSupervisor.removeLockedTaskLocked(task);
3090            }
3091        } else if (r.state != ActivityState.PAUSING) {
3092            // If the activity is PAUSING, we will complete the finish once
3093            // it is done pausing; else we can just directly finish it here.
3094            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
3095            return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
3096        } else {
3097            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
3098        }
3099
3100        return false;
3101    }
3102
3103    static final int FINISH_IMMEDIATELY = 0;
3104    static final int FINISH_AFTER_PAUSE = 1;
3105    static final int FINISH_AFTER_VISIBLE = 2;
3106
3107    final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
3108        // First things first: if this activity is currently visible,
3109        // and the resumed activity is not yet visible, then hold off on
3110        // finishing until the resumed one becomes visible.
3111        if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
3112            if (!mStackSupervisor.mStoppingActivities.contains(r)) {
3113                mStackSupervisor.mStoppingActivities.add(r);
3114                if (mStackSupervisor.mStoppingActivities.size() > 3
3115                        || r.frontOfTask && mTaskHistory.size() <= 1) {
3116                    // If we already have a few activities waiting to stop,
3117                    // then give up on things going idle and start clearing
3118                    // them out. Or if r is the last of activity of the last task the stack
3119                    // will be empty and must be cleared immediately.
3120                    mStackSupervisor.scheduleIdleLocked();
3121                } else {
3122                    mStackSupervisor.checkReadyForSleepLocked();
3123                }
3124            }
3125            if (DEBUG_STATES) Slog.v(TAG_STATES,
3126                    "Moving to STOPPING: "+ r + " (finish requested)");
3127            r.state = ActivityState.STOPPING;
3128            if (oomAdj) {
3129                mService.updateOomAdjLocked();
3130            }
3131            return r;
3132        }
3133
3134        // make sure the record is cleaned out of other places.
3135        mStackSupervisor.mStoppingActivities.remove(r);
3136        mStackSupervisor.mGoingToSleepActivities.remove(r);
3137        mStackSupervisor.mWaitingVisibleActivities.remove(r);
3138        if (mResumedActivity == r) {
3139            mResumedActivity = null;
3140        }
3141        final ActivityState prevState = r.state;
3142        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
3143        r.state = ActivityState.FINISHING;
3144
3145        if (mode == FINISH_IMMEDIATELY
3146                || (mode == FINISH_AFTER_PAUSE && prevState == ActivityState.PAUSED)
3147                || prevState == ActivityState.STOPPED
3148                || prevState == ActivityState.INITIALIZING) {
3149            // If this activity is already stopped, we can just finish
3150            // it right now.
3151            r.makeFinishingLocked();
3152            boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
3153            if (activityRemoved) {
3154                mStackSupervisor.resumeTopActivitiesLocked();
3155            }
3156            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
3157                    "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
3158                    " destroy returned removed=" + activityRemoved);
3159            return activityRemoved ? null : r;
3160        }
3161
3162        // Need to go through the full pause cycle to get this
3163        // activity into the stopped state and then finish it.
3164        if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
3165        mStackSupervisor.mFinishingActivities.add(r);
3166        r.resumeKeyDispatchingLocked();
3167        mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
3168        return r;
3169    }
3170
3171    void finishAllActivitiesLocked(boolean immediately) {
3172        boolean noActivitiesInStack = true;
3173        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3174            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3175            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3176                final ActivityRecord r = activities.get(activityNdx);
3177                noActivitiesInStack = false;
3178                if (r.finishing && !immediately) {
3179                    continue;
3180                }
3181                Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r + " immediately");
3182                finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
3183            }
3184        }
3185        if (noActivitiesInStack) {
3186            mActivityContainer.onTaskListEmptyLocked();
3187        }
3188    }
3189
3190    final boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) {
3191        // Basic case: for simple app-centric recents, we need to recreate
3192        // the task if the affinity has changed.
3193        if (srec == null || srec.task.affinity == null ||
3194                !srec.task.affinity.equals(destAffinity)) {
3195            return true;
3196        }
3197        // Document-centric case: an app may be split in to multiple documents;
3198        // they need to re-create their task if this current activity is the root
3199        // of a document, unless simply finishing it will return them to the the
3200        // correct app behind.
3201        if (srec.frontOfTask && srec.task != null && srec.task.getBaseIntent() != null
3202                && srec.task.getBaseIntent().isDocument()) {
3203            // Okay, this activity is at the root of its task.  What to do, what to do...
3204            if (srec.task.getTaskToReturnTo() != ActivityRecord.APPLICATION_ACTIVITY_TYPE) {
3205                // Finishing won't return to an application, so we need to recreate.
3206                return true;
3207            }
3208            // We now need to get the task below it to determine what to do.
3209            int taskIdx = mTaskHistory.indexOf(srec.task);
3210            if (taskIdx <= 0) {
3211                Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec);
3212                return false;
3213            }
3214            if (taskIdx == 0) {
3215                // At the bottom of the stack, nothing to go back to.
3216                return true;
3217            }
3218            TaskRecord prevTask = mTaskHistory.get(taskIdx);
3219            if (!srec.task.affinity.equals(prevTask.affinity)) {
3220                // These are different apps, so need to recreate.
3221                return true;
3222            }
3223        }
3224        return false;
3225    }
3226
3227    final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
3228            Intent resultData) {
3229        final TaskRecord task = srec.task;
3230        final ArrayList<ActivityRecord> activities = task.mActivities;
3231        final int start = activities.indexOf(srec);
3232        if (!mTaskHistory.contains(task) || (start < 0)) {
3233            return false;
3234        }
3235        int finishTo = start - 1;
3236        ActivityRecord parent = finishTo < 0 ? null : activities.get(finishTo);
3237        boolean foundParentInTask = false;
3238        final ComponentName dest = destIntent.getComponent();
3239        if (start > 0 && dest != null) {
3240            for (int i = finishTo; i >= 0; i--) {
3241                ActivityRecord r = activities.get(i);
3242                if (r.info.packageName.equals(dest.getPackageName()) &&
3243                        r.info.name.equals(dest.getClassName())) {
3244                    finishTo = i;
3245                    parent = r;
3246                    foundParentInTask = true;
3247                    break;
3248                }
3249            }
3250        }
3251
3252        IActivityController controller = mService.mController;
3253        if (controller != null) {
3254            ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
3255            if (next != null) {
3256                // ask watcher if this is allowed
3257                boolean resumeOK = true;
3258                try {
3259                    resumeOK = controller.activityResuming(next.packageName);
3260                } catch (RemoteException e) {
3261                    mService.mController = null;
3262                    Watchdog.getInstance().setActivityController(null);
3263                }
3264
3265                if (!resumeOK) {
3266                    return false;
3267                }
3268            }
3269        }
3270        final long origId = Binder.clearCallingIdentity();
3271        for (int i = start; i > finishTo; i--) {
3272            ActivityRecord r = activities.get(i);
3273            requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
3274            // Only return the supplied result for the first activity finished
3275            resultCode = Activity.RESULT_CANCELED;
3276            resultData = null;
3277        }
3278
3279        if (parent != null && foundParentInTask) {
3280            final int parentLaunchMode = parent.info.launchMode;
3281            final int destIntentFlags = destIntent.getFlags();
3282            if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
3283                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
3284                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
3285                    (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3286                parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
3287                        srec.packageName);
3288            } else {
3289                try {
3290                    ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
3291                            destIntent.getComponent(), 0, srec.userId);
3292                    int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent,
3293                            null, aInfo, null, null, parent.appToken, null,
3294                            0, -1, parent.launchedFromUid, parent.launchedFromPackage,
3295                            -1, parent.launchedFromUid, 0, null, false, true, null, null, null);
3296                    foundParentInTask = res == ActivityManager.START_SUCCESS;
3297                } catch (RemoteException e) {
3298                    foundParentInTask = false;
3299                }
3300                requestFinishActivityLocked(parent.appToken, resultCode,
3301                        resultData, "navigate-top", true);
3302            }
3303        }
3304        Binder.restoreCallingIdentity(origId);
3305        return foundParentInTask;
3306    }
3307    /**
3308     * Perform the common clean-up of an activity record.  This is called both
3309     * as part of destroyActivityLocked() (when destroying the client-side
3310     * representation) and cleaning things up as a result of its hosting
3311     * processing going away, in which case there is no remaining client-side
3312     * state to destroy so only the cleanup here is needed.
3313     *
3314     * Note: Call before #removeActivityFromHistoryLocked.
3315     */
3316    final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices,
3317            boolean setState) {
3318        if (mResumedActivity == r) {
3319            mResumedActivity = null;
3320        }
3321        if (mPausingActivity == r) {
3322            mPausingActivity = null;
3323        }
3324        mService.clearFocusedActivity(r);
3325
3326        r.configDestroy = false;
3327        r.frozenBeforeDestroy = false;
3328
3329        if (setState) {
3330            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
3331            r.state = ActivityState.DESTROYED;
3332            if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
3333            r.app = null;
3334        }
3335
3336        // Make sure this record is no longer in the pending finishes list.
3337        // This could happen, for example, if we are trimming activities
3338        // down to the max limit while they are still waiting to finish.
3339        mStackSupervisor.mFinishingActivities.remove(r);
3340        mStackSupervisor.mWaitingVisibleActivities.remove(r);
3341
3342        // Remove any pending results.
3343        if (r.finishing && r.pendingResults != null) {
3344            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
3345                PendingIntentRecord rec = apr.get();
3346                if (rec != null) {
3347                    mService.cancelIntentSenderLocked(rec, false);
3348                }
3349            }
3350            r.pendingResults = null;
3351        }
3352
3353        if (cleanServices) {
3354            cleanUpActivityServicesLocked(r);
3355        }
3356
3357        // Get rid of any pending idle timeouts.
3358        removeTimeoutsForActivityLocked(r);
3359        if (getVisibleBehindActivity() == r) {
3360            mStackSupervisor.requestVisibleBehindLocked(r, false);
3361        }
3362    }
3363
3364    private void removeTimeoutsForActivityLocked(ActivityRecord r) {
3365        mStackSupervisor.removeTimeoutsForActivityLocked(r);
3366        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
3367        mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
3368        mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
3369        r.finishLaunchTickingLocked();
3370    }
3371
3372    private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
3373        mStackSupervisor.removeChildActivityContainers(r);
3374        finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
3375        r.makeFinishingLocked();
3376        if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
3377                "Removing activity " + r + " from stack callers=" + Debug.getCallers(5));
3378
3379        r.takeFromHistory();
3380        removeTimeoutsForActivityLocked(r);
3381        if (DEBUG_STATES) Slog.v(TAG_STATES,
3382                "Moving to DESTROYED: " + r + " (removed from history)");
3383        r.state = ActivityState.DESTROYED;
3384        if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
3385        r.app = null;
3386        mWindowManager.removeAppToken(r.appToken);
3387        if (VALIDATE_TOKENS) {
3388            validateAppTokensLocked();
3389        }
3390        final TaskRecord task = r.task;
3391        if (task != null && task.removeActivity(r)) {
3392            if (DEBUG_STACK) Slog.i(TAG_STACK,
3393                    "removeActivityFromHistoryLocked: last activity removed from " + this);
3394            if (mStackSupervisor.isFocusedStack(this) && task == topTask() &&
3395                    task.isOverHomeStack()) {
3396                mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason);
3397            }
3398            removeTask(task, reason);
3399        }
3400        cleanUpActivityServicesLocked(r);
3401        r.removeUriPermissionsLocked();
3402    }
3403
3404    /**
3405     * Perform clean-up of service connections in an activity record.
3406     */
3407    final void cleanUpActivityServicesLocked(ActivityRecord r) {
3408        // Throw away any services that have been bound by this activity.
3409        if (r.connections != null) {
3410            Iterator<ConnectionRecord> it = r.connections.iterator();
3411            while (it.hasNext()) {
3412                ConnectionRecord c = it.next();
3413                mService.mServices.removeConnectionLocked(c, null, r);
3414            }
3415            r.connections = null;
3416        }
3417    }
3418
3419    final void scheduleDestroyActivities(ProcessRecord owner, String reason) {
3420        Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG);
3421        msg.obj = new ScheduleDestroyArgs(owner, reason);
3422        mHandler.sendMessage(msg);
3423    }
3424
3425    final void destroyActivitiesLocked(ProcessRecord owner, String reason) {
3426        boolean lastIsOpaque = false;
3427        boolean activityRemoved = false;
3428        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3429            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3430            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3431                final ActivityRecord r = activities.get(activityNdx);
3432                if (r.finishing) {
3433                    continue;
3434                }
3435                if (r.fullscreen) {
3436                    lastIsOpaque = true;
3437                }
3438                if (owner != null && r.app != owner) {
3439                    continue;
3440                }
3441                if (!lastIsOpaque) {
3442                    continue;
3443                }
3444                if (r.isDestroyable()) {
3445                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.state
3446                            + " resumed=" + mResumedActivity
3447                            + " pausing=" + mPausingActivity + " for reason " + reason);
3448                    if (destroyActivityLocked(r, true, reason)) {
3449                        activityRemoved = true;
3450                    }
3451                }
3452            }
3453        }
3454        if (activityRemoved) {
3455            mStackSupervisor.resumeTopActivitiesLocked();
3456        }
3457    }
3458
3459    final boolean safelyDestroyActivityLocked(ActivityRecord r, String reason) {
3460        if (r.isDestroyable()) {
3461            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3462                    "Destroying " + r + " in state " + r.state + " resumed=" + mResumedActivity
3463                    + " pausing=" + mPausingActivity + " for reason " + reason);
3464            return destroyActivityLocked(r, true, reason);
3465        }
3466        return false;
3467    }
3468
3469    final int releaseSomeActivitiesLocked(ProcessRecord app, ArraySet<TaskRecord> tasks,
3470            String reason) {
3471        // Iterate over tasks starting at the back (oldest) first.
3472        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
3473        int maxTasks = tasks.size() / 4;
3474        if (maxTasks < 1) {
3475            maxTasks = 1;
3476        }
3477        int numReleased = 0;
3478        for (int taskNdx = 0; taskNdx < mTaskHistory.size() && maxTasks > 0; taskNdx++) {
3479            final TaskRecord task = mTaskHistory.get(taskNdx);
3480            if (!tasks.contains(task)) {
3481                continue;
3482            }
3483            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Looking for activities to release in " + task);
3484            int curNum = 0;
3485            final ArrayList<ActivityRecord> activities = task.mActivities;
3486            for (int actNdx = 0; actNdx < activities.size(); actNdx++) {
3487                final ActivityRecord activity = activities.get(actNdx);
3488                if (activity.app == app && activity.isDestroyable()) {
3489                    if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + activity
3490                            + " in state " + activity.state + " resumed=" + mResumedActivity
3491                            + " pausing=" + mPausingActivity + " for reason " + reason);
3492                    destroyActivityLocked(activity, true, reason);
3493                    if (activities.get(actNdx) != activity) {
3494                        // Was removed from list, back up so we don't miss the next one.
3495                        actNdx--;
3496                    }
3497                    curNum++;
3498                }
3499            }
3500            if (curNum > 0) {
3501                numReleased += curNum;
3502                maxTasks--;
3503                if (mTaskHistory.get(taskNdx) != task) {
3504                    // The entire task got removed, back up so we don't miss the next one.
3505                    taskNdx--;
3506                }
3507            }
3508        }
3509        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE,
3510                "Done releasing: did " + numReleased + " activities");
3511        return numReleased;
3512    }
3513
3514    /**
3515     * Destroy the current CLIENT SIDE instance of an activity.  This may be
3516     * called both when actually finishing an activity, or when performing
3517     * a configuration switch where we destroy the current client-side object
3518     * but then create a new client-side object for this same HistoryRecord.
3519     */
3520    final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
3521        if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(TAG_SWITCH,
3522                "Removing activity from " + reason + ": token=" + r
3523                        + ", app=" + (r.app != null ? r.app.processName : "(null)"));
3524        EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
3525                r.userId, System.identityHashCode(r),
3526                r.task.taskId, r.shortComponentName, reason);
3527
3528        boolean removedFromHistory = false;
3529
3530        cleanUpActivityLocked(r, false, false);
3531
3532        final boolean hadApp = r.app != null;
3533
3534        if (hadApp) {
3535            if (removeFromApp) {
3536                r.app.activities.remove(r);
3537                if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
3538                    mService.mHeavyWeightProcess = null;
3539                    mService.mHandler.sendEmptyMessage(
3540                            ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
3541                }
3542                if (r.app.activities.isEmpty()) {
3543                    // Update any services we are bound to that might care about whether
3544                    // their client may have activities.
3545                    mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
3546                    // No longer have activities, so update LRU list and oom adj.
3547                    mService.updateLruProcessLocked(r.app, false, null);
3548                    mService.updateOomAdjLocked();
3549                }
3550            }
3551
3552            boolean skipDestroy = false;
3553
3554            try {
3555                if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
3556                r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
3557                        r.configChangeFlags);
3558            } catch (Exception e) {
3559                // We can just ignore exceptions here...  if the process
3560                // has crashed, our death notification will clean things
3561                // up.
3562                //Slog.w(TAG, "Exception thrown during finish", e);
3563                if (r.finishing) {
3564                    removeActivityFromHistoryLocked(r, reason + " exceptionInScheduleDestroy");
3565                    removedFromHistory = true;
3566                    skipDestroy = true;
3567                }
3568            }
3569
3570            r.nowVisible = false;
3571
3572            // If the activity is finishing, we need to wait on removing it
3573            // from the list to give it a chance to do its cleanup.  During
3574            // that time it may make calls back with its token so we need to
3575            // be able to find it on the list and so we don't want to remove
3576            // it from the list yet.  Otherwise, we can just immediately put
3577            // it in the destroyed state since we are not removing it from the
3578            // list.
3579            if (r.finishing && !skipDestroy) {
3580                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r
3581                        + " (destroy requested)");
3582                r.state = ActivityState.DESTROYING;
3583                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
3584                mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
3585            } else {
3586                if (DEBUG_STATES) Slog.v(TAG_STATES,
3587                        "Moving to DESTROYED: " + r + " (destroy skipped)");
3588                r.state = ActivityState.DESTROYED;
3589                if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
3590                r.app = null;
3591            }
3592        } else {
3593            // remove this record from the history.
3594            if (r.finishing) {
3595                removeActivityFromHistoryLocked(r, reason + " hadNoApp");
3596                removedFromHistory = true;
3597            } else {
3598                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
3599                r.state = ActivityState.DESTROYED;
3600                if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
3601                r.app = null;
3602            }
3603        }
3604
3605        r.configChangeFlags = 0;
3606
3607        if (!mLRUActivities.remove(r) && hadApp) {
3608            Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
3609        }
3610
3611        return removedFromHistory;
3612    }
3613
3614    final void activityDestroyedLocked(IBinder token, String reason) {
3615        final long origId = Binder.clearCallingIdentity();
3616        try {
3617            ActivityRecord r = ActivityRecord.forTokenLocked(token);
3618            if (r != null) {
3619                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
3620            }
3621            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + r);
3622
3623            if (isInStackLocked(r) != null) {
3624                if (r.state == ActivityState.DESTROYING) {
3625                    cleanUpActivityLocked(r, true, false);
3626                    removeActivityFromHistoryLocked(r, reason);
3627                }
3628            }
3629            mStackSupervisor.resumeTopActivitiesLocked();
3630        } finally {
3631            Binder.restoreCallingIdentity(origId);
3632        }
3633    }
3634
3635    void releaseBackgroundResources(ActivityRecord r) {
3636        if (hasVisibleBehindActivity() &&
3637                !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
3638            if (r == topRunningActivityLocked()) {
3639                // Don't release the top activity if it has requested to run behind the next
3640                // activity.
3641                return;
3642            }
3643            if (DEBUG_STATES) Slog.d(TAG_STATES, "releaseBackgroundResources activtyDisplay=" +
3644                    mActivityContainer.mActivityDisplay + " visibleBehind=" + r + " app=" + r.app +
3645                    " thread=" + r.app.thread);
3646            if (r != null && r.app != null && r.app.thread != null) {
3647                try {
3648                    r.app.thread.scheduleCancelVisibleBehind(r.appToken);
3649                } catch (RemoteException e) {
3650                }
3651                mHandler.sendEmptyMessageDelayed(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG, 500);
3652            } else {
3653                Slog.e(TAG, "releaseBackgroundResources: activity " + r + " no longer running");
3654                backgroundResourcesReleased();
3655            }
3656        }
3657    }
3658
3659    final void backgroundResourcesReleased() {
3660        mHandler.removeMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG);
3661        final ActivityRecord r = getVisibleBehindActivity();
3662        if (r != null) {
3663            mStackSupervisor.mStoppingActivities.add(r);
3664            setVisibleBehindActivity(null);
3665            mStackSupervisor.scheduleIdleTimeoutLocked(null);
3666        }
3667        mStackSupervisor.resumeTopActivitiesLocked();
3668    }
3669
3670    boolean hasVisibleBehindActivity() {
3671        return isAttached() && mActivityContainer.mActivityDisplay.hasVisibleBehindActivity();
3672    }
3673
3674    void setVisibleBehindActivity(ActivityRecord r) {
3675        if (isAttached()) {
3676            mActivityContainer.mActivityDisplay.setVisibleBehindActivity(r);
3677        }
3678    }
3679
3680    ActivityRecord getVisibleBehindActivity() {
3681        return isAttached() ? mActivityContainer.mActivityDisplay.mVisibleBehindActivity : null;
3682    }
3683
3684    private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
3685            ProcessRecord app, String listName) {
3686        int i = list.size();
3687        if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
3688            "Removing app " + app + " from list " + listName + " with " + i + " entries");
3689        while (i > 0) {
3690            i--;
3691            ActivityRecord r = list.get(i);
3692            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r);
3693            if (r.app == app) {
3694                if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!");
3695                list.remove(i);
3696                removeTimeoutsForActivityLocked(r);
3697            }
3698        }
3699    }
3700
3701    boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
3702        removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
3703        removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
3704                "mStoppingActivities");
3705        removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
3706                "mGoingToSleepActivities");
3707        removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
3708                "mWaitingVisibleActivities");
3709        removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
3710                "mFinishingActivities");
3711
3712        boolean hasVisibleActivities = false;
3713
3714        // Clean out the history list.
3715        int i = numActivities();
3716        if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
3717                "Removing app " + app + " from history with " + i + " entries");
3718        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3719            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3720            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3721                final ActivityRecord r = activities.get(activityNdx);
3722                --i;
3723                if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
3724                        "Record #" + i + " " + r + ": app=" + r.app);
3725                if (r.app == app) {
3726                    if (r.visible) {
3727                        hasVisibleActivities = true;
3728                    }
3729                    final boolean remove;
3730                    if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
3731                        // Don't currently have state for the activity, or
3732                        // it is finishing -- always remove it.
3733                        remove = true;
3734                    } else if (r.launchCount > 2 &&
3735                            r.lastLaunchTime > (SystemClock.uptimeMillis()-60000)) {
3736                        // We have launched this activity too many times since it was
3737                        // able to run, so give up and remove it.
3738                        remove = true;
3739                    } else {
3740                        // The process may be gone, but the activity lives on!
3741                        remove = false;
3742                    }
3743                    if (remove) {
3744                        if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
3745                                "Removing activity " + r + " from stack at " + i
3746                                + ": haveState=" + r.haveState
3747                                + " stateNotNeeded=" + r.stateNotNeeded
3748                                + " finishing=" + r.finishing
3749                                + " state=" + r.state + " callers=" + Debug.getCallers(5));
3750                        if (!r.finishing) {
3751                            Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
3752                            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3753                                    r.userId, System.identityHashCode(r),
3754                                    r.task.taskId, r.shortComponentName,
3755                                    "proc died without state saved");
3756                            if (r.state == ActivityState.RESUMED) {
3757                                mService.updateUsageStats(r, false);
3758                            }
3759                        }
3760                    } else {
3761                        // We have the current state for this activity, so
3762                        // it can be restarted later when needed.
3763                        if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
3764                        if (DEBUG_APP) Slog.v(TAG_APP,
3765                                "Clearing app during removeHistory for activity " + r);
3766                        r.app = null;
3767                        r.nowVisible = false;
3768                        if (!r.haveState) {
3769                            if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
3770                                    "App died, clearing saved state of " + r);
3771                            r.icicle = null;
3772                        }
3773                    }
3774                    cleanUpActivityLocked(r, true, true);
3775                    if (remove) {
3776                        removeActivityFromHistoryLocked(r, "appDied");
3777                    }
3778                }
3779            }
3780        }
3781
3782        return hasVisibleActivities;
3783    }
3784
3785    final void updateTransitLocked(int transit, Bundle options) {
3786        if (options != null) {
3787            ActivityRecord r = topRunningActivityLocked();
3788            if (r != null && r.state != ActivityState.RESUMED) {
3789                r.updateOptionsLocked(options);
3790            } else {
3791                ActivityOptions.abort(options);
3792            }
3793        }
3794        mWindowManager.prepareAppTransition(transit, false);
3795    }
3796
3797    void updateTaskMovement(TaskRecord task, boolean toFront) {
3798        if (task.isPersistable) {
3799            task.mLastTimeMoved = System.currentTimeMillis();
3800            // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
3801            // recently will be most negative, tasks sent to the bottom before that will be less
3802            // negative. Similarly for recent tasks moved to the top which will be most positive.
3803            if (!toFront) {
3804                task.mLastTimeMoved *= -1;
3805            }
3806        }
3807        mStackSupervisor.invalidateTaskLayers();
3808    }
3809
3810    void moveHomeStackTaskToTop(int homeStackTaskType) {
3811        final int top = mTaskHistory.size() - 1;
3812        for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
3813            final TaskRecord task = mTaskHistory.get(taskNdx);
3814            if (task.taskType == homeStackTaskType) {
3815                if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
3816                        "moveHomeStackTaskToTop: moving " + task);
3817                mTaskHistory.remove(taskNdx);
3818                mTaskHistory.add(top, task);
3819                updateTaskMovement(task, true);
3820                return;
3821            }
3822        }
3823    }
3824
3825    final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, Bundle options,
3826            AppTimeTracker timeTracker, String reason) {
3827        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
3828
3829        final int numTasks = mTaskHistory.size();
3830        final int index = mTaskHistory.indexOf(tr);
3831        if (numTasks == 0 || index < 0)  {
3832            // nothing to do!
3833            if (noAnimation) {
3834                ActivityOptions.abort(options);
3835            } else {
3836                updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
3837            }
3838            return;
3839        }
3840
3841        if (timeTracker != null) {
3842            // The caller wants a time tracker associated with this task.
3843            for (int i = tr.mActivities.size() - 1; i >= 0; i--) {
3844                tr.mActivities.get(i).appTimeTracker = timeTracker;
3845            }
3846        }
3847
3848        // Shift all activities with this task up to the top
3849        // of the stack, keeping them in the same internal order.
3850        insertTaskAtTop(tr, null);
3851
3852        // Don't refocus if invisible to current user
3853        ActivityRecord top = tr.getTopActivity();
3854        if (!okToShowLocked(top)) {
3855            addRecentActivityLocked(top);
3856            ActivityOptions.abort(options);
3857            return;
3858        }
3859
3860        // Set focus to the top running activity of this stack.
3861        ActivityRecord r = topRunningActivityLocked();
3862        mService.setFocusedActivityLocked(r, reason);
3863
3864        if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
3865        if (noAnimation) {
3866            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
3867            if (r != null) {
3868                mNoAnimActivities.add(r);
3869            }
3870            ActivityOptions.abort(options);
3871        } else {
3872            updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
3873        }
3874
3875        mStackSupervisor.resumeTopActivitiesLocked();
3876        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
3877
3878        if (VALIDATE_TOKENS) {
3879            validateAppTokensLocked();
3880        }
3881    }
3882
3883    /**
3884     * Worker method for rearranging history stack. Implements the function of moving all
3885     * activities for a specific task (gathering them if disjoint) into a single group at the
3886     * bottom of the stack.
3887     *
3888     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
3889     * to premeptively cancel the move.
3890     *
3891     * @param taskId The taskId to collect and move to the bottom.
3892     * @return Returns true if the move completed, false if not.
3893     */
3894    final boolean moveTaskToBackLocked(int taskId) {
3895        final TaskRecord tr = taskForIdLocked(taskId);
3896        if (tr == null) {
3897            Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
3898            return false;
3899        }
3900
3901        Slog.i(TAG, "moveTaskToBack: " + tr);
3902        mStackSupervisor.removeLockedTaskLocked(tr);
3903
3904        // If we have a watcher, preflight the move before committing to it.  First check
3905        // for *other* available tasks, but if none are available, then try again allowing the
3906        // current task to be selected.
3907        if (mStackSupervisor.isFrontStack(this) && mService.mController != null) {
3908            ActivityRecord next = topRunningActivityLocked(null, taskId);
3909            if (next == null) {
3910                next = topRunningActivityLocked(null, 0);
3911            }
3912            if (next != null) {
3913                // ask watcher if this is allowed
3914                boolean moveOK = true;
3915                try {
3916                    moveOK = mService.mController.activityResuming(next.packageName);
3917                } catch (RemoteException e) {
3918                    mService.mController = null;
3919                    Watchdog.getInstance().setActivityController(null);
3920                }
3921                if (!moveOK) {
3922                    return false;
3923                }
3924            }
3925        }
3926
3927        if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
3928
3929        boolean prevIsHome = false;
3930
3931        // If true, we should resume the home activity next if the task we are moving to the
3932        // back is over the home stack. We force to false if the task we are moving to back
3933        // is the home task and we don't want it resumed after moving to the back.
3934        final boolean canGoHome = !tr.isHomeTask() && tr.isOverHomeStack();
3935        if (canGoHome) {
3936            final TaskRecord nextTask = getNextTask(tr);
3937            if (nextTask != null) {
3938                nextTask.setTaskToReturnTo(tr.getTaskToReturnTo());
3939            } else {
3940                prevIsHome = true;
3941            }
3942        }
3943        mTaskHistory.remove(tr);
3944        mTaskHistory.add(0, tr);
3945        updateTaskMovement(tr, false);
3946
3947        // There is an assumption that moving a task to the back moves it behind the home activity.
3948        // We make sure here that some activity in the stack will launch home.
3949        int numTasks = mTaskHistory.size();
3950        for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
3951            final TaskRecord task = mTaskHistory.get(taskNdx);
3952            if (task.isOverHomeStack()) {
3953                break;
3954            }
3955            if (taskNdx == 1) {
3956                // Set the last task before tr to go to home.
3957                task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
3958            }
3959        }
3960
3961        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_TO_BACK, false);
3962        mWindowManager.moveTaskToBottom(taskId);
3963
3964        if (VALIDATE_TOKENS) {
3965            validateAppTokensLocked();
3966        }
3967
3968        final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null;
3969        if (prevIsHome || (task == tr && canGoHome) || (numTasks <= 1 && isOnHomeDisplay())) {
3970            if (!mService.mBooting && !mService.mBooted) {
3971                // Not ready yet!
3972                return false;
3973            }
3974            final int taskToReturnTo = tr.getTaskToReturnTo();
3975            tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
3976            return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null, "moveTaskToBack");
3977        }
3978
3979        mStackSupervisor.resumeTopActivitiesLocked();
3980        return true;
3981    }
3982
3983    static final void logStartActivity(int tag, ActivityRecord r,
3984            TaskRecord task) {
3985        final Uri data = r.intent.getData();
3986        final String strData = data != null ? data.toSafeString() : null;
3987
3988        EventLog.writeEvent(tag,
3989                r.userId, System.identityHashCode(r), task.taskId,
3990                r.shortComponentName, r.intent.getAction(),
3991                r.intent.getType(), strData, r.intent.getFlags());
3992    }
3993
3994    /**
3995     * Make sure the given activity matches the current configuration.  Returns
3996     * false if the activity had to be destroyed.  Returns true if the
3997     * configuration is the same, or the activity will remain running as-is
3998     * for whatever reason.  Ensures the HistoryRecord is updated with the
3999     * correct configuration and all other bookkeeping is handled.
4000     */
4001    final boolean ensureActivityConfigurationLocked(ActivityRecord r, int globalChanges,
4002            boolean preserveWindow) {
4003        if (mConfigWillChange) {
4004            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4005                    "Skipping config check (will change): " + r);
4006            return true;
4007        }
4008
4009        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4010                "Ensuring correct configuration: " + r);
4011
4012        // Short circuit: if the two configurations are the exact same
4013        // object (the common case), then there is nothing to do.
4014        final Configuration newConfig = mService.mConfiguration;
4015        final Configuration taskConfig = r.task.mOverrideConfig;
4016        if (r.configuration == newConfig
4017                && r.taskConfigOverride == taskConfig
4018                && !r.forceNewConfig) {
4019            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4020                    "Configuration unchanged in " + r);
4021            return true;
4022        }
4023
4024        // We don't worry about activities that are finishing.
4025        if (r.finishing) {
4026            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4027                    "Configuration doesn't matter in finishing " + r);
4028            r.stopFreezingScreenLocked(false);
4029            return true;
4030        }
4031
4032        // Okay we now are going to make this activity have the new config.
4033        // But then we need to figure out how it needs to deal with that.
4034        final Configuration oldConfig = r.configuration;
4035        final Configuration oldTaskOverride = r.taskConfigOverride;
4036        r.configuration = newConfig;
4037        r.taskConfigOverride = taskConfig;
4038
4039        int taskChanges = getTaskConfigurationChanges(r, taskConfig, oldTaskOverride);
4040        final int changes = oldConfig.diff(newConfig) | taskChanges;
4041        if (changes == 0 && !r.forceNewConfig) {
4042            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4043                    "Configuration no differences in " + r);
4044            return true;
4045        }
4046
4047        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4048                "Configuration changes for " + r + " ; taskChanges="
4049                        + Configuration.configurationDiffToString(taskChanges) + ", allChanges="
4050                        + Configuration.configurationDiffToString(changes));
4051
4052        // If the activity isn't currently running, just leave the new
4053        // configuration and it will pick that up next time it starts.
4054        if (r.app == null || r.app.thread == null) {
4055            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4056                    "Configuration doesn't matter not running " + r);
4057            r.stopFreezingScreenLocked(false);
4058            r.forceNewConfig = false;
4059            return true;
4060        }
4061
4062        // Figure out how to handle the changes between the configurations.
4063        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4064                "Checking to restart " + r.info.name + ": changed=0x"
4065                + Integer.toHexString(changes) + ", handles=0x"
4066                + Integer.toHexString(r.info.getRealConfigChanged()) + ", newConfig=" + newConfig);
4067
4068        if ((changes&(~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) {
4069            // Aha, the activity isn't handling the change, so DIE DIE DIE.
4070            r.configChangeFlags |= changes;
4071            r.startFreezingScreenLocked(r.app, globalChanges);
4072            r.forceNewConfig = false;
4073            if (r.app == null || r.app.thread == null) {
4074                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4075                        "Config is destroying non-running " + r);
4076                destroyActivityLocked(r, true, "config");
4077            } else if (r.state == ActivityState.PAUSING) {
4078                // A little annoying: we are waiting for this activity to
4079                // finish pausing.  Let's not do anything now, but just
4080                // flag that it needs to be restarted when done pausing.
4081                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4082                        "Config is skipping already pausing " + r);
4083                r.configDestroy = true;
4084                return true;
4085            } else if (r.state == ActivityState.RESUMED) {
4086                // Try to optimize this case: the configuration is changing
4087                // and we need to restart the top, resumed activity.
4088                // Instead of doing the normal handshaking, just say
4089                // "restart!".
4090                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4091                        "Config is relaunching resumed " + r);
4092                relaunchActivityLocked(r, r.configChangeFlags, true,
4093                        preserveWindow && isResizeOnlyChange(changes));
4094                r.configChangeFlags = 0;
4095            } else {
4096                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
4097                        "Config is relaunching non-resumed " + r);
4098                relaunchActivityLocked(r, r.configChangeFlags, false,
4099                        preserveWindow && isResizeOnlyChange(changes));
4100                r.configChangeFlags = 0;
4101            }
4102
4103            // All done...  tell the caller we weren't able to keep this
4104            // activity around.
4105            return false;
4106        }
4107
4108        // Default case: the activity can handle this new configuration, so hand it over.
4109        // NOTE: We only forward the task override configuration as the system level configuration
4110        // changes is always sent to all processes when they happen so it can just use whatever
4111        // system level configuration it last got.
4112        if (r.app != null && r.app.thread != null) {
4113            try {
4114                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending new config to " + r);
4115                r.app.thread.scheduleActivityConfigurationChanged(
4116                        r.appToken, new Configuration(taskConfig));
4117            } catch (RemoteException e) {
4118                // If process died, whatever.
4119            }
4120        }
4121        r.stopFreezingScreenLocked(false);
4122
4123        return true;
4124    }
4125
4126    private int getTaskConfigurationChanges(ActivityRecord record, Configuration taskConfig,
4127            Configuration oldTaskOverride) {
4128        // Determine what has changed.  May be nothing, if this is a config
4129        // that has come back from the app after going idle.  In that case
4130        // we just want to leave the official config object now in the
4131        // activity and do nothing else.
4132        int taskChanges = oldTaskOverride.diff(taskConfig);
4133        // We don't want to use size changes if they don't cross boundaries that are important to
4134        // the app.
4135        if ((taskChanges & ActivityInfo.CONFIG_SCREEN_SIZE) != 0) {
4136            final boolean crosses = record.crossesHorizontalSizeThreshold(
4137                    oldTaskOverride.screenWidthDp, taskConfig.screenWidthDp)
4138                    || record.crossesVerticalSizeThreshold(
4139                    oldTaskOverride.screenHeightDp, taskConfig.screenHeightDp);
4140            if (!crosses) {
4141                taskChanges &= ~ActivityInfo.CONFIG_SCREEN_SIZE;
4142            }
4143        }
4144        if ((taskChanges & ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
4145            final int oldSmallest = oldTaskOverride.smallestScreenWidthDp;
4146            final int newSmallest = taskConfig.smallestScreenWidthDp;
4147            if (!record.crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
4148                taskChanges &= ~ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
4149            }
4150        }
4151        return catchConfigChangesFromUnset(taskConfig, oldTaskOverride, taskChanges);
4152    }
4153
4154    private static int catchConfigChangesFromUnset(Configuration taskConfig,
4155            Configuration oldTaskOverride, int taskChanges) {
4156        if (taskChanges == 0) {
4157            // {@link Configuration#diff} doesn't catch changes from unset values.
4158            // Check for changes we care about.
4159            if (oldTaskOverride.orientation != taskConfig.orientation) {
4160                taskChanges |= ActivityInfo.CONFIG_ORIENTATION;
4161            }
4162            // We want to explicitly track situations where the size configuration goes from
4163            // undefined to defined. We don't care about crossing the threshold in that case,
4164            // because there is no threshold.
4165            final int oldHeight = oldTaskOverride.screenHeightDp;
4166            final int newHeight = taskConfig.screenHeightDp;
4167            final int undefinedHeight = Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
4168            if ((oldHeight == undefinedHeight && newHeight != undefinedHeight)
4169                    || (oldHeight != undefinedHeight && newHeight == undefinedHeight)) {
4170                taskChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
4171            }
4172            final int oldWidth = oldTaskOverride.screenWidthDp;
4173            final int newWidth = taskConfig.screenWidthDp;
4174            final int undefinedWidth = Configuration.SCREEN_WIDTH_DP_UNDEFINED;
4175            if ((oldWidth == undefinedWidth && newWidth != undefinedWidth)
4176                    || (oldWidth != undefinedWidth && newWidth == undefinedWidth)) {
4177                taskChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
4178            }
4179            final int oldSmallest = oldTaskOverride.smallestScreenWidthDp;
4180            final int newSmallest = taskConfig.smallestScreenWidthDp;
4181            final int undefinedSmallest = Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
4182            if ((oldSmallest == undefinedSmallest && newSmallest != undefinedSmallest)
4183                    || (oldSmallest != undefinedSmallest && newSmallest == undefinedSmallest)) {
4184                taskChanges |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
4185            }
4186        }
4187        return taskChanges;
4188    }
4189
4190    private static boolean isResizeOnlyChange(int change) {
4191        return (change & ~(ActivityInfo.CONFIG_SCREEN_SIZE
4192                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) == 0;
4193    }
4194
4195    private void relaunchActivityLocked(
4196            ActivityRecord r, int changes, boolean andResume, boolean preserveWindow) {
4197        if (mService.mSuppressResizeConfigChanges && preserveWindow) {
4198            return;
4199        }
4200
4201        List<ResultInfo> results = null;
4202        List<ReferrerIntent> newIntents = null;
4203        if (andResume) {
4204            results = r.results;
4205            newIntents = r.newIntents;
4206        }
4207        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
4208                "Relaunching: " + r + " with results=" + results + " newIntents=" + newIntents
4209                + " andResume=" + andResume + " preserveWindow=" + preserveWindow);
4210        EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
4211                : EventLogTags.AM_RELAUNCH_ACTIVITY, r.userId, System.identityHashCode(r),
4212                r.task.taskId, r.shortComponentName);
4213
4214        r.startFreezingScreenLocked(r.app, 0);
4215
4216        mStackSupervisor.removeChildActivityContainers(r);
4217
4218        try {
4219            if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
4220                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r);
4221            r.forceNewConfig = false;
4222            r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
4223                    !andResume, new Configuration(mService.mConfiguration),
4224                    new Configuration(r.task.mOverrideConfig), preserveWindow);
4225            // Note: don't need to call pauseIfSleepingLocked() here, because
4226            // the caller will only pass in 'andResume' if this activity is
4227            // currently resumed, which implies we aren't sleeping.
4228        } catch (RemoteException e) {
4229            if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
4230        }
4231
4232        if (andResume) {
4233            r.results = null;
4234            r.newIntents = null;
4235            r.state = ActivityState.RESUMED;
4236        } else {
4237            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4238            r.state = ActivityState.PAUSED;
4239        }
4240    }
4241
4242    boolean willActivityBeVisibleLocked(IBinder token) {
4243        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4244            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4245            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4246                final ActivityRecord r = activities.get(activityNdx);
4247                if (r.appToken == token) {
4248                    return true;
4249                }
4250                if (r.fullscreen && !r.finishing) {
4251                    return false;
4252                }
4253            }
4254        }
4255        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
4256        if (r == null) {
4257            return false;
4258        }
4259        if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false,"
4260                + " would have returned true for r=" + r);
4261        return !r.finishing;
4262    }
4263
4264    void closeSystemDialogsLocked() {
4265        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4266            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4267            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4268                final ActivityRecord r = activities.get(activityNdx);
4269                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
4270                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
4271                }
4272            }
4273        }
4274    }
4275
4276    boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
4277            boolean doit, boolean evenPersistent, int userId) {
4278        boolean didSomething = false;
4279        TaskRecord lastTask = null;
4280        ComponentName homeActivity = null;
4281        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4282            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4283            int numActivities = activities.size();
4284            for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
4285                ActivityRecord r = activities.get(activityNdx);
4286                final boolean sameComponent =
4287                        (r.packageName.equals(packageName) && (filterByClasses == null
4288                                || filterByClasses.contains(r.realActivity.getClassName())))
4289                        || (packageName == null && r.userId == userId);
4290                if ((userId == UserHandle.USER_ALL || r.userId == userId)
4291                        && (sameComponent || r.task == lastTask)
4292                        && (r.app == null || evenPersistent || !r.app.persistent)) {
4293                    if (!doit) {
4294                        if (r.finishing) {
4295                            // If this activity is just finishing, then it is not
4296                            // interesting as far as something to stop.
4297                            continue;
4298                        }
4299                        return true;
4300                    }
4301                    if (r.isHomeActivity()) {
4302                        if (homeActivity != null && homeActivity.equals(r.realActivity)) {
4303                            Slog.i(TAG, "Skip force-stop again " + r);
4304                            continue;
4305                        } else {
4306                            homeActivity = r.realActivity;
4307                        }
4308                    }
4309                    didSomething = true;
4310                    Slog.i(TAG, "  Force finishing activity " + r);
4311                    if (sameComponent) {
4312                        if (r.app != null) {
4313                            r.app.removed = true;
4314                        }
4315                        r.app = null;
4316                    }
4317                    lastTask = r.task;
4318                    if (finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
4319                            true)) {
4320                        // r has been deleted from mActivities, accommodate.
4321                        --numActivities;
4322                        --activityNdx;
4323                    }
4324                }
4325            }
4326        }
4327        return didSomething;
4328    }
4329
4330    void getTasksLocked(List<RunningTaskInfo> list, int callingUid, boolean allowed) {
4331        boolean focusedStack = mStackSupervisor.getFocusedStack() == this;
4332        boolean topTask = true;
4333        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4334            final TaskRecord task = mTaskHistory.get(taskNdx);
4335            if (task.getTopActivity() == null) {
4336                continue;
4337            }
4338            ActivityRecord r = null;
4339            ActivityRecord top = null;
4340            ActivityRecord tmp;
4341            int numActivities = 0;
4342            int numRunning = 0;
4343            final ArrayList<ActivityRecord> activities = task.mActivities;
4344            if (!allowed && !task.isHomeTask() && task.effectiveUid != callingUid) {
4345                continue;
4346            }
4347            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4348                tmp = activities.get(activityNdx);
4349                if (tmp.finishing) {
4350                    continue;
4351                }
4352                r = tmp;
4353
4354                // Initialize state for next task if needed.
4355                if (top == null || (top.state == ActivityState.INITIALIZING)) {
4356                    top = r;
4357                    numActivities = numRunning = 0;
4358                }
4359
4360                // Add 'r' into the current task.
4361                numActivities++;
4362                if (r.app != null && r.app.thread != null) {
4363                    numRunning++;
4364                }
4365
4366                if (DEBUG_ALL) Slog.v(
4367                    TAG, r.intent.getComponent().flattenToShortString()
4368                    + ": task=" + r.task);
4369            }
4370
4371            RunningTaskInfo ci = new RunningTaskInfo();
4372            ci.id = task.taskId;
4373            ci.stackId = mStackId;
4374            ci.baseActivity = r.intent.getComponent();
4375            ci.topActivity = top.intent.getComponent();
4376            ci.lastActiveTime = task.lastActiveTime;
4377            if (focusedStack && topTask) {
4378                // Give the latest time to ensure foreground task can be sorted
4379                // at the first, because lastActiveTime of creating task is 0.
4380                ci.lastActiveTime = System.currentTimeMillis();
4381                topTask = false;
4382            }
4383
4384            if (top.task != null) {
4385                ci.description = top.task.lastDescription;
4386            }
4387            ci.numActivities = numActivities;
4388            ci.numRunning = numRunning;
4389            list.add(ci);
4390        }
4391    }
4392
4393    public void unhandledBackLocked() {
4394        final int top = mTaskHistory.size() - 1;
4395        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Performing unhandledBack(): top activity at " + top);
4396        if (top >= 0) {
4397            final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
4398            int activityTop = activities.size() - 1;
4399            if (activityTop > 0) {
4400                finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
4401                        "unhandled-back", true);
4402            }
4403        }
4404    }
4405
4406    /**
4407     * Reset local parameters because an app's activity died.
4408     * @param app The app of the activity that died.
4409     * @return result from removeHistoryRecordsForAppLocked.
4410     */
4411    boolean handleAppDiedLocked(ProcessRecord app) {
4412        if (mPausingActivity != null && mPausingActivity.app == app) {
4413            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
4414                    "App died while pausing: " + mPausingActivity);
4415            mPausingActivity = null;
4416        }
4417        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4418            mLastPausedActivity = null;
4419            mLastNoHistoryActivity = null;
4420        }
4421
4422        return removeHistoryRecordsForAppLocked(app);
4423    }
4424
4425    void handleAppCrashLocked(ProcessRecord app) {
4426        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4427            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4428            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4429                final ActivityRecord r = activities.get(activityNdx);
4430                if (r.app == app) {
4431                    Slog.w(TAG, "  Force finishing activity "
4432                            + r.intent.getComponent().flattenToShortString());
4433                    // Force the destroy to skip right to removal.
4434                    r.app = null;
4435                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
4436                }
4437            }
4438        }
4439    }
4440
4441    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
4442            boolean dumpClient, String dumpPackage, boolean needSep, String header) {
4443        boolean printed = false;
4444        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4445            final TaskRecord task = mTaskHistory.get(taskNdx);
4446            printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
4447                    mTaskHistory.get(taskNdx).mActivities, "    ", "Hist", true, !dumpAll,
4448                    dumpClient, dumpPackage, needSep, header,
4449                    "    Task id #" + task.taskId + "\n" +
4450                    "    mFullscreen=" + task.mFullscreen + "\n" +
4451                    "    mBounds=" + task.mBounds + "\n" +
4452                    "    mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds);
4453            if (printed) {
4454                header = null;
4455            }
4456        }
4457        return printed;
4458    }
4459
4460    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
4461        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
4462
4463        if ("all".equals(name)) {
4464            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4465                activities.addAll(mTaskHistory.get(taskNdx).mActivities);
4466            }
4467        } else if ("top".equals(name)) {
4468            final int top = mTaskHistory.size() - 1;
4469            if (top >= 0) {
4470                final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities;
4471                int listTop = list.size() - 1;
4472                if (listTop >= 0) {
4473                    activities.add(list.get(listTop));
4474                }
4475            }
4476        } else {
4477            ItemMatcher matcher = new ItemMatcher();
4478            matcher.build(name);
4479
4480            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4481                for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) {
4482                    if (matcher.match(r1, r1.intent.getComponent())) {
4483                        activities.add(r1);
4484                    }
4485                }
4486            }
4487        }
4488
4489        return activities;
4490    }
4491
4492    ActivityRecord restartPackage(String packageName) {
4493        ActivityRecord starting = topRunningActivityLocked();
4494
4495        // All activities that came from the package must be
4496        // restarted as if there was a config change.
4497        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4498            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4499            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4500                final ActivityRecord a = activities.get(activityNdx);
4501                if (a.info.packageName.equals(packageName)) {
4502                    a.forceNewConfig = true;
4503                    if (starting != null && a == starting && a.visible) {
4504                        a.startFreezingScreenLocked(starting.app,
4505                                ActivityInfo.CONFIG_SCREEN_LAYOUT);
4506                    }
4507                }
4508            }
4509        }
4510
4511        return starting;
4512    }
4513
4514    void removeTask(TaskRecord task, String reason) {
4515        removeTask(task, reason, !MOVING);
4516    }
4517
4518    /**
4519     * Removes the input task from this stack.
4520     * @param task to remove.
4521     * @param reason for removal.
4522     * @param moving task to another stack. In the case we are moving we don't want to perform
4523     *               some operations on the task like removing it from window manager or recents.
4524     */
4525    void removeTask(TaskRecord task, String reason, boolean moving) {
4526        if (!moving) {
4527            mStackSupervisor.removeLockedTaskLocked(task);
4528            mWindowManager.removeTask(task.taskId);
4529        }
4530
4531        final ActivityRecord r = mResumedActivity;
4532        if (r != null && r.task == task) {
4533            mResumedActivity = null;
4534        }
4535
4536        final int taskNdx = mTaskHistory.indexOf(task);
4537        final int topTaskNdx = mTaskHistory.size() - 1;
4538        if (task.isOverHomeStack() && taskNdx < topTaskNdx) {
4539            final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1);
4540            if (!nextTask.isOverHomeStack()) {
4541                nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
4542            }
4543        }
4544        mTaskHistory.remove(task);
4545        updateTaskMovement(task, true);
4546
4547        if (!moving && task.mActivities.isEmpty()) {
4548            final boolean isVoiceSession = task.voiceSession != null;
4549            if (isVoiceSession) {
4550                try {
4551                    task.voiceSession.taskFinished(task.intent, task.taskId);
4552                } catch (RemoteException e) {
4553                }
4554            }
4555            if (task.autoRemoveFromRecents() || isVoiceSession) {
4556                // Task creator asked to remove this when done, or this task was a voice
4557                // interaction, so it should not remain on the recent tasks list.
4558                mRecentTasks.remove(task);
4559                task.removedFromRecents();
4560            }
4561        }
4562
4563        if (mTaskHistory.isEmpty()) {
4564            if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
4565            // We only need to adjust focused stack if this stack is in focus.
4566            if (isOnHomeDisplay() && mStackSupervisor.isFocusedStack(this)) {
4567                String myReason = reason + " leftTaskHistoryEmpty";
4568                if (mFullscreen || !adjustFocusToNextVisibleStackLocked(null, myReason)) {
4569                    mStackSupervisor.moveHomeStackToFront(myReason);
4570                }
4571            }
4572            if (mStacks != null) {
4573                mStacks.remove(this);
4574                mStacks.add(0, this);
4575            }
4576            if (!isHomeStack()) {
4577                mActivityContainer.onTaskListEmptyLocked();
4578            }
4579        }
4580
4581        task.stack = null;
4582    }
4583
4584    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
4585            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
4586            boolean toTop) {
4587        TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
4588                voiceInteractor);
4589        // add the task to stack first, mTaskPositioner might need the stack association
4590        addTask(task, toTop, false);
4591        if (mTaskPositioner != null) {
4592            mTaskPositioner.updateDefaultBounds(task, mTaskHistory, info.layout);
4593        } else if (mBounds != null && task.mResizeable) {
4594            task.updateOverrideConfiguration(mBounds);
4595        }
4596        return task;
4597    }
4598
4599    ArrayList<TaskRecord> getAllTasks() {
4600        return new ArrayList<>(mTaskHistory);
4601    }
4602
4603    void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
4604        task.stack = this;
4605        if (toTop) {
4606            insertTaskAtTop(task, null);
4607        } else {
4608            mTaskHistory.add(0, task);
4609            updateTaskMovement(task, false);
4610        }
4611        if (!moving && task.voiceSession != null) {
4612            try {
4613                task.voiceSession.taskStarted(task.intent, task.taskId);
4614            } catch (RemoteException e) {
4615            }
4616        }
4617    }
4618
4619    void positionTask(final TaskRecord task, int position, boolean moving) {
4620        task.stack = this;
4621        insertTaskAtPosition(task, position);
4622        if (!moving && task.voiceSession != null) {
4623            try {
4624                task.voiceSession.taskStarted(task.intent, task.taskId);
4625            } catch (RemoteException e) {
4626            }
4627        }
4628    }
4629
4630    void addConfigOverride(ActivityRecord r, TaskRecord task) {
4631        final Rect bounds = task.getLaunchBounds();
4632        task.updateOverrideConfiguration(bounds);
4633        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
4634                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
4635                (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
4636                r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind,
4637                bounds, task.mOverrideConfig, !r.isHomeActivity());
4638        r.taskConfigOverride = task.mOverrideConfig;
4639    }
4640
4641    void setFocusAndResumeStateIfNeeded(
4642            ActivityRecord r, boolean setFocus, boolean setResume, String reason) {
4643        // If the activity had focus before move focus to this stack.
4644        if (setFocus) {
4645            // If the activity owns the last resumed activity, transfer that together,
4646            // so that we don't resume the same activity again in the new stack.
4647            // Apps may depend on onResume()/onPause() being called in pairs.
4648            if (setResume) {
4649                mResumedActivity = r;
4650                // Move the stack in which we are placing the activity to the front. We don't use
4651                // ActivityManagerService.setFocusedActivityLocked, because if the activity is
4652                // already focused, the call will short-circuit and do nothing.
4653                moveToFront(reason);
4654            } else {
4655                // We need to not only move the stack to the front, but also have the activity
4656                // focused. This will achieve both goals.
4657                mService.setFocusedActivityLocked(r, reason);
4658            }
4659        }
4660    }
4661
4662    /**
4663     * Moves the input activity from its current stack to this one.
4664     * NOTE: The current task of the activity isn't moved to this stack. Instead a new task is
4665     * created on this stack which the activity is added to.
4666     * */
4667    void moveActivityToStack(ActivityRecord r) {
4668        final ActivityStack prevStack = r.task.stack;
4669        if (prevStack.mStackId == mStackId) {
4670            // You are already in the right stack silly...
4671            return;
4672        }
4673
4674        final boolean wasFocused = mStackSupervisor.isFocusedStack(prevStack)
4675                && (mStackSupervisor.topRunningActivityLocked() == r);
4676        final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r);
4677
4678        final TaskRecord task = createTaskRecord(
4679                mStackSupervisor.getNextTaskId(), r.info, r.intent, null, null, true);
4680        r.setTask(task, null);
4681        task.addActivityToTop(r);
4682        setAppTask(r, task);
4683        setFocusAndResumeStateIfNeeded(r, wasFocused, wasResumed, "moveActivityToStack");
4684    }
4685
4686    private void setAppTask(ActivityRecord r, TaskRecord task) {
4687        final Rect bounds = task.getLaunchBounds();
4688        task.updateOverrideConfiguration(bounds);
4689        mWindowManager.setAppTask(
4690                r.appToken, task.taskId, task.getLaunchBounds(), task.mOverrideConfig);
4691        r.taskConfigOverride = task.mOverrideConfig;
4692    }
4693
4694    public int getStackId() {
4695        return mStackId;
4696    }
4697
4698    @Override
4699    public String toString() {
4700        return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
4701                + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
4702    }
4703
4704    void onLockTaskPackagesUpdatedLocked() {
4705        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4706            mTaskHistory.get(taskNdx).setLockTaskAuth();
4707        }
4708    }
4709}
4710