blob: d5a50e7d3d55410888dd33eb269bfb24f440ddf8 [file] [log] [blame]
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner0eea92c2013-05-16 13:35:39 -070019import static com.android.server.am.ActivityManagerService.TAG;
20import static com.android.server.am.ActivityManagerService.localLOGV;
21import static com.android.server.am.ActivityManagerService.DEBUG_CLEANUP;
22import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
23import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
24import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
25import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
26import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
27import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
28import static com.android.server.am.ActivityManagerService.DEBUG_TRANSITION;
29import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
30import static com.android.server.am.ActivityManagerService.DEBUG_VISBILITY;
31import static com.android.server.am.ActivityManagerService.VALIDATE_TOKENS;
32
33import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
34import static com.android.server.am.ActivityStackSupervisor.DEBUG_APP;
35import static com.android.server.am.ActivityStackSupervisor.DEBUG_SAVED_STATE;
Winson Chung376543b2014-05-21 17:43:28 -070036import static com.android.server.am.ActivityStackSupervisor.DEBUG_SCREENSHOTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070037import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
Craig Mautnerde4ef022013-04-07 19:01:33 -070038import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
39
Dianne Hackborn91097de2014-04-04 18:02:06 -070040import android.service.voice.IVoiceInteractionSession;
41import com.android.internal.app.IVoiceInteractor;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070042import com.android.internal.os.BatteryStatsImpl;
Kenny Rootadd58212013-05-07 09:47:34 -070043import com.android.server.Watchdog;
Craig Mautnercae015f2013-02-08 14:31:27 -080044import com.android.server.am.ActivityManagerService.ItemMatcher;
Craig Mautner4a1cb222013-12-04 16:14:06 -080045import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
Craig Mautner4b71aa12012-12-27 17:20:01 -080046import com.android.server.wm.AppTransition;
Craig Mautner05d6272ba2013-02-11 09:39:27 -080047import com.android.server.wm.TaskGroup;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070048import com.android.server.wm.WindowManagerService;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070049
50import android.app.Activity;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070051import android.app.ActivityManager;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -070052import android.app.ActivityOptions;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070053import android.app.AppGlobals;
Craig Mautner05d6272ba2013-02-11 09:39:27 -080054import android.app.IActivityController;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070055import android.app.ResultInfo;
Craig Mautnercae015f2013-02-08 14:31:27 -080056import android.app.ActivityManager.RunningTaskInfo;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070057import android.content.ComponentName;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070058import android.content.Intent;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070059import android.content.pm.ActivityInfo;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070060import android.content.pm.PackageManager;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070061import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080062import android.content.res.Resources;
63import android.graphics.Bitmap;
Santos Cordon73ff7d82013-03-06 17:24:11 -080064import android.net.Uri;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070065import android.os.Binder;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070066import android.os.Bundle;
Craig Mautner329f4122013-11-07 09:10:42 -080067import android.os.Debug;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070068import android.os.Handler;
69import android.os.IBinder;
Zoran Marcetaf958b322012-08-09 20:27:12 +090070import android.os.Looper;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070071import android.os.Message;
Craig Mautnera0026042014-04-23 11:45:37 -070072import android.os.PersistableBundle;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070073import android.os.RemoteException;
74import android.os.SystemClock;
Craig Mautner329f4122013-11-07 09:10:42 -080075import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070076import android.os.UserHandle;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070077import android.util.EventLog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070078import android.util.Slog;
Craig Mautner59c00972012-07-30 12:10:24 -070079import android.view.Display;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070080
Craig Mautnercae015f2013-02-08 14:31:27 -080081import java.io.FileDescriptor;
Craig Mautnercae015f2013-02-08 14:31:27 -080082import java.io.PrintWriter;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070083import java.lang.ref.WeakReference;
84import java.util.ArrayList;
85import java.util.Iterator;
86import java.util.List;
Kenny Roote6585b32013-12-13 12:00:26 -080087import java.util.Objects;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070088
89/**
90 * State and management of a single stack of activities.
91 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070092final class ActivityStack {
Craig Mautner5d9c7be2013-02-15 14:02:56 -080093
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -070094 // Ticks during which we check progress while waiting for an app to launch.
95 static final int LAUNCH_TICK = 500;
96
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070097 // How long we wait until giving up on the last activity to pause. This
98 // is short because it directly impacts the responsiveness of starting the
99 // next activity.
100 static final int PAUSE_TIMEOUT = 500;
101
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700102 // How long we wait for the activity to tell us it has stopped before
103 // giving up. This is a good amount of time because we really need this
104 // from the application in order to get its saved state.
105 static final int STOP_TIMEOUT = 10*1000;
106
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700107 // How long we wait until giving up on an activity telling us it has
108 // finished destroying itself.
109 static final int DESTROY_TIMEOUT = 10*1000;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800110
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700111 // How long until we reset a task when the user returns to it. Currently
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800112 // disabled.
113 static final long ACTIVITY_INACTIVE_RESET_TIME = 0;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800114
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700115 // How long between activity launches that we consider safe to not warn
116 // the user about an unexpected activity being launched on top.
117 static final long START_WARN_TIME = 5*1000;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800118
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700119 // Set to false to disable the preview that is shown while a new activity
120 // is being started.
121 static final boolean SHOW_APP_STARTING_PREVIEW = true;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800122
Craig Mautner5eda9b32013-07-02 11:58:16 -0700123 // How long to wait for all background Activities to redraw following a call to
124 // convertToTranslucent().
125 static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
126
Craig Mautnera61bc652013-10-28 15:43:18 -0700127 static final boolean SCREENSHOT_FORCE_565 = ActivityManager.isLowRamDeviceStatic();
John Reck172e87c2013-10-02 16:55:16 -0700128
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700129 enum ActivityState {
130 INITIALIZING,
131 RESUMED,
132 PAUSING,
133 PAUSED,
134 STOPPING,
135 STOPPED,
136 FINISHING,
137 DESTROYING,
138 DESTROYED
139 }
140
141 final ActivityManagerService mService;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700142 final WindowManagerService mWindowManager;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800143
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700144 /**
145 * The back history of all previous (and possibly still
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800146 * running) activities. It contains #TaskRecord objects.
147 */
148 private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>();
149
150 /**
Dianne Hackbornbe707852011-11-11 14:32:10 -0800151 * Used for validating app tokens with window manager.
152 */
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800153 final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<TaskGroup>();
Dianne Hackbornbe707852011-11-11 14:32:10 -0800154
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700155 /**
156 * List of running activities, sorted by recent usage.
157 * The first entry in the list is the least recently used.
158 * It contains HistoryRecord objects.
159 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700160 final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<ActivityRecord>();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700161
162 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700163 * Animations that for the current transition have requested not to
164 * be considered for the transition animation.
165 */
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700166 final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700167
168 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700169 * When we are in the process of pausing an activity, before starting the
170 * next one, this variable holds the activity that is currently being paused.
171 */
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800172 ActivityRecord mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700173
174 /**
175 * This is the last activity that we put into the paused state. This is
176 * used to determine if we need to do an activity transition while sleeping,
177 * when we normally hold the top activity paused.
178 */
179 ActivityRecord mLastPausedActivity = null;
180
181 /**
Craig Mautner0f922742013-08-06 08:44:42 -0700182 * Activities that specify No History must be removed once the user navigates away from them.
183 * If the device goes to sleep with such an activity in the paused state then we save it here
184 * and finish it later if another activity replaces it on wakeup.
185 */
186 ActivityRecord mLastNoHistoryActivity = null;
187
188 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700189 * Current activity that is resumed, or null if there is none.
190 */
191 ActivityRecord mResumedActivity = null;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800192
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700193 /**
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700194 * This is the last activity that has been started. It is only used to
195 * identify when multiple activities are started at once so that the user
196 * can be warned they may not be in the activity they think they are.
197 */
198 ActivityRecord mLastStartedActivity = null;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800199
Craig Mautner5eda9b32013-07-02 11:58:16 -0700200 // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
201 // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
202 // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
203 // Activity in mTranslucentActivityWaiting is notified via
204 // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
205 // background activity being drawn then the same call will be made with a true value.
206 ActivityRecord mTranslucentActivityWaiting = null;
207 ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
208 new ArrayList<ActivityRecord>();
Craig Mautner233ceee2014-05-09 17:05:11 -0700209 // Options passed from the caller of the convertToTranslucent to the activity that will
210 // appear below it.
211 ActivityOptions mReturningActivityOptions = null;
Craig Mautner5eda9b32013-07-02 11:58:16 -0700212
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700213 /**
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700214 * Set when we know we are going to be calling updateConfiguration()
215 * soon, so want to skip intermediate config checks.
216 */
217 boolean mConfigWillChange;
218
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700219 long mLaunchStartTime = 0;
220 long mFullyDrawnStartTime = 0;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800221
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800222 /**
Craig Mautnerb12428a2012-12-20 16:07:06 -0800223 * Save the most recent screenshot for reuse. This keeps Recents from taking two identical
224 * screenshots, one for the Recents thumbnail and one for the pauseActivity thumbnail.
225 */
226 private ActivityRecord mLastScreenshotActivity = null;
227 private Bitmap mLastScreenshotBitmap = null;
228
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800229 int mThumbnailWidth = -1;
230 int mThumbnailHeight = -1;
231
Craig Mautner858d8a62013-04-23 17:08:34 -0700232 int mCurrentUser;
Amith Yamasani742a6712011-05-04 14:49:28 -0700233
Craig Mautnerc00204b2013-03-05 15:02:14 -0800234 final int mStackId;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800235 final ActivityContainer mActivityContainer;
Craig Mautnere0a38842013-12-16 16:14:02 -0800236 /** The other stacks, in order, on the attached display. Updated at attach/detach time. */
237 ArrayList<ActivityStack> mStacks;
238 /** The attached Display's unique identifier, or -1 if detached */
239 int mDisplayId;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800240
Craig Mautner27084302013-03-25 08:05:25 -0700241 /** Run all ActivityStacks through this */
242 final ActivityStackSupervisor mStackSupervisor;
243
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700244 static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700245 static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
246 static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
247 static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
248 static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
Craig Mautner5eda9b32013-07-02 11:58:16 -0700249 static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700250
251 static class ScheduleDestroyArgs {
252 final ProcessRecord mOwner;
253 final boolean mOomAdj;
254 final String mReason;
255 ScheduleDestroyArgs(ProcessRecord owner, boolean oomAdj, String reason) {
256 mOwner = owner;
257 mOomAdj = oomAdj;
258 mReason = reason;
259 }
260 }
261
Zoran Marcetaf958b322012-08-09 20:27:12 +0900262 final Handler mHandler;
263
264 final class ActivityStackHandler extends Handler {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700265 //public Handler() {
266 // if (localLOGV) Slog.v(TAG, "Handler started!");
267 //}
Craig Mautnerc8143c62013-09-03 12:15:57 -0700268 ActivityStackHandler(Looper looper) {
Zoran Marcetaf958b322012-08-09 20:27:12 +0900269 super(looper);
270 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700271
Zoran Marcetaf958b322012-08-09 20:27:12 +0900272 @Override
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700273 public void handleMessage(Message msg) {
274 switch (msg.what) {
275 case PAUSE_TIMEOUT_MSG: {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800276 ActivityRecord r = (ActivityRecord)msg.obj;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700277 // We don't at this point know if the activity is fullscreen,
278 // so we need to be conservative and assume it isn't.
Dianne Hackbornbe707852011-11-11 14:32:10 -0800279 Slog.w(TAG, "Activity pause timeout for " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700280 synchronized (mService) {
281 if (r.app != null) {
Craig Mautnerf7bfefb2013-05-16 17:30:44 -0700282 mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700283 }
Craig Mautnera0026042014-04-23 11:45:37 -0700284 activityPausedLocked(r.appToken, true, r.persistentState);
Craig Mautnerd2328952013-03-05 12:46:26 -0800285 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700286 } break;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700287 case LAUNCH_TICK_MSG: {
288 ActivityRecord r = (ActivityRecord)msg.obj;
289 synchronized (mService) {
290 if (r.continueLaunchTickingLocked()) {
Craig Mautnerf7bfefb2013-05-16 17:30:44 -0700291 mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700292 }
293 }
294 } break;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700295 case DESTROY_TIMEOUT_MSG: {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800296 ActivityRecord r = (ActivityRecord)msg.obj;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700297 // We don't at this point know if the activity is fullscreen,
298 // so we need to be conservative and assume it isn't.
Dianne Hackbornbe707852011-11-11 14:32:10 -0800299 Slog.w(TAG, "Activity destroy timeout for " + r);
Craig Mautnerd2328952013-03-05 12:46:26 -0800300 synchronized (mService) {
301 activityDestroyedLocked(r != null ? r.appToken : null);
302 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700303 } break;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700304 case STOP_TIMEOUT_MSG: {
305 ActivityRecord r = (ActivityRecord)msg.obj;
306 // We don't at this point know if the activity is fullscreen,
307 // so we need to be conservative and assume it isn't.
308 Slog.w(TAG, "Activity stop timeout for " + r);
309 synchronized (mService) {
310 if (r.isInHistory()) {
311 activityStoppedLocked(r, null, null, null);
312 }
313 }
314 } break;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700315 case DESTROY_ACTIVITIES_MSG: {
316 ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj;
317 synchronized (mService) {
318 destroyActivitiesLocked(args.mOwner, args.mOomAdj, args.mReason);
319 }
Craig Mautner5eda9b32013-07-02 11:58:16 -0700320 } break;
321 case TRANSLUCENT_TIMEOUT_MSG: {
322 synchronized (mService) {
323 notifyActivityDrawnLocked(null);
324 }
325 } break;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700326 }
327 }
Craig Mautner4b71aa12012-12-27 17:20:01 -0800328 }
329
Craig Mautner34b73df2014-01-12 21:11:08 -0800330 int numActivities() {
Craig Mautner000f0022013-02-26 15:04:29 -0800331 int count = 0;
332 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
333 count += mTaskHistory.get(taskNdx).mActivities.size();
334 }
335 return count;
336 }
337
Craig Mautner4a1cb222013-12-04 16:14:06 -0800338 ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer) {
339 mActivityContainer = activityContainer;
340 mStackSupervisor = activityContainer.getOuter();
341 mService = mStackSupervisor.mService;
342 mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
343 mWindowManager = mService.mWindowManager;
344 mStackId = activityContainer.mStackId;
345 mCurrentUser = mService.mCurrentUserId;
Winson Chung376543b2014-05-21 17:43:28 -0700346 // Get the activity screenshot thumbnail dimensions
347 Resources res = mService.mContext.getResources();
Winson Chung2eb4f9c2014-05-22 11:22:41 -0700348 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
349 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700350 }
Craig Mautner5962b122012-10-05 14:45:52 -0700351
Amith Yamasani734983f2014-03-04 16:48:05 -0800352 /**
Kenny Guy2a764942014-04-02 13:29:20 +0100353 * Checks whether the userid is a profile of the current user.
Amith Yamasani734983f2014-03-04 16:48:05 -0800354 */
Kenny Guy2a764942014-04-02 13:29:20 +0100355 private boolean isCurrentProfileLocked(int userId) {
Kenny Guyf4824a02014-04-02 19:17:41 +0100356 if (userId == mCurrentUser) return true;
Kenny Guy2a764942014-04-02 13:29:20 +0100357 for (int i = 0; i < mService.mCurrentProfileIds.length; i++) {
358 if (mService.mCurrentProfileIds[i] == userId) return true;
Amith Yamasani734983f2014-03-04 16:48:05 -0800359 }
360 return false;
361 }
362
363 boolean okToShowLocked(ActivityRecord r) {
Kenny Guy2a764942014-04-02 13:29:20 +0100364 return isCurrentProfileLocked(r.userId)
Craig Mautner5962b122012-10-05 14:45:52 -0700365 || (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0;
366 }
367
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700368 final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800369 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautner6b74cb52013-09-27 17:02:21 -0700370 ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked(notTop);
371 if (r != null) {
372 return r;
Craig Mautner11bf9a52013-02-19 14:08:51 -0800373 }
374 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700375 return null;
376 }
377
378 final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800379 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
380 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautner11bf9a52013-02-19 14:08:51 -0800381 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautnerd74f7d72013-02-26 13:41:02 -0800382 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
383 ActivityRecord r = activities.get(activityNdx);
Amith Yamasani734983f2014-03-04 16:48:05 -0800384 if (!r.finishing && !r.delayedResume && r != notTop && okToShowLocked(r)) {
Craig Mautner11bf9a52013-02-19 14:08:51 -0800385 return r;
386 }
387 }
388 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700389 return null;
390 }
391
392 /**
393 * This is a simplified version of topRunningActivityLocked that provides a number of
394 * optional skip-over modes. It is intended for use with the ActivityController hook only.
Craig Mautner9658b312013-02-28 10:55:59 -0800395 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700396 * @param token If non-null, any history records matching this token will be skipped.
397 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
Craig Mautner9658b312013-02-28 10:55:59 -0800398 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700399 * @return Returns the HistoryRecord of the next activity on the stack.
400 */
401 final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
Craig Mautner11bf9a52013-02-19 14:08:51 -0800402 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
403 TaskRecord task = mTaskHistory.get(taskNdx);
404 if (task.taskId == taskId) {
405 continue;
406 }
407 ArrayList<ActivityRecord> activities = task.mActivities;
408 for (int i = activities.size() - 1; i >= 0; --i) {
409 final ActivityRecord r = activities.get(i);
410 // Note: the taskId check depends on real taskId fields being non-zero
Amith Yamasani734983f2014-03-04 16:48:05 -0800411 if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) {
Craig Mautner11bf9a52013-02-19 14:08:51 -0800412 return r;
413 }
414 }
415 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700416 return null;
417 }
418
Craig Mautner8849a5e2013-04-02 16:41:03 -0700419 final ActivityRecord topActivity() {
420 // Iterate to find the first non-empty task stack. Note that this code can
Craig Mautnerde4ef022013-04-07 19:01:33 -0700421 // be simplified once we stop storing tasks with empty mActivities lists.
Craig Mautner8849a5e2013-04-02 16:41:03 -0700422 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
423 ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
Craig Mautnera61bc652013-10-28 15:43:18 -0700424 final int topActivityNdx = activities.size() - 1;
425 if (topActivityNdx >= 0) {
426 return activities.get(topActivityNdx);
Craig Mautner8849a5e2013-04-02 16:41:03 -0700427 }
428 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700429 return null;
Craig Mautner8849a5e2013-04-02 16:41:03 -0700430 }
431
Craig Mautner9e14d0f2013-05-01 11:26:09 -0700432 final TaskRecord topTask() {
433 final int size = mTaskHistory.size();
434 if (size > 0) {
435 return mTaskHistory.get(size - 1);
436 }
437 return null;
438 }
439
Craig Mautnerd2328952013-03-05 12:46:26 -0800440 TaskRecord taskForIdLocked(int id) {
441 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
442 final TaskRecord task = mTaskHistory.get(taskNdx);
443 if (task.taskId == id) {
444 return task;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800445 }
446 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700447 return null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700448 }
449
Craig Mautnerd2328952013-03-05 12:46:26 -0800450 ActivityRecord isInStackLocked(IBinder token) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800451 final ActivityRecord r = ActivityRecord.forToken(token);
Craig Mautnerd2328952013-03-05 12:46:26 -0800452 if (r != null) {
453 final TaskRecord task = r.task;
454 if (task.mActivities.contains(r) && mTaskHistory.contains(task)) {
455 if (task.stack != this) Slog.w(TAG,
456 "Illegal state! task does not point to stack it is in.");
457 return r;
458 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800459 }
Craig Mautnerd2328952013-03-05 12:46:26 -0800460 return null;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800461 }
462
Craig Mautner2420ead2013-04-01 17:13:20 -0700463 final boolean updateLRUListLocked(ActivityRecord r) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700464 final boolean hadit = mLRUActivities.remove(r);
465 mLRUActivities.add(r);
466 return hadit;
467 }
468
Craig Mautnerde4ef022013-04-07 19:01:33 -0700469 final boolean isHomeStack() {
470 return mStackId == HOME_STACK_ID;
471 }
472
Craig Mautnere0a38842013-12-16 16:14:02 -0800473 final boolean isOnHomeDisplay() {
474 return isAttached() &&
475 mActivityContainer.mActivityDisplay.mDisplayId == Display.DEFAULT_DISPLAY;
476 }
477
478 final void moveToFront() {
479 if (isAttached()) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800480 if (isOnHomeDisplay()) {
481 mStackSupervisor.moveHomeStack(isHomeStack());
482 }
Craig Mautnerfefeef82014-01-10 08:40:23 -0800483 mStacks.remove(this);
484 mStacks.add(this);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800485 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800486 }
487
488 final boolean isAttached() {
489 return mStacks != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800490 }
491
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700492 /**
493 * Returns the top activity in any existing task matching the given
494 * Intent. Returns null if no such task is found.
495 */
Craig Mautnerac6f8432013-07-17 13:24:59 -0700496 ActivityRecord findTaskLocked(ActivityRecord target) {
497 Intent intent = target.intent;
498 ActivityInfo info = target.info;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700499 ComponentName cls = intent.getComponent();
500 if (info.targetActivity != null) {
501 cls = new ComponentName(info.packageName, info.targetActivity);
502 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700503 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
Craig Mautnerd00f4742014-03-12 14:17:26 -0700504 boolean isDocument = intent != null & intent.isDocument();
505 // If documentData is non-null then it must match the existing task data.
506 Uri documentData = isDocument ? intent.getData() : null;
Craig Mautner000f0022013-02-26 15:04:29 -0800507
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700508 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this);
Craig Mautner000f0022013-02-26 15:04:29 -0800509 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
510 final TaskRecord task = mTaskHistory.get(taskNdx);
Dianne Hackborn91097de2014-04-04 18:02:06 -0700511 if (task.voiceSession != null) {
512 // We never match voice sessions; those always run independently.
513 if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": voice session");
514 continue;
515 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700516 if (task.userId != userId) {
517 // Looking for a different task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700518 if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": different user");
Craig Mautnerac6f8432013-07-17 13:24:59 -0700519 continue;
520 }
Craig Mautner000f0022013-02-26 15:04:29 -0800521 final ActivityRecord r = task.getTopActivity();
522 if (r == null || r.finishing || r.userId != userId ||
523 r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700524 if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": mismatch root " + r);
Craig Mautner000f0022013-02-26 15:04:29 -0800525 continue;
526 }
527
Craig Mautnerd00f4742014-03-12 14:17:26 -0700528 final Intent taskIntent = task.intent;
529 final Intent affinityIntent = task.affinityIntent;
530 final boolean taskIsDocument;
531 final Uri taskDocumentData;
532 if (taskIntent != null && taskIntent.isDocument()) {
533 taskIsDocument = true;
534 taskDocumentData = taskIntent.getData();
535 } else if (affinityIntent != null && affinityIntent.isDocument()) {
536 taskIsDocument = true;
537 taskDocumentData = affinityIntent.getData();
538 } else {
539 taskIsDocument = false;
540 taskDocumentData = null;
541 }
542
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700543 if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls="
Craig Mautnerd00f4742014-03-12 14:17:26 -0700544 + taskIntent.getComponent().flattenToShortString()
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700545 + "/aff=" + r.task.affinity + " to new cls="
546 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
Craig Mautnerd00f4742014-03-12 14:17:26 -0700547 if (!isDocument && !taskIsDocument && task.affinity != null) {
548 if (task.affinity.equals(target.taskAffinity)) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700549 if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700550 return r;
551 }
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700552 } else if (taskIntent != null && taskIntent.getComponent() != null &&
553 taskIntent.getComponent().compareTo(cls) == 0 &&
Craig Mautnerd00f4742014-03-12 14:17:26 -0700554 Objects.equals(documentData, taskDocumentData)) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700555 if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
Craig Mautner000f0022013-02-26 15:04:29 -0800556 //dump();
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700557 if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
558 + r.intent);
Craig Mautner000f0022013-02-26 15:04:29 -0800559 return r;
Craig Mautnerffcfcaa2014-06-05 09:54:38 -0700560 } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
561 affinityIntent.getComponent().compareTo(cls) == 0 &&
Craig Mautnerd00f4742014-03-12 14:17:26 -0700562 Objects.equals(documentData, taskDocumentData)) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700563 if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
Craig Mautner000f0022013-02-26 15:04:29 -0800564 //dump();
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700565 if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
566 + r.intent);
Craig Mautner000f0022013-02-26 15:04:29 -0800567 return r;
Dianne Hackborn2a272d42013-10-16 13:34:33 -0700568 } else if (DEBUG_TASKS) {
569 Slog.d(TAG, "Not a match: " + task);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700570 }
571 }
572
573 return null;
574 }
575
576 /**
577 * Returns the first activity (starting from the top of the stack) that
578 * is the same as the given activity. Returns null if no such activity
579 * is found.
580 */
Craig Mautner8849a5e2013-04-02 16:41:03 -0700581 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700582 ComponentName cls = intent.getComponent();
583 if (info.targetActivity != null) {
584 cls = new ComponentName(info.packageName, info.targetActivity);
585 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700586 final int userId = UserHandle.getUserId(info.applicationInfo.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700587
Craig Mautner000f0022013-02-26 15:04:29 -0800588 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700589 TaskRecord task = mTaskHistory.get(taskNdx);
Kenny Guy2a764942014-04-02 13:29:20 +0100590 if (!isCurrentProfileLocked(task.userId)) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700591 return null;
592 }
593 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautner000f0022013-02-26 15:04:29 -0800594 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
595 ActivityRecord r = activities.get(activityNdx);
596 if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700597 //Slog.i(TAG, "Found matching class!");
598 //dump();
599 //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
600 return r;
601 }
602 }
603 }
604
605 return null;
606 }
607
Amith Yamasani742a6712011-05-04 14:49:28 -0700608 /*
Craig Mautnerac6f8432013-07-17 13:24:59 -0700609 * Move the activities around in the stack to bring a user to the foreground.
Amith Yamasani742a6712011-05-04 14:49:28 -0700610 */
Craig Mautner93529a42013-10-04 15:03:13 -0700611 final void switchUserLocked(int userId) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800612 if (mCurrentUser == userId) {
Craig Mautner93529a42013-10-04 15:03:13 -0700613 return;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800614 }
615 mCurrentUser = userId;
616
617 // Move userId's tasks to the top.
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800618 int index = mTaskHistory.size();
Craig Mautnerdb5c4fb2013-11-06 13:55:08 -0800619 for (int i = 0; i < index; ) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700620 TaskRecord task = mTaskHistory.get(i);
Kenny Guy2a764942014-04-02 13:29:20 +0100621 if (isCurrentProfileLocked(task.userId)) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700622 if (DEBUG_TASKS) Slog.d(TAG, "switchUserLocked: stack=" + getStackId() +
623 " moving " + task + " to top");
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800624 mTaskHistory.remove(i);
625 mTaskHistory.add(task);
626 --index;
Craig Mautnerdb5c4fb2013-11-06 13:55:08 -0800627 // Use same value for i.
628 } else {
629 ++i;
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800630 }
631 }
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700632 if (VALIDATE_TOKENS) {
633 validateAppTokensLocked();
634 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700635 }
636
Craig Mautner2420ead2013-04-01 17:13:20 -0700637 void minimalResumeActivityLocked(ActivityRecord r) {
638 r.state = ActivityState.RESUMED;
639 if (DEBUG_STATES) Slog.v(TAG, "Moving to RESUMED: " + r
640 + " (starting new instance)");
641 r.stopped = false;
642 mResumedActivity = r;
643 r.task.touchActiveTime();
644 mService.addRecentTaskLocked(r.task);
645 completeResumeLocked(r);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700646 mStackSupervisor.checkReadyForSleepLocked();
Craig Mautner1e8b8722013-10-14 18:24:52 -0700647 setLaunchTime(r);
Craig Mautner2420ead2013-04-01 17:13:20 -0700648 if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700649 }
650
Dianne Hackborncee04b52013-07-03 17:01:28 -0700651 private void startLaunchTraces() {
652 if (mFullyDrawnStartTime != 0) {
653 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
654 }
655 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching", 0);
656 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
657 }
658
659 private void stopFullyDrawnTraceIfNeeded() {
660 if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
661 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
662 mFullyDrawnStartTime = 0;
663 }
664 }
665
Craig Mautnere79d42682013-04-01 19:01:53 -0700666 void setLaunchTime(ActivityRecord r) {
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700667 if (r.displayStartTime == 0) {
668 r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
669 if (mLaunchStartTime == 0) {
Dianne Hackborncee04b52013-07-03 17:01:28 -0700670 startLaunchTraces();
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700671 mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700672 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700673 } else if (mLaunchStartTime == 0) {
Dianne Hackborncee04b52013-07-03 17:01:28 -0700674 startLaunchTraces();
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700675 mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700676 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700677 }
Craig Mautneraab647e2013-02-28 16:31:36 -0800678
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700679 void clearLaunchTime(ActivityRecord r) {
Craig Mautner5c494542013-09-06 11:59:38 -0700680 // Make sure that there is no activity waiting for this to launch.
681 if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
682 r.displayStartTime = r.fullyDrawnStartTime = 0;
683 } else {
684 mStackSupervisor.removeTimeoutsForActivityLocked(r);
685 mStackSupervisor.scheduleIdleTimeoutLocked(r);
686 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700687 }
688
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800689 void awakeFromSleepingLocked() {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800690 // Ensure activities are no longer sleeping.
Craig Mautnerd44711d2013-02-23 11:24:36 -0800691 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
692 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
693 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
694 activities.get(activityNdx).setSleeping(false);
695 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800696 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800697 }
698
Craig Mautner0eea92c2013-05-16 13:35:39 -0700699 /**
700 * @return true if something must be done before going to sleep.
701 */
702 boolean checkReadyForSleepLocked() {
703 if (mResumedActivity != null) {
704 // Still have something resumed; can't sleep until it is paused.
705 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep needs to pause " + mResumedActivity);
706 if (DEBUG_USER_LEAVING) Slog.v(TAG, "Sleep => pause with userLeaving=false");
707 startPausingLocked(false, true);
708 return true;
709 }
710 if (mPausingActivity != null) {
711 // Still waiting for something to pause; can't sleep yet.
712 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivity);
713 return true;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800714 }
715
Craig Mautner0eea92c2013-05-16 13:35:39 -0700716 return false;
717 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800718
Craig Mautner0eea92c2013-05-16 13:35:39 -0700719 void goToSleep() {
720 ensureActivitiesVisibleLocked(null, 0);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800721
Craig Mautner0eea92c2013-05-16 13:35:39 -0700722 // Make sure any stopped but visible activities are now sleeping.
723 // This ensures that the activity's onStop() is called.
724 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
725 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
726 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
727 final ActivityRecord r = activities.get(activityNdx);
728 if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) {
729 r.setSleeping(true);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800730 }
731 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800732 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700733 }
Craig Mautner59c00972012-07-30 12:10:24 -0700734
Winson Chung376543b2014-05-21 17:43:28 -0700735 /**
736 * This resets the saved state from the last screenshot, forcing a new screenshot to be taken
737 * again when requested.
738 */
739 private void invalidateLastScreenshot() {
740 mLastScreenshotActivity = null;
741 if (mLastScreenshotBitmap != null) {
742 mLastScreenshotBitmap.recycle();
743 }
744 mLastScreenshotBitmap = null;
745 }
746
Dianne Hackbornd2835932010-12-13 16:28:46 -0800747 public final Bitmap screenshotActivities(ActivityRecord who) {
Winson Chung376543b2014-05-21 17:43:28 -0700748 if (DEBUG_SCREENSHOTS) Slog.d(TAG, "screenshotActivities: " + who);
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800749 if (who.noDisplay) {
Winson Chung376543b2014-05-21 17:43:28 -0700750 if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tNo display");
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800751 return null;
752 }
Craig Mautneraab647e2013-02-28 16:31:36 -0800753
Dianne Hackborn4d03fe62013-10-04 17:26:37 -0700754 TaskRecord tr = who.task;
Winson Chung376543b2014-05-21 17:43:28 -0700755 if (mService.getMostRecentTask() != tr || isHomeStack()) {
756 // This is an optimization -- since we never show Home or Recents within Recents itself,
757 // we can just go ahead and skip taking the screenshot if this is the home stack. In
758 // the case where the most recent task is not the task that was supplied, then the stack
759 // has changed, so invalidate the last screenshot().
760 invalidateLastScreenshot();
761 if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tIs Home stack? " + isHomeStack());
Dianne Hackborn4d03fe62013-10-04 17:26:37 -0700762 return null;
763 }
764
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800765 int w = mThumbnailWidth;
766 int h = mThumbnailHeight;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800767 if (w > 0) {
Craig Mautnerb12428a2012-12-20 16:07:06 -0800768 if (who != mLastScreenshotActivity || mLastScreenshotBitmap == null
Dianne Hackborn4d03fe62013-10-04 17:26:37 -0700769 || mLastScreenshotActivity.state == ActivityState.RESUMED
Craig Mautnerb12428a2012-12-20 16:07:06 -0800770 || mLastScreenshotBitmap.getWidth() != w
771 || mLastScreenshotBitmap.getHeight() != h) {
Winson Chung376543b2014-05-21 17:43:28 -0700772 if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tUpdating screenshot");
Craig Mautnerb12428a2012-12-20 16:07:06 -0800773 mLastScreenshotActivity = who;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700774 mLastScreenshotBitmap = mWindowManager.screenshotApplications(
John Reck172e87c2013-10-02 16:55:16 -0700775 who.appToken, Display.DEFAULT_DISPLAY, w, h, SCREENSHOT_FORCE_565);
Craig Mautnerb12428a2012-12-20 16:07:06 -0800776 }
777 if (mLastScreenshotBitmap != null) {
Winson Chung376543b2014-05-21 17:43:28 -0700778 if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tReusing last screenshot");
John Reck172e87c2013-10-02 16:55:16 -0700779 return mLastScreenshotBitmap.copy(mLastScreenshotBitmap.getConfig(), true);
Craig Mautnerb12428a2012-12-20 16:07:06 -0800780 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800781 }
Winson Chung376543b2014-05-21 17:43:28 -0700782 Slog.e(TAG, "Invalid thumbnail dimensions: " + w + "x" + h);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800783 return null;
784 }
785
Craig Mautnercf910b02013-04-23 11:23:27 -0700786 final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800787 if (mPausingActivity != null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800788 Slog.e(TAG, "Trying to pause when pause is already pending for "
Craig Mautnere11f2b72013-04-01 12:37:17 -0700789 + mPausingActivity, new RuntimeException("here").fillInStackTrace());
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800790 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700791 ActivityRecord prev = mResumedActivity;
792 if (prev == null) {
Craig Mautnere11f2b72013-04-01 12:37:17 -0700793 Slog.e(TAG, "Trying to pause when nothing is resumed",
794 new RuntimeException("here").fillInStackTrace());
Craig Mautner05d29032013-05-03 13:40:13 -0700795 mStackSupervisor.resumeTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700796 return;
797 }
Craig Mautnerdf88d732014-01-27 09:21:32 -0800798
799 if (mActivityContainer.mParentActivity == null) {
800 // Top level stack, not a child. Look for child stacks.
801 mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping);
802 }
803
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700804 if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
805 else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700806 mResumedActivity = null;
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800807 mPausingActivity = prev;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700808 mLastPausedActivity = prev;
Craig Mautner0f922742013-08-06 08:44:42 -0700809 mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
810 || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700811 prev.state = ActivityState.PAUSING;
812 prev.task.touchActiveTime();
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700813 clearLaunchTime(prev);
Craig Mautner6f6d56f2013-10-24 16:02:07 -0700814 final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
Craig Mautnerf6ead5d62014-04-24 10:19:20 -0700815 if (next == null || next.noDisplay || next.task != prev.task) {
Craig Mautner6f6d56f2013-10-24 16:02:07 -0700816 prev.updateThumbnail(screenshotActivities(prev), null);
817 }
Dianne Hackborncee04b52013-07-03 17:01:28 -0700818 stopFullyDrawnTraceIfNeeded();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700819
820 mService.updateCpuStats();
Craig Mautneraab647e2013-02-28 16:31:36 -0800821
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700822 if (prev.app != null && prev.app.thread != null) {
823 if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
824 try {
825 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700826 prev.userId, System.identityHashCode(prev),
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700827 prev.shortComponentName);
Jeff Sharkey5782da72013-04-25 14:32:30 -0700828 mService.updateUsageStats(prev, false);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800829 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
830 userLeaving, prev.configChangeFlags);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700831 } catch (Exception e) {
832 // Ignore exception, if process died other code will cleanup.
833 Slog.w(TAG, "Exception thrown during pause", e);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800834 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700835 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -0700836 mLastNoHistoryActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700837 }
838 } else {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800839 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700840 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -0700841 mLastNoHistoryActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700842 }
843
844 // If we are not going to sleep, we want to ensure the device is
845 // awake until the next activity is started.
Craig Mautnere11f2b72013-04-01 12:37:17 -0700846 if (!mService.isSleepingOrShuttingDown()) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700847 mStackSupervisor.acquireLaunchWakelock();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700848 }
849
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800850 if (mPausingActivity != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700851 // Have the window manager pause its key dispatching until the new
852 // activity has started. If we're pausing the activity just because
853 // the screen is being turned off and the UI is sleeping, don't interrupt
854 // key dispatch; the same activity will pick it up again on wakeup.
855 if (!uiSleeping) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800856 prev.pauseKeyDispatchingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700857 } else {
858 if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
859 }
860
861 // Schedule a pause timeout in case the app doesn't respond.
862 // We don't give it much time because this directly impacts the
863 // responsiveness seen by the user.
864 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
865 msg.obj = prev;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700866 prev.pauseTime = SystemClock.uptimeMillis();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700867 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
868 if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
869 } else {
870 // This activity failed to schedule the
871 // pause, so just treat it as being paused now.
872 if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700873 mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700874 }
875 }
Dianne Hackbornad9b32112012-09-17 15:35:01 -0700876
Craig Mautnera0026042014-04-23 11:45:37 -0700877 final void activityPausedLocked(IBinder token, boolean timeout,
878 PersistableBundle persistentState) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700879 if (DEBUG_PAUSE) Slog.v(
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800880 TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700881
Craig Mautnerd2328952013-03-05 12:46:26 -0800882 final ActivityRecord r = isInStackLocked(token);
883 if (r != null) {
884 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
Craig Mautner21d24a22014-04-23 11:45:37 -0700885 if (persistentState != null) {
886 r.persistentState = persistentState;
887 mService.notifyTaskPersisterLocked(r.task, false);
888 }
Craig Mautnerd2328952013-03-05 12:46:26 -0800889 if (mPausingActivity == r) {
890 if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
891 + (timeout ? " (due to timeout)" : " (pause complete)"));
892 r.state = ActivityState.PAUSED;
893 completePauseLocked();
894 } else {
895 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
896 r.userId, System.identityHashCode(r), r.shortComponentName,
897 mPausingActivity != null
898 ? mPausingActivity.shortComponentName : "(none)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700899 }
900 }
901 }
902
Craig Mautnera0026042014-04-23 11:45:37 -0700903 final void activityStoppedLocked(ActivityRecord r, Bundle icicle,
904 PersistableBundle persistentState, CharSequence description) {
Dianne Hackbornb61a0262012-05-14 17:19:18 -0700905 if (r.state != ActivityState.STOPPING) {
906 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + r);
907 mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
908 return;
909 }
Craig Mautner21d24a22014-04-23 11:45:37 -0700910 if (persistentState != null) {
911 r.persistentState = persistentState;
912 mService.notifyTaskPersisterLocked(r.task, false);
913 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700914 if (DEBUG_SAVED_STATE) Slog.i(TAG, "Saving icicle of " + r + ": " + icicle);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700915 if (icicle != null) {
916 // If icicle is null, this is happening due to a timeout, so we
917 // haven't really saved the state.
918 r.icicle = icicle;
919 r.haveState = true;
Dianne Hackborn07981492013-01-28 11:36:23 -0800920 r.launchCount = 0;
Craig Mautnera0026042014-04-23 11:45:37 -0700921 r.updateThumbnail(null, description);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700922 }
923 if (!r.stopped) {
924 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r + " (stop complete)");
925 mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
926 r.stopped = true;
927 r.state = ActivityState.STOPPED;
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700928 if (r.finishing) {
929 r.clearOptionsLocked();
930 } else {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700931 if (r.configDestroy) {
932 destroyActivityLocked(r, true, false, "stop-config");
Craig Mautner05d29032013-05-03 13:40:13 -0700933 mStackSupervisor.resumeTopActivitiesLocked();
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700934 } else {
Dianne Hackborna413dc02013-07-12 12:02:55 -0700935 mStackSupervisor.updatePreviousProcessLocked(r);
Dianne Hackborn50685602011-12-01 12:23:37 -0800936 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700937 }
938 }
939 }
940
Craig Mautnerc8143c62013-09-03 12:15:57 -0700941 private void completePauseLocked() {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800942 ActivityRecord prev = mPausingActivity;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700943 if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
Craig Mautneraab647e2013-02-28 16:31:36 -0800944
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800945 if (prev != null) {
946 if (prev.finishing) {
947 if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700948 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800949 } else if (prev.app != null) {
950 if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
951 if (prev.waitingVisible) {
952 prev.waitingVisible = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700953 mStackSupervisor.mWaitingVisibleActivities.remove(prev);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800954 if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
955 TAG, "Complete pause, no longer waiting: " + prev);
Dianne Hackborncbb722e2012-02-07 18:33:49 -0800956 }
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800957 if (prev.configDestroy) {
958 // The previous is being paused because the configuration
959 // is changing, which means it is actually stopping...
960 // To juggle the fact that we are also starting a new
961 // instance right now, we need to first completely stop
962 // the current instance before starting the new one.
963 if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
964 destroyActivityLocked(prev, true, false, "pause-config");
965 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700966 mStackSupervisor.mStoppingActivities.add(prev);
Craig Mautner29219d92013-04-16 20:19:12 -0700967 if (mStackSupervisor.mStoppingActivities.size() > 3 ||
968 prev.frontOfTask && mTaskHistory.size() <= 1) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800969 // If we already have a few activities waiting to stop,
970 // then give up on things going idle and start clearing
Craig Mautner29219d92013-04-16 20:19:12 -0700971 // them out. Or if r is the last of activity of the last task the stack
972 // will be empty and must be cleared immediately.
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800973 if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
Craig Mautnerf3333272013-04-22 10:55:53 -0700974 mStackSupervisor.scheduleIdleLocked();
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800975 } else {
Craig Mautner0eea92c2013-05-16 13:35:39 -0700976 mStackSupervisor.checkReadyForSleepLocked();
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800977 }
978 }
979 } else {
980 if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
981 prev = null;
Dianne Hackborncbb722e2012-02-07 18:33:49 -0800982 }
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800983 mPausingActivity = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700984 }
Dianne Hackborncbb722e2012-02-07 18:33:49 -0800985
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700986 final ActivityStack topStack = mStackSupervisor.getFocusedStack();
Craig Mautnere11f2b72013-04-01 12:37:17 -0700987 if (!mService.isSleepingOrShuttingDown()) {
Craig Mautner05d29032013-05-03 13:40:13 -0700988 mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -0800989 } else {
Craig Mautner0eea92c2013-05-16 13:35:39 -0700990 mStackSupervisor.checkReadyForSleepLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700991 ActivityRecord top = topStack.topRunningActivityLocked(null);
Dianne Hackborncc5a0552012-10-01 16:32:39 -0700992 if (top == null || (prev != null && top != prev)) {
993 // If there are no more activities available to run,
994 // do resume anyway to start something. Also if the top
995 // activity on the stack is not the just paused activity,
996 // we need to go ahead and resume it to ensure we complete
997 // an in-flight app switch.
Craig Mautner05d29032013-05-03 13:40:13 -0700998 mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
Dianne Hackborn42e620c2012-06-24 13:20:51 -0700999 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001000 }
Craig Mautneraab647e2013-02-28 16:31:36 -08001001
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001002 if (prev != null) {
1003 prev.resumeKeyDispatchingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001004
Craig Mautner525f3d92013-05-07 14:01:50 -07001005 if (prev.app != null && prev.cpuTimeAtResume > 0
1006 && mService.mBatteryStatsService.isOnBattery()) {
1007 long diff;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001008 synchronized (mService.mProcessCpuThread) {
1009 diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
Craig Mautner525f3d92013-05-07 14:01:50 -07001010 - prev.cpuTimeAtResume;
1011 }
1012 if (diff > 0) {
1013 BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
1014 synchronized (bsi) {
1015 BatteryStatsImpl.Uid.Proc ps =
1016 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
Dianne Hackbornd2932242013-08-05 18:18:42 -07001017 prev.info.packageName);
Craig Mautner525f3d92013-05-07 14:01:50 -07001018 if (ps != null) {
1019 ps.addForegroundTimeLocked(diff);
1020 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001021 }
1022 }
1023 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001024 prev.cpuTimeAtResume = 0; // reset it
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001025 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001026 }
1027
1028 /**
1029 * Once we know that we have asked an application to put an activity in
1030 * the resumed state (either by launching it or explicitly telling it),
1031 * this function updates the rest of our state to match that fact.
1032 */
Craig Mautner525f3d92013-05-07 14:01:50 -07001033 private void completeResumeLocked(ActivityRecord next) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001034 next.idle = false;
1035 next.results = null;
1036 next.newIntents = null;
Craig Mautner07566322013-09-26 16:42:55 -07001037 if (next.nowVisible) {
1038 // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
1039 mStackSupervisor.dismissKeyguard();
1040 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001041
1042 // schedule an idle timeout in case the app doesn't do it for us.
Craig Mautnerf3333272013-04-22 10:55:53 -07001043 mStackSupervisor.scheduleIdleTimeoutLocked(next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001044
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001045 mStackSupervisor.reportResumedActivityLocked(next);
1046
1047 next.resumeKeyDispatchingLocked();
1048 mNoAnimActivities.clear();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001049
1050 // Mark the point when the activity is resuming
1051 // TODO: To be more accurate, the mark should be before the onCreate,
1052 // not after the onResume. But for subsequent starts, onResume is fine.
1053 if (next.app != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001054 synchronized (mService.mProcessCpuThread) {
1055 next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001056 }
1057 } else {
1058 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
1059 }
Winson Chung376543b2014-05-21 17:43:28 -07001060
1061 // If we are resuming the activity that we had last screenshotted, then we know it will be
1062 // updated, so invalidate the last screenshot to ensure we take a fresh one when requested
1063 if (next == mLastScreenshotActivity) {
1064 invalidateLastScreenshot();
1065 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001066 }
1067
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001068 /**
1069 * Determine if home should be visible below the passed record.
1070 * @param record activity we are querying for.
1071 * @return true if home is visible below the passed activity, false otherwise.
1072 */
1073 boolean isActivityOverHome(ActivityRecord record) {
1074 // Start at record and go down, look for either home or a visible fullscreen activity.
1075 final TaskRecord recordTask = record.task;
1076 for (int taskNdx = mTaskHistory.indexOf(recordTask); taskNdx >= 0; --taskNdx) {
1077 TaskRecord task = mTaskHistory.get(taskNdx);
1078 final ArrayList<ActivityRecord> activities = task.mActivities;
1079 final int startNdx =
1080 task == recordTask ? activities.indexOf(record) : activities.size() - 1;
1081 for (int activityNdx = startNdx; activityNdx >= 0; --activityNdx) {
1082 final ActivityRecord r = activities.get(activityNdx);
1083 if (r.isHomeActivity()) {
1084 return true;
1085 }
1086 if (!r.finishing && r.fullscreen) {
1087 // Passed activity is over a fullscreen activity.
1088 return false;
1089 }
1090 }
1091 if (task.mOnTopOfHome) {
1092 // Got to the bottom of a task on top of home without finding a visible fullscreen
1093 // activity. Home is visible.
1094 return true;
1095 }
1096 }
1097 // Got to the bottom of this stack and still don't know. If this is over the home stack
1098 // then record is over home. May not work if we ever get more than two layers.
1099 return mStackSupervisor.isFrontStack(this);
1100 }
1101
Craig Mautnere3a00d72014-04-16 08:31:19 -07001102 private void setVisibile(ActivityRecord r, boolean visible) {
1103 r.visible = visible;
1104 mWindowManager.setAppVisibility(r.appToken, visible);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07001105 final ArrayList<ActivityContainer> containers = r.mChildContainers;
Craig Mautnere3a00d72014-04-16 08:31:19 -07001106 for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07001107 ActivityContainer container = containers.get(containerNdx);
Craig Mautnere3a00d72014-04-16 08:31:19 -07001108 container.setVisible(visible);
1109 }
1110 }
1111
Jose Lima7ba71252014-04-30 12:59:27 -07001112 // Checks if any of the stacks above this one has a fullscreen activity behind it.
1113 // If so, this stack is hidden, otherwise it is visible.
1114 private boolean isStackVisible() {
1115 if (!isAttached()) {
1116 return false;
1117 }
1118
1119 if (mStackSupervisor.isFrontStack(this)) {
1120 return true;
1121 }
1122
Jose Lima729cb232014-05-05 15:59:40 -07001123 /**
1124 * Start at the task above this one and go up, looking for a visible
1125 * fullscreen activity, or a translucent activity that requested the
1126 * wallpaper to be shown behind it.
1127 */
Jose Lima7ba71252014-04-30 12:59:27 -07001128 for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
1129 final ArrayList<TaskRecord> tasks = mStacks.get(i).getAllTasks();
1130 for (int taskNdx = 0; taskNdx < tasks.size(); taskNdx++) {
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001131 final ArrayList<ActivityRecord> activities = tasks.get(taskNdx).mActivities;
Jose Lima7ba71252014-04-30 12:59:27 -07001132 for (int activityNdx = 0; activityNdx < activities.size(); activityNdx++) {
1133 final ActivityRecord r = activities.get(activityNdx);
Jose Lima729cb232014-05-05 15:59:40 -07001134
1135 // Conditions for an activity to obscure the stack we're
1136 // examining:
1137 // 1. Not Finishing AND Visible AND:
1138 // 2. Either:
1139 // - Full Screen Activity OR
1140 // - On top of Home and our stack is NOT home
1141 if (!r.finishing && r.visible && (r.fullscreen ||
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001142 (!isHomeStack() && r.frontOfTask && tasks.get(taskNdx).mOnTopOfHome))) {
Jose Lima7ba71252014-04-30 12:59:27 -07001143 return false;
1144 }
1145 }
1146 }
1147 }
1148
1149 return true;
1150 }
1151
Jose Lima729cb232014-05-05 15:59:40 -07001152 final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
1153 ActivityRecord r = topRunningActivityLocked(null);
1154 if (r != null) {
1155 ensureActivitiesVisibleLocked(r, starting, null, configChanges);
1156 }
1157 }
1158
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001159 /**
1160 * Make sure that all activities that need to be visible (that is, they
1161 * currently can be seen by the user) actually are.
1162 */
Jose Lima729cb232014-05-05 15:59:40 -07001163 final void ensureActivitiesVisibleLocked(ActivityRecord top, ActivityRecord starting,
1164 String onlyThisProcess, int configChanges) {
Craig Mautnera7f2bd42013-10-15 16:13:50 -07001165 if (DEBUG_VISBILITY) Slog.v(
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001166 TAG, "ensureActivitiesVisible behind " + top
1167 + " configChanges=0x" + Integer.toHexString(configChanges));
1168
Craig Mautner5eda9b32013-07-02 11:58:16 -07001169 if (mTranslucentActivityWaiting != top) {
1170 mUndrawnActivitiesBelowTopTranslucent.clear();
1171 if (mTranslucentActivityWaiting != null) {
1172 // Call the callback with a timeout indication.
1173 notifyActivityDrawnLocked(null);
1174 mTranslucentActivityWaiting = null;
1175 }
1176 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1177 }
1178
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001179 // If the top activity is not fullscreen, then we need to
1180 // make sure any activities under it are now visible.
Craig Mautnerd44711d2013-02-23 11:24:36 -08001181 boolean aboveTop = true;
Jose Lima7ba71252014-04-30 12:59:27 -07001182 boolean behindFullscreen = !isStackVisible();
1183
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001184 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001185 final TaskRecord task = mTaskHistory.get(taskNdx);
1186 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautnerd44711d2013-02-23 11:24:36 -08001187 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1188 final ActivityRecord r = activities.get(activityNdx);
1189 if (r.finishing) {
1190 continue;
1191 }
1192 if (aboveTop && r != top) {
1193 continue;
1194 }
1195 aboveTop = false;
1196 if (!behindFullscreen) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001197 if (DEBUG_VISBILITY) Slog.v(
Craig Mautnerd44711d2013-02-23 11:24:36 -08001198 TAG, "Make visible? " + r + " finishing=" + r.finishing
1199 + " state=" + r.state);
Craig Mautner58547802013-03-05 08:23:53 -08001200
Craig Mautnerd44711d2013-02-23 11:24:36 -08001201 final boolean doThisProcess = onlyThisProcess == null
1202 || onlyThisProcess.equals(r.processName);
1203
1204 // First: if this is not the current activity being started, make
1205 // sure it matches the current configuration.
1206 if (r != starting && doThisProcess) {
1207 ensureActivityConfigurationLocked(r, 0);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001208 }
Craig Mautnerd44711d2013-02-23 11:24:36 -08001209
1210 if (r.app == null || r.app.thread == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001211 if (onlyThisProcess == null || onlyThisProcess.equals(r.processName)) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08001212 // This activity needs to be visible, but isn't even
1213 // running... get it started, but don't resume it
1214 // at this point.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001215 if (DEBUG_VISBILITY) Slog.v(TAG, "Start and freeze screen for " + r);
Craig Mautnerd44711d2013-02-23 11:24:36 -08001216 if (r != starting) {
1217 r.startFreezingScreenLocked(r.app, configChanges);
1218 }
1219 if (!r.visible) {
Craig Mautnera7f2bd42013-10-15 16:13:50 -07001220 if (DEBUG_VISBILITY) Slog.v(
Craig Mautnerd44711d2013-02-23 11:24:36 -08001221 TAG, "Starting and making visible: " + r);
Craig Mautnere3a00d72014-04-16 08:31:19 -07001222 setVisibile(r, true);
Craig Mautnerd44711d2013-02-23 11:24:36 -08001223 }
1224 if (r != starting) {
George Mount2c92c972014-03-20 09:38:23 -07001225 mStackSupervisor.startSpecificActivityLocked(r, false, false);
Craig Mautnerd44711d2013-02-23 11:24:36 -08001226 }
1227 }
1228
1229 } else if (r.visible) {
1230 // If this activity is already visible, then there is nothing
1231 // else to do here.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001232 if (DEBUG_VISBILITY) Slog.v(TAG, "Skipping: already visible at " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001233 r.stopFreezingScreenLocked(false);
Craig Mautnerd44711d2013-02-23 11:24:36 -08001234
1235 } else if (onlyThisProcess == null) {
1236 // This activity is not currently visible, but is running.
1237 // Tell it to become visible.
1238 r.visible = true;
1239 if (r.state != ActivityState.RESUMED && r != starting) {
1240 // If this activity is paused, tell it
1241 // to now show its window.
Craig Mautnera7f2bd42013-10-15 16:13:50 -07001242 if (DEBUG_VISBILITY) Slog.v(
Craig Mautnerd44711d2013-02-23 11:24:36 -08001243 TAG, "Making visible and scheduling visibility: " + r);
1244 try {
Craig Mautner5eda9b32013-07-02 11:58:16 -07001245 if (mTranslucentActivityWaiting != null) {
Craig Mautner233ceee2014-05-09 17:05:11 -07001246 r.updateOptionsLocked(mReturningActivityOptions);
Craig Mautner5eda9b32013-07-02 11:58:16 -07001247 mUndrawnActivitiesBelowTopTranslucent.add(r);
1248 }
Craig Mautnere3a00d72014-04-16 08:31:19 -07001249 setVisibile(r, true);
Craig Mautnerd44711d2013-02-23 11:24:36 -08001250 r.sleeping = false;
1251 r.app.pendingUiClean = true;
1252 r.app.thread.scheduleWindowVisibility(r.appToken, true);
1253 r.stopFreezingScreenLocked(false);
1254 } catch (Exception e) {
1255 // Just skip on any failure; we'll make it
1256 // visible when it next restarts.
1257 Slog.w(TAG, "Exception thrown making visibile: "
1258 + r.intent.getComponent(), e);
1259 }
1260 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001261 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001262
Craig Mautnerd44711d2013-02-23 11:24:36 -08001263 // Aggregate current change flags.
1264 configChanges |= r.configChangeFlags;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001265
Craig Mautnerd44711d2013-02-23 11:24:36 -08001266 if (r.fullscreen) {
1267 // At this point, nothing else needs to be shown
Craig Mautner580ea812013-04-25 12:58:38 -07001268 if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
1269 behindFullscreen = true;
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001270 } else if (!isHomeStack() && r.frontOfTask && task.mOnTopOfHome) {
Craig Mautner39e1c5a2013-10-23 15:14:22 -07001271 if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
Jose Lima729cb232014-05-05 15:59:40 -07001272 behindFullscreen = true;
Craig Mautnerd44711d2013-02-23 11:24:36 -08001273 }
1274 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001275 if (DEBUG_VISBILITY) Slog.v(
1276 TAG, "Make invisible? " + r + " finishing=" + r.finishing
1277 + " state=" + r.state
1278 + " behindFullscreen=" + behindFullscreen);
1279 // Now for any activities that aren't visible to the user, make
1280 // sure they no longer are keeping the screen frozen.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001281 if (r.visible) {
Craig Mautnera7f2bd42013-10-15 16:13:50 -07001282 if (DEBUG_VISBILITY) Slog.v(TAG, "Making invisible: " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001283 try {
Craig Mautnere3a00d72014-04-16 08:31:19 -07001284 setVisibile(r, false);
Craig Mautner4addfc52013-06-25 08:05:45 -07001285 switch (r.state) {
1286 case STOPPING:
1287 case STOPPED:
1288 if (r.app != null && r.app.thread != null) {
1289 if (DEBUG_VISBILITY) Slog.v(
1290 TAG, "Scheduling invisibility: " + r);
1291 r.app.thread.scheduleWindowVisibility(r.appToken, false);
1292 }
1293 break;
1294
1295 case INITIALIZING:
1296 case RESUMED:
1297 case PAUSING:
1298 case PAUSED:
Craig Mautner88176102013-07-22 12:57:51 -07001299 // This case created for transitioning activities from
1300 // translucent to opaque {@link Activity#convertToOpaque}.
Craig Mautnere5273b42013-09-09 12:57:47 -07001301 if (!mStackSupervisor.mStoppingActivities.contains(r)) {
1302 mStackSupervisor.mStoppingActivities.add(r);
1303 }
1304 mStackSupervisor.scheduleIdleLocked();
Craig Mautner4addfc52013-06-25 08:05:45 -07001305 break;
1306
1307 default:
1308 break;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001309 }
1310 } catch (Exception e) {
1311 // Just skip on any failure; we'll make it
1312 // visible when it next restarts.
1313 Slog.w(TAG, "Exception thrown making hidden: "
1314 + r.intent.getComponent(), e);
1315 }
1316 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001317 if (DEBUG_VISBILITY) Slog.v(TAG, "Already invisible: " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001318 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001319 }
1320 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001321 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001322 }
Craig Mautner58547802013-03-05 08:23:53 -08001323
Craig Mautner233ceee2014-05-09 17:05:11 -07001324 void convertToTranslucent(ActivityRecord r, ActivityOptions options) {
Craig Mautner5eda9b32013-07-02 11:58:16 -07001325 mTranslucentActivityWaiting = r;
1326 mUndrawnActivitiesBelowTopTranslucent.clear();
Craig Mautner233ceee2014-05-09 17:05:11 -07001327 mReturningActivityOptions = options;
Craig Mautner5eda9b32013-07-02 11:58:16 -07001328 mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
1329 }
1330
1331 /**
1332 * Called as activities below the top translucent activity are redrawn. When the last one is
1333 * redrawn notify the top activity by calling
1334 * {@link Activity#onTranslucentConversionComplete}.
1335 *
1336 * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
1337 * occurred and the activity will be notified immediately.
1338 */
1339 void notifyActivityDrawnLocked(ActivityRecord r) {
Craig Mautner6985bad2014-04-21 15:22:06 -07001340 mActivityContainer.setDrawn();
Craig Mautner5eda9b32013-07-02 11:58:16 -07001341 if ((r == null)
1342 || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
1343 mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
1344 // The last undrawn activity below the top has just been drawn. If there is an
1345 // opaque activity at the top, notify it that it can become translucent safely now.
1346 final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
1347 mTranslucentActivityWaiting = null;
1348 mUndrawnActivitiesBelowTopTranslucent.clear();
1349 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1350
Craig Mautner71dd1b62014-02-18 15:48:52 -08001351 if (waitingActivity != null) {
1352 mWindowManager.setWindowOpaque(waitingActivity.appToken, false);
1353 if (waitingActivity.app != null && waitingActivity.app.thread != null) {
1354 try {
1355 waitingActivity.app.thread.scheduleTranslucentConversionComplete(
1356 waitingActivity.appToken, r != null);
1357 } catch (RemoteException e) {
1358 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07001359 }
1360 }
1361 }
1362 }
1363
Craig Mautnera61bc652013-10-28 15:43:18 -07001364 /** If any activities below the top running one are in the INITIALIZING state and they have a
1365 * starting window displayed then remove that starting window. It is possible that the activity
1366 * in this state will never resumed in which case that starting window will be orphaned. */
1367 void cancelInitializingActivities() {
1368 final ActivityRecord topActivity = topRunningActivityLocked(null);
1369 boolean aboveTop = true;
1370 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1371 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1372 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1373 final ActivityRecord r = activities.get(activityNdx);
1374 if (aboveTop) {
1375 if (r == topActivity) {
1376 aboveTop = false;
1377 }
1378 continue;
1379 }
1380
1381 if (r.state == ActivityState.INITIALIZING && r.mStartingWindowShown) {
1382 if (DEBUG_VISBILITY) Slog.w(TAG, "Found orphaned starting window " + r);
1383 r.mStartingWindowShown = false;
1384 mWindowManager.removeAppStartingWindow(r.appToken);
1385 }
1386 }
1387 }
1388 }
1389
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001390 /**
1391 * Ensure that the top activity in the stack is resumed.
1392 *
1393 * @param prev The previously resumed activity, for when in the process
1394 * of pausing; can be null to call from elsewhere.
1395 *
1396 * @return Returns true if something is being resumed, or false if
1397 * nothing happened.
1398 */
1399 final boolean resumeTopActivityLocked(ActivityRecord prev) {
Dianne Hackborn84375872012-06-01 19:03:50 -07001400 return resumeTopActivityLocked(prev, null);
1401 }
1402
1403 final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
Craig Mautner5314a402013-09-26 12:40:16 -07001404 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
1405
Craig Mautnerdf88d732014-01-27 09:21:32 -08001406 ActivityRecord parent = mActivityContainer.mParentActivity;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07001407 if ((parent != null && parent.state != ActivityState.RESUMED) ||
Craig Mautner6985bad2014-04-21 15:22:06 -07001408 !mActivityContainer.isAttached()) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08001409 // Do not resume this stack if its parent is not resumed.
1410 // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
1411 return false;
1412 }
1413
Craig Mautnera61bc652013-10-28 15:43:18 -07001414 cancelInitializingActivities();
1415
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001416 // Find the first activity that is not finishing.
1417 ActivityRecord next = topRunningActivityLocked(null);
1418
1419 // Remember how we'll process this pause/resume situation, and ensure
1420 // that the state is reset however we wind up proceeding.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001421 final boolean userLeaving = mStackSupervisor.mUserLeaving;
1422 mStackSupervisor.mUserLeaving = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001423
1424 if (next == null) {
1425 // There are no more activities! Let's just start up the
1426 // Launcher...
Craig Mautnerde4ef022013-04-07 19:01:33 -07001427 ActivityOptions.abort(options);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001428 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
Craig Mautnercf910b02013-04-23 11:23:27 -07001429 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Craig Mautnere0a38842013-12-16 16:14:02 -08001430 // Only resume home if on home display
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001431 return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001432 }
1433
1434 next.delayedResume = false;
Craig Mautner58547802013-03-05 08:23:53 -08001435
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001436 // If the top activity is the resumed one, nothing to do.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001437 if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
1438 mStackSupervisor.allResumedActivitiesComplete()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001439 // Make sure we have executed any pending transitions, since there
1440 // should be nothing left to do at this point.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001441 mWindowManager.executeAppTransition();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001442 mNoAnimActivities.clear();
Dianne Hackborn84375872012-06-01 19:03:50 -07001443 ActivityOptions.abort(options);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001444 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next);
Craig Mautnercf910b02013-04-23 11:23:27 -07001445 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001446 return false;
1447 }
1448
Craig Mautner525f3d92013-05-07 14:01:50 -07001449 final TaskRecord nextTask = next.task;
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001450 final TaskRecord prevTask = prev != null ? prev.task : null;
bulicccd230712014-05-12 14:34:50 -07001451 if (prevTask != null && prevTask.stack == this &&
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001452 prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) {
Craig Mautnercf910b02013-04-23 11:23:27 -07001453 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Craig Mautner525f3d92013-05-07 14:01:50 -07001454 if (prevTask == nextTask) {
Craig Mautner1aa9d0d3f2013-12-16 15:58:31 -08001455 prevTask.setFrontOfTask();
Craig Mautner525f3d92013-05-07 14:01:50 -07001456 } else if (prevTask != topTask()) {
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001457 // This task is going away but it was supposed to return to the home task.
Craig Mautnere418ecd2013-05-01 17:02:29 -07001458 // Now the task above it has to return to the home task instead.
Craig Mautner525f3d92013-05-07 14:01:50 -07001459 final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001460 mTaskHistory.get(taskNdx).mOnTopOfHome = true;
Craig Mautnere418ecd2013-05-01 17:02:29 -07001461 } else {
Craig Mautnere0a38842013-12-16 16:14:02 -08001462 if (DEBUG_STATES && isOnHomeDisplay()) Slog.d(TAG,
1463 "resumeTopActivityLocked: Launching home next");
1464 // Only resume home if on home display
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001465 return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev);
Craig Mautnere418ecd2013-05-01 17:02:29 -07001466 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001467 }
1468
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001469 // If we are sleeping, and there is no resumed activity, and the top
1470 // activity is paused, well that is the state we want.
Craig Mautner5314a402013-09-26 12:40:16 -07001471 if (mService.isSleepingOrShuttingDown()
p13451dbad2872012-04-18 11:39:23 +09001472 && mLastPausedActivity == next
Craig Mautner5314a402013-09-26 12:40:16 -07001473 && mStackSupervisor.allPausedActivitiesComplete()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001474 // Make sure we have executed any pending transitions, since there
1475 // should be nothing left to do at this point.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001476 mWindowManager.executeAppTransition();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001477 mNoAnimActivities.clear();
Dianne Hackborn84375872012-06-01 19:03:50 -07001478 ActivityOptions.abort(options);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001479 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Going to sleep and all paused");
Craig Mautnercf910b02013-04-23 11:23:27 -07001480 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001481 return false;
1482 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001483
1484 // Make sure that the user who owns this activity is started. If not,
1485 // we will just leave it as is because someone should be bringing
1486 // another user's activities to the top of the stack.
1487 if (mService.mStartedUsers.get(next.userId) == null) {
1488 Slog.w(TAG, "Skipping resume of top activity " + next
1489 + ": user " + next.userId + " is stopped");
Craig Mautnercf910b02013-04-23 11:23:27 -07001490 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001491 return false;
1492 }
1493
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001494 // The activity may be waiting for stop, but that is no longer
1495 // appropriate for it.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001496 mStackSupervisor.mStoppingActivities.remove(next);
Craig Mautner0eea92c2013-05-16 13:35:39 -07001497 mStackSupervisor.mGoingToSleepActivities.remove(next);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001498 next.sleeping = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001499 mStackSupervisor.mWaitingVisibleActivities.remove(next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001500
1501 if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);
1502
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001503 // If we are currently pausing an activity, then don't do anything
1504 // until that is done.
Craig Mautner69ada552013-04-18 13:51:51 -07001505 if (!mStackSupervisor.allPausedActivitiesComplete()) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001506 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG,
1507 "resumeTopActivityLocked: Skip resume: some activity pausing.");
Craig Mautnercf910b02013-04-23 11:23:27 -07001508 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08001509 return false;
1510 }
1511
Dianne Hackborn0dad3642010-09-09 21:25:35 -07001512 // Okay we are now going to start a switch, to 'next'. We may first
1513 // have to pause the current activity, but this is an important point
1514 // where we have decided to go to 'next' so keep track of that.
Dianne Hackborn034093a42010-09-20 22:24:38 -07001515 // XXX "App Redirected" dialog is getting too many false positives
1516 // at this point, so turn off for now.
1517 if (false) {
1518 if (mLastStartedActivity != null && !mLastStartedActivity.finishing) {
1519 long now = SystemClock.uptimeMillis();
1520 final boolean inTime = mLastStartedActivity.startTime != 0
1521 && (mLastStartedActivity.startTime + START_WARN_TIME) >= now;
1522 final int lastUid = mLastStartedActivity.info.applicationInfo.uid;
1523 final int nextUid = next.info.applicationInfo.uid;
1524 if (inTime && lastUid != nextUid
1525 && lastUid != next.launchedFromUid
1526 && mService.checkPermission(
1527 android.Manifest.permission.STOP_APP_SWITCHES,
1528 -1, next.launchedFromUid)
1529 != PackageManager.PERMISSION_GRANTED) {
1530 mService.showLaunchWarningLocked(mLastStartedActivity, next);
1531 } else {
1532 next.startTime = now;
1533 mLastStartedActivity = next;
1534 }
Dianne Hackborn0dad3642010-09-09 21:25:35 -07001535 } else {
Dianne Hackborn034093a42010-09-20 22:24:38 -07001536 next.startTime = SystemClock.uptimeMillis();
Dianne Hackborn0dad3642010-09-09 21:25:35 -07001537 mLastStartedActivity = next;
1538 }
Dianne Hackborn0dad3642010-09-09 21:25:35 -07001539 }
Craig Mautner58547802013-03-05 08:23:53 -08001540
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001541 // We need to start pausing the current activity so the top one
1542 // can be resumed...
Craig Mautner5314a402013-09-26 12:40:16 -07001543 boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);
Craig Mautnereb957862013-04-24 15:34:32 -07001544 if (mResumedActivity != null) {
1545 pausing = true;
1546 startPausingLocked(userLeaving, false);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001547 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
Craig Mautnereb957862013-04-24 15:34:32 -07001548 }
1549 if (pausing) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001550 if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
1551 "resumeTopActivityLocked: Skip resume: need to start pausing");
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001552 // At this point we want to put the upcoming activity's process
1553 // at the top of the LRU list, since we know we will be needing it
1554 // very soon and it would be a waste to let it get killed if it
1555 // happens to be sitting towards the end.
1556 if (next.app != null && next.app.thread != null) {
1557 // No reason to do full oom adj update here; we'll let that
1558 // happen whenever it needs to later.
Dianne Hackborndb926082013-10-31 16:32:44 -07001559 mService.updateLruProcessLocked(next.app, true, null);
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001560 }
Craig Mautnercf910b02013-04-23 11:23:27 -07001561 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001562 return true;
1563 }
1564
Christopher Tated3f175c2012-06-14 14:16:54 -07001565 // If the most recent activity was noHistory but was only stopped rather
1566 // than stopped+finished because the device went to sleep, we need to make
1567 // sure to finish it as we're making a new activity topmost.
Dianne Hackborn91097de2014-04-04 18:02:06 -07001568 if (mService.isSleeping() && mLastNoHistoryActivity != null &&
Craig Mautner0f922742013-08-06 08:44:42 -07001569 !mLastNoHistoryActivity.finishing) {
1570 if (DEBUG_STATES) Slog.d(TAG, "no-history finish of " + mLastNoHistoryActivity +
1571 " on new resume");
1572 requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
1573 null, "no-history", false);
1574 mLastNoHistoryActivity = null;
Christopher Tated3f175c2012-06-14 14:16:54 -07001575 }
1576
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001577 if (prev != null && prev != next) {
1578 if (!prev.waitingVisible && next != null && !next.nowVisible) {
1579 prev.waitingVisible = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001580 mStackSupervisor.mWaitingVisibleActivities.add(prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001581 if (DEBUG_SWITCH) Slog.v(
1582 TAG, "Resuming top, waiting visible to hide: " + prev);
1583 } else {
1584 // The next activity is already visible, so hide the previous
1585 // activity's windows right now so we can show the new one ASAP.
1586 // We only do this if the previous is finishing, which should mean
1587 // it is on top of the one being resumed so hiding it quickly
1588 // is good. Otherwise, we want to do the normal route of allowing
1589 // the resumed activity to be shown so we can decide if the
1590 // previous should actually be hidden depending on whether the
1591 // new one is found to be full-screen or not.
1592 if (prev.finishing) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001593 mWindowManager.setAppVisibility(prev.appToken, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001594 if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: "
1595 + prev + ", waitingVisible="
1596 + (prev != null ? prev.waitingVisible : null)
1597 + ", nowVisible=" + next.nowVisible);
1598 } else {
1599 if (DEBUG_SWITCH) Slog.v(TAG, "Previous already visible but still waiting to hide: "
1600 + prev + ", waitingVisible="
1601 + (prev != null ? prev.waitingVisible : null)
1602 + ", nowVisible=" + next.nowVisible);
1603 }
1604 }
1605 }
1606
Dianne Hackborne7f97212011-02-24 14:40:20 -08001607 // Launching this app's activity, make sure the app is no longer
1608 // considered stopped.
1609 try {
1610 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -07001611 next.packageName, false, next.userId); /* TODO: Verify if correct userid */
Dianne Hackborne7f97212011-02-24 14:40:20 -08001612 } catch (RemoteException e1) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08001613 } catch (IllegalArgumentException e) {
1614 Slog.w(TAG, "Failed trying to unstop package "
1615 + next.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08001616 }
1617
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001618 // We are starting up the next activity, so tell the window manager
1619 // that the previous one will be hidden soon. This way it can know
1620 // to ignore it when computing the desired screen orientation.
Craig Mautner525f3d92013-05-07 14:01:50 -07001621 boolean anim = true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001622 if (prev != null) {
1623 if (prev.finishing) {
1624 if (DEBUG_TRANSITION) Slog.v(TAG,
1625 "Prepare close transition: prev=" + prev);
1626 if (mNoAnimActivities.contains(prev)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001627 anim = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001628 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001629 } else {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001630 mWindowManager.prepareAppTransition(prev.task == next.task
Craig Mautner4b71aa12012-12-27 17:20:01 -08001631 ? AppTransition.TRANSIT_ACTIVITY_CLOSE
1632 : AppTransition.TRANSIT_TASK_CLOSE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001633 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001634 mWindowManager.setAppWillBeHidden(prev.appToken);
1635 mWindowManager.setAppVisibility(prev.appToken, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001636 } else {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001637 if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001638 if (mNoAnimActivities.contains(next)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001639 anim = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001640 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001641 } else {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001642 mWindowManager.prepareAppTransition(prev.task == next.task
Craig Mautner4b71aa12012-12-27 17:20:01 -08001643 ? AppTransition.TRANSIT_ACTIVITY_OPEN
1644 : AppTransition.TRANSIT_TASK_OPEN, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001645 }
1646 }
1647 if (false) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001648 mWindowManager.setAppWillBeHidden(prev.appToken);
1649 mWindowManager.setAppVisibility(prev.appToken, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001650 }
Craig Mautner967212c2013-04-13 21:10:58 -07001651 } else {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001652 if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001653 if (mNoAnimActivities.contains(next)) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001654 anim = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001655 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001656 } else {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001657 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001658 }
1659 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001660
1661 Bundle resumeAnimOptions = null;
Craig Mautner525f3d92013-05-07 14:01:50 -07001662 if (anim) {
Adam Powellcfbe9be2013-11-06 14:58:58 -08001663 ActivityOptions opts = next.getOptionsForTargetActivityLocked();
1664 if (opts != null) {
1665 resumeAnimOptions = opts.toBundle();
1666 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001667 next.applyOptionsLocked();
1668 } else {
1669 next.clearOptionsLocked();
1670 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001671
Craig Mautnercf910b02013-04-23 11:23:27 -07001672 ActivityStack lastStack = mStackSupervisor.getLastStack();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001673 if (next.app != null && next.app.thread != null) {
1674 if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
1675
1676 // This activity is now becoming visible.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001677 mWindowManager.setAppVisibility(next.appToken, true);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001678
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07001679 // schedule launch ticks to collect information about slow apps.
1680 next.startLaunchTickingLocked();
1681
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001682 ActivityRecord lastResumedActivity =
1683 lastStack == null ? null :lastStack.mResumedActivity;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 ActivityState lastState = next.state;
1685
1686 mService.updateCpuStats();
Craig Mautner58547802013-03-05 08:23:53 -08001687
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001688 if (DEBUG_STATES) Slog.v(TAG, "Moving to RESUMED: " + next + " (in existing)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001689 next.state = ActivityState.RESUMED;
1690 mResumedActivity = next;
1691 next.task.touchActiveTime();
Craig Mautnerd2328952013-03-05 12:46:26 -08001692 mService.addRecentTaskLocked(next.task);
Dianne Hackborndb926082013-10-31 16:32:44 -07001693 mService.updateLruProcessLocked(next.app, true, null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001694 updateLRUListLocked(next);
Dianne Hackborndb926082013-10-31 16:32:44 -07001695 mService.updateOomAdjLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001696
1697 // Have the window manager re-evaluate the orientation of
1698 // the screen based on the new activity order.
Craig Mautner525f3d92013-05-07 14:01:50 -07001699 boolean notUpdated = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001700 if (mStackSupervisor.isFrontStack(this)) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001701 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner8d341ef2013-03-26 09:03:27 -07001702 mService.mConfiguration,
1703 next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
1704 if (config != null) {
1705 next.frozenBeforeDestroy = true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001706 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001707 notUpdated = !mService.updateConfigurationLocked(config, next, false, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001708 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001709
Craig Mautner525f3d92013-05-07 14:01:50 -07001710 if (notUpdated) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001711 // The configuration update wasn't able to keep the existing
1712 // instance of the activity, and instead started a new one.
1713 // We should be all done, but let's just make sure our activity
1714 // is still at the top and schedule another run if something
1715 // weird happened.
1716 ActivityRecord nextNext = topRunningActivityLocked(null);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001717 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001718 "Activity config changed during resume: " + next
1719 + ", new next: " + nextNext);
1720 if (nextNext != next) {
1721 // Do over!
Craig Mautner05d29032013-05-03 13:40:13 -07001722 mStackSupervisor.scheduleResumeTopActivities();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001723 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001724 if (mStackSupervisor.reportResumedActivityLocked(next)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001725 mNoAnimActivities.clear();
Craig Mautnercf910b02013-04-23 11:23:27 -07001726 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001727 return true;
1728 }
Craig Mautnercf910b02013-04-23 11:23:27 -07001729 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001730 return false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001731 }
Craig Mautner58547802013-03-05 08:23:53 -08001732
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001733 try {
1734 // Deliver all pending results.
Craig Mautner05d6272ba2013-02-11 09:39:27 -08001735 ArrayList<ResultInfo> a = next.results;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001736 if (a != null) {
1737 final int N = a.size();
1738 if (!next.finishing && N > 0) {
1739 if (DEBUG_RESULTS) Slog.v(
1740 TAG, "Delivering results to " + next
1741 + ": " + a);
Dianne Hackbornbe707852011-11-11 14:32:10 -08001742 next.app.thread.scheduleSendResult(next.appToken, a);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001743 }
1744 }
1745
1746 if (next.newIntents != null) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08001747 next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001748 }
1749
1750 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001751 next.userId, System.identityHashCode(next),
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001752 next.task.taskId, next.shortComponentName);
Craig Mautner58547802013-03-05 08:23:53 -08001753
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001754 next.sleeping = false;
Craig Mautner2420ead2013-04-01 17:13:20 -07001755 mService.showAskCompatModeDialogLocked(next);
Dianne Hackborn905577f2011-09-07 18:31:28 -07001756 next.app.pendingUiClean = true;
Dianne Hackborna413dc02013-07-12 12:02:55 -07001757 next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
George Mount2c92c972014-03-20 09:38:23 -07001758 next.clearOptionsLocked();
Dianne Hackborna413dc02013-07-12 12:02:55 -07001759 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001760 mService.isNextTransitionForward(), resumeAnimOptions);
Craig Mautner58547802013-03-05 08:23:53 -08001761
Craig Mautner0eea92c2013-05-16 13:35:39 -07001762 mStackSupervisor.checkReadyForSleepLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001763
Craig Mautnerac6f8432013-07-17 13:24:59 -07001764 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Resumed " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001765 } catch (Exception e) {
1766 // Whoops, need to restart this activity!
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001767 if (DEBUG_STATES) Slog.v(TAG, "Resume failed; resetting state to "
1768 + lastState + ": " + next);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001769 next.state = lastState;
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001770 if (lastStack != null) {
1771 lastStack.mResumedActivity = lastResumedActivity;
1772 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001773 Slog.i(TAG, "Restarting because process died: " + next);
1774 if (!next.hasBeenLaunched) {
1775 next.hasBeenLaunched = true;
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001776 } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
1777 mStackSupervisor.isFrontStack(lastStack)) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001778 mWindowManager.setAppStartingWindow(
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001779 next.appToken, next.packageName, next.theme,
1780 mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
Adam Powell04fe6eb2013-05-31 14:39:48 -07001781 next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
1782 next.windowFlags, null, true);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001783 }
George Mount2c92c972014-03-20 09:38:23 -07001784 mStackSupervisor.startSpecificActivityLocked(next, true, false);
Craig Mautnercf910b02013-04-23 11:23:27 -07001785 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001786 return true;
1787 }
1788
1789 // From this point on, if something goes wrong there is no way
1790 // to recover the activity.
1791 try {
1792 next.visible = true;
1793 completeResumeLocked(next);
1794 } catch (Exception e) {
1795 // If any exception gets thrown, toss away this
1796 // activity and try the next one.
1797 Slog.w(TAG, "Exception thrown during resume of " + next, e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08001798 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001799 "resume-exception", true);
Craig Mautnercf910b02013-04-23 11:23:27 -07001800 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001801 return true;
1802 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001803 next.stopped = false;
1804
1805 } else {
1806 // Whoops, need to restart this activity!
1807 if (!next.hasBeenLaunched) {
1808 next.hasBeenLaunched = true;
1809 } else {
1810 if (SHOW_APP_STARTING_PREVIEW) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001811 mWindowManager.setAppStartingWindow(
Dianne Hackbornbe707852011-11-11 14:32:10 -08001812 next.appToken, next.packageName, next.theme,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001813 mService.compatibilityInfoForPackageLocked(
1814 next.info.applicationInfo),
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001815 next.nonLocalizedLabel,
Adam Powell04fe6eb2013-05-31 14:39:48 -07001816 next.labelRes, next.icon, next.logo, next.windowFlags,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08001817 null, true);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001818 }
1819 if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
1820 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001821 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);
George Mount2c92c972014-03-20 09:38:23 -07001822 mStackSupervisor.startSpecificActivityLocked(next, true, true);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001823 }
1824
Craig Mautnercf910b02013-04-23 11:23:27 -07001825 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001826 return true;
1827 }
1828
Craig Mautnerac6f8432013-07-17 13:24:59 -07001829 private void insertTaskAtTop(TaskRecord task) {
Craig Mautner9c85c202013-10-04 20:11:26 -07001830 // If this is being moved to the top by another activity or being launched from the home
1831 // activity, set mOnTopOfHome accordingly.
Craig Mautnere0a38842013-12-16 16:14:02 -08001832 if (isOnHomeDisplay()) {
1833 ActivityStack lastStack = mStackSupervisor.getLastStack();
1834 final boolean fromHome = lastStack.isHomeStack();
1835 if (!isHomeStack() && (fromHome || topTask() != task)) {
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001836 task.mOnTopOfHome = fromHome;
Craig Mautnere0a38842013-12-16 16:14:02 -08001837 }
1838 } else {
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00001839 task.mOnTopOfHome = false;
Craig Mautner9c85c202013-10-04 20:11:26 -07001840 }
Craig Mautnerd99384d2013-10-14 07:09:18 -07001841
Craig Mautnerac6f8432013-07-17 13:24:59 -07001842 mTaskHistory.remove(task);
1843 // Now put task at top.
1844 int stackNdx = mTaskHistory.size();
Kenny Guy2a764942014-04-02 13:29:20 +01001845 if (!isCurrentProfileLocked(task.userId)) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001846 // Put non-current user tasks below current user tasks.
1847 while (--stackNdx >= 0) {
Kenny Guy2a764942014-04-02 13:29:20 +01001848 if (!isCurrentProfileLocked(mTaskHistory.get(stackNdx).userId)) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001849 break;
1850 }
1851 }
1852 ++stackNdx;
1853 }
1854 mTaskHistory.add(stackNdx, task);
Craig Mautner21d24a22014-04-23 11:45:37 -07001855 updateTaskMovement(task, true);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001856 }
Craig Mautner11bf9a52013-02-19 14:08:51 -08001857
Craig Mautner8849a5e2013-04-02 16:41:03 -07001858 final void startActivityLocked(ActivityRecord r, boolean newTask,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001859 boolean doResume, boolean keepCurTransition, Bundle options) {
Craig Mautnerd2328952013-03-05 12:46:26 -08001860 TaskRecord rTask = r.task;
1861 final int taskId = rTask.taskId;
1862 if (taskForIdLocked(taskId) == null || newTask) {
Craig Mautner77878772013-03-04 19:46:24 -08001863 // Last activity in task had been removed or ActivityManagerService is reusing task.
1864 // Insert or replace.
Craig Mautner77878772013-03-04 19:46:24 -08001865 // Might not even be in.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001866 insertTaskAtTop(rTask);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001867 mWindowManager.moveTaskToTop(taskId);
Craig Mautner77878772013-03-04 19:46:24 -08001868 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001869 TaskRecord task = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001870 if (!newTask) {
1871 // If starting in an existing task, find where that is...
Craig Mautner70a86932013-02-28 22:37:44 -08001872 boolean startIt = true;
1873 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1874 task = mTaskHistory.get(taskNdx);
1875 if (task == r.task) {
1876 // Here it is! Now, if this is not yet visible to the
1877 // user, then just add it without starting; it will
1878 // get started when the user navigates back to it.
Craig Mautner70a86932013-02-28 22:37:44 -08001879 if (!startIt) {
1880 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
1881 + task, new RuntimeException("here").fillInStackTrace());
1882 task.addActivityToTop(r);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001883 r.putInHistory();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001884 mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
1885 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
Craig Mautnerac6f8432013-07-17 13:24:59 -07001886 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001887 r.userId, r.info.configChanges, task.voiceSession != null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001888 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08001889 validateAppTokensLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001890 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001891 ActivityOptions.abort(options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001892 return;
1893 }
1894 break;
Craig Mautner70a86932013-02-28 22:37:44 -08001895 } else if (task.numFullscreen > 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001896 startIt = false;
1897 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001898 }
1899 }
1900
1901 // Place a new activity at top of stack, so it is next to interact
1902 // with the user.
Craig Mautner70a86932013-02-28 22:37:44 -08001903
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001904 // If we are not placing the new activity frontmost, we do not want
1905 // to deliver the onUserLeaving callback to the actual frontmost
1906 // activity
Craig Mautner70a86932013-02-28 22:37:44 -08001907 if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001908 mStackSupervisor.mUserLeaving = false;
Craig Mautner70a86932013-02-28 22:37:44 -08001909 if (DEBUG_USER_LEAVING) Slog.v(TAG,
1910 "startActivity() behind front, mUserLeaving=false");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001911 }
Craig Mautner70a86932013-02-28 22:37:44 -08001912
1913 task = r.task;
1914
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001915 // Slot the activity into the history stack and proceed
Craig Mautner70a86932013-02-28 22:37:44 -08001916 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
Craig Mautner56f52db2013-02-25 10:03:01 -08001917 new RuntimeException("here").fillInStackTrace());
Craig Mautner70a86932013-02-28 22:37:44 -08001918 task.addActivityToTop(r);
Craig Mautner1aa9d0d3f2013-12-16 15:58:31 -08001919 task.setFrontOfTask();
Craig Mautner70a86932013-02-28 22:37:44 -08001920
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001921 r.putInHistory();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001922 if (!isHomeStack() || numActivities() > 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001923 // We want to show the starting preview window if we are
1924 // switching to a new task, or the next activity's process is
1925 // not currently running.
1926 boolean showStartingIcon = newTask;
1927 ProcessRecord proc = r.app;
1928 if (proc == null) {
1929 proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
1930 }
1931 if (proc == null || proc.thread == null) {
1932 showStartingIcon = true;
1933 }
1934 if (DEBUG_TRANSITION) Slog.v(TAG,
1935 "Prepare open transition: starting " + r);
1936 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001937 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001938 mNoAnimActivities.add(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001939 } else {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001940 mWindowManager.prepareAppTransition(newTask
Craig Mautner4b71aa12012-12-27 17:20:01 -08001941 ? AppTransition.TRANSIT_TASK_OPEN
1942 : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001943 mNoAnimActivities.remove(r);
1944 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001945 mWindowManager.addAppToken(task.mActivities.indexOf(r),
Craig Mautnerc00204b2013-03-05 15:02:14 -08001946 r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
Craig Mautner5d9f5472013-11-12 14:02:52 -08001947 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001948 r.info.configChanges, task.voiceSession != null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001949 boolean doShow = true;
1950 if (newTask) {
1951 // Even though this activity is starting fresh, we still need
1952 // to reset it to make sure we apply affinities to move any
1953 // existing activities from other tasks in to it.
1954 // If the caller has requested that the target task be
1955 // reset, then do so.
1956 if ((r.intent.getFlags()
Craig Mautnerd00f4742014-03-12 14:17:26 -07001957 & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001958 resetTaskIfNeededLocked(r, r);
1959 doShow = topRunningNonDelayedActivityLocked(null) == r;
1960 }
1961 }
1962 if (SHOW_APP_STARTING_PREVIEW && doShow) {
1963 // Figure out if we are transitioning from another activity that is
1964 // "has the same starting icon" as the next one. This allows the
1965 // window manager to keep the previous window it had previously
1966 // created, if it still had one.
1967 ActivityRecord prev = mResumedActivity;
1968 if (prev != null) {
1969 // We don't want to reuse the previous starting preview if:
1970 // (1) The current activity is in a different task.
Craig Mautner29219d92013-04-16 20:19:12 -07001971 if (prev.task != r.task) {
1972 prev = null;
1973 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001974 // (2) The current activity is already displayed.
Craig Mautner29219d92013-04-16 20:19:12 -07001975 else if (prev.nowVisible) {
1976 prev = null;
1977 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001978 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001979 mWindowManager.setAppStartingWindow(
Dianne Hackbornbe707852011-11-11 14:32:10 -08001980 r.appToken, r.packageName, r.theme,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001981 mService.compatibilityInfoForPackageLocked(
1982 r.info.applicationInfo), r.nonLocalizedLabel,
Adam Powell04fe6eb2013-05-31 14:39:48 -07001983 r.labelRes, r.icon, r.logo, r.windowFlags,
Dianne Hackbornbe707852011-11-11 14:32:10 -08001984 prev != null ? prev.appToken : null, showStartingIcon);
Craig Mautnera61bc652013-10-28 15:43:18 -07001985 r.mStartingWindowShown = true;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001986 }
1987 } else {
1988 // If this is the first activity, don't do any fancy animations,
1989 // because there is nothing for it to animate on top of.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001990 mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
Craig Mautnerc00204b2013-03-05 15:02:14 -08001991 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
Craig Mautner5d9f5472013-11-12 14:02:52 -08001992 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001993 r.info.configChanges, task.voiceSession != null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001994 ActivityOptions.abort(options);
Craig Mautner233ceee2014-05-09 17:05:11 -07001995 options = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001996 }
1997 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08001998 validateAppTokensLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001999 }
2000
2001 if (doResume) {
Craig Mautner233ceee2014-05-09 17:05:11 -07002002 mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002003 }
2004 }
2005
Dianne Hackbornbe707852011-11-11 14:32:10 -08002006 final void validateAppTokensLocked() {
2007 mValidateAppTokens.clear();
Craig Mautner000f0022013-02-26 15:04:29 -08002008 mValidateAppTokens.ensureCapacity(numActivities());
2009 final int numTasks = mTaskHistory.size();
2010 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
2011 TaskRecord task = mTaskHistory.get(taskNdx);
2012 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautnerc8143c62013-09-03 12:15:57 -07002013 if (activities.isEmpty()) {
Craig Mautner000f0022013-02-26 15:04:29 -08002014 continue;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08002015 }
Craig Mautner000f0022013-02-26 15:04:29 -08002016 TaskGroup group = new TaskGroup();
2017 group.taskId = task.taskId;
2018 mValidateAppTokens.add(group);
2019 final int numActivities = activities.size();
2020 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2021 final ActivityRecord r = activities.get(activityNdx);
2022 group.tokens.add(r.appToken);
2023 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002024 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002025 mWindowManager.validateAppTokens(mStackId, mValidateAppTokens);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002026 }
2027
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002028 /**
2029 * Perform a reset of the given task, if needed as part of launching it.
2030 * Returns the new HistoryRecord at the top of the task.
2031 */
Craig Mautnere3a74d52013-02-22 14:14:58 -08002032 /**
2033 * Helper method for #resetTaskIfNeededLocked.
2034 * We are inside of the task being reset... we'll either finish this activity, push it out
2035 * for another task, or leave it as-is.
2036 * @param task The task containing the Activity (taskTop) that might be reset.
2037 * @param forceReset
2038 * @return An ActivityOptions that needs to be processed.
2039 */
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002040 final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002041 ActivityOptions topOptions = null;
2042
2043 int replyChainEnd = -1;
2044 boolean canMoveOptions = true;
2045
2046 // We only do this for activities that are not the root of the task (since if we finish
2047 // the root, we may no longer have the task!).
2048 final ArrayList<ActivityRecord> activities = task.mActivities;
2049 final int numActivities = activities.size();
2050 for (int i = numActivities - 1; i > 0; --i ) {
2051 ActivityRecord target = activities.get(i);
2052
2053 final int flags = target.info.flags;
2054 final boolean finishOnTaskLaunch =
2055 (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
2056 final boolean allowTaskReparenting =
2057 (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
2058 final boolean clearWhenTaskReset =
2059 (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
2060
2061 if (!finishOnTaskLaunch
2062 && !clearWhenTaskReset
2063 && target.resultTo != null) {
2064 // If this activity is sending a reply to a previous
2065 // activity, we can't do anything with it now until
2066 // we reach the start of the reply chain.
2067 // XXX note that we are assuming the result is always
2068 // to the previous activity, which is almost always
2069 // the case but we really shouldn't count on.
2070 if (replyChainEnd < 0) {
2071 replyChainEnd = i;
2072 }
2073 } else if (!finishOnTaskLaunch
2074 && !clearWhenTaskReset
2075 && allowTaskReparenting
2076 && target.taskAffinity != null
2077 && !target.taskAffinity.equals(task.affinity)) {
2078 // If this activity has an affinity for another
2079 // task, then we need to move it out of here. We will
2080 // move it as far out of the way as possible, to the
2081 // bottom of the activity stack. This also keeps it
2082 // correctly ordered with any activities we previously
2083 // moved.
Craig Mautner329f4122013-11-07 09:10:42 -08002084 final ThumbnailHolder newThumbHolder;
2085 final TaskRecord targetTask;
Craig Mautnerdccb7702013-09-17 15:53:34 -07002086 final ActivityRecord bottom =
2087 !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
Craig Mautner329f4122013-11-07 09:10:42 -08002088 mTaskHistory.get(0).mActivities.get(0) : null;
Craig Mautnerdccb7702013-09-17 15:53:34 -07002089 if (bottom != null && target.taskAffinity != null
2090 && target.taskAffinity.equals(bottom.task.affinity)) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002091 // If the activity currently at the bottom has the
2092 // same task affinity as the one we are moving,
2093 // then merge it into the same task.
Craig Mautner329f4122013-11-07 09:10:42 -08002094 targetTask = bottom.task;
2095 newThumbHolder = bottom.thumbHolder == null ? targetTask : bottom.thumbHolder;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002096 if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
Craig Mautnerdccb7702013-09-17 15:53:34 -07002097 + " out to bottom task " + bottom.task);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002098 } else {
Craig Mautner329f4122013-11-07 09:10:42 -08002099 targetTask = createTaskRecord(mStackSupervisor.getNextTaskId(), target.info,
Dianne Hackborn91097de2014-04-04 18:02:06 -07002100 null, null, null, false);
Craig Mautner329f4122013-11-07 09:10:42 -08002101 newThumbHolder = targetTask;
2102 targetTask.affinityIntent = target.intent;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002103 if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
2104 + " out to new task " + target.task);
2105 }
2106
Craig Mautnerd00f4742014-03-12 14:17:26 -07002107 target.thumbHolder = newThumbHolder;
Craig Mautner329f4122013-11-07 09:10:42 -08002108
Craig Mautnere3a74d52013-02-22 14:14:58 -08002109 final int targetTaskId = targetTask.taskId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002110 mWindowManager.setAppGroupId(target.appToken, targetTaskId);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002111
Craig Mautner525f3d92013-05-07 14:01:50 -07002112 boolean noOptions = canMoveOptions;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002113 final int start = replyChainEnd < 0 ? i : replyChainEnd;
2114 for (int srcPos = start; srcPos >= i; --srcPos) {
Craig Mautnerdccb7702013-09-17 15:53:34 -07002115 final ActivityRecord p = activities.get(srcPos);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002116 if (p.finishing) {
2117 continue;
2118 }
2119
Craig Mautner525f3d92013-05-07 14:01:50 -07002120 ThumbnailHolder curThumbHolder = p.thumbHolder;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002121 canMoveOptions = false;
Craig Mautner525f3d92013-05-07 14:01:50 -07002122 if (noOptions && topOptions == null) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002123 topOptions = p.takeOptionsLocked();
2124 if (topOptions != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002125 noOptions = false;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002126 }
2127 }
2128 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing activity " + p + " from task="
Craig Mautner329f4122013-11-07 09:10:42 -08002129 + task + " adding to task=" + targetTask
2130 + " Callers=" + Debug.getCallers(4));
Craig Mautnere3a74d52013-02-22 14:14:58 -08002131 if (DEBUG_TASKS) Slog.v(TAG, "Pushing next activity " + p
2132 + " out to target's task " + target.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002133 p.setTask(targetTask, curThumbHolder, false);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002134 targetTask.addActivityAtBottom(p);
Craig Mautner0247fc82013-02-28 14:32:06 -08002135
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002136 mWindowManager.setAppGroupId(p.appToken, targetTaskId);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002137 }
2138
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002139 mWindowManager.moveTaskToBottom(targetTaskId);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002140 if (VALIDATE_TOKENS) {
2141 validateAppTokensLocked();
2142 }
2143
2144 replyChainEnd = -1;
2145 } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) {
2146 // If the activity should just be removed -- either
2147 // because it asks for it, or the task should be
2148 // cleared -- then finish it and anything that is
2149 // part of its reply chain.
2150 int end;
2151 if (clearWhenTaskReset) {
2152 // In this case, we want to finish this activity
2153 // and everything above it, so be sneaky and pretend
2154 // like these are all in the reply chain.
2155 end = numActivities - 1;
2156 } else if (replyChainEnd < 0) {
2157 end = i;
2158 } else {
2159 end = replyChainEnd;
2160 }
Craig Mautner525f3d92013-05-07 14:01:50 -07002161 boolean noOptions = canMoveOptions;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002162 for (int srcPos = i; srcPos <= end; srcPos++) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002163 ActivityRecord p = activities.get(srcPos);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002164 if (p.finishing) {
2165 continue;
2166 }
2167 canMoveOptions = false;
Craig Mautner525f3d92013-05-07 14:01:50 -07002168 if (noOptions && topOptions == null) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002169 topOptions = p.takeOptionsLocked();
2170 if (topOptions != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07002171 noOptions = false;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002172 }
2173 }
Craig Mautner58547802013-03-05 08:23:53 -08002174 if (DEBUG_TASKS) Slog.w(TAG,
2175 "resetTaskIntendedTask: calling finishActivity on " + p);
Craig Mautnerd44711d2013-02-23 11:24:36 -08002176 if (finishActivityLocked(p, Activity.RESULT_CANCELED, null, "reset", false)) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002177 end--;
2178 srcPos--;
2179 }
2180 }
2181 replyChainEnd = -1;
2182 } else {
2183 // If we were in the middle of a chain, well the
2184 // activity that started it all doesn't want anything
2185 // special, so leave it all as-is.
2186 replyChainEnd = -1;
2187 }
2188 }
2189
2190 return topOptions;
2191 }
2192
2193 /**
2194 * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given
2195 * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop.
2196 * @param affinityTask The task we are looking for an affinity to.
2197 * @param task Task that resetTaskIfNeededLocked.taskTop belongs to.
2198 * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked.
2199 * @param forceReset Flag passed in to resetTaskIfNeededLocked.
2200 */
Craig Mautner525f3d92013-05-07 14:01:50 -07002201 private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task,
Craig Mautner77878772013-03-04 19:46:24 -08002202 boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002203 int replyChainEnd = -1;
2204 final int taskId = task.taskId;
2205 final String taskAffinity = task.affinity;
2206
2207 final ArrayList<ActivityRecord> activities = affinityTask.mActivities;
2208 final int numActivities = activities.size();
2209 // Do not operate on the root Activity.
2210 for (int i = numActivities - 1; i > 0; --i) {
2211 ActivityRecord target = activities.get(i);
2212
2213 final int flags = target.info.flags;
2214 boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
2215 boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
2216
2217 if (target.resultTo != null) {
2218 // If this activity is sending a reply to a previous
2219 // activity, we can't do anything with it now until
2220 // we reach the start of the reply chain.
2221 // XXX note that we are assuming the result is always
2222 // to the previous activity, which is almost always
2223 // the case but we really shouldn't count on.
2224 if (replyChainEnd < 0) {
2225 replyChainEnd = i;
2226 }
2227 } else if (topTaskIsHigher
2228 && allowTaskReparenting
2229 && taskAffinity != null
2230 && taskAffinity.equals(target.taskAffinity)) {
2231 // This activity has an affinity for our task. Either remove it if we are
2232 // clearing or move it over to our task. Note that
2233 // we currently punt on the case where we are resetting a
2234 // task that is not at the top but who has activities above
2235 // with an affinity to it... this is really not a normal
2236 // case, and we will need to later pull that task to the front
2237 // and usually at that point we will do the reset and pick
2238 // up those remaining activities. (This only happens if
2239 // someone starts an activity in a new task from an activity
2240 // in a task that is not currently on top.)
2241 if (forceReset || finishOnTaskLaunch) {
2242 final int start = replyChainEnd >= 0 ? replyChainEnd : i;
2243 if (DEBUG_TASKS) Slog.v(TAG, "Finishing task at index " + start + " to " + i);
2244 for (int srcPos = start; srcPos >= i; --srcPos) {
2245 final ActivityRecord p = activities.get(srcPos);
2246 if (p.finishing) {
2247 continue;
2248 }
Craig Mautnerd44711d2013-02-23 11:24:36 -08002249 finishActivityLocked(p, Activity.RESULT_CANCELED, null, "reset", false);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002250 }
2251 } else {
Craig Mautner77878772013-03-04 19:46:24 -08002252 if (taskInsertionPoint < 0) {
2253 taskInsertionPoint = task.mActivities.size();
Craig Mautnerd2328952013-03-05 12:46:26 -08002254
Craig Mautner77878772013-03-04 19:46:24 -08002255 }
Craig Mautner77878772013-03-04 19:46:24 -08002256
2257 final int start = replyChainEnd >= 0 ? replyChainEnd : i;
2258 if (DEBUG_TASKS) Slog.v(TAG, "Reparenting from task=" + affinityTask + ":"
2259 + start + "-" + i + " to task=" + task + ":" + taskInsertionPoint);
2260 for (int srcPos = start; srcPos >= i; --srcPos) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002261 final ActivityRecord p = activities.get(srcPos);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002262 p.setTask(task, null, false);
Craig Mautner77878772013-03-04 19:46:24 -08002263 task.addActivityAtIndex(taskInsertionPoint, p);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002264
Craig Mautnere3a74d52013-02-22 14:14:58 -08002265 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing and adding activity " + p
2266 + " to stack at " + task,
2267 new RuntimeException("here").fillInStackTrace());
2268 if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p + " from " + srcPos
2269 + " in to resetting task " + task);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002270 mWindowManager.setAppGroupId(p.appToken, taskId);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002271 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002272 mWindowManager.moveTaskToTop(taskId);
Craig Mautner9658b312013-02-28 10:55:59 -08002273 if (VALIDATE_TOKENS) {
2274 validateAppTokensLocked();
2275 }
Craig Mautnere3a74d52013-02-22 14:14:58 -08002276
2277 // Now we've moved it in to place... but what if this is
2278 // a singleTop activity and we have put it on top of another
2279 // instance of the same activity? Then we drop the instance
2280 // below so it remains singleTop.
2281 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
2282 ArrayList<ActivityRecord> taskActivities = task.mActivities;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002283 int targetNdx = taskActivities.indexOf(target);
2284 if (targetNdx > 0) {
2285 ActivityRecord p = taskActivities.get(targetNdx - 1);
2286 if (p.intent.getComponent().equals(target.intent.getComponent())) {
Craig Mautner58547802013-03-05 08:23:53 -08002287 finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
2288 false);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002289 }
2290 }
2291 }
2292 }
2293
2294 replyChainEnd = -1;
2295 }
2296 }
Craig Mautner77878772013-03-04 19:46:24 -08002297 return taskInsertionPoint;
Craig Mautnere3a74d52013-02-22 14:14:58 -08002298 }
2299
Craig Mautner8849a5e2013-04-02 16:41:03 -07002300 final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
Craig Mautnere3a74d52013-02-22 14:14:58 -08002301 ActivityRecord newActivity) {
2302 boolean forceReset =
2303 (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
2304 if (ACTIVITY_INACTIVE_RESET_TIME > 0
2305 && taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
2306 if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
2307 forceReset = true;
2308 }
2309 }
2310
2311 final TaskRecord task = taskTop.task;
2312
2313 /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
2314 * for remaining tasks. Used for later tasks to reparent to task. */
2315 boolean taskFound = false;
2316
2317 /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */
2318 ActivityOptions topOptions = null;
2319
Craig Mautner77878772013-03-04 19:46:24 -08002320 // Preserve the location for reparenting in the new task.
2321 int reparentInsertionPoint = -1;
2322
Craig Mautnere3a74d52013-02-22 14:14:58 -08002323 for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
2324 final TaskRecord targetTask = mTaskHistory.get(i);
2325
2326 if (targetTask == task) {
2327 topOptions = resetTargetTaskIfNeededLocked(task, forceReset);
2328 taskFound = true;
2329 } else {
Craig Mautner77878772013-03-04 19:46:24 -08002330 reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task,
2331 taskFound, forceReset, reparentInsertionPoint);
Craig Mautnere3a74d52013-02-22 14:14:58 -08002332 }
2333 }
2334
Craig Mautner70a86932013-02-28 22:37:44 -08002335 int taskNdx = mTaskHistory.indexOf(task);
2336 do {
2337 taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
2338 } while (taskTop == null && taskNdx >= 0);
2339
Craig Mautnere3a74d52013-02-22 14:14:58 -08002340 if (topOptions != null) {
2341 // If we got some ActivityOptions from an activity on top that
2342 // was removed from the task, propagate them to the new real top.
2343 if (taskTop != null) {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002344 taskTop.updateOptionsLocked(topOptions);
2345 } else {
Craig Mautnere3a74d52013-02-22 14:14:58 -08002346 topOptions.abort();
2347 }
2348 }
2349
2350 return taskTop;
2351 }
2352
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002353 void sendActivityResultLocked(int callingUid, ActivityRecord r,
2354 String resultWho, int requestCode, int resultCode, Intent data) {
2355
2356 if (callingUid > 0) {
2357 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
Dianne Hackborn7e269642010-08-25 19:50:20 -07002358 data, r.getUriPermissionsLocked());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002359 }
2360
2361 if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
2362 + " : who=" + resultWho + " req=" + requestCode
2363 + " res=" + resultCode + " data=" + data);
2364 if (mResumedActivity == r && r.app != null && r.app.thread != null) {
2365 try {
2366 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2367 list.add(new ResultInfo(resultWho, requestCode,
2368 resultCode, data));
Dianne Hackbornbe707852011-11-11 14:32:10 -08002369 r.app.thread.scheduleSendResult(r.appToken, list);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002370 return;
2371 } catch (Exception e) {
2372 Slog.w(TAG, "Exception thrown sending result to " + r, e);
2373 }
2374 }
2375
2376 r.addResultLocked(null, resultWho, requestCode, resultCode, data);
2377 }
2378
Craig Mautner04f0b702013-10-22 12:31:01 -07002379 private void adjustFocusedActivityLocked(ActivityRecord r) {
2380 if (mStackSupervisor.isFrontStack(this) && mService.mFocusedActivity == r) {
2381 ActivityRecord next = topRunningActivityLocked(null);
2382 if (next != r) {
2383 final TaskRecord task = r.task;
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00002384 if (r.frontOfTask && task == topTask() && task.mOnTopOfHome) {
2385 mStackSupervisor.moveHomeToTop();
Craig Mautner04f0b702013-10-22 12:31:01 -07002386 }
2387 }
Winson Chung648c83b2014-04-28 15:11:56 -07002388 ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
2389 if (top != null) {
2390 mService.setFocusedActivityLocked(top);
2391 }
Craig Mautner04f0b702013-10-22 12:31:01 -07002392 }
2393 }
2394
Craig Mautnerf3333272013-04-22 10:55:53 -07002395 final void stopActivityLocked(ActivityRecord r) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002396 if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);
2397 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
2398 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
2399 if (!r.finishing) {
Dianne Hackborn91097de2014-04-04 18:02:06 -07002400 if (!mService.isSleeping()) {
Christopher Tated3f175c2012-06-14 14:16:54 -07002401 if (DEBUG_STATES) {
2402 Slog.d(TAG, "no-history finish of " + r);
2403 }
2404 requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002405 "no-history", false);
Christopher Tated3f175c2012-06-14 14:16:54 -07002406 } else {
2407 if (DEBUG_STATES) Slog.d(TAG, "Not finishing noHistory " + r
2408 + " on stop because we're just sleeping");
2409 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002410 }
Christopher Tate5007ddd2012-06-12 13:08:18 -07002411 }
2412
2413 if (r.app != null && r.app.thread != null) {
Craig Mautner04f0b702013-10-22 12:31:01 -07002414 adjustFocusedActivityLocked(r);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002415 r.resumeKeyDispatchingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002416 try {
2417 r.stopped = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002418 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r
2419 + " (stop requested)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002420 r.state = ActivityState.STOPPING;
2421 if (DEBUG_VISBILITY) Slog.v(
2422 TAG, "Stopping visible=" + r.visible + " for " + r);
2423 if (!r.visible) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002424 mWindowManager.setAppVisibility(r.appToken, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002425 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002426 r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
Craig Mautnere11f2b72013-04-01 12:37:17 -07002427 if (mService.isSleepingOrShuttingDown()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002428 r.setSleeping(true);
2429 }
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07002430 Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07002431 mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002432 } catch (Exception e) {
2433 // Maybe just ignore exceptions here... if the process
2434 // has crashed, our death notification will clean things
2435 // up.
2436 Slog.w(TAG, "Exception thrown during pause", e);
2437 // Just in case, assume it to be stopped.
2438 r.stopped = true;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002439 if (DEBUG_STATES) Slog.v(TAG, "Stop failed; moving to STOPPED: " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002440 r.state = ActivityState.STOPPED;
2441 if (r.configDestroy) {
Dianne Hackborn28695e02011-11-02 21:59:51 -07002442 destroyActivityLocked(r, true, false, "stop-except");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002443 }
2444 }
2445 }
2446 }
Craig Mautner23ac33b2013-04-01 16:26:35 -07002447
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002448 /**
2449 * @return Returns true if the activity is being finished, false if for
2450 * some reason it is being left as-is.
2451 */
2452 final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002453 Intent resultData, String reason, boolean oomAdj) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -08002454 ActivityRecord r = isInStackLocked(token);
Christopher Tated3f175c2012-06-14 14:16:54 -07002455 if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(
Craig Mautnerd74f7d72013-02-26 13:41:02 -08002456 TAG, "Finishing activity token=" + token + " r="
Christopher Tated3f175c2012-06-14 14:16:54 -07002457 + ", result=" + resultCode + ", data=" + resultData
2458 + ", reason=" + reason);
Craig Mautnerd74f7d72013-02-26 13:41:02 -08002459 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002460 return false;
2461 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002462
Craig Mautnerd44711d2013-02-23 11:24:36 -08002463 finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002464 return true;
2465 }
2466
Craig Mautnerd2328952013-03-05 12:46:26 -08002467 final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
Craig Mautner9658b312013-02-28 10:55:59 -08002468 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2469 ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2470 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2471 ActivityRecord r = activities.get(activityNdx);
2472 if (r.resultTo == self && r.requestCode == requestCode) {
2473 if ((r.resultWho == null && resultWho == null) ||
2474 (r.resultWho != null && r.resultWho.equals(resultWho))) {
2475 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
2476 false);
2477 }
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002478 }
2479 }
2480 }
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002481 mService.updateOomAdjLocked();
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002482 }
2483
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002484 final void finishTopRunningActivityLocked(ProcessRecord app) {
2485 ActivityRecord r = topRunningActivityLocked(null);
2486 if (r != null && r.app == app) {
2487 // If the top running activity is from this crashing
2488 // process, then terminate it to avoid getting in a loop.
2489 Slog.w(TAG, " Force finishing activity "
2490 + r.intent.getComponent().flattenToShortString());
Craig Mautner9658b312013-02-28 10:55:59 -08002491 int taskNdx = mTaskHistory.indexOf(r.task);
2492 int activityNdx = r.task.mActivities.indexOf(r);
Craig Mautnerd2328952013-03-05 12:46:26 -08002493 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002494 // Also terminate any activities below it that aren't yet
2495 // stopped, to avoid a situation where one will get
2496 // re-start our crashing activity once it gets resumed again.
Craig Mautner9658b312013-02-28 10:55:59 -08002497 --activityNdx;
2498 if (activityNdx < 0) {
2499 do {
2500 --taskNdx;
2501 if (taskNdx < 0) {
2502 break;
2503 }
2504 activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
2505 } while (activityNdx < 0);
2506 }
2507 if (activityNdx >= 0) {
2508 r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002509 if (r.state == ActivityState.RESUMED
2510 || r.state == ActivityState.PAUSING
2511 || r.state == ActivityState.PAUSED) {
Craig Mautner4ef26932013-09-18 15:15:52 -07002512 if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002513 Slog.w(TAG, " Force finishing activity "
2514 + r.intent.getComponent().flattenToShortString());
Craig Mautnerd2328952013-03-05 12:46:26 -08002515 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002516 }
2517 }
2518 }
2519 }
2520 }
2521
Craig Mautnerd2328952013-03-05 12:46:26 -08002522 final boolean finishActivityAffinityLocked(ActivityRecord r) {
Craig Mautnerd74f7d72013-02-26 13:41:02 -08002523 ArrayList<ActivityRecord> activities = r.task.mActivities;
2524 for (int index = activities.indexOf(r); index >= 0; --index) {
2525 ActivityRecord cur = activities.get(index);
Kenny Roote6585b32013-12-13 12:00:26 -08002526 if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) {
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002527 break;
2528 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002529 finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002530 }
2531 return true;
2532 }
2533
Dianne Hackborn5c607432012-02-28 14:44:19 -08002534 final void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
2535 // send the result
2536 ActivityRecord resultTo = r.resultTo;
2537 if (resultTo != null) {
2538 if (DEBUG_RESULTS) Slog.v(TAG, "Adding result to " + resultTo
2539 + " who=" + r.resultWho + " req=" + r.requestCode
2540 + " res=" + resultCode + " data=" + resultData);
2541 if (r.info.applicationInfo.uid > 0) {
2542 mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
2543 resultTo.packageName, resultData,
2544 resultTo.getUriPermissionsLocked());
2545 }
2546 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
2547 resultData);
2548 r.resultTo = null;
2549 }
2550 else if (DEBUG_RESULTS) Slog.v(TAG, "No result destination from " + r);
2551
2552 // Make sure this HistoryRecord is not holding on to other resources,
2553 // because clients have remote IPC references to this object so we
2554 // can't assume that will go away and want to avoid circular IPC refs.
2555 r.results = null;
2556 r.pendingResults = null;
2557 r.newIntents = null;
2558 r.icicle = null;
2559 }
2560
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002561 /**
2562 * @return Returns true if this activity has been removed from the history
2563 * list, or false if it is still in the list and will be removed later.
2564 */
Craig Mautnerf3333272013-04-22 10:55:53 -07002565 final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
2566 String reason, boolean oomAdj) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002567 if (r.finishing) {
2568 Slog.w(TAG, "Duplicate finish request for " + r);
2569 return false;
2570 }
2571
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002572 r.makeFinishing();
Craig Mautneraea74a52014-03-08 14:23:10 -08002573 final TaskRecord task = r.task;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002574 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07002575 r.userId, System.identityHashCode(r),
Craig Mautneraea74a52014-03-08 14:23:10 -08002576 task.taskId, r.shortComponentName, reason);
2577 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautnerd44711d2013-02-23 11:24:36 -08002578 final int index = activities.indexOf(r);
2579 if (index < (activities.size() - 1)) {
Craig Mautneraea74a52014-03-08 14:23:10 -08002580 task.setFrontOfTask();
Craig Mautnerd00f4742014-03-12 14:17:26 -07002581 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08002582 // If the caller asked that this activity (and all above it)
2583 // be cleared when the task is reset, don't lose that information,
2584 // but propagate it up to the next activity.
Craig Mautner1aa9d0d3f2013-12-16 15:58:31 -08002585 ActivityRecord next = activities.get(index+1);
Craig Mautnerd44711d2013-02-23 11:24:36 -08002586 next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002587 }
2588 }
2589
2590 r.pauseKeyDispatchingLocked();
Craig Mautner04f0b702013-10-22 12:31:01 -07002591
2592 adjustFocusedActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002593
Dianne Hackborn5c607432012-02-28 14:44:19 -08002594 finishActivityResultsLocked(r, resultCode, resultData);
Craig Mautner2420ead2013-04-01 17:13:20 -07002595
Craig Mautnerde4ef022013-04-07 19:01:33 -07002596 if (mResumedActivity == r) {
Craig Mautner0247fc82013-02-28 14:32:06 -08002597 boolean endTask = index <= 0;
Craig Mautner323f7802013-10-01 21:16:22 -07002598 if (DEBUG_VISBILITY || DEBUG_TRANSITION) Slog.v(TAG,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002599 "Prepare close transition: finishing " + r);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002600 mWindowManager.prepareAppTransition(endTask
Craig Mautner4b71aa12012-12-27 17:20:01 -08002601 ? AppTransition.TRANSIT_TASK_CLOSE
2602 : AppTransition.TRANSIT_ACTIVITY_CLOSE, false);
Craig Mautner0247fc82013-02-28 14:32:06 -08002603
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002604 // Tell window manager to prepare for this one to be removed.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002605 mWindowManager.setAppVisibility(r.appToken, false);
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07002606
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002607 if (mPausingActivity == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002608 if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
2609 if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false");
2610 startPausingLocked(false, false);
2611 }
2612
Craig Mautneraea74a52014-03-08 14:23:10 -08002613 if (endTask) {
2614 mStackSupervisor.endLockTaskModeIfTaskEnding(task);
2615 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002616 } else if (r.state != ActivityState.PAUSING) {
2617 // If the activity is PAUSING, we will complete the finish once
2618 // it is done pausing; else we can just directly finish it here.
2619 if (DEBUG_PAUSE) Slog.v(TAG, "Finish not pausing: " + r);
Craig Mautnerd44711d2013-02-23 11:24:36 -08002620 return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002621 } else {
2622 if (DEBUG_PAUSE) Slog.v(TAG, "Finish waiting for pause of: " + r);
2623 }
2624
2625 return false;
2626 }
2627
Craig Mautnerf3333272013-04-22 10:55:53 -07002628 static final int FINISH_IMMEDIATELY = 0;
2629 static final int FINISH_AFTER_PAUSE = 1;
2630 static final int FINISH_AFTER_VISIBLE = 2;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002631
Craig Mautnerf3333272013-04-22 10:55:53 -07002632 final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002633 // First things first: if this activity is currently visible,
2634 // and the resumed activity is not yet visible, then hold off on
2635 // finishing until the resumed one becomes visible.
2636 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07002637 if (!mStackSupervisor.mStoppingActivities.contains(r)) {
2638 mStackSupervisor.mStoppingActivities.add(r);
Craig Mautner29219d92013-04-16 20:19:12 -07002639 if (mStackSupervisor.mStoppingActivities.size() > 3
2640 || r.frontOfTask && mTaskHistory.size() <= 1) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002641 // If we already have a few activities waiting to stop,
2642 // then give up on things going idle and start clearing
Craig Mautner29219d92013-04-16 20:19:12 -07002643 // them out. Or if r is the last of activity of the last task the stack
2644 // will be empty and must be cleared immediately.
Craig Mautnerf3333272013-04-22 10:55:53 -07002645 mStackSupervisor.scheduleIdleLocked();
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002646 } else {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002647 mStackSupervisor.checkReadyForSleepLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002648 }
2649 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002650 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r
2651 + " (finish requested)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002652 r.state = ActivityState.STOPPING;
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002653 if (oomAdj) {
2654 mService.updateOomAdjLocked();
2655 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002656 return r;
2657 }
2658
2659 // make sure the record is cleaned out of other places.
Craig Mautnerde4ef022013-04-07 19:01:33 -07002660 mStackSupervisor.mStoppingActivities.remove(r);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002661 mStackSupervisor.mGoingToSleepActivities.remove(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002662 mStackSupervisor.mWaitingVisibleActivities.remove(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002663 if (mResumedActivity == r) {
2664 mResumedActivity = null;
2665 }
2666 final ActivityState prevState = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002667 if (DEBUG_STATES) Slog.v(TAG, "Moving to FINISHING: " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002668 r.state = ActivityState.FINISHING;
2669
2670 if (mode == FINISH_IMMEDIATELY
2671 || prevState == ActivityState.STOPPED
2672 || prevState == ActivityState.INITIALIZING) {
2673 // If this activity is already stopped, we can just finish
2674 // it right now.
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002675 boolean activityRemoved = destroyActivityLocked(r, true,
2676 oomAdj, "finish-imm");
Dianne Hackborn42e620c2012-06-24 13:20:51 -07002677 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07002678 mStackSupervisor.resumeTopActivitiesLocked();
Dianne Hackborn42e620c2012-06-24 13:20:51 -07002679 }
2680 return activityRemoved ? null : r;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002681 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002682
2683 // Need to go through the full pause cycle to get this
2684 // activity into the stopped state and then finish it.
2685 if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
Craig Mautnerf3333272013-04-22 10:55:53 -07002686 mStackSupervisor.mFinishingActivities.add(r);
Martin Wallgrenc8733b82011-08-31 12:39:31 +02002687 r.resumeKeyDispatchingLocked();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002688 mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002689 return r;
2690 }
2691
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002692 void finishAllActivitiesLocked() {
2693 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2694 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2695 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2696 final ActivityRecord r = activities.get(activityNdx);
2697 if (r.finishing) {
2698 continue;
2699 }
2700 Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r);
2701 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
2702 }
2703 }
2704 }
2705
Craig Mautnerd2328952013-03-05 12:46:26 -08002706 final boolean navigateUpToLocked(IBinder token, Intent destIntent, int resultCode,
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002707 Intent resultData) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002708 final ActivityRecord srec = ActivityRecord.forToken(token);
Craig Mautner0247fc82013-02-28 14:32:06 -08002709 final TaskRecord task = srec.task;
2710 final ArrayList<ActivityRecord> activities = task.mActivities;
2711 final int start = activities.indexOf(srec);
2712 if (!mTaskHistory.contains(task) || (start < 0)) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002713 return false;
2714 }
2715 int finishTo = start - 1;
Craig Mautner0247fc82013-02-28 14:32:06 -08002716 ActivityRecord parent = finishTo < 0 ? null : activities.get(finishTo);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002717 boolean foundParentInTask = false;
Craig Mautner0247fc82013-02-28 14:32:06 -08002718 final ComponentName dest = destIntent.getComponent();
2719 if (start > 0 && dest != null) {
2720 for (int i = finishTo; i >= 0; i--) {
2721 ActivityRecord r = activities.get(i);
2722 if (r.info.packageName.equals(dest.getPackageName()) &&
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002723 r.info.name.equals(dest.getClassName())) {
2724 finishTo = i;
2725 parent = r;
2726 foundParentInTask = true;
2727 break;
2728 }
2729 }
2730 }
2731
2732 IActivityController controller = mService.mController;
2733 if (controller != null) {
2734 ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
2735 if (next != null) {
2736 // ask watcher if this is allowed
2737 boolean resumeOK = true;
2738 try {
2739 resumeOK = controller.activityResuming(next.packageName);
2740 } catch (RemoteException e) {
2741 mService.mController = null;
Kenny Rootadd58212013-05-07 09:47:34 -07002742 Watchdog.getInstance().setActivityController(null);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002743 }
2744
2745 if (!resumeOK) {
2746 return false;
2747 }
2748 }
2749 }
2750 final long origId = Binder.clearCallingIdentity();
2751 for (int i = start; i > finishTo; i--) {
Craig Mautner0247fc82013-02-28 14:32:06 -08002752 ActivityRecord r = activities.get(i);
2753 requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002754 // Only return the supplied result for the first activity finished
2755 resultCode = Activity.RESULT_CANCELED;
2756 resultData = null;
2757 }
2758
2759 if (parent != null && foundParentInTask) {
2760 final int parentLaunchMode = parent.info.launchMode;
2761 final int destIntentFlags = destIntent.getFlags();
2762 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
2763 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
2764 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
2765 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2766 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
2767 } else {
2768 try {
2769 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
2770 destIntent.getComponent(), 0, srec.userId);
Craig Mautner6170f732013-04-02 13:05:23 -07002771 int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent,
Dianne Hackborn91097de2014-04-04 18:02:06 -07002772 null, aInfo, null, null, parent.appToken, null,
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002773 0, -1, parent.launchedFromUid, parent.launchedFromPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08002774 0, null, true, null, null);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08002775 foundParentInTask = res == ActivityManager.START_SUCCESS;
2776 } catch (RemoteException e) {
2777 foundParentInTask = false;
2778 }
2779 requestFinishActivityLocked(parent.appToken, resultCode,
2780 resultData, "navigate-up", true);
2781 }
2782 }
2783 Binder.restoreCallingIdentity(origId);
2784 return foundParentInTask;
2785 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002786 /**
2787 * Perform the common clean-up of an activity record. This is called both
2788 * as part of destroyActivityLocked() (when destroying the client-side
2789 * representation) and cleaning things up as a result of its hosting
2790 * processing going away, in which case there is no remaining client-side
2791 * state to destroy so only the cleanup here is needed.
2792 */
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002793 final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices,
2794 boolean setState) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002795 if (mResumedActivity == r) {
2796 mResumedActivity = null;
2797 }
Craig Mautner1872ce32014-03-28 23:05:42 +00002798 if (mPausingActivity == r) {
2799 mPausingActivity = null;
2800 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07002801 mService.clearFocusedActivity(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002802
2803 r.configDestroy = false;
2804 r.frozenBeforeDestroy = false;
2805
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002806 if (setState) {
2807 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (cleaning up)");
2808 r.state = ActivityState.DESTROYED;
Dianne Hackborn07981492013-01-28 11:36:23 -08002809 if (DEBUG_APP) Slog.v(TAG, "Clearing app during cleanUp for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002810 r.app = null;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002811 }
2812
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002813 // Make sure this record is no longer in the pending finishes list.
2814 // This could happen, for example, if we are trimming activities
2815 // down to the max limit while they are still waiting to finish.
Craig Mautnerf3333272013-04-22 10:55:53 -07002816 mStackSupervisor.mFinishingActivities.remove(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002817 mStackSupervisor.mWaitingVisibleActivities.remove(r);
Craig Mautner2420ead2013-04-01 17:13:20 -07002818
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002819 // Remove any pending results.
2820 if (r.finishing && r.pendingResults != null) {
2821 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
2822 PendingIntentRecord rec = apr.get();
2823 if (rec != null) {
2824 mService.cancelIntentSenderLocked(rec, false);
2825 }
2826 }
2827 r.pendingResults = null;
2828 }
2829
2830 if (cleanServices) {
Craig Mautner2420ead2013-04-01 17:13:20 -07002831 cleanUpActivityServicesLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002832 }
2833
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002834 // Get rid of any pending idle timeouts.
Dianne Hackborn42e620c2012-06-24 13:20:51 -07002835 removeTimeoutsForActivityLocked(r);
2836 }
2837
2838 private void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002839 mStackSupervisor.removeTimeoutsForActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002840 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07002841 mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002842 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002843 r.finishLaunchTickingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002844 }
2845
Craig Mautner04a0ea62014-01-13 12:51:26 -08002846 private void removeActivityFromHistoryLocked(ActivityRecord r) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002847 mStackSupervisor.removeChildActivityContainers(r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002848 finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
2849 r.makeFinishing();
2850 if (DEBUG_ADD_REMOVE) {
2851 RuntimeException here = new RuntimeException("here");
2852 here.fillInStackTrace();
2853 Slog.i(TAG, "Removing activity " + r + " from stack");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002854 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002855 r.takeFromHistory();
2856 removeTimeoutsForActivityLocked(r);
Craig Mautner0247fc82013-02-28 14:32:06 -08002857 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (removed from history)");
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002858 r.state = ActivityState.DESTROYED;
Dianne Hackborn07981492013-01-28 11:36:23 -08002859 if (DEBUG_APP) Slog.v(TAG, "Clearing app during remove for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002860 r.app = null;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002861 mWindowManager.removeAppToken(r.appToken);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002862 if (VALIDATE_TOKENS) {
2863 validateAppTokensLocked();
2864 }
Craig Mautner312ba862014-02-10 17:55:01 -08002865 final TaskRecord task = r.task;
2866 if (task != null && task.removeActivity(r)) {
2867 if (DEBUG_STACK) Slog.i(TAG,
2868 "removeActivityFromHistoryLocked: last activity removed from " + this);
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00002869 if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) {
2870 mStackSupervisor.moveHomeToTop();
Craig Mautner312ba862014-02-10 17:55:01 -08002871 }
Craig Mautner41db4a72014-05-07 17:20:56 -07002872 removeTask(task);
Craig Mautner312ba862014-02-10 17:55:01 -08002873 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002874 cleanUpActivityServicesLocked(r);
2875 r.removeUriPermissionsLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002876 }
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07002877
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002878 /**
2879 * Perform clean-up of service connections in an activity record.
2880 */
2881 final void cleanUpActivityServicesLocked(ActivityRecord r) {
2882 // Throw away any services that have been bound by this activity.
2883 if (r.connections != null) {
2884 Iterator<ConnectionRecord> it = r.connections.iterator();
2885 while (it.hasNext()) {
2886 ConnectionRecord c = it.next();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002887 mService.mServices.removeConnectionLocked(c, null, r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002888 }
2889 r.connections = null;
2890 }
2891 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07002892
2893 final void scheduleDestroyActivities(ProcessRecord owner, boolean oomAdj, String reason) {
2894 Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG);
2895 msg.obj = new ScheduleDestroyArgs(owner, oomAdj, reason);
2896 mHandler.sendMessage(msg);
2897 }
2898
Dianne Hackborn28695e02011-11-02 21:59:51 -07002899 final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String reason) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07002900 boolean lastIsOpaque = false;
Dianne Hackborn42e620c2012-06-24 13:20:51 -07002901 boolean activityRemoved = false;
Craig Mautnerd44711d2013-02-23 11:24:36 -08002902 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2903 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2904 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2905 final ActivityRecord r = activities.get(activityNdx);
2906 if (r.finishing) {
2907 continue;
2908 }
2909 if (r.fullscreen) {
2910 lastIsOpaque = true;
2911 }
2912 if (owner != null && r.app != owner) {
2913 continue;
2914 }
2915 if (!lastIsOpaque) {
2916 continue;
2917 }
2918 // We can destroy this one if we have its icicle saved and
2919 // it is not in the process of pausing/stopping/finishing.
2920 if (r.app != null && r != mResumedActivity && r != mPausingActivity
2921 && r.haveState && !r.visible && r.stopped
2922 && r.state != ActivityState.DESTROYING
2923 && r.state != ActivityState.DESTROYED) {
2924 if (DEBUG_SWITCH) Slog.v(TAG, "Destroying " + r + " in state " + r.state
2925 + " resumed=" + mResumedActivity
2926 + " pausing=" + mPausingActivity);
2927 if (destroyActivityLocked(r, true, oomAdj, reason)) {
2928 activityRemoved = true;
2929 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07002930 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002931 }
2932 }
Dianne Hackborn42e620c2012-06-24 13:20:51 -07002933 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07002934 mStackSupervisor.resumeTopActivitiesLocked();
Dianne Hackborn42e620c2012-06-24 13:20:51 -07002935 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002936 }
2937
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002938 /**
2939 * Destroy the current CLIENT SIDE instance of an activity. This may be
2940 * called both when actually finishing an activity, or when performing
2941 * a configuration switch where we destroy the current client-side object
2942 * but then create a new client-side object for this same HistoryRecord.
2943 */
2944 final boolean destroyActivityLocked(ActivityRecord r,
Dianne Hackborn28695e02011-11-02 21:59:51 -07002945 boolean removeFromApp, boolean oomAdj, String reason) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002946 if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07002947 TAG, "Removing activity from " + reason + ": token=" + r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002948 + ", app=" + (r.app != null ? r.app.processName : "(null)"));
2949 EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07002950 r.userId, System.identityHashCode(r),
Dianne Hackborn28695e02011-11-02 21:59:51 -07002951 r.task.taskId, r.shortComponentName, reason);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002952
2953 boolean removedFromHistory = false;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002954
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002955 cleanUpActivityLocked(r, false, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002956
2957 final boolean hadApp = r.app != null;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002958
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002959 if (hadApp) {
2960 if (removeFromApp) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002961 r.app.activities.remove(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002962 if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
2963 mService.mHeavyWeightProcess = null;
2964 mService.mHandler.sendEmptyMessage(
2965 ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
2966 }
Craig Mautnerc8143c62013-09-03 12:15:57 -07002967 if (r.app.activities.isEmpty()) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07002968 // No longer have activities, so update LRU list and oom adj.
Dianne Hackborndb926082013-10-31 16:32:44 -07002969 mService.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002970 mService.updateOomAdjLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002971 }
2972 }
2973
2974 boolean skipDestroy = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07002975
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002976 try {
2977 if (DEBUG_SWITCH) Slog.i(TAG, "Destroying: " + r);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002978 r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002979 r.configChangeFlags);
2980 } catch (Exception e) {
2981 // We can just ignore exceptions here... if the process
2982 // has crashed, our death notification will clean things
2983 // up.
2984 //Slog.w(TAG, "Exception thrown during finish", e);
2985 if (r.finishing) {
2986 removeActivityFromHistoryLocked(r);
2987 removedFromHistory = true;
2988 skipDestroy = true;
2989 }
2990 }
2991
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002992 r.nowVisible = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07002993
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002994 // If the activity is finishing, we need to wait on removing it
2995 // from the list to give it a chance to do its cleanup. During
2996 // that time it may make calls back with its token so we need to
2997 // be able to find it on the list and so we don't want to remove
2998 // it from the list yet. Otherwise, we can just immediately put
2999 // it in the destroyed state since we are not removing it from the
3000 // list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003001 if (r.finishing && !skipDestroy) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003002 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYING: " + r
3003 + " (destroy requested)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003004 r.state = ActivityState.DESTROYING;
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07003005 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003006 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
3007 } else {
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07003008 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (destroy skipped)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003009 r.state = ActivityState.DESTROYED;
Dianne Hackborn07981492013-01-28 11:36:23 -08003010 if (DEBUG_APP) Slog.v(TAG, "Clearing app during destroy for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003011 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003012 }
3013 } else {
3014 // remove this record from the history.
3015 if (r.finishing) {
3016 removeActivityFromHistoryLocked(r);
3017 removedFromHistory = true;
3018 } else {
Craig Mautnerf7bfefb2013-05-16 17:30:44 -07003019 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (no app)");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003020 r.state = ActivityState.DESTROYED;
Dianne Hackborn07981492013-01-28 11:36:23 -08003021 if (DEBUG_APP) Slog.v(TAG, "Clearing app during destroy for activity " + r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003022 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003023 }
3024 }
3025
3026 r.configChangeFlags = 0;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07003027
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003028 if (!mLRUActivities.remove(r) && hadApp) {
3029 Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
3030 }
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07003031
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003032 return removedFromHistory;
3033 }
3034
Craig Mautnerd2328952013-03-05 12:46:26 -08003035 final void activityDestroyedLocked(IBinder token) {
3036 final long origId = Binder.clearCallingIdentity();
3037 try {
3038 ActivityRecord r = ActivityRecord.forToken(token);
3039 if (r != null) {
3040 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003041 }
Craig Mautnerd2328952013-03-05 12:46:26 -08003042
3043 if (isInStackLocked(token) != null) {
3044 if (r.state == ActivityState.DESTROYING) {
3045 cleanUpActivityLocked(r, true, false);
3046 removeActivityFromHistoryLocked(r);
3047 }
3048 }
Craig Mautner05d29032013-05-03 13:40:13 -07003049 mStackSupervisor.resumeTopActivitiesLocked();
Craig Mautnerd2328952013-03-05 12:46:26 -08003050 } finally {
3051 Binder.restoreCallingIdentity(origId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003052 }
3053 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07003054
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003055 private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
3056 ProcessRecord app, String listName) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003057 int i = list.size();
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003058 if (DEBUG_CLEANUP) Slog.v(
3059 TAG, "Removing app " + app + " from list " + listName
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003060 + " with " + i + " entries");
3061 while (i > 0) {
3062 i--;
Craig Mautner05d6272ba2013-02-11 09:39:27 -08003063 ActivityRecord r = list.get(i);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003064 if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003065 if (r.app == app) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003066 if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003067 list.remove(i);
Dianne Hackborn42e620c2012-06-24 13:20:51 -07003068 removeTimeoutsForActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003069 }
3070 }
3071 }
3072
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003073 boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
3074 removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
Craig Mautnerde4ef022013-04-07 19:01:33 -07003075 removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
3076 "mStoppingActivities");
Craig Mautner0eea92c2013-05-16 13:35:39 -07003077 removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
3078 "mGoingToSleepActivities");
Craig Mautnerde4ef022013-04-07 19:01:33 -07003079 removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003080 "mWaitingVisibleActivities");
Craig Mautnerf3333272013-04-22 10:55:53 -07003081 removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
3082 "mFinishingActivities");
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003083
3084 boolean hasVisibleActivities = false;
3085
3086 // Clean out the history list.
Craig Mautner0247fc82013-02-28 14:32:06 -08003087 int i = numActivities();
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003088 if (DEBUG_CLEANUP) Slog.v(
3089 TAG, "Removing app " + app + " from history with " + i + " entries");
Craig Mautner0247fc82013-02-28 14:32:06 -08003090 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3091 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3092 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3093 final ActivityRecord r = activities.get(activityNdx);
3094 --i;
3095 if (DEBUG_CLEANUP) Slog.v(
3096 TAG, "Record #" + i + " " + r + ": app=" + r.app);
3097 if (r.app == app) {
3098 boolean remove;
3099 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
3100 // Don't currently have state for the activity, or
3101 // it is finishing -- always remove it.
3102 remove = true;
3103 } else if (r.launchCount > 2 &&
3104 r.lastLaunchTime > (SystemClock.uptimeMillis()-60000)) {
3105 // We have launched this activity too many times since it was
3106 // able to run, so give up and remove it.
3107 remove = true;
3108 } else {
3109 // The process may be gone, but the activity lives on!
3110 remove = false;
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003111 }
Craig Mautner0247fc82013-02-28 14:32:06 -08003112 if (remove) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07003113 if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
Craig Mautner0247fc82013-02-28 14:32:06 -08003114 RuntimeException here = new RuntimeException("here");
3115 here.fillInStackTrace();
3116 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
3117 + ": haveState=" + r.haveState
3118 + " stateNotNeeded=" + r.stateNotNeeded
3119 + " finishing=" + r.finishing
3120 + " state=" + r.state, here);
3121 }
3122 if (!r.finishing) {
3123 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
3124 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3125 r.userId, System.identityHashCode(r),
3126 r.task.taskId, r.shortComponentName,
3127 "proc died without state saved");
Jeff Sharkey5782da72013-04-25 14:32:30 -07003128 if (r.state == ActivityState.RESUMED) {
3129 mService.updateUsageStats(r, false);
3130 }
Craig Mautner0247fc82013-02-28 14:32:06 -08003131 }
3132 removeActivityFromHistoryLocked(r);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003133
Craig Mautner0247fc82013-02-28 14:32:06 -08003134 } else {
3135 // We have the current state for this activity, so
3136 // it can be restarted later when needed.
3137 if (localLOGV) Slog.v(
3138 TAG, "Keeping entry, setting app to null");
3139 if (r.visible) {
3140 hasVisibleActivities = true;
3141 }
3142 if (DEBUG_APP) Slog.v(TAG, "Clearing app during removeHistory for activity "
3143 + r);
3144 r.app = null;
3145 r.nowVisible = false;
3146 if (!r.haveState) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07003147 if (DEBUG_SAVED_STATE) Slog.i(TAG,
Craig Mautner0247fc82013-02-28 14:32:06 -08003148 "App died, clearing saved state of " + r);
3149 r.icicle = null;
3150 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003151 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003152
Craig Mautnerd2328952013-03-05 12:46:26 -08003153 cleanUpActivityLocked(r, true, true);
Craig Mautner0247fc82013-02-28 14:32:06 -08003154 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003155 }
3156 }
3157
3158 return hasVisibleActivities;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003159 }
Craig Mautner0247fc82013-02-28 14:32:06 -08003160
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003161 final void updateTransitLocked(int transit, Bundle options) {
3162 if (options != null) {
3163 ActivityRecord r = topRunningActivityLocked(null);
3164 if (r != null && r.state != ActivityState.RESUMED) {
3165 r.updateOptionsLocked(options);
3166 } else {
3167 ActivityOptions.abort(options);
3168 }
3169 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003170 mWindowManager.prepareAppTransition(transit, false);
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003171 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003172
Craig Mautner21d24a22014-04-23 11:45:37 -07003173 void updateTaskMovement(TaskRecord task, boolean toFront) {
3174 if (task.isPersistable) {
3175 task.mLastTimeMoved = System.currentTimeMillis();
3176 // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
3177 // recently will be most negative, tasks sent to the bottom before that will be less
3178 // negative. Similarly for recent tasks moved to the top which will be most positive.
3179 if (!toFront) {
3180 task.mLastTimeMoved *= -1;
3181 }
3182 }
3183 }
3184
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00003185 void moveHomeTaskToTop() {
Craig Mautnera82aa092013-09-13 15:34:08 -07003186 final int top = mTaskHistory.size() - 1;
3187 for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
3188 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00003189 if (task.isHomeTask()) {
3190 if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG, "moveHomeTaskToTop: moving " + task);
Craig Mautnera82aa092013-09-13 15:34:08 -07003191 mTaskHistory.remove(taskNdx);
3192 mTaskHistory.add(top, task);
Craig Mautner21d24a22014-04-23 11:45:37 -07003193 updateTaskMovement(task, true);
Craig Mautnera82aa092013-09-13 15:34:08 -07003194 mWindowManager.moveTaskToTop(task.taskId);
3195 return;
3196 }
3197 }
3198 }
3199
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003200 final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08003201 if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003202
Craig Mautner11bf9a52013-02-19 14:08:51 -08003203 final int numTasks = mTaskHistory.size();
3204 final int index = mTaskHistory.indexOf(tr);
Craig Mautner86d67a42013-05-14 10:34:38 -07003205 if (numTasks == 0 || index < 0) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08003206 // nothing to do!
3207 if (reason != null &&
3208 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
3209 ActivityOptions.abort(options);
3210 } else {
3211 updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
3212 }
3213 return;
3214 }
3215
Craig Mautnere0a38842013-12-16 16:14:02 -08003216 moveToFront();
Craig Mautnerfb1e20d2013-06-23 21:24:13 -07003217
Craig Mautner11bf9a52013-02-19 14:08:51 -08003218 // Shift all activities with this task up to the top
3219 // of the stack, keeping them in the same internal order.
Craig Mautnerac6f8432013-07-17 13:24:59 -07003220 insertTaskAtTop(tr);
Craig Mautner11bf9a52013-02-19 14:08:51 -08003221
3222 if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003223 if (reason != null &&
3224 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003225 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003226 ActivityRecord r = topRunningActivityLocked(null);
3227 if (r != null) {
3228 mNoAnimActivities.add(r);
3229 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003230 ActivityOptions.abort(options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003231 } else {
Craig Mautner4b71aa12012-12-27 17:20:01 -08003232 updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003233 }
Craig Mautner30e2d722013-02-12 11:30:16 -08003234
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003235 mWindowManager.moveTaskToTop(tr.taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003236
Craig Mautner05d29032013-05-03 13:40:13 -07003237 mStackSupervisor.resumeTopActivitiesLocked();
Craig Mautner58547802013-03-05 08:23:53 -08003238 EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
Craig Mautner11bf9a52013-02-19 14:08:51 -08003239
3240 if (VALIDATE_TOKENS) {
3241 validateAppTokensLocked();
3242 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003243 }
3244
3245 /**
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003246 * Worker method for rearranging history stack. Implements the function of moving all
3247 * activities for a specific task (gathering them if disjoint) into a single group at the
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003248 * bottom of the stack.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003249 *
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003250 * If a watcher is installed, the action is preflighted and the watcher has an opportunity
3251 * to premeptively cancel the move.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003252 *
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003253 * @param taskId The taskId to collect and move to the bottom.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003254 * @return Returns true if the move completed, false if not.
3255 */
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003256 final boolean moveTaskToBackLocked(int taskId, ActivityRecord reason) {
Craig Mautneraea74a52014-03-08 14:23:10 -08003257 final TaskRecord tr = taskForIdLocked(taskId);
3258 if (tr == null) {
3259 Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
3260 return false;
3261 }
3262
3263 Slog.i(TAG, "moveTaskToBack: " + tr);
3264
3265 mStackSupervisor.endLockTaskModeIfTaskEnding(tr);
Craig Mautnerb44de0d2013-02-21 20:00:58 -08003266
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003267 // If we have a watcher, preflight the move before committing to it. First check
3268 // for *other* available tasks, but if none are available, then try again allowing the
3269 // current task to be selected.
Craig Mautnerde4ef022013-04-07 19:01:33 -07003270 if (mStackSupervisor.isFrontStack(this) && mService.mController != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003271 ActivityRecord next = topRunningActivityLocked(null, taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003272 if (next == null) {
3273 next = topRunningActivityLocked(null, 0);
3274 }
3275 if (next != null) {
3276 // ask watcher if this is allowed
3277 boolean moveOK = true;
3278 try {
3279 moveOK = mService.mController.activityResuming(next.packageName);
3280 } catch (RemoteException e) {
3281 mService.mController = null;
Kenny Rootadd58212013-05-07 09:47:34 -07003282 Watchdog.getInstance().setActivityController(null);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003283 }
3284 if (!moveOK) {
3285 return false;
3286 }
3287 }
3288 }
3289
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003290 if (DEBUG_TRANSITION) Slog.v(TAG,
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003291 "Prepare to back transition: task=" + taskId);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003292
Craig Mautner11bf9a52013-02-19 14:08:51 -08003293 mTaskHistory.remove(tr);
3294 mTaskHistory.add(0, tr);
Craig Mautner21d24a22014-04-23 11:45:37 -07003295 updateTaskMovement(tr, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003296
Craig Mautnerc8143c62013-09-03 12:15:57 -07003297 // There is an assumption that moving a task to the back moves it behind the home activity.
3298 // We make sure here that some activity in the stack will launch home.
Craig Mautnerc8143c62013-09-03 12:15:57 -07003299 int numTasks = mTaskHistory.size();
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003300 for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
3301 final TaskRecord task = mTaskHistory.get(taskNdx);
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00003302 if (task.mOnTopOfHome) {
Craig Mautnerc8143c62013-09-03 12:15:57 -07003303 break;
3304 }
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003305 if (taskNdx == 1) {
3306 // Set the last task before tr to go to home.
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00003307 task.mOnTopOfHome = true;
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003308 }
Craig Mautnerc8143c62013-09-03 12:15:57 -07003309 }
3310
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003311 if (reason != null &&
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003312 (reason.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
3313 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003314 ActivityRecord r = topRunningActivityLocked(null);
3315 if (r != null) {
3316 mNoAnimActivities.add(r);
3317 }
3318 } else {
Craig Mautnerc8143c62013-09-03 12:15:57 -07003319 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_TO_BACK, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003320 }
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003321 mWindowManager.moveTaskToBottom(taskId);
Craig Mautnerb44de0d2013-02-21 20:00:58 -08003322
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003323 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003324 validateAppTokensLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003325 }
3326
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003327 final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null;
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00003328 if (task == tr && tr.mOnTopOfHome || numTasks <= 1 && isOnHomeDisplay()) {
3329 tr.mOnTopOfHome = false;
3330 return mStackSupervisor.resumeHomeActivity(null);
Craig Mautnerde4ef022013-04-07 19:01:33 -07003331 }
3332
Craig Mautner05d29032013-05-03 13:40:13 -07003333 mStackSupervisor.resumeTopActivitiesLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003334 return true;
3335 }
Dianne Hackborn15491c62012-09-19 10:59:14 -07003336
Craig Mautner8849a5e2013-04-02 16:41:03 -07003337 static final void logStartActivity(int tag, ActivityRecord r,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003338 TaskRecord task) {
Santos Cordon73ff7d82013-03-06 17:24:11 -08003339 final Uri data = r.intent.getData();
3340 final String strData = data != null ? data.toSafeString() : null;
3341
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003342 EventLog.writeEvent(tag,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003343 r.userId, System.identityHashCode(r), task.taskId,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003344 r.shortComponentName, r.intent.getAction(),
Santos Cordon73ff7d82013-03-06 17:24:11 -08003345 r.intent.getType(), strData, r.intent.getFlags());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003346 }
3347
3348 /**
3349 * Make sure the given activity matches the current configuration. Returns
3350 * false if the activity had to be destroyed. Returns true if the
3351 * configuration is the same, or the activity will remain running as-is
3352 * for whatever reason. Ensures the HistoryRecord is updated with the
3353 * correct configuration and all other bookkeeping is handled.
3354 */
3355 final boolean ensureActivityConfigurationLocked(ActivityRecord r,
3356 int globalChanges) {
3357 if (mConfigWillChange) {
3358 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
3359 "Skipping config check (will change): " + r);
3360 return true;
3361 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003362
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003363 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
3364 "Ensuring correct configuration: " + r);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07003365
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003366 // Short circuit: if the two configurations are the exact same
3367 // object (the common case), then there is nothing to do.
3368 Configuration newConfig = mService.mConfiguration;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003369 if (r.configuration == newConfig && !r.forceNewConfig) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003370 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
3371 "Configuration unchanged in " + r);
3372 return true;
3373 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003374
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003375 // We don't worry about activities that are finishing.
3376 if (r.finishing) {
3377 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
3378 "Configuration doesn't matter in finishing " + r);
3379 r.stopFreezingScreenLocked(false);
3380 return true;
3381 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003382
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003383 // Okay we now are going to make this activity have the new config.
3384 // But then we need to figure out how it needs to deal with that.
3385 Configuration oldConfig = r.configuration;
3386 r.configuration = newConfig;
Dianne Hackborn58f42a52011-10-10 13:46:34 -07003387
3388 // Determine what has changed. May be nothing, if this is a config
3389 // that has come back from the app after going idle. In that case
3390 // we just want to leave the official config object now in the
3391 // activity and do nothing else.
3392 final int changes = oldConfig.diff(newConfig);
3393 if (changes == 0 && !r.forceNewConfig) {
3394 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
3395 "Configuration no differences in " + r);
3396 return true;
3397 }
3398
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003399 // If the activity isn't currently running, just leave the new
3400 // configuration and it will pick that up next time it starts.
3401 if (r.app == null || r.app.thread == null) {
3402 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
3403 "Configuration doesn't matter not running " + r);
3404 r.stopFreezingScreenLocked(false);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003405 r.forceNewConfig = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003406 return true;
3407 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003408
Dianne Hackborn58f42a52011-10-10 13:46:34 -07003409 // Figure out how to handle the changes between the configurations.
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003410 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
3411 Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
3412 + Integer.toHexString(changes) + ", handles=0x"
Dianne Hackborne6676352011-06-01 16:51:20 -07003413 + Integer.toHexString(r.info.getRealConfigChanged())
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003414 + ", newConfig=" + newConfig);
3415 }
Dianne Hackborne6676352011-06-01 16:51:20 -07003416 if ((changes&(~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) {
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003417 // Aha, the activity isn't handling the change, so DIE DIE DIE.
3418 r.configChangeFlags |= changes;
3419 r.startFreezingScreenLocked(r.app, globalChanges);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003420 r.forceNewConfig = false;
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003421 if (r.app == null || r.app.thread == null) {
3422 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
Dianne Hackbornb61a0262012-05-14 17:19:18 -07003423 "Config is destroying non-running " + r);
Dianne Hackborn28695e02011-11-02 21:59:51 -07003424 destroyActivityLocked(r, true, false, "config");
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003425 } else if (r.state == ActivityState.PAUSING) {
3426 // A little annoying: we are waiting for this activity to
3427 // finish pausing. Let's not do anything now, but just
3428 // flag that it needs to be restarted when done pausing.
3429 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
Dianne Hackbornb61a0262012-05-14 17:19:18 -07003430 "Config is skipping already pausing " + r);
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003431 r.configDestroy = true;
3432 return true;
3433 } else if (r.state == ActivityState.RESUMED) {
3434 // Try to optimize this case: the configuration is changing
3435 // and we need to restart the top, resumed activity.
3436 // Instead of doing the normal handshaking, just say
3437 // "restart!".
3438 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
Dianne Hackbornb61a0262012-05-14 17:19:18 -07003439 "Config is relaunching resumed " + r);
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003440 relaunchActivityLocked(r, r.configChangeFlags, true);
3441 r.configChangeFlags = 0;
3442 } else {
3443 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
Dianne Hackbornb61a0262012-05-14 17:19:18 -07003444 "Config is relaunching non-resumed " + r);
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003445 relaunchActivityLocked(r, r.configChangeFlags, false);
3446 r.configChangeFlags = 0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003447 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003448
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -07003449 // All done... tell the caller we weren't able to keep this
3450 // activity around.
3451 return false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003452 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003453
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003454 // Default case: the activity can handle this new configuration, so
3455 // hand it over. Note that we don't need to give it the new
3456 // configuration, since we always send configuration changes to all
3457 // process when they happen so it can just use whatever configuration
3458 // it last got.
3459 if (r.app != null && r.app.thread != null) {
3460 try {
3461 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + r);
Dianne Hackbornbe707852011-11-11 14:32:10 -08003462 r.app.thread.scheduleActivityConfigurationChanged(r.appToken);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003463 } catch (RemoteException e) {
3464 // If process died, whatever.
3465 }
3466 }
3467 r.stopFreezingScreenLocked(false);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003468
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003469 return true;
3470 }
3471
Craig Mautnerc8143c62013-09-03 12:15:57 -07003472 private boolean relaunchActivityLocked(ActivityRecord r,
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003473 int changes, boolean andResume) {
3474 List<ResultInfo> results = null;
3475 List<Intent> newIntents = null;
3476 if (andResume) {
3477 results = r.results;
3478 newIntents = r.newIntents;
3479 }
3480 if (DEBUG_SWITCH) Slog.v(TAG, "Relaunching: " + r
3481 + " with results=" + results + " newIntents=" + newIntents
3482 + " andResume=" + andResume);
3483 EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003484 : EventLogTags.AM_RELAUNCH_ACTIVITY, r.userId, System.identityHashCode(r),
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003485 r.task.taskId, r.shortComponentName);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07003486
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003487 r.startFreezingScreenLocked(r.app, 0);
Craig Mautner9db9a0b2013-04-29 17:05:56 -07003488
Craig Mautner34b73df2014-01-12 21:11:08 -08003489 mStackSupervisor.removeChildActivityContainers(r);
3490
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003491 try {
Dianne Hackbornb61a0262012-05-14 17:19:18 -07003492 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,
3493 (andResume ? "Relaunching to RESUMED " : "Relaunching to PAUSED ")
3494 + r);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003495 r.forceNewConfig = false;
Dianne Hackbornbe707852011-11-11 14:32:10 -08003496 r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003497 changes, !andResume, new Configuration(mService.mConfiguration));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003498 // Note: don't need to call pauseIfSleepingLocked() here, because
3499 // the caller will only pass in 'andResume' if this activity is
3500 // currently resumed, which implies we aren't sleeping.
3501 } catch (RemoteException e) {
Dianne Hackbornb61a0262012-05-14 17:19:18 -07003502 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG, "Relaunch failed", e);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003503 }
3504
3505 if (andResume) {
3506 r.results = null;
3507 r.newIntents = null;
Dianne Hackbornb61a0262012-05-14 17:19:18 -07003508 r.state = ActivityState.RESUMED;
3509 } else {
3510 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
3511 r.state = ActivityState.PAUSED;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003512 }
3513
3514 return true;
3515 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003516
3517 boolean willActivityBeVisibleLocked(IBinder token) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08003518 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3519 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3520 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3521 final ActivityRecord r = activities.get(activityNdx);
3522 if (r.appToken == token) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003523 return true;
Craig Mautnerd44711d2013-02-23 11:24:36 -08003524 }
3525 if (r.fullscreen && !r.finishing) {
3526 return false;
3527 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003528 }
3529 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003530 final ActivityRecord r = ActivityRecord.forToken(token);
3531 if (r == null) {
3532 return false;
3533 }
3534 if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false,"
3535 + " would have returned true for r=" + r);
3536 return !r.finishing;
Craig Mautnercae015f2013-02-08 14:31:27 -08003537 }
3538
3539 void closeSystemDialogsLocked() {
Craig Mautnerd44711d2013-02-23 11:24:36 -08003540 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3541 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3542 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3543 final ActivityRecord r = activities.get(activityNdx);
3544 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Craig Mautnerd2328952013-03-05 12:46:26 -08003545 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
Craig Mautnerd44711d2013-02-23 11:24:36 -08003546 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003547 }
3548 }
3549 }
3550
3551 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
3552 boolean didSomething = false;
3553 TaskRecord lastTask = null;
Craig Mautner56f52db2013-02-25 10:03:01 -08003554 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3555 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3556 int numActivities = activities.size();
3557 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
3558 ActivityRecord r = activities.get(activityNdx);
3559 final boolean samePackage = r.packageName.equals(name)
3560 || (name == null && r.userId == userId);
3561 if ((userId == UserHandle.USER_ALL || r.userId == userId)
3562 && (samePackage || r.task == lastTask)
3563 && (r.app == null || evenPersistent || !r.app.persistent)) {
3564 if (!doit) {
3565 if (r.finishing) {
3566 // If this activity is just finishing, then it is not
3567 // interesting as far as something to stop.
3568 continue;
3569 }
3570 return true;
Craig Mautnercae015f2013-02-08 14:31:27 -08003571 }
Craig Mautner56f52db2013-02-25 10:03:01 -08003572 didSomething = true;
3573 Slog.i(TAG, " Force finishing activity " + r);
3574 if (samePackage) {
3575 if (r.app != null) {
3576 r.app.removed = true;
3577 }
3578 r.app = null;
Craig Mautnercae015f2013-02-08 14:31:27 -08003579 }
Craig Mautner56f52db2013-02-25 10:03:01 -08003580 lastTask = r.task;
Craig Mautnerd94b1b42013-05-01 11:58:03 -07003581 if (finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
3582 true)) {
3583 // r has been deleted from mActivities, accommodate.
3584 --numActivities;
3585 --activityNdx;
3586 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003587 }
3588 }
3589 }
3590 return didSomething;
3591 }
3592
Dianne Hackborn09233282014-04-30 11:33:59 -07003593 void getTasksLocked(List<RunningTaskInfo> list, int callingUid, boolean allowed) {
Craig Mautnerc0fd8052013-09-19 11:20:17 -07003594 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautneraab647e2013-02-28 16:31:36 -08003595 final TaskRecord task = mTaskHistory.get(taskNdx);
3596 ActivityRecord r = null;
3597 ActivityRecord top = null;
3598 int numActivities = 0;
3599 int numRunning = 0;
3600 final ArrayList<ActivityRecord> activities = task.mActivities;
Craig Mautner5cbaaa32013-10-29 13:39:26 -07003601 if (activities.isEmpty()) {
3602 continue;
3603 }
Dianne Hackborn09233282014-04-30 11:33:59 -07003604 if (!allowed && !task.isHomeTask() && task.creatorUid != callingUid) {
3605 continue;
3606 }
Craig Mautneraab647e2013-02-28 16:31:36 -08003607 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3608 r = activities.get(activityNdx);
Craig Mautnercae015f2013-02-08 14:31:27 -08003609
Craig Mautneraab647e2013-02-28 16:31:36 -08003610 // Initialize state for next task if needed.
3611 if (top == null || (top.state == ActivityState.INITIALIZING)) {
3612 top = r;
3613 numActivities = numRunning = 0;
Craig Mautnercae015f2013-02-08 14:31:27 -08003614 }
Craig Mautneraab647e2013-02-28 16:31:36 -08003615
3616 // Add 'r' into the current task.
3617 numActivities++;
3618 if (r.app != null && r.app.thread != null) {
3619 numRunning++;
3620 }
3621
3622 if (localLOGV) Slog.v(
3623 TAG, r.intent.getComponent().flattenToShortString()
3624 + ": task=" + r.task);
3625 }
3626
3627 RunningTaskInfo ci = new RunningTaskInfo();
3628 ci.id = task.taskId;
3629 ci.baseActivity = r.intent.getComponent();
3630 ci.topActivity = top.intent.getComponent();
Craig Mautnerc0fd8052013-09-19 11:20:17 -07003631 ci.lastActiveTime = task.lastActiveTime;
3632
Craig Mautneraab647e2013-02-28 16:31:36 -08003633 if (top.thumbHolder != null) {
3634 ci.description = top.thumbHolder.lastDescription;
3635 }
3636 ci.numActivities = numActivities;
3637 ci.numRunning = numRunning;
3638 //System.out.println(
3639 // "#" + maxNum + ": " + " descr=" + ci.description);
Craig Mautneraab647e2013-02-28 16:31:36 -08003640 list.add(ci);
Craig Mautnercae015f2013-02-08 14:31:27 -08003641 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003642 }
3643
3644 public void unhandledBackLocked() {
Craig Mautneraab647e2013-02-28 16:31:36 -08003645 final int top = mTaskHistory.size() - 1;
Craig Mautnercae015f2013-02-08 14:31:27 -08003646 if (DEBUG_SWITCH) Slog.d(
3647 TAG, "Performing unhandledBack(): top activity at " + top);
Craig Mautneraab647e2013-02-28 16:31:36 -08003648 if (top >= 0) {
3649 final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
3650 int activityTop = activities.size() - 1;
3651 if (activityTop > 0) {
3652 finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
3653 "unhandled-back", true);
3654 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003655 }
3656 }
3657
Craig Mautner6b74cb52013-09-27 17:02:21 -07003658 /**
3659 * Reset local parameters because an app's activity died.
3660 * @param app The app of the activity that died.
Craig Mautner19091252013-10-05 00:03:53 -07003661 * @return result from removeHistoryRecordsForAppLocked.
Craig Mautner6b74cb52013-09-27 17:02:21 -07003662 */
3663 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautnere79d42682013-04-01 19:01:53 -07003664 if (mPausingActivity != null && mPausingActivity.app == app) {
3665 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
3666 "App died while pausing: " + mPausingActivity);
3667 mPausingActivity = null;
3668 }
3669 if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
3670 mLastPausedActivity = null;
Craig Mautner0f922742013-08-06 08:44:42 -07003671 mLastNoHistoryActivity = null;
Craig Mautnere79d42682013-04-01 19:01:53 -07003672 }
3673
Craig Mautner19091252013-10-05 00:03:53 -07003674 return removeHistoryRecordsForAppLocked(app);
Craig Mautnere79d42682013-04-01 19:01:53 -07003675 }
3676
Craig Mautnercae015f2013-02-08 14:31:27 -08003677 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnerd44711d2013-02-23 11:24:36 -08003678 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3679 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3680 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3681 final ActivityRecord r = activities.get(activityNdx);
3682 if (r.app == app) {
3683 Slog.w(TAG, " Force finishing activity "
3684 + r.intent.getComponent().flattenToShortString());
Craig Mautnerd2328952013-03-05 12:46:26 -08003685 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
Craig Mautnerd44711d2013-02-23 11:24:36 -08003686 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003687 }
3688 }
3689 }
3690
Dianne Hackborn390517b2013-05-30 15:03:32 -07003691 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07003692 boolean dumpClient, String dumpPackage, boolean needSep, String header) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07003693 boolean printed = false;
Craig Mautneraab647e2013-02-28 16:31:36 -08003694 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3695 final TaskRecord task = mTaskHistory.get(taskNdx);
Dianne Hackborn390517b2013-05-30 15:03:32 -07003696 printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
3697 mTaskHistory.get(taskNdx).mActivities, " ", "Hist", true, !dumpAll,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07003698 dumpClient, dumpPackage, needSep, header,
Craig Mautnerac6f8432013-07-17 13:24:59 -07003699 " Task id #" + task.taskId);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07003700 if (printed) {
3701 header = null;
3702 }
Craig Mautneraab647e2013-02-28 16:31:36 -08003703 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07003704 return printed;
Craig Mautnercae015f2013-02-08 14:31:27 -08003705 }
3706
3707 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3708 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
3709
3710 if ("all".equals(name)) {
Craig Mautneraab647e2013-02-28 16:31:36 -08003711 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3712 activities.addAll(mTaskHistory.get(taskNdx).mActivities);
Craig Mautnercae015f2013-02-08 14:31:27 -08003713 }
3714 } else if ("top".equals(name)) {
Craig Mautneraab647e2013-02-28 16:31:36 -08003715 final int top = mTaskHistory.size() - 1;
3716 if (top >= 0) {
3717 final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities;
3718 int listTop = list.size() - 1;
3719 if (listTop >= 0) {
3720 activities.add(list.get(listTop));
3721 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003722 }
3723 } else {
3724 ItemMatcher matcher = new ItemMatcher();
3725 matcher.build(name);
3726
Craig Mautneraab647e2013-02-28 16:31:36 -08003727 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3728 for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) {
3729 if (matcher.match(r1, r1.intent.getComponent())) {
3730 activities.add(r1);
3731 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003732 }
3733 }
3734 }
3735
3736 return activities;
3737 }
3738
3739 ActivityRecord restartPackage(String packageName) {
3740 ActivityRecord starting = topRunningActivityLocked(null);
3741
3742 // All activities that came from the package must be
3743 // restarted as if there was a config change.
Craig Mautneraab647e2013-02-28 16:31:36 -08003744 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3745 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3746 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3747 final ActivityRecord a = activities.get(activityNdx);
3748 if (a.info.packageName.equals(packageName)) {
3749 a.forceNewConfig = true;
3750 if (starting != null && a == starting && a.visible) {
3751 a.startFreezingScreenLocked(starting.app,
3752 ActivityInfo.CONFIG_SCREEN_LAYOUT);
3753 }
Craig Mautnercae015f2013-02-08 14:31:27 -08003754 }
3755 }
3756 }
3757
3758 return starting;
3759 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -08003760
Craig Mautner41db4a72014-05-07 17:20:56 -07003761 void removeTask(TaskRecord task) {
Craig Mautneraea74a52014-03-08 14:23:10 -08003762 mStackSupervisor.endLockTaskModeIfTaskEnding(task);
Craig Mautner04a0ea62014-01-13 12:51:26 -08003763 mWindowManager.removeTask(task.taskId);
3764 final ActivityRecord r = mResumedActivity;
3765 if (r != null && r.task == task) {
3766 mResumedActivity = null;
3767 }
3768
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003769 final int taskNdx = mTaskHistory.indexOf(task);
3770 final int topTaskNdx = mTaskHistory.size() - 1;
Craig Mautnerb9a6c8a2014-05-29 16:50:59 +00003771 if (task.mOnTopOfHome && taskNdx < topTaskNdx) {
3772 mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true;
Craig Mautnerae7ecab2013-09-18 11:48:14 -07003773 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07003774 mTaskHistory.remove(task);
Craig Mautner21d24a22014-04-23 11:45:37 -07003775 updateTaskMovement(task, true);
Craig Mautner41db4a72014-05-07 17:20:56 -07003776
3777 if (task.mActivities.isEmpty()) {
3778 final boolean isVoiceSession = task.voiceSession != null;
3779 if (isVoiceSession) {
3780 try {
3781 task.voiceSession.taskFinished(task.intent, task.taskId);
3782 } catch (RemoteException e) {
3783 }
Dianne Hackbornc03c9162014-05-02 10:45:59 -07003784 }
Craig Mautner41db4a72014-05-07 17:20:56 -07003785 if (task.autoRemoveFromRecents() || isVoiceSession) {
3786 // Task creator asked to remove this when done, or this task was a voice
3787 // interaction, so it should not remain on the recent tasks list.
3788 mService.mRecentTasks.remove(task);
3789 }
Dianne Hackborn91097de2014-04-04 18:02:06 -07003790 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08003791
3792 if (mTaskHistory.isEmpty()) {
3793 if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this);
3794 if (isOnHomeDisplay()) {
3795 mStackSupervisor.moveHomeStack(!isHomeStack());
3796 }
Craig Mautner593a4e62014-01-15 17:55:51 -08003797 if (mStacks != null) {
3798 mStacks.remove(this);
3799 mStacks.add(0, this);
3800 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08003801 }
Craig Mautner0247fc82013-02-28 14:32:06 -08003802 }
3803
Dianne Hackborn91097de2014-04-04 18:02:06 -07003804 TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
3805 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
3806 boolean toTop) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003807 TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
3808 voiceInteractor);
Dianne Hackbornc03c9162014-05-02 10:45:59 -07003809 addTask(task, toTop, false);
Craig Mautner5d9c7be2013-02-15 14:02:56 -08003810 return task;
3811 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003812
3813 ArrayList<TaskRecord> getAllTasks() {
3814 return new ArrayList<TaskRecord>(mTaskHistory);
3815 }
3816
Dianne Hackbornc03c9162014-05-02 10:45:59 -07003817 void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08003818 task.stack = this;
3819 if (toTop) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07003820 insertTaskAtTop(task);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003821 } else {
3822 mTaskHistory.add(0, task);
Craig Mautner21d24a22014-04-23 11:45:37 -07003823 updateTaskMovement(task, false);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003824 }
Dianne Hackbornc03c9162014-05-02 10:45:59 -07003825 if (!moving && task.voiceSession != null) {
3826 try {
3827 task.voiceSession.taskStarted(task.intent, task.taskId);
3828 } catch (RemoteException e) {
3829 }
3830 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003831 }
3832
3833 public int getStackId() {
3834 return mStackId;
3835 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07003836
3837 @Override
3838 public String toString() {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07003839 return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
3840 + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
Craig Mautnerde4ef022013-04-07 19:01:33 -07003841 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003842}