blob: a4fd7ad65474d9d178d59ffcfda6e21884638854 [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 {
Dianne Hackborn78a369c2013-06-11 17:10:32 -0700990 app.addPackage(r.info.packageName, mService.mProcessTracker);
Craig Mautnere79d42682013-04-01 19:01:53 -0700991 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 Mautner1d001b62013-06-18 16:52:43 -07001189 final TaskRecord task = r.task;
1190 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautner858d8a62013-04-23 17:08:34 -07001191 int stackNdx;
1192 for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1193 if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) {
1194 break;
1195 }
1196 }
1197 if (stackNdx == 0) {
1198 // Time to create the first app stack for this user.
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001199 int stackId = mService.createStack(-1, HOME_STACK_ID,
1200 StackBox.TASK_STACK_GOES_OVER, 1.0f);
Craig Mautner29219d92013-04-16 20:19:12 -07001201 mFocusedStack = getStack(stackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001202 }
Craig Mautner1d001b62013-06-18 16:52:43 -07001203 if (task != null) {
1204 mFocusedStack = task.stack;
1205 }
Craig Mautner29219d92013-04-16 20:19:12 -07001206 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001207 }
1208 return mHomeStack;
1209 }
1210
Craig Mautner29219d92013-04-16 20:19:12 -07001211 void setFocusedStack(ActivityRecord r) {
1212 if (r == null) {
1213 return;
1214 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001215 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001216 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001217 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1218 stackStateToString(mStackState) + " new=" +
1219 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1220 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001221 mStackState = STACK_STATE_HOME_TO_FRONT;
1222 }
1223 } else {
1224 mFocusedStack = r.task.stack;
1225 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001226 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1227 stackStateToString(mStackState) + " new=" +
1228 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1229 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001230 mStackState = STACK_STATE_HOME_TO_BACK;
1231 }
1232 }
1233 }
1234
Craig Mautner8849a5e2013-04-02 16:41:03 -07001235 final int startActivityUncheckedLocked(ActivityRecord r,
1236 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1237 Bundle options) {
1238 final Intent intent = r.intent;
1239 final int callingUid = r.launchedFromUid;
1240
1241 int launchFlags = intent.getFlags();
1242
Craig Mautner8849a5e2013-04-02 16:41:03 -07001243 // We'll invoke onUserLeaving before onPause only if the launching
1244 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001245 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1246 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001247
1248 // If the caller has asked not to resume at this point, we make note
1249 // of this in the record so that we can skip it when trying to find
1250 // the top running activity.
1251 if (!doResume) {
1252 r.delayedResume = true;
1253 }
1254
1255 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1256
1257 // If the onlyIfNeeded flag is set, then we can do this if the activity
1258 // being launched is the same as the one making the call... or, as
1259 // a special case, if we do not know the caller then we count the
1260 // current top activity as the caller.
1261 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1262 ActivityRecord checkedCaller = sourceRecord;
1263 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001264 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001265 }
1266 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1267 // Caller is not the same as launcher, so always needed.
1268 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1269 }
1270 }
1271
1272 if (sourceRecord == null) {
1273 // This activity is not being started from another... in this
1274 // case we -always- start a new task.
1275 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001276 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1277 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001278 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1279 }
1280 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1281 // The original activity who is starting us is running as a single
1282 // instance... this new activity it is starting must go on its
1283 // own task.
1284 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1285 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1286 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1287 // The activity being started is a single instance... it always
1288 // gets launched into its own task.
1289 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1290 }
1291
Craig Mautnerde4ef022013-04-07 19:01:33 -07001292 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001293 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001294 if (sourceRecord != null) {
1295 sourceTask = sourceRecord.task;
1296 sourceStack = sourceTask.stack;
1297 } else {
1298 sourceTask = null;
1299 sourceStack = null;
1300 }
1301
Craig Mautner8849a5e2013-04-02 16:41:03 -07001302 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1303 // For whatever reason this activity is being launched into a new
1304 // task... yet the caller has requested a result back. Well, that
1305 // is pretty messed up, so instead immediately send back a cancel
1306 // and let the new task continue launched as normal without a
1307 // dependency on its originator.
1308 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1309 r.resultTo.task.stack.sendActivityResultLocked(-1,
1310 r.resultTo, r.resultWho, r.requestCode,
1311 Activity.RESULT_CANCELED, null);
1312 r.resultTo = null;
1313 }
1314
1315 boolean addingToTask = false;
1316 boolean movedHome = false;
1317 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001318 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001319 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1320 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1321 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1322 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1323 // If bring to front is requested, and no result is requested, and
1324 // we can find a task that was started with this same
1325 // component, then instead of launching bring that one to the front.
1326 if (r.resultTo == null) {
1327 // See if there is a task to bring to the front. If this is
1328 // a SINGLE_INSTANCE activity, there can be one and only one
1329 // instance of it in the history, and it is always in its own
1330 // unique task, so we do a special search.
1331 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1332 ? findTaskLocked(intent, r.info)
1333 : findActivityLocked(intent, r.info);
1334 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001335 if (r.task == null) {
1336 r.task = intentActivity.task;
1337 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001338 targetStack = intentActivity.task.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001339 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001340 if (intentActivity.task.intent == null) {
1341 // This task was started because of movement of
1342 // the activity based on affinity... now that we
1343 // are actually launching it, we can assign the
1344 // base intent.
1345 intentActivity.task.setIntent(intent, r.info);
1346 }
1347 // If the target task is not in the front, then we need
1348 // to bring it to the front... except... well, with
1349 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1350 // to have the same behavior as if a new instance was
1351 // being started, which means not bringing it to the front
1352 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001353 final ActivityStack lastStack = getLastStack();
1354 ActivityRecord curTop = lastStack == null?
1355 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001356 if (curTop != null && curTop.task != intentActivity.task) {
1357 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001358 if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001359 // We really do want to push this one into the
1360 // user's face, right now.
1361 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001362 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001363 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1364 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001365 // Caller wants to appear on home activity, so before starting
1366 // their own activity we will bring home to the front.
1367 r.mLaunchHomeTaskNext = true;
1368 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001369 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1370 options = null;
1371 }
1372 }
1373 // If the caller has requested that the target task be
1374 // reset, then do so.
1375 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1376 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1377 }
1378 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1379 // We don't need to start a new activity, and
1380 // the client said not to do anything if that
1381 // is the case, so this is it! And for paranoia, make
1382 // sure we have correctly resumed the top activity.
1383 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001384 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001385 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001386 } else {
1387 ActivityOptions.abort(options);
1388 }
Craig Mautner29219d92013-04-16 20:19:12 -07001389 if (r.task == null) Slog.v(TAG,
1390 "startActivityUncheckedLocked: task left null",
1391 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001392 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1393 }
1394 if ((launchFlags &
1395 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1396 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1397 // The caller has requested to completely replace any
1398 // existing task with its new activity. Well that should
1399 // not be too hard...
1400 reuseTask = intentActivity.task;
1401 reuseTask.performClearTaskLocked();
1402 reuseTask.setIntent(r.intent, r.info);
1403 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1404 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1405 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1406 // In this situation we want to remove all activities
1407 // from the task up to the one being started. In most
1408 // cases this means we are resetting the task to its
1409 // initial state.
1410 ActivityRecord top =
1411 intentActivity.task.performClearTaskLocked(r, launchFlags);
1412 if (top != null) {
1413 if (top.frontOfTask) {
1414 // Activity aliases may mean we use different
1415 // intents for the top activity, so make sure
1416 // the task now has the identity of the new
1417 // intent.
1418 top.task.setIntent(r.intent, r.info);
1419 }
1420 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1421 r, top.task);
1422 top.deliverNewIntentLocked(callingUid, r.intent);
1423 } else {
1424 // A special case: we need to
1425 // start the activity because it is not currently
1426 // running, and the caller has asked to clear the
1427 // current task to have this activity at the top.
1428 addingToTask = true;
1429 // Now pretend like this activity is being started
1430 // by the top of its task, so it is put in the
1431 // right place.
1432 sourceRecord = intentActivity;
1433 }
1434 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1435 // In this case the top activity on the task is the
1436 // same as the one being launched, so we take that
1437 // as a request to bring the task to the foreground.
1438 // If the top activity in the task is the root
1439 // activity, deliver this new intent to it if it
1440 // desires.
1441 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1442 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1443 && intentActivity.realActivity.equals(r.realActivity)) {
1444 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1445 intentActivity.task);
1446 if (intentActivity.frontOfTask) {
1447 intentActivity.task.setIntent(r.intent, r.info);
1448 }
1449 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1450 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1451 // In this case we are launching the root activity
1452 // of the task, but with a different intent. We
1453 // should start a new instance on top.
1454 addingToTask = true;
1455 sourceRecord = intentActivity;
1456 }
1457 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1458 // In this case an activity is being launched in to an
1459 // existing task, without resetting that task. This
1460 // is typically the situation of launching an activity
1461 // from a notification or shortcut. We want to place
1462 // the new activity on top of the current task.
1463 addingToTask = true;
1464 sourceRecord = intentActivity;
1465 } else if (!intentActivity.task.rootWasReset) {
1466 // In this case we are launching in to an existing task
1467 // that has not yet been started from its front door.
1468 // The current task has been brought to the front.
1469 // Ideally, we'd probably like to place this new task
1470 // at the bottom of its stack, but that's a little hard
1471 // to do with the current organization of the code so
1472 // for now we'll just drop it.
1473 intentActivity.task.setIntent(r.intent, r.info);
1474 }
1475 if (!addingToTask && reuseTask == null) {
1476 // We didn't do anything... but it was needed (a.k.a., client
1477 // don't use that intent!) And for paranoia, make
1478 // sure we have correctly resumed the top activity.
1479 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001480 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1481 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001482 } else {
1483 ActivityOptions.abort(options);
1484 }
Craig Mautner29219d92013-04-16 20:19:12 -07001485 if (r.task == null) Slog.v(TAG,
1486 "startActivityUncheckedLocked: task left null",
1487 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001488 return ActivityManager.START_TASK_TO_FRONT;
1489 }
1490 }
1491 }
1492 }
1493
1494 //String uri = r.intent.toURI();
1495 //Intent intent2 = new Intent(uri);
1496 //Slog.i(TAG, "Given intent: " + r.intent);
1497 //Slog.i(TAG, "URI is: " + uri);
1498 //Slog.i(TAG, "To intent: " + intent2);
1499
1500 if (r.packageName != null) {
1501 // If the activity being launched is the same as the one currently
1502 // at the top, then we need to check if it should only be launched
1503 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001504 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001505 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001506 if (top != null && r.resultTo == null) {
1507 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1508 if (top.app != null && top.app.thread != null) {
1509 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1510 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1511 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1512 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1513 top.task);
1514 // For paranoia, make sure we have correctly
1515 // resumed the top activity.
1516 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001517 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001518 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001519 }
1520 ActivityOptions.abort(options);
1521 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1522 // We don't need to start a new activity, and
1523 // the client said not to do anything if that
1524 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001525 if (r.task == null) Slog.v(TAG,
1526 "startActivityUncheckedLocked: task left null",
1527 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001528 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1529 }
1530 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001531 if (r.task == null) Slog.v(TAG,
1532 "startActivityUncheckedLocked: task left null",
1533 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001534 return ActivityManager.START_DELIVERED_TO_TOP;
1535 }
1536 }
1537 }
1538 }
1539
1540 } else {
1541 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001542 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1543 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001544 }
1545 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001546 if (r.task == null) Slog.v(TAG,
1547 "startActivityUncheckedLocked: task left null",
1548 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001549 return ActivityManager.START_CLASS_NOT_FOUND;
1550 }
1551
1552 boolean newTask = false;
1553 boolean keepCurTransition = false;
1554
1555 // Should this be considered a new task?
1556 if (r.resultTo == null && !addingToTask
1557 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001558 targetStack = getCorrectStack(r);
1559 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001560 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001561 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1562 null, true);
1563 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1564 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001565 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001566 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001567 }
1568 newTask = true;
1569 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001570 if ((launchFlags &
1571 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1572 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1573 // Caller wants to appear on home activity, so before starting
1574 // their own activity we will bring home to the front.
1575 r.mLaunchHomeTaskNext = true;
1576 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001577 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001578 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001579 sourceTask = sourceRecord.task;
1580 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001581 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001582 if (!addingToTask &&
1583 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1584 // In this case, we are adding the activity to an existing
1585 // task, but the caller has asked to clear that task if the
1586 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001587 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001588 keepCurTransition = true;
1589 if (top != null) {
1590 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1591 top.deliverNewIntentLocked(callingUid, r.intent);
1592 // For paranoia, make sure we have correctly
1593 // resumed the top activity.
1594 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001595 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001596 targetStack.resumeTopActivityLocked(null);
1597 }
1598 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001599 if (r.task == null) Slog.v(TAG,
1600 "startActivityUncheckedLocked: task left null",
1601 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001602 return ActivityManager.START_DELIVERED_TO_TOP;
1603 }
1604 } else if (!addingToTask &&
1605 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1606 // In this case, we are launching an activity in our own task
1607 // that may already be running somewhere in the history, and
1608 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001609 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001610 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001611 final TaskRecord task = top.task;
1612 task.moveActivityToFrontLocked(top);
1613 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001614 top.updateOptionsLocked(options);
1615 top.deliverNewIntentLocked(callingUid, r.intent);
1616 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001617 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001618 targetStack.resumeTopActivityLocked(null);
1619 }
Craig Mautner29219d92013-04-16 20:19:12 -07001620 if (r.task == null) Slog.v(TAG,
1621 "startActivityUncheckedLocked: task left null",
1622 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001623 return ActivityManager.START_DELIVERED_TO_TOP;
1624 }
1625 }
1626 // An existing activity is starting this new activity, so we want
1627 // to keep the new one in the same task as the one that is starting
1628 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001629 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001630 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1631 + " in existing task " + r.task);
1632
1633 } else {
1634 // This not being started from an existing activity, and not part
1635 // of a new task... just put it in the top task, though these days
1636 // this case should never happen.
Craig Mautner1602ec22013-05-12 10:24:27 -07001637 targetStack = getCorrectStack(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001638 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001639 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001640 r.setTask(prev != null ? prev.task
1641 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1642 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001643 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1644 + " in new guessed " + r.task);
1645 }
1646
1647 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1648 intent, r.getUriPermissionsLocked());
1649
1650 if (newTask) {
1651 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1652 }
1653 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001654 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001655 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001656 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001657 return ActivityManager.START_SUCCESS;
1658 }
1659
Craig Mautnerf3333272013-04-22 10:55:53 -07001660 // Checked.
1661 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1662 Configuration config) {
1663 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1664
1665 ActivityRecord res = null;
1666
1667 ArrayList<ActivityRecord> stops = null;
1668 ArrayList<ActivityRecord> finishes = null;
1669 ArrayList<UserStartedState> startingUsers = null;
1670 int NS = 0;
1671 int NF = 0;
1672 IApplicationThread sendThumbnail = null;
1673 boolean booting = false;
1674 boolean enableScreen = false;
1675 boolean activityRemoved = false;
1676
1677 ActivityRecord r = ActivityRecord.forToken(token);
1678 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001679 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1680 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001681 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1682 r.finishLaunchTickingLocked();
Craig Mautner525f3d92013-05-07 14:01:50 -07001683 res = r.task.stack.activityIdleInternalLocked(token);
Craig Mautnerf3333272013-04-22 10:55:53 -07001684 if (res != null) {
1685 if (fromTimeout) {
1686 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1687 }
1688
1689 // This is a hack to semi-deal with a race condition
1690 // in the client where it can be constructed with a
1691 // newer configuration from when we asked it to launch.
1692 // We'll update with whatever configuration it now says
1693 // it used to launch.
1694 if (config != null) {
1695 r.configuration = config;
1696 }
1697
1698 // We are now idle. If someone is waiting for a thumbnail from
1699 // us, we can now deliver.
1700 r.idle = true;
1701 if (allResumedActivitiesIdle()) {
1702 mService.scheduleAppGcsLocked();
1703 }
1704 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1705 sendThumbnail = r.app.thread;
1706 r.thumbnailNeeded = false;
1707 }
1708
1709 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1710 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1711 mService.mBooted = true;
1712 enableScreen = true;
1713 }
1714 } else if (fromTimeout) {
1715 reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
1716 }
1717 }
1718
1719 // Atomically retrieve all of the other things to do.
1720 stops = processStoppingActivitiesLocked(true);
1721 NS = stops != null ? stops.size() : 0;
1722 if ((NF=mFinishingActivities.size()) > 0) {
1723 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1724 mFinishingActivities.clear();
1725 }
1726
1727 final ArrayList<ActivityRecord> thumbnails;
1728 final int NT = mCancelledThumbnails.size();
1729 if (NT > 0) {
1730 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1731 mCancelledThumbnails.clear();
1732 } else {
1733 thumbnails = null;
1734 }
1735
1736 if (isFrontStack(mHomeStack)) {
1737 booting = mService.mBooting;
1738 mService.mBooting = false;
1739 }
1740
1741 if (mStartingUsers.size() > 0) {
1742 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1743 mStartingUsers.clear();
1744 }
1745
1746 // Perform the following actions from unsynchronized state.
1747 final IApplicationThread thumbnailThread = sendThumbnail;
1748 mHandler.post(new Runnable() {
1749 @Override
1750 public void run() {
1751 if (thumbnailThread != null) {
1752 try {
1753 thumbnailThread.requestThumbnail(token);
1754 } catch (Exception e) {
1755 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1756 mService.sendPendingThumbnail(null, token, null, null, true);
1757 }
1758 }
1759
1760 // Report back to any thumbnail receivers.
1761 for (int i = 0; i < NT; i++) {
1762 ActivityRecord r = thumbnails.get(i);
1763 mService.sendPendingThumbnail(r, null, null, null, true);
1764 }
1765 }
1766 });
1767
1768 // Stop any activities that are scheduled to do so but have been
1769 // waiting for the next one to start.
1770 for (int i = 0; i < NS; i++) {
1771 r = stops.get(i);
1772 final ActivityStack stack = r.task.stack;
1773 if (r.finishing) {
1774 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1775 } else {
1776 stack.stopActivityLocked(r);
1777 }
1778 }
1779
1780 // Finish any activities that are scheduled to do so but have been
1781 // waiting for the next one to start.
1782 for (int i = 0; i < NF; i++) {
1783 r = finishes.get(i);
1784 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1785 }
1786
1787 if (booting) {
1788 mService.finishBooting();
1789 } else if (startingUsers != null) {
1790 for (int i = 0; i < startingUsers.size(); i++) {
1791 mService.finishUserSwitch(startingUsers.get(i));
1792 }
1793 }
1794
1795 mService.trimApplications();
1796 //dump();
1797 //mWindowManager.dump();
1798
1799 if (enableScreen) {
1800 mService.enableScreenAfterBoot();
1801 }
1802
1803 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001804 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001805 }
1806
1807 return res;
1808 }
1809
Craig Mautner8d341ef2013-03-26 09:03:27 -07001810 void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1811 // Just in case.
1812 final int numStacks = mStacks.size();
1813 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001814 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001815 }
1816 }
1817
1818 void closeSystemDialogsLocked() {
1819 final int numStacks = mStacks.size();
1820 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1821 final ActivityStack stack = mStacks.get(stackNdx);
1822 stack.closeSystemDialogsLocked();
1823 }
1824 }
1825
1826 /**
1827 * @return true if some activity was finished (or would have finished if doit were true).
1828 */
1829 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1830 boolean didSomething = false;
1831 final int numStacks = mStacks.size();
1832 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1833 final ActivityStack stack = mStacks.get(stackNdx);
1834 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1835 didSomething = true;
1836 }
1837 }
1838 return didSomething;
1839 }
1840
Craig Mautner05d29032013-05-03 13:40:13 -07001841 boolean resumeTopActivitiesLocked() {
1842 return resumeTopActivitiesLocked(null, null, null);
1843 }
1844
1845 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1846 Bundle targetOptions) {
1847 if (targetStack == null) {
1848 targetStack = getFocusedStack();
1849 }
1850 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001851 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001852 final ActivityStack stack = mStacks.get(stackNdx);
1853 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001854 if (stack == targetStack) {
1855 result = stack.resumeTopActivityLocked(target, targetOptions);
1856 } else {
1857 stack.resumeTopActivityLocked(null);
1858 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001859 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001860 }
Craig Mautner05d29032013-05-03 13:40:13 -07001861 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001862 }
1863
1864 void finishTopRunningActivityLocked(ProcessRecord app) {
1865 final int numStacks = mStacks.size();
1866 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1867 final ActivityStack stack = mStacks.get(stackNdx);
1868 stack.finishTopRunningActivityLocked(app);
1869 }
1870 }
1871
Craig Mautner8d341ef2013-03-26 09:03:27 -07001872 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
1873 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1874 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001875 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
1876 mStacks.get(stackNdx));
Craig Mautner8d341ef2013-03-26 09:03:27 -07001877 return;
1878 }
1879 }
1880 }
1881
Craig Mautner967212c2013-04-13 21:10:58 -07001882 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001883 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1884 final ActivityStack stack = mStacks.get(stackNdx);
1885 if (stack.getStackId() == stackId) {
1886 return stack;
1887 }
1888 }
1889 return null;
1890 }
1891
Craig Mautner967212c2013-04-13 21:10:58 -07001892 ArrayList<ActivityStack> getStacks() {
1893 return new ArrayList<ActivityStack>(mStacks);
1894 }
1895
1896 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07001897 while (true) {
1898 if (++mLastStackId <= HOME_STACK_ID) {
1899 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001900 }
Craig Mautner858d8a62013-04-23 17:08:34 -07001901 if (getStack(mLastStackId) == null) {
1902 break;
1903 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001904 }
Craig Mautner858d8a62013-04-23 17:08:34 -07001905 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
1906 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001907 }
1908
1909 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07001910 final TaskRecord task = anyTaskForIdLocked(taskId);
1911 if (task == null) {
1912 return;
1913 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001914 final ActivityStack stack = getStack(stackId);
1915 if (stack == null) {
1916 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
1917 return;
1918 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07001919 removeTask(task);
1920 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07001921 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07001922 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07001923 }
1924
Craig Mautner8849a5e2013-04-02 16:41:03 -07001925 ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
1926 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1927 final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info);
1928 if (ar != null) {
1929 return ar;
1930 }
1931 }
1932 return null;
1933 }
1934
1935 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
1936 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1937 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
1938 if (ar != null) {
1939 return ar;
1940 }
1941 }
1942 return null;
1943 }
1944
Craig Mautner8d341ef2013-03-26 09:03:27 -07001945 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001946 scheduleSleepTimeout();
1947 if (!mGoingToSleep.isHeld()) {
1948 mGoingToSleep.acquire();
1949 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1950 final ActivityStack stack = mStacks.get(stackNdx);
1951 if (stack.mResumedActivity != null) {
1952 stack.stopIfSleepingLocked();
1953 }
1954 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001955 }
1956 }
1957
1958 boolean shutdownLocked(int timeout) {
1959 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07001960 goingToSleepLocked();
1961 checkReadyForSleepLocked();
1962
1963 final long endTime = System.currentTimeMillis() + timeout;
1964 while (true) {
1965 boolean cantShutdown = false;
1966 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1967 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
1968 }
1969 if (cantShutdown) {
1970 long timeRemaining = endTime - System.currentTimeMillis();
1971 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001972 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001973 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001974 } catch (InterruptedException e) {
1975 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001976 } else {
1977 Slog.w(TAG, "Activity manager shutdown timed out");
1978 timedout = true;
1979 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001980 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001981 } else {
1982 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001983 }
1984 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001985
1986 // Force checkReadyForSleep to complete.
1987 mSleepTimeout = true;
1988 checkReadyForSleepLocked();
1989
Craig Mautner8d341ef2013-03-26 09:03:27 -07001990 return timedout;
1991 }
1992
1993 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001994 removeSleepTimeouts();
1995 if (mGoingToSleep.isHeld()) {
1996 mGoingToSleep.release();
1997 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001998 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001999 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002000 stack.awakeFromSleepingLocked();
2001 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07002002 resumeTopActivitiesLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -07002003 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002004 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002005 mGoingToSleepActivities.clear();
2006 }
2007
2008 void activitySleptLocked(ActivityRecord r) {
2009 mGoingToSleepActivities.remove(r);
2010 checkReadyForSleepLocked();
2011 }
2012
2013 void checkReadyForSleepLocked() {
2014 if (!mService.isSleepingOrShuttingDown()) {
2015 // Do not care.
2016 return;
2017 }
2018
2019 if (!mSleepTimeout) {
2020 boolean dontSleep = false;
2021 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2022 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2023 }
2024
2025 if (mStoppingActivities.size() > 0) {
2026 // Still need to tell some activities to stop; can't sleep yet.
2027 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2028 + mStoppingActivities.size() + " activities");
2029 scheduleIdleLocked();
2030 dontSleep = true;
2031 }
2032
2033 if (mGoingToSleepActivities.size() > 0) {
2034 // Still need to tell some activities to sleep; can't sleep yet.
2035 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2036 + mGoingToSleepActivities.size() + " activities");
2037 dontSleep = true;
2038 }
2039
2040 if (dontSleep) {
2041 return;
2042 }
2043 }
2044
2045 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2046 mStacks.get(stackNdx).goToSleep();
2047 }
2048
2049 removeSleepTimeouts();
2050
2051 if (mGoingToSleep.isHeld()) {
2052 mGoingToSleep.release();
2053 }
2054 if (mService.mShuttingDown) {
2055 mService.notifyAll();
2056 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002057 }
2058
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002059 boolean reportResumedActivityLocked(ActivityRecord r) {
2060 final ActivityStack stack = r.task.stack;
2061 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002062 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002063 }
2064 if (allResumedActivitiesComplete()) {
2065 ensureActivitiesVisibleLocked(null, 0);
2066 mWindowManager.executeAppTransition();
2067 return true;
2068 }
2069 return false;
2070 }
2071
Craig Mautner8d341ef2013-03-26 09:03:27 -07002072 void handleAppCrashLocked(ProcessRecord app) {
2073 final int numStacks = mStacks.size();
2074 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2075 final ActivityStack stack = mStacks.get(stackNdx);
2076 stack.handleAppCrashLocked(app);
2077 }
2078 }
2079
Craig Mautnerde4ef022013-04-07 19:01:33 -07002080 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002081 // First the front stacks. In case any are not fullscreen and are in front of home.
2082 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002083 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002084 final ActivityStack stack = mStacks.get(stackNdx);
2085 if (isFrontStack(stack)) {
2086 showHomeBehindStack =
2087 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2088 }
2089 }
2090 // Now do back stacks.
2091 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2092 final ActivityStack stack = mStacks.get(stackNdx);
2093 if (!isFrontStack(stack)) {
2094 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2095 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002096 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002097 }
2098
2099 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2100 final int numStacks = mStacks.size();
2101 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2102 final ActivityStack stack = mStacks.get(stackNdx);
2103 stack.scheduleDestroyActivities(app, false, reason);
2104 }
2105 }
2106
2107 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner858d8a62013-04-23 17:08:34 -07002108 mUserStates.put(mCurrentUser, new UserState());
Craig Mautner2420ead2013-04-01 17:13:20 -07002109 mCurrentUser = userId;
Craig Mautner858d8a62013-04-23 17:08:34 -07002110 UserState userState = mUserStates.get(userId);
2111 if (userState != null) {
2112 userState.restore();
2113 mUserStates.delete(userId);
2114 } else {
2115 mFocusedStack = null;
Craig Mautner76ea2242013-05-15 11:40:05 -07002116 if (DEBUG_STACK) Slog.d(TAG, "switchUserLocked: mStackState=" +
2117 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautner858d8a62013-04-23 17:08:34 -07002118 mStackState = STACK_STATE_HOME_IN_FRONT;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002119 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002120
2121 mStartingUsers.add(uss);
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002122 boolean haveActivities = mHomeStack.switchUserLocked(userId);
Craig Mautner858d8a62013-04-23 17:08:34 -07002123
2124 resumeTopActivitiesLocked();
2125
Craig Mautner8d341ef2013-03-26 09:03:27 -07002126 return haveActivities;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002127 }
2128
Craig Mautnerde4ef022013-04-07 19:01:33 -07002129 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2130 int N = mStoppingActivities.size();
2131 if (N <= 0) return null;
2132
2133 ArrayList<ActivityRecord> stops = null;
2134
2135 final boolean nowVisible = allResumedActivitiesVisible();
2136 for (int i=0; i<N; i++) {
2137 ActivityRecord s = mStoppingActivities.get(i);
2138 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2139 + nowVisible + " waitingVisible=" + s.waitingVisible
2140 + " finishing=" + s.finishing);
2141 if (s.waitingVisible && nowVisible) {
2142 mWaitingVisibleActivities.remove(s);
2143 s.waitingVisible = false;
2144 if (s.finishing) {
2145 // If this activity is finishing, it is sitting on top of
2146 // everyone else but we now know it is no longer needed...
2147 // so get rid of it. Otherwise, we need to go through the
2148 // normal flow and hide it once we determine that it is
2149 // hidden by the activities in front of it.
2150 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002151 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002152 }
2153 }
2154 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2155 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2156 if (stops == null) {
2157 stops = new ArrayList<ActivityRecord>();
2158 }
2159 stops.add(s);
2160 mStoppingActivities.remove(i);
2161 N--;
2162 i--;
2163 }
2164 }
2165
2166 return stops;
2167 }
2168
Craig Mautnercf910b02013-04-23 11:23:27 -07002169 void validateTopActivitiesLocked() {
2170 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2171 final ActivityStack stack = mStacks.get(stackNdx);
2172 final ActivityRecord r = stack.topRunningActivityLocked(null);
2173 if (isFrontStack(stack)) {
2174 if (r == null) {
2175 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2176 } else {
2177 if (stack.mPausingActivity != null) {
2178 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2179 " state=" + r.state);
2180 }
2181 if (r.state != ActivityState.INITIALIZING &&
2182 r.state != ActivityState.RESUMED) {
2183 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2184 " state=" + r.state);
2185 }
2186 }
2187 } else {
2188 if (stack.mResumedActivity != null) {
2189 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2190 " state=" + r.state);
2191 }
2192 if (r != null && (r.state == ActivityState.INITIALIZING
2193 || r.state == ActivityState.RESUMED)) {
2194 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2195 " state=" + r.state);
2196 }
2197 }
2198 }
2199 }
2200
Craig Mautner76ea2242013-05-15 11:40:05 -07002201 private static String stackStateToString(int stackState) {
2202 switch (stackState) {
2203 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2204 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2205 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2206 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2207 default: return "Unknown stackState=" + stackState;
2208 }
2209 }
2210
Craig Mautner27084302013-03-25 08:05:25 -07002211 public void dump(PrintWriter pw, String prefix) {
2212 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2213 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002214 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002215 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2216 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautner27084302013-03-25 08:05:25 -07002217 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002218
Craig Mautner20e72272013-04-01 13:45:53 -07002219 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002220 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002221 }
2222
Dianne Hackborn390517b2013-05-30 15:03:32 -07002223 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2224 boolean needSep, String prefix) {
2225 if (activity != null) {
2226 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2227 if (needSep) {
2228 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002229 }
2230 pw.print(prefix);
2231 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002232 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002233 }
2234 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002235 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002236 }
2237
Craig Mautner8d341ef2013-03-26 09:03:27 -07002238 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2239 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002240 boolean printed = false;
2241 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002242 final int numStacks = mStacks.size();
2243 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2244 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002245 StringBuilder stackHeader = new StringBuilder(128);
2246 stackHeader.append(" Stack #");
2247 stackHeader.append(mStacks.indexOf(stack));
2248 stackHeader.append(":");
2249 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2250 stackHeader.toString());
2251 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2252 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002253
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002254 needSep = printed;
2255 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002256 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002257 if (pr) {
2258 printed = true;
2259 needSep = false;
2260 }
2261 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002262 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002263 if (pr) {
2264 printed = true;
2265 needSep = false;
2266 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002267 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002268 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002269 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002270 if (pr) {
2271 printed = true;
2272 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002273 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002274 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002275 }
2276
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002277 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2278 false, dumpPackage, true, " Activities waiting to finish:", null);
2279 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2280 false, dumpPackage, true, " Activities waiting to stop:", null);
2281 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2282 false, dumpPackage, true, " Activities waiting for another to become visible:",
2283 null);
2284 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2285 false, dumpPackage, true, " Activities waiting to sleep:", null);
2286 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2287 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002288
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002289 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002290 }
2291
Dianne Hackborn390517b2013-05-30 15:03:32 -07002292 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002293 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002294 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002295 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002296 String innerPrefix = null;
2297 String[] args = null;
2298 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002299 for (int i=list.size()-1; i>=0; i--) {
2300 final ActivityRecord r = list.get(i);
2301 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2302 continue;
2303 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002304 if (innerPrefix == null) {
2305 innerPrefix = prefix + " ";
2306 args = new String[0];
2307 }
2308 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002309 final boolean full = !brief && (complete || !r.isInHistory());
2310 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002311 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002312 needNL = false;
2313 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002314 if (header1 != null) {
2315 pw.println(header1);
2316 header1 = null;
2317 }
2318 if (header2 != null) {
2319 pw.println(header2);
2320 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002321 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002322 if (lastTask != r.task) {
2323 lastTask = r.task;
2324 pw.print(prefix);
2325 pw.print(full ? "* " : " ");
2326 pw.println(lastTask);
2327 if (full) {
2328 lastTask.dump(pw, prefix + " ");
2329 } else if (complete) {
2330 // Complete + brief == give a summary. Isn't that obvious?!?
2331 if (lastTask.intent != null) {
2332 pw.print(prefix); pw.print(" ");
2333 pw.println(lastTask.intent.toInsecureStringWithClip());
2334 }
2335 }
2336 }
2337 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2338 pw.print(" #"); pw.print(i); pw.print(": ");
2339 pw.println(r);
2340 if (full) {
2341 r.dump(pw, innerPrefix);
2342 } else if (complete) {
2343 // Complete + brief == give a summary. Isn't that obvious?!?
2344 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2345 if (r.app != null) {
2346 pw.print(innerPrefix); pw.println(r.app);
2347 }
2348 }
2349 if (client && r.app != null && r.app.thread != null) {
2350 // flush anything that is already in the PrintWriter since the thread is going
2351 // to write to the file descriptor directly
2352 pw.flush();
2353 try {
2354 TransferPipe tp = new TransferPipe();
2355 try {
2356 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2357 r.appToken, innerPrefix, args);
2358 // Short timeout, since blocking here can
2359 // deadlock with the application.
2360 tp.go(fd, 2000);
2361 } finally {
2362 tp.kill();
2363 }
2364 } catch (IOException e) {
2365 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2366 } catch (RemoteException e) {
2367 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2368 }
2369 needNL = true;
2370 }
2371 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002372 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002373 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002374
Craig Mautnerf3333272013-04-22 10:55:53 -07002375 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002376 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002377 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2378 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002379 }
2380
2381 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002382 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002383 }
2384
2385 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002386 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002387 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2388 }
2389
Craig Mautner05d29032013-05-03 13:40:13 -07002390 final void scheduleResumeTopActivities() {
2391 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2392 }
2393
Craig Mautner0eea92c2013-05-16 13:35:39 -07002394 void removeSleepTimeouts() {
2395 mSleepTimeout = false;
2396 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2397 }
2398
2399 final void scheduleSleepTimeout() {
2400 removeSleepTimeouts();
2401 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2402 }
2403
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002404 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002405
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002406 public ActivityStackSupervisorHandler(Looper looper) {
2407 super(looper);
2408 }
2409
Craig Mautnerf3333272013-04-22 10:55:53 -07002410 void activityIdleInternal(ActivityRecord r) {
2411 synchronized (mService) {
2412 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2413 }
2414 }
2415
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002416 @Override
2417 public void handleMessage(Message msg) {
2418 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002419 case IDLE_TIMEOUT_MSG: {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002420 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" +
2421 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002422 if (mService.mDidDexOpt) {
2423 mService.mDidDexOpt = false;
2424 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2425 nmsg.obj = msg.obj;
2426 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2427 return;
2428 }
2429 // We don't at this point know if the activity is fullscreen,
2430 // so we need to be conservative and assume it isn't.
2431 activityIdleInternal((ActivityRecord)msg.obj);
2432 } break;
2433 case IDLE_NOW_MSG: {
2434 activityIdleInternal((ActivityRecord)msg.obj);
2435 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002436 case RESUME_TOP_ACTIVITY_MSG: {
2437 synchronized (mService) {
2438 resumeTopActivitiesLocked();
2439 }
2440 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002441 case SLEEP_TIMEOUT_MSG: {
2442 synchronized (mService) {
2443 if (mService.isSleepingOrShuttingDown()) {
2444 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2445 mSleepTimeout = true;
2446 checkReadyForSleepLocked();
2447 }
2448 }
2449 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002450 }
2451 }
2452 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002453
2454 private final class UserState {
2455 final ActivityStack mSavedFocusedStack;
2456 final int mSavedStackState;
2457
2458 public UserState() {
2459 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2460 mSavedFocusedStack = supervisor.mFocusedStack;
2461 mSavedStackState = supervisor.mStackState;
2462 }
2463
2464 void restore() {
2465 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2466 supervisor.mFocusedStack = mSavedFocusedStack;
Craig Mautner76ea2242013-05-15 11:40:05 -07002467 if (DEBUG_STACK) Slog.d(TAG, "UserState.restore: mStackState old=" +
2468 stackStateToString(mSavedStackState));
Craig Mautner858d8a62013-04-23 17:08:34 -07002469 supervisor.mStackState = mSavedStackState;
2470 }
2471 }
Craig Mautner27084302013-03-25 08:05:25 -07002472}