blob: 6fe28f4c884eae1265e7e6adcc8f531158391753 [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautner0eea92c2013-05-16 13:35:39 -070025import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070026import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070027import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070028import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070029import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
30import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070031import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070032import static com.android.server.am.ActivityManagerService.TAG;
33
Craig Mautner2420ead2013-04-01 17:13:20 -070034import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070035import android.app.ActivityManager;
36import android.app.ActivityOptions;
37import android.app.AppGlobals;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070038import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070039import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070040import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070041import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070042import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070044import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070046import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070048import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.pm.ApplicationInfo;
52import android.content.pm.PackageManager;
53import android.content.pm.ResolveInfo;
54import android.content.res.Configuration;
55import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070056import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070057import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070058import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070059import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070060import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070061import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070062import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070063import android.os.PowerManager;
Craig Mautner8d341ef2013-03-26 09:03:27 -070064import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070065import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070066import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070067import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070068import android.util.Slog;
Craig Mautner858d8a62013-04-23 17:08:34 -070069import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070070
Craig Mautner23ac33b2013-04-01 16:26:35 -070071import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070072import com.android.internal.os.TransferPipe;
Craig Mautner6170f732013-04-02 13:05:23 -070073import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070074import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerde4ef022013-04-07 19:01:33 -070075import com.android.server.wm.StackBox;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070076import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077
Craig Mautner8d341ef2013-03-26 09:03:27 -070078import java.io.FileDescriptor;
79import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070080import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070081import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070082import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070083
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070084public final class ActivityStackSupervisor {
Craig Mautnerde4ef022013-04-07 19:01:33 -070085 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
86 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
87 static final boolean DEBUG_APP = DEBUG || false;
88 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
89 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070090 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -070091
Craig Mautner2219a1b2013-03-25 09:44:30 -070092 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -070093
Craig Mautnerf3333272013-04-22 10:55:53 -070094 /** How long we wait until giving up on the last activity telling us it is idle. */
95 static final int IDLE_TIMEOUT = 10*1000;
96
Craig Mautner0eea92c2013-05-16 13:35:39 -070097 /** How long we can hold the sleep wake lock before giving up. */
98 static final int SLEEP_TIMEOUT = 5*1000;
99
Craig Mautner05d29032013-05-03 13:40:13 -0700100 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
101 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
102 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700103 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautnerf3333272013-04-22 10:55:53 -0700104
Craig Mautner27084302013-03-25 08:05:25 -0700105 final ActivityManagerService mService;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700106 final Context mContext;
107 final Looper mLooper;
Craig Mautner27084302013-03-25 08:05:25 -0700108
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700109 final ActivityStackSupervisorHandler mHandler;
110
111 /** Short cut */
112 WindowManagerService mWindowManager;
113
Craig Mautner27084302013-03-25 08:05:25 -0700114 /** Dismiss the keyguard after the next activity is displayed? */
115 private boolean mDismissKeyguardOnNextActivity = false;
116
Craig Mautner8d341ef2013-03-26 09:03:27 -0700117 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700118 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700119
120 /** Task identifier that activities are currently being started in. Incremented each time a
121 * new task is created. */
122 private int mCurTaskId = 0;
123
Craig Mautner2420ead2013-04-01 17:13:20 -0700124 /** The current user */
125 private int mCurrentUser;
126
Craig Mautner8d341ef2013-03-26 09:03:27 -0700127 /** The stack containing the launcher app */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700128 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700129
Craig Mautnerde4ef022013-04-07 19:01:33 -0700130 /** The non-home stack currently receiving input or launching the next activity. If home is
Craig Mautner41c0f352013-05-28 08:39:25 -0700131 * in front then mHomeStack overrides mFocusedStack.
132 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
Craig Mautner29219d92013-04-16 20:19:12 -0700133 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700134
135 /** All the non-launcher stacks */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700136 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
137
Craig Mautnerde4ef022013-04-07 19:01:33 -0700138 private static final int STACK_STATE_HOME_IN_FRONT = 0;
139 private static final int STACK_STATE_HOME_TO_BACK = 1;
140 private static final int STACK_STATE_HOME_IN_BACK = 2;
141 private static final int STACK_STATE_HOME_TO_FRONT = 3;
142 private int mStackState = STACK_STATE_HOME_IN_FRONT;
143
144 /** List of activities that are waiting for a new activity to become visible before completing
145 * whatever operation they are supposed to do. */
146 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
147
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700148 /** List of processes waiting to find out about the next visible activity. */
149 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
150 new ArrayList<IActivityManager.WaitResult>();
151
152 /** List of processes waiting to find out about the next launched activity. */
153 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
154 new ArrayList<IActivityManager.WaitResult>();
155
Craig Mautnerde4ef022013-04-07 19:01:33 -0700156 /** List of activities that are ready to be stopped, but waiting for the next activity to
157 * settle down before doing so. */
158 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
159
Craig Mautnerf3333272013-04-22 10:55:53 -0700160 /** List of activities that are ready to be finished, but waiting for the previous activity to
161 * settle down before doing so. It contains ActivityRecord objects. */
162 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
163
Craig Mautner0eea92c2013-05-16 13:35:39 -0700164 /** List of activities that are in the process of going to sleep. */
165 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
166
Craig Mautnerf3333272013-04-22 10:55:53 -0700167 /** List of ActivityRecord objects that have been finished and must still report back to a
168 * pending thumbnail receiver. */
169 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
170
171 /** Used on user changes */
172 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
173
Craig Mautnerde4ef022013-04-07 19:01:33 -0700174 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
175 * is being brought in front of us. */
176 boolean mUserLeaving = false;
177
Craig Mautner858d8a62013-04-23 17:08:34 -0700178 /** Stacks belonging to users other than mCurrentUser. Indexed by userId. */
179 final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
180
Craig Mautner0eea92c2013-05-16 13:35:39 -0700181 /** Set when we have taken too long waiting to go to sleep. */
182 boolean mSleepTimeout = false;
183
184 /**
185 * Set when the system is going to sleep, until we have
186 * successfully paused the current activity and released our wake lock.
187 * At that point the system is allowed to actually sleep.
188 */
189 final PowerManager.WakeLock mGoingToSleep;
190
Craig Mautner2219a1b2013-03-25 09:44:30 -0700191 public ActivityStackSupervisor(ActivityManagerService service, Context context,
192 Looper looper) {
Craig Mautner27084302013-03-25 08:05:25 -0700193 mService = service;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700194 mContext = context;
195 mLooper = looper;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700196 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
197 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700198 mHandler = new ActivityStackSupervisorHandler(looper);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700199 }
200
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700201 void setWindowManager(WindowManagerService wm) {
202 mWindowManager = wm;
203 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700204 mStacks.add(mHomeStack);
Craig Mautner27084302013-03-25 08:05:25 -0700205 }
206
207 void dismissKeyguard() {
208 if (mDismissKeyguardOnNextActivity) {
209 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700210 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700211 }
212 }
213
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700214 ActivityStack getFocusedStack() {
Craig Mautnerf88c50f2013-04-18 19:25:12 -0700215 if (mFocusedStack == null) {
216 return mHomeStack;
217 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700218 switch (mStackState) {
219 case STACK_STATE_HOME_IN_FRONT:
220 case STACK_STATE_HOME_TO_FRONT:
221 return mHomeStack;
222 case STACK_STATE_HOME_IN_BACK:
223 case STACK_STATE_HOME_TO_BACK:
224 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700225 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700226 }
Craig Mautner20e72272013-04-01 13:45:53 -0700227 }
228
Craig Mautnerde4ef022013-04-07 19:01:33 -0700229 ActivityStack getLastStack() {
230 switch (mStackState) {
231 case STACK_STATE_HOME_IN_FRONT:
232 case STACK_STATE_HOME_TO_BACK:
233 return mHomeStack;
234 case STACK_STATE_HOME_TO_FRONT:
235 case STACK_STATE_HOME_IN_BACK:
236 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700237 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700238 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700239 }
240
Craig Mautnerde4ef022013-04-07 19:01:33 -0700241 boolean isFrontStack(ActivityStack stack) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700242 return (stack.mCurrentUser == mCurrentUser) &&
243 !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
Craig Mautner20e72272013-04-01 13:45:53 -0700244 }
245
Craig Mautnerde4ef022013-04-07 19:01:33 -0700246 void moveHomeStack(boolean toFront) {
247 final boolean homeInFront = isFrontStack(mHomeStack);
248 if (homeInFront ^ toFront) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700249 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
250 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
251 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700252 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
253 }
254 }
255
Craig Mautner69ada552013-04-18 13:51:51 -0700256 boolean resumeHomeActivity(ActivityRecord prev) {
257 moveHomeStack(true);
258 if (prev != null) {
259 prev.mLaunchHomeTaskNext = false;
260 }
261 if (mHomeStack.topRunningActivityLocked(null) != null) {
Craig Mautner05d29032013-05-03 13:40:13 -0700262 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700263 }
264 return mService.startHomeActivityLocked(mCurrentUser);
265 }
266
Craig Mautnerde4ef022013-04-07 19:01:33 -0700267 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r,
268 ActivityStack stack) {
269 if (stack == mHomeStack) {
270 return;
271 }
272 if ((sourceRecord == null && getLastStack() == mHomeStack) ||
Craig Mautner86d67a42013-05-14 10:34:38 -0700273 (sourceRecord != null && sourceRecord.isHomeActivity())) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700274 if (r == null) {
275 r = stack.topRunningActivityLocked(null);
276 }
Craig Mautner86d67a42013-05-14 10:34:38 -0700277 if (r != null && !r.isHomeActivity() && r.isRootActivity()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700278 r.mLaunchHomeTaskNext = true;
279 }
280 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700281 }
282
Craig Mautner27084302013-03-25 08:05:25 -0700283 void setDismissKeyguard(boolean dismiss) {
284 mDismissKeyguardOnNextActivity = dismiss;
285 }
286
Craig Mautner8d341ef2013-03-26 09:03:27 -0700287 TaskRecord anyTaskForIdLocked(int id) {
288 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
289 ActivityStack stack = mStacks.get(stackNdx);
290 TaskRecord task = stack.taskForIdLocked(id);
291 if (task != null) {
292 return task;
293 }
294 }
295 return null;
296 }
297
Craig Mautner6170f732013-04-02 13:05:23 -0700298 ActivityRecord isInAnyStackLocked(IBinder token) {
299 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
300 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
301 if (r != null) {
302 return r;
303 }
304 }
305 return null;
306 }
307
Craig Mautner8d341ef2013-03-26 09:03:27 -0700308 int getNextTaskId() {
309 do {
310 mCurTaskId++;
311 if (mCurTaskId <= 0) {
312 mCurTaskId = 1;
313 }
314 } while (anyTaskForIdLocked(mCurTaskId) != null);
315 return mCurTaskId;
316 }
317
Craig Mautnerde4ef022013-04-07 19:01:33 -0700318 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700319 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700320 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700321 final ActivityRecord r = stack.mResumedActivity;
322 if (r != null && r.task == task) {
323 stack.mResumedActivity = null;
324 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700325 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700326 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700327 mStacks.remove(stack);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700328 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700329 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700330 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Craig Mautner41c0f352013-05-28 08:39:25 -0700331 if (getFocusedStack().mStackId == stackId) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700332 // If this is the last app stack, set mFocusedStack to null.
Craig Mautner29219d92013-04-16 20:19:12 -0700333 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700334 }
335 }
336 }
337
338 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700339 ActivityStack stack = getFocusedStack();
340 if (stack == null) {
341 return null;
342 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700343 ActivityRecord resumedActivity = stack.mResumedActivity;
344 if (resumedActivity == null || resumedActivity.app == null) {
345 resumedActivity = stack.mPausingActivity;
346 if (resumedActivity == null || resumedActivity.app == null) {
347 resumedActivity = stack.topRunningActivityLocked(null);
348 }
349 }
350 return resumedActivity;
351 }
352
Craig Mautner20e72272013-04-01 13:45:53 -0700353 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
354 boolean didSomething = false;
355 final String processName = app.processName;
356 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
357 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner858d8a62013-04-23 17:08:34 -0700358 if (!isFrontStack(stack)) {
359 continue;
360 }
Craig Mautner20e72272013-04-01 13:45:53 -0700361 ActivityRecord hr = stack.topRunningActivityLocked(null);
362 if (hr != null) {
363 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
364 && processName.equals(hr.processName)) {
365 try {
366 if (headless) {
367 Slog.e(TAG, "Starting activities not supported on headless device: "
368 + hr);
Craig Mautner2420ead2013-04-01 17:13:20 -0700369 } else if (realStartActivityLocked(hr, app, true, true)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700370 didSomething = true;
371 }
372 } catch (Exception e) {
373 Slog.w(TAG, "Exception in new application when starting activity "
374 + hr.intent.getComponent().flattenToShortString(), e);
375 throw e;
376 }
Craig Mautner20e72272013-04-01 13:45:53 -0700377 }
378 }
379 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700380 if (!didSomething) {
381 ensureActivitiesVisibleLocked(null, 0);
382 }
Craig Mautner20e72272013-04-01 13:45:53 -0700383 return didSomething;
384 }
385
386 boolean allResumedActivitiesIdle() {
387 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerdbcb31f2013-04-02 12:32:53 -0700388 final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity;
389 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner20e72272013-04-01 13:45:53 -0700390 return false;
391 }
392 }
393 return true;
394 }
395
Craig Mautnerde4ef022013-04-07 19:01:33 -0700396 boolean allResumedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700397 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
398 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner967212c2013-04-13 21:10:58 -0700399 if (isFrontStack(stack)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700400 final ActivityRecord r = stack.mResumedActivity;
401 if (r != null && r.state != ActivityState.RESUMED) {
402 return false;
403 }
404 }
405 }
406 // TODO: Not sure if this should check if all Paused are complete too.
407 switch (mStackState) {
408 case STACK_STATE_HOME_TO_BACK:
Craig Mautner76ea2242013-05-15 11:40:05 -0700409 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
410 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
411 stackStateToString(STACK_STATE_HOME_IN_BACK));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700412 mStackState = STACK_STATE_HOME_IN_BACK;
413 break;
414 case STACK_STATE_HOME_TO_FRONT:
Craig Mautner76ea2242013-05-15 11:40:05 -0700415 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
416 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
417 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700418 mStackState = STACK_STATE_HOME_IN_FRONT;
419 break;
420 }
421 return true;
422 }
423
424 boolean allResumedActivitiesVisible() {
425 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
426 final ActivityStack stack = mStacks.get(stackNdx);
427 final ActivityRecord r = stack.mResumedActivity;
428 if (r != null && (!r.nowVisible || r.waitingVisible)) {
429 return false;
430 }
431 }
432 return true;
433 }
434
Craig Mautnercf910b02013-04-23 11:23:27 -0700435 boolean pauseBackStacks(boolean userLeaving) {
436 boolean someActivityPaused = false;
437 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
438 final ActivityStack stack = mStacks.get(stackNdx);
439 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
440 stack.startPausingLocked(userLeaving, false);
441 someActivityPaused = true;
442 }
443 }
444 return someActivityPaused;
445 }
446
Craig Mautnerde4ef022013-04-07 19:01:33 -0700447 boolean allPausedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700448 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
449 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner69ada552013-04-18 13:51:51 -0700450 final ActivityRecord r = stack.mPausingActivity;
451 if (r != null && r.state != ActivityState.PAUSED
452 && r.state != ActivityState.STOPPED
453 && r.state != ActivityState.STOPPING) {
454 return false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700455 }
456 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700457 return true;
458 }
459
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700460 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700461 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700462 WaitResult w = mWaitingActivityVisible.get(i);
463 w.timeout = false;
464 if (r != null) {
465 w.who = new ComponentName(r.info.packageName, r.info.name);
466 }
467 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
468 w.thisTime = w.totalTime;
469 }
470 mService.notifyAll();
471 dismissKeyguard();
472 }
473
474 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
475 long thisTime, long totalTime) {
476 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700477 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700478 w.timeout = timeout;
479 if (r != null) {
480 w.who = new ComponentName(r.info.packageName, r.info.name);
481 }
482 w.thisTime = thisTime;
483 w.totalTime = totalTime;
484 }
485 mService.notifyAll();
486 }
487
Craig Mautner29219d92013-04-16 20:19:12 -0700488 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700489 final ActivityStack focusedStack = getFocusedStack();
490 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
491 if (r != null) {
492 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700493 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700494
Craig Mautner29219d92013-04-16 20:19:12 -0700495 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
496 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner1602ec22013-05-12 10:24:27 -0700497 if (stack.mCurrentUser == mCurrentUser && stack != focusedStack &&
498 isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700499 r = stack.topRunningActivityLocked(null);
500 if (r != null) {
501 return r;
502 }
503 }
504 }
505 return null;
506 }
507
Craig Mautner20e72272013-04-01 13:45:53 -0700508 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
509 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
510 ActivityRecord r = null;
Craig Mautner20e72272013-04-01 13:45:53 -0700511 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
512 final ActivityStack stack = mStacks.get(stackNdx);
513 final ActivityRecord ar =
514 stack.getTasksLocked(maxNum - list.size(), receiver, pending, list);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700515 if (isFrontStack(stack)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700516 r = ar;
517 }
518 }
519 return r;
520 }
521
Craig Mautner23ac33b2013-04-01 16:26:35 -0700522 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
523 String profileFile, ParcelFileDescriptor profileFd, int userId) {
524 // Collect information about the target of the Intent.
525 ActivityInfo aInfo;
526 try {
527 ResolveInfo rInfo =
528 AppGlobals.getPackageManager().resolveIntent(
529 intent, resolvedType,
530 PackageManager.MATCH_DEFAULT_ONLY
531 | ActivityManagerService.STOCK_PM_FLAGS, userId);
532 aInfo = rInfo != null ? rInfo.activityInfo : null;
533 } catch (RemoteException e) {
534 aInfo = null;
535 }
536
537 if (aInfo != null) {
538 // Store the found target back into the intent, because now that
539 // we have it we never want to do this again. For example, if the
540 // user navigates back to this point in the history, we should
541 // always restart the exact same activity.
542 intent.setComponent(new ComponentName(
543 aInfo.applicationInfo.packageName, aInfo.name));
544
545 // Don't debug things in the system process
546 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
547 if (!aInfo.processName.equals("system")) {
548 mService.setDebugApp(aInfo.processName, true, false);
549 }
550 }
551
552 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
553 if (!aInfo.processName.equals("system")) {
554 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
555 }
556 }
557
558 if (profileFile != null) {
559 if (!aInfo.processName.equals("system")) {
560 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
561 profileFile, profileFd,
562 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
563 }
564 }
565 }
566 return aInfo;
567 }
568
Craig Mautner2219a1b2013-03-25 09:44:30 -0700569 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700570 moveHomeStack(true);
Craig Mautner6170f732013-04-02 13:05:23 -0700571 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700572 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700573 }
574
Craig Mautner23ac33b2013-04-01 16:26:35 -0700575 final int startActivityMayWait(IApplicationThread caller, int callingUid,
576 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
577 String resultWho, int requestCode, int startFlags, String profileFile,
578 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
579 Bundle options, int userId) {
580 // Refuse possible leaked file descriptors
581 if (intent != null && intent.hasFileDescriptors()) {
582 throw new IllegalArgumentException("File descriptors passed in Intent");
583 }
584 boolean componentSpecified = intent.getComponent() != null;
585
586 // Don't modify the client's object!
587 intent = new Intent(intent);
588
589 // Collect information about the target of the Intent.
590 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
591 profileFile, profileFd, userId);
592
593 synchronized (mService) {
594 int callingPid;
595 if (callingUid >= 0) {
596 callingPid = -1;
597 } else if (caller == null) {
598 callingPid = Binder.getCallingPid();
599 callingUid = Binder.getCallingUid();
600 } else {
601 callingPid = callingUid = -1;
602 }
603
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700604 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700605 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700606 && mService.mConfiguration.diff(config) != 0;
607 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700608 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700609
610 final long origId = Binder.clearCallingIdentity();
611
612 if (aInfo != null &&
613 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
614 // This may be a heavy-weight process! Check to see if we already
615 // have another, different heavy-weight process running.
616 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
617 if (mService.mHeavyWeightProcess != null &&
618 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
619 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700620 int realCallingUid = callingUid;
621 if (caller != null) {
622 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
623 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700624 realCallingUid = callerApp.info.uid;
625 } else {
626 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700627 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700628 + intent.toString());
629 ActivityOptions.abort(options);
630 return ActivityManager.START_PERMISSION_DENIED;
631 }
632 }
633
634 IIntentSender target = mService.getIntentSenderLocked(
635 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
636 realCallingUid, userId, null, null, 0, new Intent[] { intent },
637 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
638 | PendingIntent.FLAG_ONE_SHOT, null);
639
640 Intent newIntent = new Intent();
641 if (requestCode >= 0) {
642 // Caller is requesting a result.
643 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
644 }
645 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
646 new IntentSender(target));
647 if (mService.mHeavyWeightProcess.activities.size() > 0) {
648 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
649 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
650 hist.packageName);
651 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
652 hist.task.taskId);
653 }
654 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
655 aInfo.packageName);
656 newIntent.setFlags(intent.getFlags());
657 newIntent.setClassName("android",
658 HeavyWeightSwitcherActivity.class.getName());
659 intent = newIntent;
660 resolvedType = null;
661 caller = null;
662 callingUid = Binder.getCallingUid();
663 callingPid = Binder.getCallingPid();
664 componentSpecified = true;
665 try {
666 ResolveInfo rInfo =
667 AppGlobals.getPackageManager().resolveIntent(
668 intent, null,
669 PackageManager.MATCH_DEFAULT_ONLY
670 | ActivityManagerService.STOCK_PM_FLAGS, userId);
671 aInfo = rInfo != null ? rInfo.activityInfo : null;
672 aInfo = mService.getActivityInfoForUser(aInfo, userId);
673 } catch (RemoteException e) {
674 aInfo = null;
675 }
676 }
677 }
678 }
679
Craig Mautner6170f732013-04-02 13:05:23 -0700680 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700681 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
682 callingPackage, startFlags, options, componentSpecified, null);
683
Craig Mautnerde4ef022013-04-07 19:01:33 -0700684 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700685 // If the caller also wants to switch to a new configuration,
686 // do so now. This allows a clean switch, as we are waiting
687 // for the current activity to pause (so we will not destroy
688 // it), and have not yet started the next activity.
689 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
690 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700691 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700692 if (DEBUG_CONFIGURATION) Slog.v(TAG,
693 "Updating to new configuration after starting activity.");
694 mService.updateConfigurationLocked(config, null, false, false);
695 }
696
697 Binder.restoreCallingIdentity(origId);
698
699 if (outResult != null) {
700 outResult.result = res;
701 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700702 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700703 do {
704 try {
705 mService.wait();
706 } catch (InterruptedException e) {
707 }
708 } while (!outResult.timeout && outResult.who == null);
709 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700710 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700711 if (r.nowVisible) {
712 outResult.timeout = false;
713 outResult.who = new ComponentName(r.info.packageName, r.info.name);
714 outResult.totalTime = 0;
715 outResult.thisTime = 0;
716 } else {
717 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700718 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700719 do {
720 try {
721 mService.wait();
722 } catch (InterruptedException e) {
723 }
724 } while (!outResult.timeout && outResult.who == null);
725 }
726 }
727 }
728
729 return res;
730 }
731 }
732
733 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
734 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
735 Bundle options, int userId) {
736 if (intents == null) {
737 throw new NullPointerException("intents is null");
738 }
739 if (resolvedTypes == null) {
740 throw new NullPointerException("resolvedTypes is null");
741 }
742 if (intents.length != resolvedTypes.length) {
743 throw new IllegalArgumentException("intents are length different than resolvedTypes");
744 }
745
Craig Mautner23ac33b2013-04-01 16:26:35 -0700746
747 int callingPid;
748 if (callingUid >= 0) {
749 callingPid = -1;
750 } else if (caller == null) {
751 callingPid = Binder.getCallingPid();
752 callingUid = Binder.getCallingUid();
753 } else {
754 callingPid = callingUid = -1;
755 }
756 final long origId = Binder.clearCallingIdentity();
757 try {
758 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700759 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700760 for (int i=0; i<intents.length; i++) {
761 Intent intent = intents[i];
762 if (intent == null) {
763 continue;
764 }
765
766 // Refuse possible leaked file descriptors
767 if (intent != null && intent.hasFileDescriptors()) {
768 throw new IllegalArgumentException("File descriptors passed in Intent");
769 }
770
771 boolean componentSpecified = intent.getComponent() != null;
772
773 // Don't modify the client's object!
774 intent = new Intent(intent);
775
776 // Collect information about the target of the Intent.
777 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
778 0, null, null, userId);
779 // TODO: New, check if this is correct
780 aInfo = mService.getActivityInfoForUser(aInfo, userId);
781
782 if (aInfo != null &&
783 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
784 != 0) {
785 throw new IllegalArgumentException(
786 "FLAG_CANT_SAVE_STATE not supported here");
787 }
788
789 Bundle theseOptions;
790 if (options != null && i == intents.length-1) {
791 theseOptions = options;
792 } else {
793 theseOptions = null;
794 }
Craig Mautner6170f732013-04-02 13:05:23 -0700795 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700796 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
797 0, theseOptions, componentSpecified, outActivity);
798 if (res < 0) {
799 return res;
800 }
801
802 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
803 }
804 }
805 } finally {
806 Binder.restoreCallingIdentity(origId);
807 }
808
809 return ActivityManager.START_SUCCESS;
810 }
811
Craig Mautner2420ead2013-04-01 17:13:20 -0700812 final boolean realStartActivityLocked(ActivityRecord r,
813 ProcessRecord app, boolean andResume, boolean checkConfig)
814 throws RemoteException {
815
816 r.startFreezingScreenLocked(app, 0);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700817 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700818
819 // schedule launch ticks to collect information about slow apps.
820 r.startLaunchTickingLocked();
821
822 // Have the window manager re-evaluate the orientation of
823 // the screen based on the new activity order. Note that
824 // as a result of this, it can call back into the activity
825 // manager with a new orientation. We don't care about that,
826 // because the activity is not currently running so we are
827 // just restarting it anyway.
828 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700829 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700830 mService.mConfiguration,
831 r.mayFreezeScreenLocked(app) ? r.appToken : null);
832 mService.updateConfigurationLocked(config, r, false, false);
833 }
834
835 r.app = app;
836 app.waitingToKill = null;
837 r.launchCount++;
838 r.lastLaunchTime = SystemClock.uptimeMillis();
839
840 if (localLOGV) Slog.v(TAG, "Launching: " + r);
841
842 int idx = app.activities.indexOf(r);
843 if (idx < 0) {
844 app.activities.add(r);
845 }
846 mService.updateLruProcessLocked(app, true);
847
848 final ActivityStack stack = r.task.stack;
849 try {
850 if (app.thread == null) {
851 throw new RemoteException();
852 }
853 List<ResultInfo> results = null;
854 List<Intent> newIntents = null;
855 if (andResume) {
856 results = r.results;
857 newIntents = r.newIntents;
858 }
859 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
860 + " icicle=" + r.icicle
861 + " with results=" + results + " newIntents=" + newIntents
862 + " andResume=" + andResume);
863 if (andResume) {
864 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
865 r.userId, System.identityHashCode(r),
866 r.task.taskId, r.shortComponentName);
867 }
Craig Mautner86d67a42013-05-14 10:34:38 -0700868 if (r.isHomeActivity()) {
Craig Mautner2420ead2013-04-01 17:13:20 -0700869 mService.mHomeProcess = app;
870 }
871 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
872 r.sleeping = false;
873 r.forceNewConfig = false;
874 mService.showAskCompatModeDialogLocked(r);
875 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
876 String profileFile = null;
877 ParcelFileDescriptor profileFd = null;
878 boolean profileAutoStop = false;
879 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
880 if (mService.mProfileProc == null || mService.mProfileProc == app) {
881 mService.mProfileProc = app;
882 profileFile = mService.mProfileFile;
883 profileFd = mService.mProfileFd;
884 profileAutoStop = mService.mAutoStopProfiler;
885 }
886 }
887 app.hasShownUi = true;
888 app.pendingUiClean = true;
889 if (profileFd != null) {
890 try {
891 profileFd = profileFd.dup();
892 } catch (IOException e) {
893 if (profileFd != null) {
894 try {
895 profileFd.close();
896 } catch (IOException o) {
897 }
898 profileFd = null;
899 }
900 }
901 }
902 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
903 System.identityHashCode(r), r.info,
904 new Configuration(mService.mConfiguration),
905 r.compat, r.icicle, results, newIntents, !andResume,
906 mService.isNextTransitionForward(), profileFile, profileFd,
907 profileAutoStop);
908
909 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
910 // This may be a heavy-weight process! Note that the package
911 // manager will ensure that only activity can run in the main
912 // process of the .apk, which is the only thing that will be
913 // considered heavy-weight.
914 if (app.processName.equals(app.info.packageName)) {
915 if (mService.mHeavyWeightProcess != null
916 && mService.mHeavyWeightProcess != app) {
917 Slog.w(TAG, "Starting new heavy weight process " + app
918 + " when already running "
919 + mService.mHeavyWeightProcess);
920 }
921 mService.mHeavyWeightProcess = app;
922 Message msg = mService.mHandler.obtainMessage(
923 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
924 msg.obj = r;
925 mService.mHandler.sendMessage(msg);
926 }
927 }
928
929 } catch (RemoteException e) {
930 if (r.launchFailed) {
931 // This is the second time we failed -- finish activity
932 // and give up.
933 Slog.e(TAG, "Second failure launching "
934 + r.intent.getComponent().flattenToShortString()
935 + ", giving up", e);
936 mService.appDiedLocked(app, app.pid, app.thread);
937 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
938 "2nd-crash", false);
939 return false;
940 }
941
942 // This is the first time we failed -- restart process and
943 // retry.
944 app.activities.remove(r);
945 throw e;
946 }
947
948 r.launchFailed = false;
949 if (stack.updateLRUListLocked(r)) {
950 Slog.w(TAG, "Activity " + r
951 + " being launched, but already in LRU list");
952 }
953
954 if (andResume) {
955 // As part of the process of launching, ActivityThread also performs
956 // a resume.
957 stack.minimalResumeActivityLocked(r);
958 } else {
959 // This activity is not starting in the resumed state... which
960 // should look like we asked it to pause+stop (but remain visible),
961 // and it has done so and reported back the current icicle and
962 // other state.
963 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
964 + " (starting in stopped state)");
965 r.state = ActivityState.STOPPED;
966 r.stopped = true;
967 }
968
969 // Launch the new version setup screen if needed. We do this -after-
970 // launching the initial activity (that is, home), so that it can have
971 // a chance to initialize itself while in the background, making the
972 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700973 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -0700974 mService.startSetupActivityLocked();
975 }
976
977 return true;
978 }
979
Craig Mautnere79d42682013-04-01 19:01:53 -0700980 void startSpecificActivityLocked(ActivityRecord r,
981 boolean andResume, boolean checkConfig) {
982 // Is this activity's application already running?
983 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
984 r.info.applicationInfo.uid);
985
986 r.task.stack.setLaunchTime(r);
987
988 if (app != null && app.thread != null) {
989 try {
990 app.addPackage(r.info.packageName);
991 realStartActivityLocked(r, app, andResume, checkConfig);
992 return;
993 } catch (RemoteException e) {
994 Slog.w(TAG, "Exception when starting activity "
995 + r.intent.getComponent().flattenToShortString(), e);
996 }
997
998 // If a dead object exception was thrown -- fall through to
999 // restart the application.
1000 }
1001
1002 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1003 "activity", r.intent.getComponent(), false, false);
1004 }
1005
Craig Mautner6170f732013-04-02 13:05:23 -07001006 final int startActivityLocked(IApplicationThread caller,
1007 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1008 String resultWho, int requestCode,
1009 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1010 boolean componentSpecified, ActivityRecord[] outActivity) {
1011 int err = ActivityManager.START_SUCCESS;
1012
1013 ProcessRecord callerApp = null;
1014 if (caller != null) {
1015 callerApp = mService.getRecordForAppLocked(caller);
1016 if (callerApp != null) {
1017 callingPid = callerApp.pid;
1018 callingUid = callerApp.info.uid;
1019 } else {
1020 Slog.w(TAG, "Unable to find app for caller " + caller
1021 + " (pid=" + callingPid + ") when starting: "
1022 + intent.toString());
1023 err = ActivityManager.START_PERMISSION_DENIED;
1024 }
1025 }
1026
1027 if (err == ActivityManager.START_SUCCESS) {
1028 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1029 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1030 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1031 }
1032
1033 ActivityRecord sourceRecord = null;
1034 ActivityRecord resultRecord = null;
1035 if (resultTo != null) {
1036 sourceRecord = isInAnyStackLocked(resultTo);
1037 if (DEBUG_RESULTS) Slog.v(
1038 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1039 if (sourceRecord != null) {
1040 if (requestCode >= 0 && !sourceRecord.finishing) {
1041 resultRecord = sourceRecord;
1042 }
1043 }
1044 }
1045 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1046
1047 int launchFlags = intent.getFlags();
1048
1049 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1050 && sourceRecord != null) {
1051 // Transfer the result target from the source activity to the new
1052 // one being started, including any failures.
1053 if (requestCode >= 0) {
1054 ActivityOptions.abort(options);
1055 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1056 }
1057 resultRecord = sourceRecord.resultTo;
1058 resultWho = sourceRecord.resultWho;
1059 requestCode = sourceRecord.requestCode;
1060 sourceRecord.resultTo = null;
1061 if (resultRecord != null) {
1062 resultRecord.removeResultsLocked(
1063 sourceRecord, resultWho, requestCode);
1064 }
1065 }
1066
1067 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1068 // We couldn't find a class that can handle the given Intent.
1069 // That's the end of that!
1070 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1071 }
1072
1073 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1074 // We couldn't find the specific class specified in the Intent.
1075 // Also the end of the line.
1076 err = ActivityManager.START_CLASS_NOT_FOUND;
1077 }
1078
1079 if (err != ActivityManager.START_SUCCESS) {
1080 if (resultRecord != null) {
1081 resultStack.sendActivityResultLocked(-1,
1082 resultRecord, resultWho, requestCode,
1083 Activity.RESULT_CANCELED, null);
1084 }
1085 setDismissKeyguard(false);
1086 ActivityOptions.abort(options);
1087 return err;
1088 }
1089
1090 final int startAnyPerm = mService.checkPermission(
1091 START_ANY_ACTIVITY, callingPid, callingUid);
1092 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1093 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1094 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1095 if (resultRecord != null) {
1096 resultStack.sendActivityResultLocked(-1,
1097 resultRecord, resultWho, requestCode,
1098 Activity.RESULT_CANCELED, null);
1099 }
1100 setDismissKeyguard(false);
1101 String msg;
1102 if (!aInfo.exported) {
1103 msg = "Permission Denial: starting " + intent.toString()
1104 + " from " + callerApp + " (pid=" + callingPid
1105 + ", uid=" + callingUid + ")"
1106 + " not exported from uid " + aInfo.applicationInfo.uid;
1107 } else {
1108 msg = "Permission Denial: starting " + intent.toString()
1109 + " from " + callerApp + " (pid=" + callingPid
1110 + ", uid=" + callingUid + ")"
1111 + " requires " + aInfo.permission;
1112 }
1113 Slog.w(TAG, msg);
1114 throw new SecurityException(msg);
1115 }
1116
Ben Gruver6617c3c2013-04-03 18:45:22 -07001117 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent,
Ben Gruver7b879f42013-04-08 14:56:55 -07001118 callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001119
Craig Mautner6170f732013-04-02 13:05:23 -07001120 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001121 try {
1122 // The Intent we give to the watcher has the extra data
1123 // stripped off, since it can contain private information.
1124 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001125 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001126 aInfo.applicationInfo.packageName);
1127 } catch (RemoteException e) {
1128 mService.mController = null;
1129 }
Ben Gruver5e207332013-04-03 17:41:37 -07001130 }
Craig Mautner6170f732013-04-02 13:05:23 -07001131
Ben Gruver5e207332013-04-03 17:41:37 -07001132 if (abort) {
1133 if (resultRecord != null) {
1134 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001135 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001136 }
Ben Gruver5e207332013-04-03 17:41:37 -07001137 // We pretend to the caller that it was really started, but
1138 // they will just get a cancel result.
1139 setDismissKeyguard(false);
1140 ActivityOptions.abort(options);
1141 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001142 }
1143
1144 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1145 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001146 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001147 if (outActivity != null) {
1148 outActivity[0] = r;
1149 }
1150
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001151 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001152 if (stack.mResumedActivity == null
1153 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001154 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1155 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001156 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001157 mService.mPendingActivityLaunches.add(pal);
1158 setDismissKeyguard(false);
1159 ActivityOptions.abort(options);
1160 return ActivityManager.START_SWITCHES_CANCELED;
1161 }
1162 }
1163
1164 if (mService.mDidAppSwitch) {
1165 // This is the second allowed switch since we stopped switches,
1166 // so now just generally allow switches. Use case: user presses
1167 // home (switches disabled, switch to home, mDidAppSwitch now true);
1168 // user taps a home icon (coming from home so allowed, we hit here
1169 // and now allow anyone to switch again).
1170 mService.mAppSwitchesAllowedTime = 0;
1171 } else {
1172 mService.mDidAppSwitch = true;
1173 }
1174
1175 mService.doPendingActivityLaunchesLocked(false);
1176
Craig Mautner8849a5e2013-04-02 16:41:03 -07001177 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001178 if (stack.mPausingActivity == null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001179 // Someone asked to have the keyguard dismissed on the next
1180 // activity start, but we are not actually doing an activity
1181 // switch... just dismiss the keyguard now, because we
1182 // probably want to see whatever is behind it.
1183 dismissKeyguard();
1184 }
1185 return err;
1186 }
1187
Craig Mautnerde4ef022013-04-07 19:01:33 -07001188 ActivityStack getCorrectStack(ActivityRecord r) {
Craig Mautner86d67a42013-05-14 10:34:38 -07001189 if (r.isApplicationActivity() || (r.task != null && r.task.isApplicationTask())) {
Craig Mautner858d8a62013-04-23 17:08:34 -07001190 int stackNdx;
1191 for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1192 if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) {
1193 break;
1194 }
1195 }
1196 if (stackNdx == 0) {
1197 // Time to create the first app stack for this user.
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001198 int stackId = mService.createStack(-1, HOME_STACK_ID,
1199 StackBox.TASK_STACK_GOES_OVER, 1.0f);
Craig Mautner29219d92013-04-16 20:19:12 -07001200 mFocusedStack = getStack(stackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001201 }
Craig Mautner29219d92013-04-16 20:19:12 -07001202 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001203 }
1204 return mHomeStack;
1205 }
1206
Craig Mautner29219d92013-04-16 20:19:12 -07001207 void setFocusedStack(ActivityRecord r) {
1208 if (r == null) {
1209 return;
1210 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001211 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001212 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001213 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1214 stackStateToString(mStackState) + " new=" +
1215 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1216 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001217 mStackState = STACK_STATE_HOME_TO_FRONT;
1218 }
1219 } else {
1220 mFocusedStack = r.task.stack;
1221 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001222 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1223 stackStateToString(mStackState) + " new=" +
1224 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1225 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001226 mStackState = STACK_STATE_HOME_TO_BACK;
1227 }
1228 }
1229 }
1230
Craig Mautner8849a5e2013-04-02 16:41:03 -07001231 final int startActivityUncheckedLocked(ActivityRecord r,
1232 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1233 Bundle options) {
1234 final Intent intent = r.intent;
1235 final int callingUid = r.launchedFromUid;
1236
1237 int launchFlags = intent.getFlags();
1238
Craig Mautner8849a5e2013-04-02 16:41:03 -07001239 // We'll invoke onUserLeaving before onPause only if the launching
1240 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001241 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1242 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001243
1244 // If the caller has asked not to resume at this point, we make note
1245 // of this in the record so that we can skip it when trying to find
1246 // the top running activity.
1247 if (!doResume) {
1248 r.delayedResume = true;
1249 }
1250
1251 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1252
1253 // If the onlyIfNeeded flag is set, then we can do this if the activity
1254 // being launched is the same as the one making the call... or, as
1255 // a special case, if we do not know the caller then we count the
1256 // current top activity as the caller.
1257 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1258 ActivityRecord checkedCaller = sourceRecord;
1259 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001260 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001261 }
1262 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1263 // Caller is not the same as launcher, so always needed.
1264 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1265 }
1266 }
1267
1268 if (sourceRecord == null) {
1269 // This activity is not being started from another... in this
1270 // case we -always- start a new task.
1271 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001272 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1273 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001274 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1275 }
1276 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1277 // The original activity who is starting us is running as a single
1278 // instance... this new activity it is starting must go on its
1279 // own task.
1280 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1281 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1282 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1283 // The activity being started is a single instance... it always
1284 // gets launched into its own task.
1285 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1286 }
1287
Craig Mautnerde4ef022013-04-07 19:01:33 -07001288 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001289 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001290 if (sourceRecord != null) {
1291 sourceTask = sourceRecord.task;
1292 sourceStack = sourceTask.stack;
1293 } else {
1294 sourceTask = null;
1295 sourceStack = null;
1296 }
1297
Craig Mautner8849a5e2013-04-02 16:41:03 -07001298 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1299 // For whatever reason this activity is being launched into a new
1300 // task... yet the caller has requested a result back. Well, that
1301 // is pretty messed up, so instead immediately send back a cancel
1302 // and let the new task continue launched as normal without a
1303 // dependency on its originator.
1304 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1305 r.resultTo.task.stack.sendActivityResultLocked(-1,
1306 r.resultTo, r.resultWho, r.requestCode,
1307 Activity.RESULT_CANCELED, null);
1308 r.resultTo = null;
1309 }
1310
1311 boolean addingToTask = false;
1312 boolean movedHome = false;
1313 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001314 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001315 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1316 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1317 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1318 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1319 // If bring to front is requested, and no result is requested, and
1320 // we can find a task that was started with this same
1321 // component, then instead of launching bring that one to the front.
1322 if (r.resultTo == null) {
1323 // See if there is a task to bring to the front. If this is
1324 // a SINGLE_INSTANCE activity, there can be one and only one
1325 // instance of it in the history, and it is always in its own
1326 // unique task, so we do a special search.
1327 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1328 ? findTaskLocked(intent, r.info)
1329 : findActivityLocked(intent, r.info);
1330 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001331 if (r.task == null) {
1332 r.task = intentActivity.task;
1333 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001334 targetStack = intentActivity.task.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001335 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001336 if (intentActivity.task.intent == null) {
1337 // This task was started because of movement of
1338 // the activity based on affinity... now that we
1339 // are actually launching it, we can assign the
1340 // base intent.
1341 intentActivity.task.setIntent(intent, r.info);
1342 }
1343 // If the target task is not in the front, then we need
1344 // to bring it to the front... except... well, with
1345 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1346 // to have the same behavior as if a new instance was
1347 // being started, which means not bringing it to the front
1348 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001349 final ActivityStack lastStack = getLastStack();
1350 ActivityRecord curTop = lastStack == null?
1351 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001352 if (curTop != null && curTop.task != intentActivity.task) {
1353 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001354 if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001355 // We really do want to push this one into the
1356 // user's face, right now.
1357 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001358 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001359 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1360 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001361 // Caller wants to appear on home activity, so before starting
1362 // their own activity we will bring home to the front.
1363 r.mLaunchHomeTaskNext = true;
1364 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001365 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1366 options = null;
1367 }
1368 }
1369 // If the caller has requested that the target task be
1370 // reset, then do so.
1371 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1372 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1373 }
1374 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1375 // We don't need to start a new activity, and
1376 // the client said not to do anything if that
1377 // is the case, so this is it! And for paranoia, make
1378 // sure we have correctly resumed the top activity.
1379 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001380 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001381 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001382 } else {
1383 ActivityOptions.abort(options);
1384 }
Craig Mautner29219d92013-04-16 20:19:12 -07001385 if (r.task == null) Slog.v(TAG,
1386 "startActivityUncheckedLocked: task left null",
1387 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001388 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1389 }
1390 if ((launchFlags &
1391 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1392 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1393 // The caller has requested to completely replace any
1394 // existing task with its new activity. Well that should
1395 // not be too hard...
1396 reuseTask = intentActivity.task;
1397 reuseTask.performClearTaskLocked();
1398 reuseTask.setIntent(r.intent, r.info);
1399 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1400 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1401 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1402 // In this situation we want to remove all activities
1403 // from the task up to the one being started. In most
1404 // cases this means we are resetting the task to its
1405 // initial state.
1406 ActivityRecord top =
1407 intentActivity.task.performClearTaskLocked(r, launchFlags);
1408 if (top != null) {
1409 if (top.frontOfTask) {
1410 // Activity aliases may mean we use different
1411 // intents for the top activity, so make sure
1412 // the task now has the identity of the new
1413 // intent.
1414 top.task.setIntent(r.intent, r.info);
1415 }
1416 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1417 r, top.task);
1418 top.deliverNewIntentLocked(callingUid, r.intent);
1419 } else {
1420 // A special case: we need to
1421 // start the activity because it is not currently
1422 // running, and the caller has asked to clear the
1423 // current task to have this activity at the top.
1424 addingToTask = true;
1425 // Now pretend like this activity is being started
1426 // by the top of its task, so it is put in the
1427 // right place.
1428 sourceRecord = intentActivity;
1429 }
1430 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1431 // In this case the top activity on the task is the
1432 // same as the one being launched, so we take that
1433 // as a request to bring the task to the foreground.
1434 // If the top activity in the task is the root
1435 // activity, deliver this new intent to it if it
1436 // desires.
1437 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1438 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1439 && intentActivity.realActivity.equals(r.realActivity)) {
1440 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1441 intentActivity.task);
1442 if (intentActivity.frontOfTask) {
1443 intentActivity.task.setIntent(r.intent, r.info);
1444 }
1445 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1446 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1447 // In this case we are launching the root activity
1448 // of the task, but with a different intent. We
1449 // should start a new instance on top.
1450 addingToTask = true;
1451 sourceRecord = intentActivity;
1452 }
1453 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1454 // In this case an activity is being launched in to an
1455 // existing task, without resetting that task. This
1456 // is typically the situation of launching an activity
1457 // from a notification or shortcut. We want to place
1458 // the new activity on top of the current task.
1459 addingToTask = true;
1460 sourceRecord = intentActivity;
1461 } else if (!intentActivity.task.rootWasReset) {
1462 // In this case we are launching in to an existing task
1463 // that has not yet been started from its front door.
1464 // The current task has been brought to the front.
1465 // Ideally, we'd probably like to place this new task
1466 // at the bottom of its stack, but that's a little hard
1467 // to do with the current organization of the code so
1468 // for now we'll just drop it.
1469 intentActivity.task.setIntent(r.intent, r.info);
1470 }
1471 if (!addingToTask && reuseTask == null) {
1472 // We didn't do anything... but it was needed (a.k.a., client
1473 // don't use that intent!) And for paranoia, make
1474 // sure we have correctly resumed the top activity.
1475 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001476 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1477 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001478 } else {
1479 ActivityOptions.abort(options);
1480 }
Craig Mautner29219d92013-04-16 20:19:12 -07001481 if (r.task == null) Slog.v(TAG,
1482 "startActivityUncheckedLocked: task left null",
1483 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001484 return ActivityManager.START_TASK_TO_FRONT;
1485 }
1486 }
1487 }
1488 }
1489
1490 //String uri = r.intent.toURI();
1491 //Intent intent2 = new Intent(uri);
1492 //Slog.i(TAG, "Given intent: " + r.intent);
1493 //Slog.i(TAG, "URI is: " + uri);
1494 //Slog.i(TAG, "To intent: " + intent2);
1495
1496 if (r.packageName != null) {
1497 // If the activity being launched is the same as the one currently
1498 // at the top, then we need to check if it should only be launched
1499 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001500 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001501 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001502 if (top != null && r.resultTo == null) {
1503 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1504 if (top.app != null && top.app.thread != null) {
1505 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1506 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1507 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1508 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1509 top.task);
1510 // For paranoia, make sure we have correctly
1511 // resumed the top activity.
1512 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001513 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001514 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001515 }
1516 ActivityOptions.abort(options);
1517 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1518 // We don't need to start a new activity, and
1519 // the client said not to do anything if that
1520 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001521 if (r.task == null) Slog.v(TAG,
1522 "startActivityUncheckedLocked: task left null",
1523 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001524 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1525 }
1526 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001527 if (r.task == null) Slog.v(TAG,
1528 "startActivityUncheckedLocked: task left null",
1529 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001530 return ActivityManager.START_DELIVERED_TO_TOP;
1531 }
1532 }
1533 }
1534 }
1535
1536 } else {
1537 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001538 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1539 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001540 }
1541 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001542 if (r.task == null) Slog.v(TAG,
1543 "startActivityUncheckedLocked: task left null",
1544 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001545 return ActivityManager.START_CLASS_NOT_FOUND;
1546 }
1547
1548 boolean newTask = false;
1549 boolean keepCurTransition = false;
1550
1551 // Should this be considered a new task?
1552 if (r.resultTo == null && !addingToTask
1553 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001554 targetStack = getCorrectStack(r);
1555 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001556 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001557 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1558 null, true);
1559 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1560 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001561 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001562 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001563 }
1564 newTask = true;
1565 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001566 if ((launchFlags &
1567 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1568 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1569 // Caller wants to appear on home activity, so before starting
1570 // their own activity we will bring home to the front.
1571 r.mLaunchHomeTaskNext = true;
1572 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001573 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001574 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001575 sourceTask = sourceRecord.task;
1576 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001577 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001578 if (!addingToTask &&
1579 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1580 // In this case, we are adding the activity to an existing
1581 // task, but the caller has asked to clear that task if the
1582 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001583 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001584 keepCurTransition = true;
1585 if (top != null) {
1586 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1587 top.deliverNewIntentLocked(callingUid, r.intent);
1588 // For paranoia, make sure we have correctly
1589 // resumed the top activity.
1590 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001591 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001592 targetStack.resumeTopActivityLocked(null);
1593 }
1594 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001595 if (r.task == null) Slog.v(TAG,
1596 "startActivityUncheckedLocked: task left null",
1597 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001598 return ActivityManager.START_DELIVERED_TO_TOP;
1599 }
1600 } else if (!addingToTask &&
1601 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1602 // In this case, we are launching an activity in our own task
1603 // that may already be running somewhere in the history, and
1604 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001605 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001606 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001607 final TaskRecord task = top.task;
1608 task.moveActivityToFrontLocked(top);
1609 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001610 top.updateOptionsLocked(options);
1611 top.deliverNewIntentLocked(callingUid, r.intent);
1612 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001613 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001614 targetStack.resumeTopActivityLocked(null);
1615 }
Craig Mautner29219d92013-04-16 20:19:12 -07001616 if (r.task == null) Slog.v(TAG,
1617 "startActivityUncheckedLocked: task left null",
1618 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001619 return ActivityManager.START_DELIVERED_TO_TOP;
1620 }
1621 }
1622 // An existing activity is starting this new activity, so we want
1623 // to keep the new one in the same task as the one that is starting
1624 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001625 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001626 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1627 + " in existing task " + r.task);
1628
1629 } else {
1630 // This not being started from an existing activity, and not part
1631 // of a new task... just put it in the top task, though these days
1632 // this case should never happen.
Craig Mautner1602ec22013-05-12 10:24:27 -07001633 targetStack = getCorrectStack(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001634 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001635 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001636 r.setTask(prev != null ? prev.task
1637 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1638 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001639 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1640 + " in new guessed " + r.task);
1641 }
1642
1643 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1644 intent, r.getUriPermissionsLocked());
1645
1646 if (newTask) {
1647 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1648 }
1649 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001650 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001651 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1652 return ActivityManager.START_SUCCESS;
1653 }
1654
Craig Mautnerf3333272013-04-22 10:55:53 -07001655 // Checked.
1656 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1657 Configuration config) {
1658 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1659
1660 ActivityRecord res = null;
1661
1662 ArrayList<ActivityRecord> stops = null;
1663 ArrayList<ActivityRecord> finishes = null;
1664 ArrayList<UserStartedState> startingUsers = null;
1665 int NS = 0;
1666 int NF = 0;
1667 IApplicationThread sendThumbnail = null;
1668 boolean booting = false;
1669 boolean enableScreen = false;
1670 boolean activityRemoved = false;
1671
1672 ActivityRecord r = ActivityRecord.forToken(token);
1673 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001674 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1675 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001676 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1677 r.finishLaunchTickingLocked();
Craig Mautner525f3d92013-05-07 14:01:50 -07001678 res = r.task.stack.activityIdleInternalLocked(token);
Craig Mautnerf3333272013-04-22 10:55:53 -07001679 if (res != null) {
1680 if (fromTimeout) {
1681 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1682 }
1683
1684 // This is a hack to semi-deal with a race condition
1685 // in the client where it can be constructed with a
1686 // newer configuration from when we asked it to launch.
1687 // We'll update with whatever configuration it now says
1688 // it used to launch.
1689 if (config != null) {
1690 r.configuration = config;
1691 }
1692
1693 // We are now idle. If someone is waiting for a thumbnail from
1694 // us, we can now deliver.
1695 r.idle = true;
1696 if (allResumedActivitiesIdle()) {
1697 mService.scheduleAppGcsLocked();
1698 }
1699 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1700 sendThumbnail = r.app.thread;
1701 r.thumbnailNeeded = false;
1702 }
1703
1704 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1705 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1706 mService.mBooted = true;
1707 enableScreen = true;
1708 }
1709 } else if (fromTimeout) {
1710 reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
1711 }
1712 }
1713
1714 // Atomically retrieve all of the other things to do.
1715 stops = processStoppingActivitiesLocked(true);
1716 NS = stops != null ? stops.size() : 0;
1717 if ((NF=mFinishingActivities.size()) > 0) {
1718 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1719 mFinishingActivities.clear();
1720 }
1721
1722 final ArrayList<ActivityRecord> thumbnails;
1723 final int NT = mCancelledThumbnails.size();
1724 if (NT > 0) {
1725 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1726 mCancelledThumbnails.clear();
1727 } else {
1728 thumbnails = null;
1729 }
1730
1731 if (isFrontStack(mHomeStack)) {
1732 booting = mService.mBooting;
1733 mService.mBooting = false;
1734 }
1735
1736 if (mStartingUsers.size() > 0) {
1737 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1738 mStartingUsers.clear();
1739 }
1740
1741 // Perform the following actions from unsynchronized state.
1742 final IApplicationThread thumbnailThread = sendThumbnail;
1743 mHandler.post(new Runnable() {
1744 @Override
1745 public void run() {
1746 if (thumbnailThread != null) {
1747 try {
1748 thumbnailThread.requestThumbnail(token);
1749 } catch (Exception e) {
1750 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1751 mService.sendPendingThumbnail(null, token, null, null, true);
1752 }
1753 }
1754
1755 // Report back to any thumbnail receivers.
1756 for (int i = 0; i < NT; i++) {
1757 ActivityRecord r = thumbnails.get(i);
1758 mService.sendPendingThumbnail(r, null, null, null, true);
1759 }
1760 }
1761 });
1762
1763 // Stop any activities that are scheduled to do so but have been
1764 // waiting for the next one to start.
1765 for (int i = 0; i < NS; i++) {
1766 r = stops.get(i);
1767 final ActivityStack stack = r.task.stack;
1768 if (r.finishing) {
1769 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1770 } else {
1771 stack.stopActivityLocked(r);
1772 }
1773 }
1774
1775 // Finish any activities that are scheduled to do so but have been
1776 // waiting for the next one to start.
1777 for (int i = 0; i < NF; i++) {
1778 r = finishes.get(i);
1779 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1780 }
1781
1782 if (booting) {
1783 mService.finishBooting();
1784 } else if (startingUsers != null) {
1785 for (int i = 0; i < startingUsers.size(); i++) {
1786 mService.finishUserSwitch(startingUsers.get(i));
1787 }
1788 }
1789
1790 mService.trimApplications();
1791 //dump();
1792 //mWindowManager.dump();
1793
1794 if (enableScreen) {
1795 mService.enableScreenAfterBoot();
1796 }
1797
1798 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001799 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001800 }
1801
1802 return res;
1803 }
1804
Craig Mautner8d341ef2013-03-26 09:03:27 -07001805 void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1806 // Just in case.
1807 final int numStacks = mStacks.size();
1808 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001809 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001810 }
1811 }
1812
1813 void closeSystemDialogsLocked() {
1814 final int numStacks = mStacks.size();
1815 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1816 final ActivityStack stack = mStacks.get(stackNdx);
1817 stack.closeSystemDialogsLocked();
1818 }
1819 }
1820
1821 /**
1822 * @return true if some activity was finished (or would have finished if doit were true).
1823 */
1824 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1825 boolean didSomething = false;
1826 final int numStacks = mStacks.size();
1827 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1828 final ActivityStack stack = mStacks.get(stackNdx);
1829 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1830 didSomething = true;
1831 }
1832 }
1833 return didSomething;
1834 }
1835
Craig Mautner05d29032013-05-03 13:40:13 -07001836 boolean resumeTopActivitiesLocked() {
1837 return resumeTopActivitiesLocked(null, null, null);
1838 }
1839
1840 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1841 Bundle targetOptions) {
1842 if (targetStack == null) {
1843 targetStack = getFocusedStack();
1844 }
1845 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001846 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001847 final ActivityStack stack = mStacks.get(stackNdx);
1848 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001849 if (stack == targetStack) {
1850 result = stack.resumeTopActivityLocked(target, targetOptions);
1851 } else {
1852 stack.resumeTopActivityLocked(null);
1853 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001854 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001855 }
Craig Mautner05d29032013-05-03 13:40:13 -07001856 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001857 }
1858
1859 void finishTopRunningActivityLocked(ProcessRecord app) {
1860 final int numStacks = mStacks.size();
1861 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1862 final ActivityStack stack = mStacks.get(stackNdx);
1863 stack.finishTopRunningActivityLocked(app);
1864 }
1865 }
1866
Craig Mautner8d341ef2013-03-26 09:03:27 -07001867 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
1868 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1869 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
1870 return;
1871 }
1872 }
1873 }
1874
Craig Mautner967212c2013-04-13 21:10:58 -07001875 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001876 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1877 final ActivityStack stack = mStacks.get(stackNdx);
1878 if (stack.getStackId() == stackId) {
1879 return stack;
1880 }
1881 }
1882 return null;
1883 }
1884
Craig Mautner967212c2013-04-13 21:10:58 -07001885 ArrayList<ActivityStack> getStacks() {
1886 return new ArrayList<ActivityStack>(mStacks);
1887 }
1888
1889 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07001890 while (true) {
1891 if (++mLastStackId <= HOME_STACK_ID) {
1892 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001893 }
Craig Mautner858d8a62013-04-23 17:08:34 -07001894 if (getStack(mLastStackId) == null) {
1895 break;
1896 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001897 }
Craig Mautner858d8a62013-04-23 17:08:34 -07001898 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
1899 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001900 }
1901
1902 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07001903 final TaskRecord task = anyTaskForIdLocked(taskId);
1904 if (task == null) {
1905 return;
1906 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001907 final ActivityStack stack = getStack(stackId);
1908 if (stack == null) {
1909 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
1910 return;
1911 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07001912 removeTask(task);
1913 stack.addTask(task, toTop);
1914 if (toTop) {
1915 moveHomeStack(stack.isHomeStack());
1916 setFocusedStack(task.getTopActivity());
1917 }
1918 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07001919 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07001920 }
1921
Craig Mautner8849a5e2013-04-02 16:41:03 -07001922 ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
1923 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1924 final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info);
1925 if (ar != null) {
1926 return ar;
1927 }
1928 }
1929 return null;
1930 }
1931
1932 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
1933 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1934 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
1935 if (ar != null) {
1936 return ar;
1937 }
1938 }
1939 return null;
1940 }
1941
Craig Mautner8d341ef2013-03-26 09:03:27 -07001942 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001943 scheduleSleepTimeout();
1944 if (!mGoingToSleep.isHeld()) {
1945 mGoingToSleep.acquire();
1946 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1947 final ActivityStack stack = mStacks.get(stackNdx);
1948 if (stack.mResumedActivity != null) {
1949 stack.stopIfSleepingLocked();
1950 }
1951 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001952 }
1953 }
1954
1955 boolean shutdownLocked(int timeout) {
1956 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07001957 goingToSleepLocked();
1958 checkReadyForSleepLocked();
1959
1960 final long endTime = System.currentTimeMillis() + timeout;
1961 while (true) {
1962 boolean cantShutdown = false;
1963 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1964 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
1965 }
1966 if (cantShutdown) {
1967 long timeRemaining = endTime - System.currentTimeMillis();
1968 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001969 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001970 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001971 } catch (InterruptedException e) {
1972 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001973 } else {
1974 Slog.w(TAG, "Activity manager shutdown timed out");
1975 timedout = true;
1976 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001977 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001978 } else {
1979 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001980 }
1981 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001982
1983 // Force checkReadyForSleep to complete.
1984 mSleepTimeout = true;
1985 checkReadyForSleepLocked();
1986
Craig Mautner8d341ef2013-03-26 09:03:27 -07001987 return timedout;
1988 }
1989
1990 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001991 removeSleepTimeouts();
1992 if (mGoingToSleep.isHeld()) {
1993 mGoingToSleep.release();
1994 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001995 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001996 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001997 stack.awakeFromSleepingLocked();
1998 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001999 resumeTopActivitiesLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -07002000 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002001 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002002 mGoingToSleepActivities.clear();
2003 }
2004
2005 void activitySleptLocked(ActivityRecord r) {
2006 mGoingToSleepActivities.remove(r);
2007 checkReadyForSleepLocked();
2008 }
2009
2010 void checkReadyForSleepLocked() {
2011 if (!mService.isSleepingOrShuttingDown()) {
2012 // Do not care.
2013 return;
2014 }
2015
2016 if (!mSleepTimeout) {
2017 boolean dontSleep = false;
2018 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2019 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2020 }
2021
2022 if (mStoppingActivities.size() > 0) {
2023 // Still need to tell some activities to stop; can't sleep yet.
2024 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2025 + mStoppingActivities.size() + " activities");
2026 scheduleIdleLocked();
2027 dontSleep = true;
2028 }
2029
2030 if (mGoingToSleepActivities.size() > 0) {
2031 // Still need to tell some activities to sleep; can't sleep yet.
2032 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2033 + mGoingToSleepActivities.size() + " activities");
2034 dontSleep = true;
2035 }
2036
2037 if (dontSleep) {
2038 return;
2039 }
2040 }
2041
2042 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2043 mStacks.get(stackNdx).goToSleep();
2044 }
2045
2046 removeSleepTimeouts();
2047
2048 if (mGoingToSleep.isHeld()) {
2049 mGoingToSleep.release();
2050 }
2051 if (mService.mShuttingDown) {
2052 mService.notifyAll();
2053 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002054 }
2055
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002056 boolean reportResumedActivityLocked(ActivityRecord r) {
2057 final ActivityStack stack = r.task.stack;
2058 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002059 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002060 mService.setFocusedActivityLocked(r);
2061 }
2062 if (allResumedActivitiesComplete()) {
2063 ensureActivitiesVisibleLocked(null, 0);
2064 mWindowManager.executeAppTransition();
2065 return true;
2066 }
2067 return false;
2068 }
2069
Craig Mautner8d341ef2013-03-26 09:03:27 -07002070 void handleAppCrashLocked(ProcessRecord app) {
2071 final int numStacks = mStacks.size();
2072 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2073 final ActivityStack stack = mStacks.get(stackNdx);
2074 stack.handleAppCrashLocked(app);
2075 }
2076 }
2077
Craig Mautnerde4ef022013-04-07 19:01:33 -07002078 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002079 // First the front stacks. In case any are not fullscreen and are in front of home.
2080 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002081 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002082 final ActivityStack stack = mStacks.get(stackNdx);
2083 if (isFrontStack(stack)) {
2084 showHomeBehindStack =
2085 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2086 }
2087 }
2088 // Now do back stacks.
2089 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2090 final ActivityStack stack = mStacks.get(stackNdx);
2091 if (!isFrontStack(stack)) {
2092 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2093 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002094 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002095 }
2096
2097 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2098 final int numStacks = mStacks.size();
2099 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2100 final ActivityStack stack = mStacks.get(stackNdx);
2101 stack.scheduleDestroyActivities(app, false, reason);
2102 }
2103 }
2104
2105 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner858d8a62013-04-23 17:08:34 -07002106 mUserStates.put(mCurrentUser, new UserState());
Craig Mautner2420ead2013-04-01 17:13:20 -07002107 mCurrentUser = userId;
Craig Mautner858d8a62013-04-23 17:08:34 -07002108 UserState userState = mUserStates.get(userId);
2109 if (userState != null) {
2110 userState.restore();
2111 mUserStates.delete(userId);
2112 } else {
2113 mFocusedStack = null;
Craig Mautner76ea2242013-05-15 11:40:05 -07002114 if (DEBUG_STACK) Slog.d(TAG, "switchUserLocked: mStackState=" +
2115 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautner858d8a62013-04-23 17:08:34 -07002116 mStackState = STACK_STATE_HOME_IN_FRONT;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002117 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002118
2119 mStartingUsers.add(uss);
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002120 boolean haveActivities = mHomeStack.switchUserLocked(userId);
Craig Mautner858d8a62013-04-23 17:08:34 -07002121
2122 resumeTopActivitiesLocked();
2123
Craig Mautner8d341ef2013-03-26 09:03:27 -07002124 return haveActivities;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002125 }
2126
Craig Mautnerde4ef022013-04-07 19:01:33 -07002127 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2128 int N = mStoppingActivities.size();
2129 if (N <= 0) return null;
2130
2131 ArrayList<ActivityRecord> stops = null;
2132
2133 final boolean nowVisible = allResumedActivitiesVisible();
2134 for (int i=0; i<N; i++) {
2135 ActivityRecord s = mStoppingActivities.get(i);
2136 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2137 + nowVisible + " waitingVisible=" + s.waitingVisible
2138 + " finishing=" + s.finishing);
2139 if (s.waitingVisible && nowVisible) {
2140 mWaitingVisibleActivities.remove(s);
2141 s.waitingVisible = false;
2142 if (s.finishing) {
2143 // If this activity is finishing, it is sitting on top of
2144 // everyone else but we now know it is no longer needed...
2145 // so get rid of it. Otherwise, we need to go through the
2146 // normal flow and hide it once we determine that it is
2147 // hidden by the activities in front of it.
2148 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002149 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002150 }
2151 }
2152 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2153 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2154 if (stops == null) {
2155 stops = new ArrayList<ActivityRecord>();
2156 }
2157 stops.add(s);
2158 mStoppingActivities.remove(i);
2159 N--;
2160 i--;
2161 }
2162 }
2163
2164 return stops;
2165 }
2166
Craig Mautnercf910b02013-04-23 11:23:27 -07002167 void validateTopActivitiesLocked() {
2168 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2169 final ActivityStack stack = mStacks.get(stackNdx);
2170 final ActivityRecord r = stack.topRunningActivityLocked(null);
2171 if (isFrontStack(stack)) {
2172 if (r == null) {
2173 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2174 } else {
2175 if (stack.mPausingActivity != null) {
2176 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2177 " state=" + r.state);
2178 }
2179 if (r.state != ActivityState.INITIALIZING &&
2180 r.state != ActivityState.RESUMED) {
2181 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2182 " state=" + r.state);
2183 }
2184 }
2185 } else {
2186 if (stack.mResumedActivity != null) {
2187 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2188 " state=" + r.state);
2189 }
2190 if (r != null && (r.state == ActivityState.INITIALIZING
2191 || r.state == ActivityState.RESUMED)) {
2192 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2193 " state=" + r.state);
2194 }
2195 }
2196 }
2197 }
2198
Craig Mautner76ea2242013-05-15 11:40:05 -07002199 private static String stackStateToString(int stackState) {
2200 switch (stackState) {
2201 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2202 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2203 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2204 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2205 default: return "Unknown stackState=" + stackState;
2206 }
2207 }
2208
Craig Mautner27084302013-03-25 08:05:25 -07002209 public void dump(PrintWriter pw, String prefix) {
2210 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2211 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002212 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002213 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2214 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautner27084302013-03-25 08:05:25 -07002215 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002216
Craig Mautner20e72272013-04-01 13:45:53 -07002217 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002218 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002219 }
2220
Dianne Hackborn390517b2013-05-30 15:03:32 -07002221 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2222 boolean needSep, String prefix) {
2223 if (activity != null) {
2224 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2225 if (needSep) {
2226 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002227 }
2228 pw.print(prefix);
2229 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002230 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002231 }
2232 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002233 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002234 }
2235
Craig Mautner8d341ef2013-03-26 09:03:27 -07002236 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2237 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002238 boolean printed = false;
2239 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002240 final int numStacks = mStacks.size();
2241 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2242 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002243 StringBuilder stackHeader = new StringBuilder(128);
2244 stackHeader.append(" Stack #");
2245 stackHeader.append(mStacks.indexOf(stack));
2246 stackHeader.append(":");
2247 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2248 stackHeader.toString());
2249 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2250 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002251
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002252 needSep = printed;
2253 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002254 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002255 if (pr) {
2256 printed = true;
2257 needSep = false;
2258 }
2259 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002260 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002261 if (pr) {
2262 printed = true;
2263 needSep = false;
2264 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002265 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002266 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002267 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002268 if (pr) {
2269 printed = true;
2270 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002271 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002272 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002273 }
2274
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002275 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2276 false, dumpPackage, true, " Activities waiting to finish:", null);
2277 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2278 false, dumpPackage, true, " Activities waiting to stop:", null);
2279 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2280 false, dumpPackage, true, " Activities waiting for another to become visible:",
2281 null);
2282 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2283 false, dumpPackage, true, " Activities waiting to sleep:", null);
2284 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2285 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002286
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002287 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002288 }
2289
Dianne Hackborn390517b2013-05-30 15:03:32 -07002290 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002291 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002292 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002293 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002294 String innerPrefix = null;
2295 String[] args = null;
2296 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002297 for (int i=list.size()-1; i>=0; i--) {
2298 final ActivityRecord r = list.get(i);
2299 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2300 continue;
2301 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002302 if (innerPrefix == null) {
2303 innerPrefix = prefix + " ";
2304 args = new String[0];
2305 }
2306 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002307 final boolean full = !brief && (complete || !r.isInHistory());
2308 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002309 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002310 needNL = false;
2311 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002312 if (header1 != null) {
2313 pw.println(header1);
2314 header1 = null;
2315 }
2316 if (header2 != null) {
2317 pw.println(header2);
2318 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002319 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002320 if (lastTask != r.task) {
2321 lastTask = r.task;
2322 pw.print(prefix);
2323 pw.print(full ? "* " : " ");
2324 pw.println(lastTask);
2325 if (full) {
2326 lastTask.dump(pw, prefix + " ");
2327 } else if (complete) {
2328 // Complete + brief == give a summary. Isn't that obvious?!?
2329 if (lastTask.intent != null) {
2330 pw.print(prefix); pw.print(" ");
2331 pw.println(lastTask.intent.toInsecureStringWithClip());
2332 }
2333 }
2334 }
2335 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2336 pw.print(" #"); pw.print(i); pw.print(": ");
2337 pw.println(r);
2338 if (full) {
2339 r.dump(pw, innerPrefix);
2340 } else if (complete) {
2341 // Complete + brief == give a summary. Isn't that obvious?!?
2342 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2343 if (r.app != null) {
2344 pw.print(innerPrefix); pw.println(r.app);
2345 }
2346 }
2347 if (client && r.app != null && r.app.thread != null) {
2348 // flush anything that is already in the PrintWriter since the thread is going
2349 // to write to the file descriptor directly
2350 pw.flush();
2351 try {
2352 TransferPipe tp = new TransferPipe();
2353 try {
2354 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2355 r.appToken, innerPrefix, args);
2356 // Short timeout, since blocking here can
2357 // deadlock with the application.
2358 tp.go(fd, 2000);
2359 } finally {
2360 tp.kill();
2361 }
2362 } catch (IOException e) {
2363 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2364 } catch (RemoteException e) {
2365 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2366 }
2367 needNL = true;
2368 }
2369 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002370 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002371 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002372
Craig Mautnerf3333272013-04-22 10:55:53 -07002373 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002374 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002375 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2376 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002377 }
2378
2379 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002380 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002381 }
2382
2383 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002384 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002385 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2386 }
2387
Craig Mautner05d29032013-05-03 13:40:13 -07002388 final void scheduleResumeTopActivities() {
2389 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2390 }
2391
Craig Mautner0eea92c2013-05-16 13:35:39 -07002392 void removeSleepTimeouts() {
2393 mSleepTimeout = false;
2394 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2395 }
2396
2397 final void scheduleSleepTimeout() {
2398 removeSleepTimeouts();
2399 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2400 }
2401
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002402 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002403
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002404 public ActivityStackSupervisorHandler(Looper looper) {
2405 super(looper);
2406 }
2407
Craig Mautnerf3333272013-04-22 10:55:53 -07002408 void activityIdleInternal(ActivityRecord r) {
2409 synchronized (mService) {
2410 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2411 }
2412 }
2413
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002414 @Override
2415 public void handleMessage(Message msg) {
2416 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002417 case IDLE_TIMEOUT_MSG: {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002418 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" +
2419 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002420 if (mService.mDidDexOpt) {
2421 mService.mDidDexOpt = false;
2422 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2423 nmsg.obj = msg.obj;
2424 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2425 return;
2426 }
2427 // We don't at this point know if the activity is fullscreen,
2428 // so we need to be conservative and assume it isn't.
2429 activityIdleInternal((ActivityRecord)msg.obj);
2430 } break;
2431 case IDLE_NOW_MSG: {
2432 activityIdleInternal((ActivityRecord)msg.obj);
2433 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002434 case RESUME_TOP_ACTIVITY_MSG: {
2435 synchronized (mService) {
2436 resumeTopActivitiesLocked();
2437 }
2438 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002439 case SLEEP_TIMEOUT_MSG: {
2440 synchronized (mService) {
2441 if (mService.isSleepingOrShuttingDown()) {
2442 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2443 mSleepTimeout = true;
2444 checkReadyForSleepLocked();
2445 }
2446 }
2447 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002448 }
2449 }
2450 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002451
2452 private final class UserState {
2453 final ActivityStack mSavedFocusedStack;
2454 final int mSavedStackState;
2455
2456 public UserState() {
2457 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2458 mSavedFocusedStack = supervisor.mFocusedStack;
2459 mSavedStackState = supervisor.mStackState;
2460 }
2461
2462 void restore() {
2463 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2464 supervisor.mFocusedStack = mSavedFocusedStack;
Craig Mautner76ea2242013-05-15 11:40:05 -07002465 if (DEBUG_STACK) Slog.d(TAG, "UserState.restore: mStackState old=" +
2466 stackStateToString(mSavedStackState));
Craig Mautner858d8a62013-04-23 17:08:34 -07002467 supervisor.mStackState = mSavedStackState;
2468 }
2469 }
Craig Mautner27084302013-03-25 08:05:25 -07002470}