blob: 8a7a2fa7723822a84a85fea10f02cd8df4a475a5 [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;
Craig Mautner6170f732013-04-02 13:05:23 -070072import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070073import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerde4ef022013-04-07 19:01:33 -070074import com.android.server.wm.StackBox;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070075import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070076
Craig Mautner8d341ef2013-03-26 09:03:27 -070077import java.io.FileDescriptor;
78import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070079import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070080import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070081import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070082
83public class ActivityStackSupervisor {
Craig Mautnerde4ef022013-04-07 19:01:33 -070084 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
85 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
86 static final boolean DEBUG_APP = DEBUG || false;
87 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
88 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070089 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -070090
Craig Mautner2219a1b2013-03-25 09:44:30 -070091 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -070092
Craig Mautnerf3333272013-04-22 10:55:53 -070093 /** How long we wait until giving up on the last activity telling us it is idle. */
94 static final int IDLE_TIMEOUT = 10*1000;
95
Craig Mautner0eea92c2013-05-16 13:35:39 -070096 /** How long we can hold the sleep wake lock before giving up. */
97 static final int SLEEP_TIMEOUT = 5*1000;
98
Craig Mautner05d29032013-05-03 13:40:13 -070099 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
100 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
101 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700102 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautnerf3333272013-04-22 10:55:53 -0700103
Craig Mautner27084302013-03-25 08:05:25 -0700104 final ActivityManagerService mService;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700105 final Context mContext;
106 final Looper mLooper;
Craig Mautner27084302013-03-25 08:05:25 -0700107
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700108 final ActivityStackSupervisorHandler mHandler;
109
110 /** Short cut */
111 WindowManagerService mWindowManager;
112
Craig Mautner27084302013-03-25 08:05:25 -0700113 /** Dismiss the keyguard after the next activity is displayed? */
114 private boolean mDismissKeyguardOnNextActivity = false;
115
Craig Mautner8d341ef2013-03-26 09:03:27 -0700116 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700117 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700118
119 /** Task identifier that activities are currently being started in. Incremented each time a
120 * new task is created. */
121 private int mCurTaskId = 0;
122
Craig Mautner2420ead2013-04-01 17:13:20 -0700123 /** The current user */
124 private int mCurrentUser;
125
Craig Mautner8d341ef2013-03-26 09:03:27 -0700126 /** The stack containing the launcher app */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700127 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700128
Craig Mautnerde4ef022013-04-07 19:01:33 -0700129 /** The non-home stack currently receiving input or launching the next activity. If home is
Craig Mautner29219d92013-04-16 20:19:12 -0700130 * in front then mHomeStack overrides mFocusedStack. */
131 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700132
133 /** All the non-launcher stacks */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700134 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
135
Craig Mautnerde4ef022013-04-07 19:01:33 -0700136 private static final int STACK_STATE_HOME_IN_FRONT = 0;
137 private static final int STACK_STATE_HOME_TO_BACK = 1;
138 private static final int STACK_STATE_HOME_IN_BACK = 2;
139 private static final int STACK_STATE_HOME_TO_FRONT = 3;
140 private int mStackState = STACK_STATE_HOME_IN_FRONT;
141
142 /** List of activities that are waiting for a new activity to become visible before completing
143 * whatever operation they are supposed to do. */
144 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
145
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700146 /** List of processes waiting to find out about the next visible activity. */
147 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
148 new ArrayList<IActivityManager.WaitResult>();
149
150 /** List of processes waiting to find out about the next launched activity. */
151 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
152 new ArrayList<IActivityManager.WaitResult>();
153
Craig Mautnerde4ef022013-04-07 19:01:33 -0700154 /** List of activities that are ready to be stopped, but waiting for the next activity to
155 * settle down before doing so. */
156 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
157
Craig Mautnerf3333272013-04-22 10:55:53 -0700158 /** List of activities that are ready to be finished, but waiting for the previous activity to
159 * settle down before doing so. It contains ActivityRecord objects. */
160 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
161
Craig Mautner0eea92c2013-05-16 13:35:39 -0700162 /** List of activities that are in the process of going to sleep. */
163 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
164
Craig Mautnerf3333272013-04-22 10:55:53 -0700165 /** List of ActivityRecord objects that have been finished and must still report back to a
166 * pending thumbnail receiver. */
167 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
168
169 /** Used on user changes */
170 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
171
Craig Mautnerde4ef022013-04-07 19:01:33 -0700172 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
173 * is being brought in front of us. */
174 boolean mUserLeaving = false;
175
Craig Mautner858d8a62013-04-23 17:08:34 -0700176 /** Stacks belonging to users other than mCurrentUser. Indexed by userId. */
177 final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
178
Craig Mautner0eea92c2013-05-16 13:35:39 -0700179 /** Set when we have taken too long waiting to go to sleep. */
180 boolean mSleepTimeout = false;
181
182 /**
183 * Set when the system is going to sleep, until we have
184 * successfully paused the current activity and released our wake lock.
185 * At that point the system is allowed to actually sleep.
186 */
187 final PowerManager.WakeLock mGoingToSleep;
188
Craig Mautner2219a1b2013-03-25 09:44:30 -0700189 public ActivityStackSupervisor(ActivityManagerService service, Context context,
190 Looper looper) {
Craig Mautner27084302013-03-25 08:05:25 -0700191 mService = service;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700192 mContext = context;
193 mLooper = looper;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700194 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
195 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700196 mHandler = new ActivityStackSupervisorHandler(looper);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700197 }
198
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700199 void setWindowManager(WindowManagerService wm) {
200 mWindowManager = wm;
201 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700202 mStacks.add(mHomeStack);
Craig Mautner27084302013-03-25 08:05:25 -0700203 }
204
205 void dismissKeyguard() {
206 if (mDismissKeyguardOnNextActivity) {
207 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700208 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700209 }
210 }
211
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700212 ActivityStack getFocusedStack() {
Craig Mautnerf88c50f2013-04-18 19:25:12 -0700213 if (mFocusedStack == null) {
214 return mHomeStack;
215 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700216 switch (mStackState) {
217 case STACK_STATE_HOME_IN_FRONT:
218 case STACK_STATE_HOME_TO_FRONT:
219 return mHomeStack;
220 case STACK_STATE_HOME_IN_BACK:
221 case STACK_STATE_HOME_TO_BACK:
222 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700223 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700224 }
Craig Mautner20e72272013-04-01 13:45:53 -0700225 }
226
Craig Mautnerde4ef022013-04-07 19:01:33 -0700227 ActivityStack getLastStack() {
228 switch (mStackState) {
229 case STACK_STATE_HOME_IN_FRONT:
230 case STACK_STATE_HOME_TO_BACK:
231 return mHomeStack;
232 case STACK_STATE_HOME_TO_FRONT:
233 case STACK_STATE_HOME_IN_BACK:
234 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700235 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700236 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700237 }
238
Craig Mautnerde4ef022013-04-07 19:01:33 -0700239 boolean isFrontStack(ActivityStack stack) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700240 return (stack.mCurrentUser == mCurrentUser) &&
241 !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
Craig Mautner20e72272013-04-01 13:45:53 -0700242 }
243
Craig Mautnerde4ef022013-04-07 19:01:33 -0700244 void moveHomeStack(boolean toFront) {
245 final boolean homeInFront = isFrontStack(mHomeStack);
246 if (homeInFront ^ toFront) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700247 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
248 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
249 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700250 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
251 }
252 }
253
Craig Mautner69ada552013-04-18 13:51:51 -0700254 boolean resumeHomeActivity(ActivityRecord prev) {
255 moveHomeStack(true);
256 if (prev != null) {
257 prev.mLaunchHomeTaskNext = false;
258 }
259 if (mHomeStack.topRunningActivityLocked(null) != null) {
Craig Mautner05d29032013-05-03 13:40:13 -0700260 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700261 }
262 return mService.startHomeActivityLocked(mCurrentUser);
263 }
264
Craig Mautnerde4ef022013-04-07 19:01:33 -0700265 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r,
266 ActivityStack stack) {
267 if (stack == mHomeStack) {
268 return;
269 }
270 if ((sourceRecord == null && getLastStack() == mHomeStack) ||
Craig Mautner86d67a42013-05-14 10:34:38 -0700271 (sourceRecord != null && sourceRecord.isHomeActivity())) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700272 if (r == null) {
273 r = stack.topRunningActivityLocked(null);
274 }
Craig Mautner86d67a42013-05-14 10:34:38 -0700275 if (r != null && !r.isHomeActivity() && r.isRootActivity()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700276 r.mLaunchHomeTaskNext = true;
277 }
278 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700279 }
280
Craig Mautner27084302013-03-25 08:05:25 -0700281 void setDismissKeyguard(boolean dismiss) {
282 mDismissKeyguardOnNextActivity = dismiss;
283 }
284
Craig Mautner8d341ef2013-03-26 09:03:27 -0700285 TaskRecord anyTaskForIdLocked(int id) {
286 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
287 ActivityStack stack = mStacks.get(stackNdx);
288 TaskRecord task = stack.taskForIdLocked(id);
289 if (task != null) {
290 return task;
291 }
292 }
293 return null;
294 }
295
Craig Mautner6170f732013-04-02 13:05:23 -0700296 ActivityRecord isInAnyStackLocked(IBinder token) {
297 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
298 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
299 if (r != null) {
300 return r;
301 }
302 }
303 return null;
304 }
305
Craig Mautner8d341ef2013-03-26 09:03:27 -0700306 int getNextTaskId() {
307 do {
308 mCurTaskId++;
309 if (mCurTaskId <= 0) {
310 mCurTaskId = 1;
311 }
312 } while (anyTaskForIdLocked(mCurTaskId) != null);
313 return mCurTaskId;
314 }
315
Craig Mautnerde4ef022013-04-07 19:01:33 -0700316 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700317 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700318 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700319 final ActivityRecord r = stack.mResumedActivity;
320 if (r != null && r.task == task) {
321 stack.mResumedActivity = null;
322 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700323 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700324 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700325 mStacks.remove(stack);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700326 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700327 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700328 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Guang Zhubefa8b52013-05-12 23:10:39 -0700329 if (mFocusedStack.mStackId == stackId) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700330 // If this is the last app stack, set mFocusedStack to null.
Craig Mautner29219d92013-04-16 20:19:12 -0700331 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700332 }
333 }
334 }
335
336 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700337 ActivityStack stack = getFocusedStack();
338 if (stack == null) {
339 return null;
340 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700341 ActivityRecord resumedActivity = stack.mResumedActivity;
342 if (resumedActivity == null || resumedActivity.app == null) {
343 resumedActivity = stack.mPausingActivity;
344 if (resumedActivity == null || resumedActivity.app == null) {
345 resumedActivity = stack.topRunningActivityLocked(null);
346 }
347 }
348 return resumedActivity;
349 }
350
Craig Mautner20e72272013-04-01 13:45:53 -0700351 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
352 boolean didSomething = false;
353 final String processName = app.processName;
354 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
355 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner858d8a62013-04-23 17:08:34 -0700356 if (!isFrontStack(stack)) {
357 continue;
358 }
Craig Mautner20e72272013-04-01 13:45:53 -0700359 ActivityRecord hr = stack.topRunningActivityLocked(null);
360 if (hr != null) {
361 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
362 && processName.equals(hr.processName)) {
363 try {
364 if (headless) {
365 Slog.e(TAG, "Starting activities not supported on headless device: "
366 + hr);
Craig Mautner2420ead2013-04-01 17:13:20 -0700367 } else if (realStartActivityLocked(hr, app, true, true)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700368 didSomething = true;
369 }
370 } catch (Exception e) {
371 Slog.w(TAG, "Exception in new application when starting activity "
372 + hr.intent.getComponent().flattenToShortString(), e);
373 throw e;
374 }
Craig Mautner20e72272013-04-01 13:45:53 -0700375 }
376 }
377 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700378 if (!didSomething) {
379 ensureActivitiesVisibleLocked(null, 0);
380 }
Craig Mautner20e72272013-04-01 13:45:53 -0700381 return didSomething;
382 }
383
384 boolean allResumedActivitiesIdle() {
385 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerdbcb31f2013-04-02 12:32:53 -0700386 final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity;
387 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner20e72272013-04-01 13:45:53 -0700388 return false;
389 }
390 }
391 return true;
392 }
393
Craig Mautnerde4ef022013-04-07 19:01:33 -0700394 boolean allResumedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700395 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
396 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner967212c2013-04-13 21:10:58 -0700397 if (isFrontStack(stack)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700398 final ActivityRecord r = stack.mResumedActivity;
399 if (r != null && r.state != ActivityState.RESUMED) {
400 return false;
401 }
402 }
403 }
404 // TODO: Not sure if this should check if all Paused are complete too.
405 switch (mStackState) {
406 case STACK_STATE_HOME_TO_BACK:
Craig Mautner76ea2242013-05-15 11:40:05 -0700407 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
408 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
409 stackStateToString(STACK_STATE_HOME_IN_BACK));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700410 mStackState = STACK_STATE_HOME_IN_BACK;
411 break;
412 case STACK_STATE_HOME_TO_FRONT:
Craig Mautner76ea2242013-05-15 11:40:05 -0700413 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
414 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
415 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700416 mStackState = STACK_STATE_HOME_IN_FRONT;
417 break;
418 }
419 return true;
420 }
421
422 boolean allResumedActivitiesVisible() {
423 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
424 final ActivityStack stack = mStacks.get(stackNdx);
425 final ActivityRecord r = stack.mResumedActivity;
426 if (r != null && (!r.nowVisible || r.waitingVisible)) {
427 return false;
428 }
429 }
430 return true;
431 }
432
Craig Mautnercf910b02013-04-23 11:23:27 -0700433 boolean pauseBackStacks(boolean userLeaving) {
434 boolean someActivityPaused = false;
435 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
436 final ActivityStack stack = mStacks.get(stackNdx);
437 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
438 stack.startPausingLocked(userLeaving, false);
439 someActivityPaused = true;
440 }
441 }
442 return someActivityPaused;
443 }
444
Craig Mautnerde4ef022013-04-07 19:01:33 -0700445 boolean allPausedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700446 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
447 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner69ada552013-04-18 13:51:51 -0700448 final ActivityRecord r = stack.mPausingActivity;
449 if (r != null && r.state != ActivityState.PAUSED
450 && r.state != ActivityState.STOPPED
451 && r.state != ActivityState.STOPPING) {
452 return false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700453 }
454 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700455 return true;
456 }
457
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700458 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700459 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700460 WaitResult w = mWaitingActivityVisible.get(i);
461 w.timeout = false;
462 if (r != null) {
463 w.who = new ComponentName(r.info.packageName, r.info.name);
464 }
465 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
466 w.thisTime = w.totalTime;
467 }
468 mService.notifyAll();
469 dismissKeyguard();
470 }
471
472 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
473 long thisTime, long totalTime) {
474 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700475 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700476 w.timeout = timeout;
477 if (r != null) {
478 w.who = new ComponentName(r.info.packageName, r.info.name);
479 }
480 w.thisTime = thisTime;
481 w.totalTime = totalTime;
482 }
483 mService.notifyAll();
484 }
485
Craig Mautner29219d92013-04-16 20:19:12 -0700486 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700487 final ActivityStack focusedStack = getFocusedStack();
488 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
489 if (r != null) {
490 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700491 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700492
Craig Mautner29219d92013-04-16 20:19:12 -0700493 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
494 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner1602ec22013-05-12 10:24:27 -0700495 if (stack.mCurrentUser == mCurrentUser && stack != focusedStack &&
496 isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700497 r = stack.topRunningActivityLocked(null);
498 if (r != null) {
499 return r;
500 }
501 }
502 }
503 return null;
504 }
505
Craig Mautner20e72272013-04-01 13:45:53 -0700506 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
507 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
508 ActivityRecord r = null;
Craig Mautner20e72272013-04-01 13:45:53 -0700509 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
510 final ActivityStack stack = mStacks.get(stackNdx);
511 final ActivityRecord ar =
512 stack.getTasksLocked(maxNum - list.size(), receiver, pending, list);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700513 if (isFrontStack(stack)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700514 r = ar;
515 }
516 }
517 return r;
518 }
519
Craig Mautner23ac33b2013-04-01 16:26:35 -0700520 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
521 String profileFile, ParcelFileDescriptor profileFd, int userId) {
522 // Collect information about the target of the Intent.
523 ActivityInfo aInfo;
524 try {
525 ResolveInfo rInfo =
526 AppGlobals.getPackageManager().resolveIntent(
527 intent, resolvedType,
528 PackageManager.MATCH_DEFAULT_ONLY
529 | ActivityManagerService.STOCK_PM_FLAGS, userId);
530 aInfo = rInfo != null ? rInfo.activityInfo : null;
531 } catch (RemoteException e) {
532 aInfo = null;
533 }
534
535 if (aInfo != null) {
536 // Store the found target back into the intent, because now that
537 // we have it we never want to do this again. For example, if the
538 // user navigates back to this point in the history, we should
539 // always restart the exact same activity.
540 intent.setComponent(new ComponentName(
541 aInfo.applicationInfo.packageName, aInfo.name));
542
543 // Don't debug things in the system process
544 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
545 if (!aInfo.processName.equals("system")) {
546 mService.setDebugApp(aInfo.processName, true, false);
547 }
548 }
549
550 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
551 if (!aInfo.processName.equals("system")) {
552 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
553 }
554 }
555
556 if (profileFile != null) {
557 if (!aInfo.processName.equals("system")) {
558 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
559 profileFile, profileFd,
560 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
561 }
562 }
563 }
564 return aInfo;
565 }
566
Craig Mautner2219a1b2013-03-25 09:44:30 -0700567 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700568 moveHomeStack(true);
Craig Mautner6170f732013-04-02 13:05:23 -0700569 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700570 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700571 }
572
Craig Mautner23ac33b2013-04-01 16:26:35 -0700573 final int startActivityMayWait(IApplicationThread caller, int callingUid,
574 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
575 String resultWho, int requestCode, int startFlags, String profileFile,
576 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
577 Bundle options, int userId) {
578 // Refuse possible leaked file descriptors
579 if (intent != null && intent.hasFileDescriptors()) {
580 throw new IllegalArgumentException("File descriptors passed in Intent");
581 }
582 boolean componentSpecified = intent.getComponent() != null;
583
584 // Don't modify the client's object!
585 intent = new Intent(intent);
586
587 // Collect information about the target of the Intent.
588 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
589 profileFile, profileFd, userId);
590
591 synchronized (mService) {
592 int callingPid;
593 if (callingUid >= 0) {
594 callingPid = -1;
595 } else if (caller == null) {
596 callingPid = Binder.getCallingPid();
597 callingUid = Binder.getCallingUid();
598 } else {
599 callingPid = callingUid = -1;
600 }
601
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700602 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700603 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700604 && mService.mConfiguration.diff(config) != 0;
605 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700606 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700607
608 final long origId = Binder.clearCallingIdentity();
609
610 if (aInfo != null &&
611 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
612 // This may be a heavy-weight process! Check to see if we already
613 // have another, different heavy-weight process running.
614 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
615 if (mService.mHeavyWeightProcess != null &&
616 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
617 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700618 int realCallingUid = callingUid;
619 if (caller != null) {
620 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
621 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700622 realCallingUid = callerApp.info.uid;
623 } else {
624 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700625 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700626 + intent.toString());
627 ActivityOptions.abort(options);
628 return ActivityManager.START_PERMISSION_DENIED;
629 }
630 }
631
632 IIntentSender target = mService.getIntentSenderLocked(
633 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
634 realCallingUid, userId, null, null, 0, new Intent[] { intent },
635 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
636 | PendingIntent.FLAG_ONE_SHOT, null);
637
638 Intent newIntent = new Intent();
639 if (requestCode >= 0) {
640 // Caller is requesting a result.
641 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
642 }
643 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
644 new IntentSender(target));
645 if (mService.mHeavyWeightProcess.activities.size() > 0) {
646 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
647 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
648 hist.packageName);
649 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
650 hist.task.taskId);
651 }
652 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
653 aInfo.packageName);
654 newIntent.setFlags(intent.getFlags());
655 newIntent.setClassName("android",
656 HeavyWeightSwitcherActivity.class.getName());
657 intent = newIntent;
658 resolvedType = null;
659 caller = null;
660 callingUid = Binder.getCallingUid();
661 callingPid = Binder.getCallingPid();
662 componentSpecified = true;
663 try {
664 ResolveInfo rInfo =
665 AppGlobals.getPackageManager().resolveIntent(
666 intent, null,
667 PackageManager.MATCH_DEFAULT_ONLY
668 | ActivityManagerService.STOCK_PM_FLAGS, userId);
669 aInfo = rInfo != null ? rInfo.activityInfo : null;
670 aInfo = mService.getActivityInfoForUser(aInfo, userId);
671 } catch (RemoteException e) {
672 aInfo = null;
673 }
674 }
675 }
676 }
677
Craig Mautner6170f732013-04-02 13:05:23 -0700678 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700679 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
680 callingPackage, startFlags, options, componentSpecified, null);
681
Craig Mautnerde4ef022013-04-07 19:01:33 -0700682 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700683 // If the caller also wants to switch to a new configuration,
684 // do so now. This allows a clean switch, as we are waiting
685 // for the current activity to pause (so we will not destroy
686 // it), and have not yet started the next activity.
687 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
688 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700689 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700690 if (DEBUG_CONFIGURATION) Slog.v(TAG,
691 "Updating to new configuration after starting activity.");
692 mService.updateConfigurationLocked(config, null, false, false);
693 }
694
695 Binder.restoreCallingIdentity(origId);
696
697 if (outResult != null) {
698 outResult.result = res;
699 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700700 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700701 do {
702 try {
703 mService.wait();
704 } catch (InterruptedException e) {
705 }
706 } while (!outResult.timeout && outResult.who == null);
707 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700708 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700709 if (r.nowVisible) {
710 outResult.timeout = false;
711 outResult.who = new ComponentName(r.info.packageName, r.info.name);
712 outResult.totalTime = 0;
713 outResult.thisTime = 0;
714 } else {
715 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700716 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700717 do {
718 try {
719 mService.wait();
720 } catch (InterruptedException e) {
721 }
722 } while (!outResult.timeout && outResult.who == null);
723 }
724 }
725 }
726
727 return res;
728 }
729 }
730
731 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
732 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
733 Bundle options, int userId) {
734 if (intents == null) {
735 throw new NullPointerException("intents is null");
736 }
737 if (resolvedTypes == null) {
738 throw new NullPointerException("resolvedTypes is null");
739 }
740 if (intents.length != resolvedTypes.length) {
741 throw new IllegalArgumentException("intents are length different than resolvedTypes");
742 }
743
Craig Mautner23ac33b2013-04-01 16:26:35 -0700744
745 int callingPid;
746 if (callingUid >= 0) {
747 callingPid = -1;
748 } else if (caller == null) {
749 callingPid = Binder.getCallingPid();
750 callingUid = Binder.getCallingUid();
751 } else {
752 callingPid = callingUid = -1;
753 }
754 final long origId = Binder.clearCallingIdentity();
755 try {
756 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700757 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700758 for (int i=0; i<intents.length; i++) {
759 Intent intent = intents[i];
760 if (intent == null) {
761 continue;
762 }
763
764 // Refuse possible leaked file descriptors
765 if (intent != null && intent.hasFileDescriptors()) {
766 throw new IllegalArgumentException("File descriptors passed in Intent");
767 }
768
769 boolean componentSpecified = intent.getComponent() != null;
770
771 // Don't modify the client's object!
772 intent = new Intent(intent);
773
774 // Collect information about the target of the Intent.
775 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
776 0, null, null, userId);
777 // TODO: New, check if this is correct
778 aInfo = mService.getActivityInfoForUser(aInfo, userId);
779
780 if (aInfo != null &&
781 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
782 != 0) {
783 throw new IllegalArgumentException(
784 "FLAG_CANT_SAVE_STATE not supported here");
785 }
786
787 Bundle theseOptions;
788 if (options != null && i == intents.length-1) {
789 theseOptions = options;
790 } else {
791 theseOptions = null;
792 }
Craig Mautner6170f732013-04-02 13:05:23 -0700793 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700794 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
795 0, theseOptions, componentSpecified, outActivity);
796 if (res < 0) {
797 return res;
798 }
799
800 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
801 }
802 }
803 } finally {
804 Binder.restoreCallingIdentity(origId);
805 }
806
807 return ActivityManager.START_SUCCESS;
808 }
809
Craig Mautner2420ead2013-04-01 17:13:20 -0700810 final boolean realStartActivityLocked(ActivityRecord r,
811 ProcessRecord app, boolean andResume, boolean checkConfig)
812 throws RemoteException {
813
814 r.startFreezingScreenLocked(app, 0);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700815 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700816
817 // schedule launch ticks to collect information about slow apps.
818 r.startLaunchTickingLocked();
819
820 // Have the window manager re-evaluate the orientation of
821 // the screen based on the new activity order. Note that
822 // as a result of this, it can call back into the activity
823 // manager with a new orientation. We don't care about that,
824 // because the activity is not currently running so we are
825 // just restarting it anyway.
826 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700827 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700828 mService.mConfiguration,
829 r.mayFreezeScreenLocked(app) ? r.appToken : null);
830 mService.updateConfigurationLocked(config, r, false, false);
831 }
832
833 r.app = app;
834 app.waitingToKill = null;
835 r.launchCount++;
836 r.lastLaunchTime = SystemClock.uptimeMillis();
837
838 if (localLOGV) Slog.v(TAG, "Launching: " + r);
839
840 int idx = app.activities.indexOf(r);
841 if (idx < 0) {
842 app.activities.add(r);
843 }
844 mService.updateLruProcessLocked(app, true);
845
846 final ActivityStack stack = r.task.stack;
847 try {
848 if (app.thread == null) {
849 throw new RemoteException();
850 }
851 List<ResultInfo> results = null;
852 List<Intent> newIntents = null;
853 if (andResume) {
854 results = r.results;
855 newIntents = r.newIntents;
856 }
857 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
858 + " icicle=" + r.icicle
859 + " with results=" + results + " newIntents=" + newIntents
860 + " andResume=" + andResume);
861 if (andResume) {
862 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
863 r.userId, System.identityHashCode(r),
864 r.task.taskId, r.shortComponentName);
865 }
Craig Mautner86d67a42013-05-14 10:34:38 -0700866 if (r.isHomeActivity()) {
Craig Mautner2420ead2013-04-01 17:13:20 -0700867 mService.mHomeProcess = app;
868 }
869 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
870 r.sleeping = false;
871 r.forceNewConfig = false;
872 mService.showAskCompatModeDialogLocked(r);
873 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
874 String profileFile = null;
875 ParcelFileDescriptor profileFd = null;
876 boolean profileAutoStop = false;
877 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
878 if (mService.mProfileProc == null || mService.mProfileProc == app) {
879 mService.mProfileProc = app;
880 profileFile = mService.mProfileFile;
881 profileFd = mService.mProfileFd;
882 profileAutoStop = mService.mAutoStopProfiler;
883 }
884 }
885 app.hasShownUi = true;
886 app.pendingUiClean = true;
887 if (profileFd != null) {
888 try {
889 profileFd = profileFd.dup();
890 } catch (IOException e) {
891 if (profileFd != null) {
892 try {
893 profileFd.close();
894 } catch (IOException o) {
895 }
896 profileFd = null;
897 }
898 }
899 }
900 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
901 System.identityHashCode(r), r.info,
902 new Configuration(mService.mConfiguration),
903 r.compat, r.icicle, results, newIntents, !andResume,
904 mService.isNextTransitionForward(), profileFile, profileFd,
905 profileAutoStop);
906
907 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
908 // This may be a heavy-weight process! Note that the package
909 // manager will ensure that only activity can run in the main
910 // process of the .apk, which is the only thing that will be
911 // considered heavy-weight.
912 if (app.processName.equals(app.info.packageName)) {
913 if (mService.mHeavyWeightProcess != null
914 && mService.mHeavyWeightProcess != app) {
915 Slog.w(TAG, "Starting new heavy weight process " + app
916 + " when already running "
917 + mService.mHeavyWeightProcess);
918 }
919 mService.mHeavyWeightProcess = app;
920 Message msg = mService.mHandler.obtainMessage(
921 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
922 msg.obj = r;
923 mService.mHandler.sendMessage(msg);
924 }
925 }
926
927 } catch (RemoteException e) {
928 if (r.launchFailed) {
929 // This is the second time we failed -- finish activity
930 // and give up.
931 Slog.e(TAG, "Second failure launching "
932 + r.intent.getComponent().flattenToShortString()
933 + ", giving up", e);
934 mService.appDiedLocked(app, app.pid, app.thread);
935 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
936 "2nd-crash", false);
937 return false;
938 }
939
940 // This is the first time we failed -- restart process and
941 // retry.
942 app.activities.remove(r);
943 throw e;
944 }
945
946 r.launchFailed = false;
947 if (stack.updateLRUListLocked(r)) {
948 Slog.w(TAG, "Activity " + r
949 + " being launched, but already in LRU list");
950 }
951
952 if (andResume) {
953 // As part of the process of launching, ActivityThread also performs
954 // a resume.
955 stack.minimalResumeActivityLocked(r);
956 } else {
957 // This activity is not starting in the resumed state... which
958 // should look like we asked it to pause+stop (but remain visible),
959 // and it has done so and reported back the current icicle and
960 // other state.
961 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
962 + " (starting in stopped state)");
963 r.state = ActivityState.STOPPED;
964 r.stopped = true;
965 }
966
967 // Launch the new version setup screen if needed. We do this -after-
968 // launching the initial activity (that is, home), so that it can have
969 // a chance to initialize itself while in the background, making the
970 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700971 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -0700972 mService.startSetupActivityLocked();
973 }
974
975 return true;
976 }
977
Craig Mautnere79d42682013-04-01 19:01:53 -0700978 void startSpecificActivityLocked(ActivityRecord r,
979 boolean andResume, boolean checkConfig) {
980 // Is this activity's application already running?
981 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
982 r.info.applicationInfo.uid);
983
984 r.task.stack.setLaunchTime(r);
985
986 if (app != null && app.thread != null) {
987 try {
988 app.addPackage(r.info.packageName);
989 realStartActivityLocked(r, app, andResume, checkConfig);
990 return;
991 } catch (RemoteException e) {
992 Slog.w(TAG, "Exception when starting activity "
993 + r.intent.getComponent().flattenToShortString(), e);
994 }
995
996 // If a dead object exception was thrown -- fall through to
997 // restart the application.
998 }
999
1000 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1001 "activity", r.intent.getComponent(), false, false);
1002 }
1003
Craig Mautner6170f732013-04-02 13:05:23 -07001004 final int startActivityLocked(IApplicationThread caller,
1005 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1006 String resultWho, int requestCode,
1007 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1008 boolean componentSpecified, ActivityRecord[] outActivity) {
1009 int err = ActivityManager.START_SUCCESS;
1010
1011 ProcessRecord callerApp = null;
1012 if (caller != null) {
1013 callerApp = mService.getRecordForAppLocked(caller);
1014 if (callerApp != null) {
1015 callingPid = callerApp.pid;
1016 callingUid = callerApp.info.uid;
1017 } else {
1018 Slog.w(TAG, "Unable to find app for caller " + caller
1019 + " (pid=" + callingPid + ") when starting: "
1020 + intent.toString());
1021 err = ActivityManager.START_PERMISSION_DENIED;
1022 }
1023 }
1024
1025 if (err == ActivityManager.START_SUCCESS) {
1026 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1027 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1028 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1029 }
1030
1031 ActivityRecord sourceRecord = null;
1032 ActivityRecord resultRecord = null;
1033 if (resultTo != null) {
1034 sourceRecord = isInAnyStackLocked(resultTo);
1035 if (DEBUG_RESULTS) Slog.v(
1036 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1037 if (sourceRecord != null) {
1038 if (requestCode >= 0 && !sourceRecord.finishing) {
1039 resultRecord = sourceRecord;
1040 }
1041 }
1042 }
1043 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1044
1045 int launchFlags = intent.getFlags();
1046
1047 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1048 && sourceRecord != null) {
1049 // Transfer the result target from the source activity to the new
1050 // one being started, including any failures.
1051 if (requestCode >= 0) {
1052 ActivityOptions.abort(options);
1053 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1054 }
1055 resultRecord = sourceRecord.resultTo;
1056 resultWho = sourceRecord.resultWho;
1057 requestCode = sourceRecord.requestCode;
1058 sourceRecord.resultTo = null;
1059 if (resultRecord != null) {
1060 resultRecord.removeResultsLocked(
1061 sourceRecord, resultWho, requestCode);
1062 }
1063 }
1064
1065 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1066 // We couldn't find a class that can handle the given Intent.
1067 // That's the end of that!
1068 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1069 }
1070
1071 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1072 // We couldn't find the specific class specified in the Intent.
1073 // Also the end of the line.
1074 err = ActivityManager.START_CLASS_NOT_FOUND;
1075 }
1076
1077 if (err != ActivityManager.START_SUCCESS) {
1078 if (resultRecord != null) {
1079 resultStack.sendActivityResultLocked(-1,
1080 resultRecord, resultWho, requestCode,
1081 Activity.RESULT_CANCELED, null);
1082 }
1083 setDismissKeyguard(false);
1084 ActivityOptions.abort(options);
1085 return err;
1086 }
1087
1088 final int startAnyPerm = mService.checkPermission(
1089 START_ANY_ACTIVITY, callingPid, callingUid);
1090 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1091 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1092 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1093 if (resultRecord != null) {
1094 resultStack.sendActivityResultLocked(-1,
1095 resultRecord, resultWho, requestCode,
1096 Activity.RESULT_CANCELED, null);
1097 }
1098 setDismissKeyguard(false);
1099 String msg;
1100 if (!aInfo.exported) {
1101 msg = "Permission Denial: starting " + intent.toString()
1102 + " from " + callerApp + " (pid=" + callingPid
1103 + ", uid=" + callingUid + ")"
1104 + " not exported from uid " + aInfo.applicationInfo.uid;
1105 } else {
1106 msg = "Permission Denial: starting " + intent.toString()
1107 + " from " + callerApp + " (pid=" + callingPid
1108 + ", uid=" + callingUid + ")"
1109 + " requires " + aInfo.permission;
1110 }
1111 Slog.w(TAG, msg);
1112 throw new SecurityException(msg);
1113 }
1114
Ben Gruver6617c3c2013-04-03 18:45:22 -07001115 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent,
Ben Gruver7b879f42013-04-08 14:56:55 -07001116 callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001117
Craig Mautner6170f732013-04-02 13:05:23 -07001118 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001119 try {
1120 // The Intent we give to the watcher has the extra data
1121 // stripped off, since it can contain private information.
1122 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001123 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001124 aInfo.applicationInfo.packageName);
1125 } catch (RemoteException e) {
1126 mService.mController = null;
1127 }
Ben Gruver5e207332013-04-03 17:41:37 -07001128 }
Craig Mautner6170f732013-04-02 13:05:23 -07001129
Ben Gruver5e207332013-04-03 17:41:37 -07001130 if (abort) {
1131 if (resultRecord != null) {
1132 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001133 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001134 }
Ben Gruver5e207332013-04-03 17:41:37 -07001135 // We pretend to the caller that it was really started, but
1136 // they will just get a cancel result.
1137 setDismissKeyguard(false);
1138 ActivityOptions.abort(options);
1139 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001140 }
1141
1142 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1143 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001144 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001145 if (outActivity != null) {
1146 outActivity[0] = r;
1147 }
1148
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001149 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001150 if (stack.mResumedActivity == null
1151 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001152 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1153 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001154 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001155 mService.mPendingActivityLaunches.add(pal);
1156 setDismissKeyguard(false);
1157 ActivityOptions.abort(options);
1158 return ActivityManager.START_SWITCHES_CANCELED;
1159 }
1160 }
1161
1162 if (mService.mDidAppSwitch) {
1163 // This is the second allowed switch since we stopped switches,
1164 // so now just generally allow switches. Use case: user presses
1165 // home (switches disabled, switch to home, mDidAppSwitch now true);
1166 // user taps a home icon (coming from home so allowed, we hit here
1167 // and now allow anyone to switch again).
1168 mService.mAppSwitchesAllowedTime = 0;
1169 } else {
1170 mService.mDidAppSwitch = true;
1171 }
1172
1173 mService.doPendingActivityLaunchesLocked(false);
1174
Craig Mautner8849a5e2013-04-02 16:41:03 -07001175 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001176 if (stack.mPausingActivity == null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001177 // Someone asked to have the keyguard dismissed on the next
1178 // activity start, but we are not actually doing an activity
1179 // switch... just dismiss the keyguard now, because we
1180 // probably want to see whatever is behind it.
1181 dismissKeyguard();
1182 }
1183 return err;
1184 }
1185
Craig Mautnerde4ef022013-04-07 19:01:33 -07001186 ActivityStack getCorrectStack(ActivityRecord r) {
Craig Mautner86d67a42013-05-14 10:34:38 -07001187 if (r.isApplicationActivity() || (r.task != null && r.task.isApplicationTask())) {
Craig Mautner858d8a62013-04-23 17:08:34 -07001188 int stackNdx;
1189 for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1190 if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) {
1191 break;
1192 }
1193 }
1194 if (stackNdx == 0) {
1195 // Time to create the first app stack for this user.
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001196 int stackId = mService.createStack(-1, HOME_STACK_ID,
1197 StackBox.TASK_STACK_GOES_OVER, 1.0f);
Craig Mautner29219d92013-04-16 20:19:12 -07001198 mFocusedStack = getStack(stackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001199 }
Craig Mautner29219d92013-04-16 20:19:12 -07001200 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001201 }
1202 return mHomeStack;
1203 }
1204
Craig Mautner29219d92013-04-16 20:19:12 -07001205 void setFocusedStack(ActivityRecord r) {
1206 if (r == null) {
1207 return;
1208 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001209 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001210 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001211 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1212 stackStateToString(mStackState) + " new=" +
1213 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1214 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001215 mStackState = STACK_STATE_HOME_TO_FRONT;
1216 }
1217 } else {
1218 mFocusedStack = r.task.stack;
1219 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001220 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1221 stackStateToString(mStackState) + " new=" +
1222 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1223 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001224 mStackState = STACK_STATE_HOME_TO_BACK;
1225 }
1226 }
1227 }
1228
Craig Mautner8849a5e2013-04-02 16:41:03 -07001229 final int startActivityUncheckedLocked(ActivityRecord r,
1230 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1231 Bundle options) {
1232 final Intent intent = r.intent;
1233 final int callingUid = r.launchedFromUid;
1234
1235 int launchFlags = intent.getFlags();
1236
Craig Mautner8849a5e2013-04-02 16:41:03 -07001237 // We'll invoke onUserLeaving before onPause only if the launching
1238 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001239 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1240 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001241
1242 // If the caller has asked not to resume at this point, we make note
1243 // of this in the record so that we can skip it when trying to find
1244 // the top running activity.
1245 if (!doResume) {
1246 r.delayedResume = true;
1247 }
1248
1249 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1250
1251 // If the onlyIfNeeded flag is set, then we can do this if the activity
1252 // being launched is the same as the one making the call... or, as
1253 // a special case, if we do not know the caller then we count the
1254 // current top activity as the caller.
1255 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1256 ActivityRecord checkedCaller = sourceRecord;
1257 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001258 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001259 }
1260 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1261 // Caller is not the same as launcher, so always needed.
1262 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1263 }
1264 }
1265
1266 if (sourceRecord == null) {
1267 // This activity is not being started from another... in this
1268 // case we -always- start a new task.
1269 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001270 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1271 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001272 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1273 }
1274 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1275 // The original activity who is starting us is running as a single
1276 // instance... this new activity it is starting must go on its
1277 // own task.
1278 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1279 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1280 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1281 // The activity being started is a single instance... it always
1282 // gets launched into its own task.
1283 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1284 }
1285
Craig Mautnerde4ef022013-04-07 19:01:33 -07001286 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001287 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001288 if (sourceRecord != null) {
1289 sourceTask = sourceRecord.task;
1290 sourceStack = sourceTask.stack;
1291 } else {
1292 sourceTask = null;
1293 sourceStack = null;
1294 }
1295
Craig Mautner8849a5e2013-04-02 16:41:03 -07001296 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1297 // For whatever reason this activity is being launched into a new
1298 // task... yet the caller has requested a result back. Well, that
1299 // is pretty messed up, so instead immediately send back a cancel
1300 // and let the new task continue launched as normal without a
1301 // dependency on its originator.
1302 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1303 r.resultTo.task.stack.sendActivityResultLocked(-1,
1304 r.resultTo, r.resultWho, r.requestCode,
1305 Activity.RESULT_CANCELED, null);
1306 r.resultTo = null;
1307 }
1308
1309 boolean addingToTask = false;
1310 boolean movedHome = false;
1311 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001312 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001313 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1314 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1315 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1316 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1317 // If bring to front is requested, and no result is requested, and
1318 // we can find a task that was started with this same
1319 // component, then instead of launching bring that one to the front.
1320 if (r.resultTo == null) {
1321 // See if there is a task to bring to the front. If this is
1322 // a SINGLE_INSTANCE activity, there can be one and only one
1323 // instance of it in the history, and it is always in its own
1324 // unique task, so we do a special search.
1325 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1326 ? findTaskLocked(intent, r.info)
1327 : findActivityLocked(intent, r.info);
1328 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001329 if (r.task == null) {
1330 r.task = intentActivity.task;
1331 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001332 targetStack = intentActivity.task.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001333 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001334 if (intentActivity.task.intent == null) {
1335 // This task was started because of movement of
1336 // the activity based on affinity... now that we
1337 // are actually launching it, we can assign the
1338 // base intent.
1339 intentActivity.task.setIntent(intent, r.info);
1340 }
1341 // If the target task is not in the front, then we need
1342 // to bring it to the front... except... well, with
1343 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1344 // to have the same behavior as if a new instance was
1345 // being started, which means not bringing it to the front
1346 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001347 final ActivityStack lastStack = getLastStack();
1348 ActivityRecord curTop = lastStack == null?
1349 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001350 if (curTop != null && curTop.task != intentActivity.task) {
1351 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001352 if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001353 // We really do want to push this one into the
1354 // user's face, right now.
1355 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001356 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001357 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1358 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001359 // Caller wants to appear on home activity, so before starting
1360 // their own activity we will bring home to the front.
1361 r.mLaunchHomeTaskNext = true;
1362 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001363 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1364 options = null;
1365 }
1366 }
1367 // If the caller has requested that the target task be
1368 // reset, then do so.
1369 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1370 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1371 }
1372 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1373 // We don't need to start a new activity, and
1374 // the client said not to do anything if that
1375 // is the case, so this is it! And for paranoia, make
1376 // sure we have correctly resumed the top activity.
1377 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001378 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001379 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001380 } else {
1381 ActivityOptions.abort(options);
1382 }
Craig Mautner29219d92013-04-16 20:19:12 -07001383 if (r.task == null) Slog.v(TAG,
1384 "startActivityUncheckedLocked: task left null",
1385 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001386 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1387 }
1388 if ((launchFlags &
1389 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1390 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1391 // The caller has requested to completely replace any
1392 // existing task with its new activity. Well that should
1393 // not be too hard...
1394 reuseTask = intentActivity.task;
1395 reuseTask.performClearTaskLocked();
1396 reuseTask.setIntent(r.intent, r.info);
1397 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1398 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1399 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1400 // In this situation we want to remove all activities
1401 // from the task up to the one being started. In most
1402 // cases this means we are resetting the task to its
1403 // initial state.
1404 ActivityRecord top =
1405 intentActivity.task.performClearTaskLocked(r, launchFlags);
1406 if (top != null) {
1407 if (top.frontOfTask) {
1408 // Activity aliases may mean we use different
1409 // intents for the top activity, so make sure
1410 // the task now has the identity of the new
1411 // intent.
1412 top.task.setIntent(r.intent, r.info);
1413 }
1414 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1415 r, top.task);
1416 top.deliverNewIntentLocked(callingUid, r.intent);
1417 } else {
1418 // A special case: we need to
1419 // start the activity because it is not currently
1420 // running, and the caller has asked to clear the
1421 // current task to have this activity at the top.
1422 addingToTask = true;
1423 // Now pretend like this activity is being started
1424 // by the top of its task, so it is put in the
1425 // right place.
1426 sourceRecord = intentActivity;
1427 }
1428 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1429 // In this case the top activity on the task is the
1430 // same as the one being launched, so we take that
1431 // as a request to bring the task to the foreground.
1432 // If the top activity in the task is the root
1433 // activity, deliver this new intent to it if it
1434 // desires.
1435 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1436 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1437 && intentActivity.realActivity.equals(r.realActivity)) {
1438 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1439 intentActivity.task);
1440 if (intentActivity.frontOfTask) {
1441 intentActivity.task.setIntent(r.intent, r.info);
1442 }
1443 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1444 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1445 // In this case we are launching the root activity
1446 // of the task, but with a different intent. We
1447 // should start a new instance on top.
1448 addingToTask = true;
1449 sourceRecord = intentActivity;
1450 }
1451 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1452 // In this case an activity is being launched in to an
1453 // existing task, without resetting that task. This
1454 // is typically the situation of launching an activity
1455 // from a notification or shortcut. We want to place
1456 // the new activity on top of the current task.
1457 addingToTask = true;
1458 sourceRecord = intentActivity;
1459 } else if (!intentActivity.task.rootWasReset) {
1460 // In this case we are launching in to an existing task
1461 // that has not yet been started from its front door.
1462 // The current task has been brought to the front.
1463 // Ideally, we'd probably like to place this new task
1464 // at the bottom of its stack, but that's a little hard
1465 // to do with the current organization of the code so
1466 // for now we'll just drop it.
1467 intentActivity.task.setIntent(r.intent, r.info);
1468 }
1469 if (!addingToTask && reuseTask == null) {
1470 // We didn't do anything... but it was needed (a.k.a., client
1471 // don't use that intent!) And for paranoia, make
1472 // sure we have correctly resumed the top activity.
1473 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001474 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1475 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001476 } else {
1477 ActivityOptions.abort(options);
1478 }
Craig Mautner29219d92013-04-16 20:19:12 -07001479 if (r.task == null) Slog.v(TAG,
1480 "startActivityUncheckedLocked: task left null",
1481 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001482 return ActivityManager.START_TASK_TO_FRONT;
1483 }
1484 }
1485 }
1486 }
1487
1488 //String uri = r.intent.toURI();
1489 //Intent intent2 = new Intent(uri);
1490 //Slog.i(TAG, "Given intent: " + r.intent);
1491 //Slog.i(TAG, "URI is: " + uri);
1492 //Slog.i(TAG, "To intent: " + intent2);
1493
1494 if (r.packageName != null) {
1495 // If the activity being launched is the same as the one currently
1496 // at the top, then we need to check if it should only be launched
1497 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001498 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001499 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001500 if (top != null && r.resultTo == null) {
1501 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1502 if (top.app != null && top.app.thread != null) {
1503 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1504 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1505 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1506 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1507 top.task);
1508 // For paranoia, make sure we have correctly
1509 // resumed the top activity.
1510 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001511 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001512 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001513 }
1514 ActivityOptions.abort(options);
1515 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1516 // We don't need to start a new activity, and
1517 // the client said not to do anything if that
1518 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001519 if (r.task == null) Slog.v(TAG,
1520 "startActivityUncheckedLocked: task left null",
1521 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001522 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1523 }
1524 top.deliverNewIntentLocked(callingUid, r.intent);
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_DELIVERED_TO_TOP;
1529 }
1530 }
1531 }
1532 }
1533
1534 } else {
1535 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001536 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1537 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001538 }
1539 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001540 if (r.task == null) Slog.v(TAG,
1541 "startActivityUncheckedLocked: task left null",
1542 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001543 return ActivityManager.START_CLASS_NOT_FOUND;
1544 }
1545
1546 boolean newTask = false;
1547 boolean keepCurTransition = false;
1548
1549 // Should this be considered a new task?
1550 if (r.resultTo == null && !addingToTask
1551 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001552 targetStack = getCorrectStack(r);
1553 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001554 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001555 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1556 null, true);
1557 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1558 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001559 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001560 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001561 }
1562 newTask = true;
1563 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001564 if ((launchFlags &
1565 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1566 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1567 // Caller wants to appear on home activity, so before starting
1568 // their own activity we will bring home to the front.
1569 r.mLaunchHomeTaskNext = true;
1570 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001571 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001572 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001573 sourceTask = sourceRecord.task;
1574 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001575 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001576 if (!addingToTask &&
1577 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1578 // In this case, we are adding the activity to an existing
1579 // task, but the caller has asked to clear that task if the
1580 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001581 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001582 keepCurTransition = true;
1583 if (top != null) {
1584 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1585 top.deliverNewIntentLocked(callingUid, r.intent);
1586 // For paranoia, make sure we have correctly
1587 // resumed the top activity.
1588 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001589 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001590 targetStack.resumeTopActivityLocked(null);
1591 }
1592 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001593 if (r.task == null) Slog.v(TAG,
1594 "startActivityUncheckedLocked: task left null",
1595 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001596 return ActivityManager.START_DELIVERED_TO_TOP;
1597 }
1598 } else if (!addingToTask &&
1599 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1600 // In this case, we are launching an activity in our own task
1601 // that may already be running somewhere in the history, and
1602 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001603 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001604 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001605 final TaskRecord task = top.task;
1606 task.moveActivityToFrontLocked(top);
1607 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001608 top.updateOptionsLocked(options);
1609 top.deliverNewIntentLocked(callingUid, r.intent);
1610 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001611 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001612 targetStack.resumeTopActivityLocked(null);
1613 }
Craig Mautner29219d92013-04-16 20:19:12 -07001614 if (r.task == null) Slog.v(TAG,
1615 "startActivityUncheckedLocked: task left null",
1616 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001617 return ActivityManager.START_DELIVERED_TO_TOP;
1618 }
1619 }
1620 // An existing activity is starting this new activity, so we want
1621 // to keep the new one in the same task as the one that is starting
1622 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001623 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001624 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1625 + " in existing task " + r.task);
1626
1627 } else {
1628 // This not being started from an existing activity, and not part
1629 // of a new task... just put it in the top task, though these days
1630 // this case should never happen.
Craig Mautner1602ec22013-05-12 10:24:27 -07001631 targetStack = getCorrectStack(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001632 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001633 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001634 r.setTask(prev != null ? prev.task
1635 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1636 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001637 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1638 + " in new guessed " + r.task);
1639 }
1640
1641 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1642 intent, r.getUriPermissionsLocked());
1643
1644 if (newTask) {
1645 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1646 }
1647 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001648 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001649 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1650 return ActivityManager.START_SUCCESS;
1651 }
1652
Craig Mautnerf3333272013-04-22 10:55:53 -07001653 // Checked.
1654 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1655 Configuration config) {
1656 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1657
1658 ActivityRecord res = null;
1659
1660 ArrayList<ActivityRecord> stops = null;
1661 ArrayList<ActivityRecord> finishes = null;
1662 ArrayList<UserStartedState> startingUsers = null;
1663 int NS = 0;
1664 int NF = 0;
1665 IApplicationThread sendThumbnail = null;
1666 boolean booting = false;
1667 boolean enableScreen = false;
1668 boolean activityRemoved = false;
1669
1670 ActivityRecord r = ActivityRecord.forToken(token);
1671 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001672 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1673 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001674 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1675 r.finishLaunchTickingLocked();
Craig Mautner525f3d92013-05-07 14:01:50 -07001676 res = r.task.stack.activityIdleInternalLocked(token);
Craig Mautnerf3333272013-04-22 10:55:53 -07001677 if (res != null) {
1678 if (fromTimeout) {
1679 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1680 }
1681
1682 // This is a hack to semi-deal with a race condition
1683 // in the client where it can be constructed with a
1684 // newer configuration from when we asked it to launch.
1685 // We'll update with whatever configuration it now says
1686 // it used to launch.
1687 if (config != null) {
1688 r.configuration = config;
1689 }
1690
1691 // We are now idle. If someone is waiting for a thumbnail from
1692 // us, we can now deliver.
1693 r.idle = true;
1694 if (allResumedActivitiesIdle()) {
1695 mService.scheduleAppGcsLocked();
1696 }
1697 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1698 sendThumbnail = r.app.thread;
1699 r.thumbnailNeeded = false;
1700 }
1701
1702 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1703 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1704 mService.mBooted = true;
1705 enableScreen = true;
1706 }
1707 } else if (fromTimeout) {
1708 reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
1709 }
1710 }
1711
1712 // Atomically retrieve all of the other things to do.
1713 stops = processStoppingActivitiesLocked(true);
1714 NS = stops != null ? stops.size() : 0;
1715 if ((NF=mFinishingActivities.size()) > 0) {
1716 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1717 mFinishingActivities.clear();
1718 }
1719
1720 final ArrayList<ActivityRecord> thumbnails;
1721 final int NT = mCancelledThumbnails.size();
1722 if (NT > 0) {
1723 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1724 mCancelledThumbnails.clear();
1725 } else {
1726 thumbnails = null;
1727 }
1728
1729 if (isFrontStack(mHomeStack)) {
1730 booting = mService.mBooting;
1731 mService.mBooting = false;
1732 }
1733
1734 if (mStartingUsers.size() > 0) {
1735 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1736 mStartingUsers.clear();
1737 }
1738
1739 // Perform the following actions from unsynchronized state.
1740 final IApplicationThread thumbnailThread = sendThumbnail;
1741 mHandler.post(new Runnable() {
1742 @Override
1743 public void run() {
1744 if (thumbnailThread != null) {
1745 try {
1746 thumbnailThread.requestThumbnail(token);
1747 } catch (Exception e) {
1748 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1749 mService.sendPendingThumbnail(null, token, null, null, true);
1750 }
1751 }
1752
1753 // Report back to any thumbnail receivers.
1754 for (int i = 0; i < NT; i++) {
1755 ActivityRecord r = thumbnails.get(i);
1756 mService.sendPendingThumbnail(r, null, null, null, true);
1757 }
1758 }
1759 });
1760
1761 // Stop any activities that are scheduled to do so but have been
1762 // waiting for the next one to start.
1763 for (int i = 0; i < NS; i++) {
1764 r = stops.get(i);
1765 final ActivityStack stack = r.task.stack;
1766 if (r.finishing) {
1767 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1768 } else {
1769 stack.stopActivityLocked(r);
1770 }
1771 }
1772
1773 // Finish any activities that are scheduled to do so but have been
1774 // waiting for the next one to start.
1775 for (int i = 0; i < NF; i++) {
1776 r = finishes.get(i);
1777 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1778 }
1779
1780 if (booting) {
1781 mService.finishBooting();
1782 } else if (startingUsers != null) {
1783 for (int i = 0; i < startingUsers.size(); i++) {
1784 mService.finishUserSwitch(startingUsers.get(i));
1785 }
1786 }
1787
1788 mService.trimApplications();
1789 //dump();
1790 //mWindowManager.dump();
1791
1792 if (enableScreen) {
1793 mService.enableScreenAfterBoot();
1794 }
1795
1796 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001797 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001798 }
1799
1800 return res;
1801 }
1802
Craig Mautner8d341ef2013-03-26 09:03:27 -07001803 void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1804 // Just in case.
1805 final int numStacks = mStacks.size();
1806 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001807 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001808 }
1809 }
1810
1811 void closeSystemDialogsLocked() {
1812 final int numStacks = mStacks.size();
1813 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1814 final ActivityStack stack = mStacks.get(stackNdx);
1815 stack.closeSystemDialogsLocked();
1816 }
1817 }
1818
1819 /**
1820 * @return true if some activity was finished (or would have finished if doit were true).
1821 */
1822 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1823 boolean didSomething = false;
1824 final int numStacks = mStacks.size();
1825 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1826 final ActivityStack stack = mStacks.get(stackNdx);
1827 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1828 didSomething = true;
1829 }
1830 }
1831 return didSomething;
1832 }
1833
Craig Mautner05d29032013-05-03 13:40:13 -07001834 boolean resumeTopActivitiesLocked() {
1835 return resumeTopActivitiesLocked(null, null, null);
1836 }
1837
1838 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1839 Bundle targetOptions) {
1840 if (targetStack == null) {
1841 targetStack = getFocusedStack();
1842 }
1843 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001844 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001845 final ActivityStack stack = mStacks.get(stackNdx);
1846 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001847 if (stack == targetStack) {
1848 result = stack.resumeTopActivityLocked(target, targetOptions);
1849 } else {
1850 stack.resumeTopActivityLocked(null);
1851 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001852 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001853 }
Craig Mautner05d29032013-05-03 13:40:13 -07001854 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001855 }
1856
1857 void finishTopRunningActivityLocked(ProcessRecord app) {
1858 final int numStacks = mStacks.size();
1859 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1860 final ActivityStack stack = mStacks.get(stackNdx);
1861 stack.finishTopRunningActivityLocked(app);
1862 }
1863 }
1864
Craig Mautner8d341ef2013-03-26 09:03:27 -07001865 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
1866 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1867 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
1868 return;
1869 }
1870 }
1871 }
1872
Craig Mautner967212c2013-04-13 21:10:58 -07001873 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001874 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1875 final ActivityStack stack = mStacks.get(stackNdx);
1876 if (stack.getStackId() == stackId) {
1877 return stack;
1878 }
1879 }
1880 return null;
1881 }
1882
Craig Mautner967212c2013-04-13 21:10:58 -07001883 ArrayList<ActivityStack> getStacks() {
1884 return new ArrayList<ActivityStack>(mStacks);
1885 }
1886
1887 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07001888 while (true) {
1889 if (++mLastStackId <= HOME_STACK_ID) {
1890 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001891 }
Craig Mautner858d8a62013-04-23 17:08:34 -07001892 if (getStack(mLastStackId) == null) {
1893 break;
1894 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001895 }
Craig Mautner858d8a62013-04-23 17:08:34 -07001896 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
1897 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001898 }
1899
1900 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07001901 final TaskRecord task = anyTaskForIdLocked(taskId);
1902 if (task == null) {
1903 return;
1904 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001905 final ActivityStack stack = getStack(stackId);
1906 if (stack == null) {
1907 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
1908 return;
1909 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07001910 removeTask(task);
1911 stack.addTask(task, toTop);
1912 if (toTop) {
1913 moveHomeStack(stack.isHomeStack());
1914 setFocusedStack(task.getTopActivity());
1915 }
1916 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07001917 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07001918 }
1919
Craig Mautner8849a5e2013-04-02 16:41:03 -07001920 ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
1921 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1922 final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info);
1923 if (ar != null) {
1924 return ar;
1925 }
1926 }
1927 return null;
1928 }
1929
1930 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
1931 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1932 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
1933 if (ar != null) {
1934 return ar;
1935 }
1936 }
1937 return null;
1938 }
1939
Craig Mautner8d341ef2013-03-26 09:03:27 -07001940 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001941 scheduleSleepTimeout();
1942 if (!mGoingToSleep.isHeld()) {
1943 mGoingToSleep.acquire();
1944 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1945 final ActivityStack stack = mStacks.get(stackNdx);
1946 if (stack.mResumedActivity != null) {
1947 stack.stopIfSleepingLocked();
1948 }
1949 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001950 }
1951 }
1952
1953 boolean shutdownLocked(int timeout) {
1954 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07001955 goingToSleepLocked();
1956 checkReadyForSleepLocked();
1957
1958 final long endTime = System.currentTimeMillis() + timeout;
1959 while (true) {
1960 boolean cantShutdown = false;
1961 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1962 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
1963 }
1964 if (cantShutdown) {
1965 long timeRemaining = endTime - System.currentTimeMillis();
1966 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001967 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001968 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001969 } catch (InterruptedException e) {
1970 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001971 } else {
1972 Slog.w(TAG, "Activity manager shutdown timed out");
1973 timedout = true;
1974 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001975 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001976 } else {
1977 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001978 }
1979 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07001980
1981 // Force checkReadyForSleep to complete.
1982 mSleepTimeout = true;
1983 checkReadyForSleepLocked();
1984
Craig Mautner8d341ef2013-03-26 09:03:27 -07001985 return timedout;
1986 }
1987
1988 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07001989 removeSleepTimeouts();
1990 if (mGoingToSleep.isHeld()) {
1991 mGoingToSleep.release();
1992 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001993 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07001994 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001995 stack.awakeFromSleepingLocked();
1996 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001997 resumeTopActivitiesLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001998 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001999 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002000 mGoingToSleepActivities.clear();
2001 }
2002
2003 void activitySleptLocked(ActivityRecord r) {
2004 mGoingToSleepActivities.remove(r);
2005 checkReadyForSleepLocked();
2006 }
2007
2008 void checkReadyForSleepLocked() {
2009 if (!mService.isSleepingOrShuttingDown()) {
2010 // Do not care.
2011 return;
2012 }
2013
2014 if (!mSleepTimeout) {
2015 boolean dontSleep = false;
2016 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2017 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2018 }
2019
2020 if (mStoppingActivities.size() > 0) {
2021 // Still need to tell some activities to stop; can't sleep yet.
2022 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2023 + mStoppingActivities.size() + " activities");
2024 scheduleIdleLocked();
2025 dontSleep = true;
2026 }
2027
2028 if (mGoingToSleepActivities.size() > 0) {
2029 // Still need to tell some activities to sleep; can't sleep yet.
2030 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2031 + mGoingToSleepActivities.size() + " activities");
2032 dontSleep = true;
2033 }
2034
2035 if (dontSleep) {
2036 return;
2037 }
2038 }
2039
2040 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2041 mStacks.get(stackNdx).goToSleep();
2042 }
2043
2044 removeSleepTimeouts();
2045
2046 if (mGoingToSleep.isHeld()) {
2047 mGoingToSleep.release();
2048 }
2049 if (mService.mShuttingDown) {
2050 mService.notifyAll();
2051 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002052 }
2053
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002054 boolean reportResumedActivityLocked(ActivityRecord r) {
2055 final ActivityStack stack = r.task.stack;
2056 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002057 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002058 mService.setFocusedActivityLocked(r);
2059 }
2060 if (allResumedActivitiesComplete()) {
2061 ensureActivitiesVisibleLocked(null, 0);
2062 mWindowManager.executeAppTransition();
2063 return true;
2064 }
2065 return false;
2066 }
2067
Craig Mautner8d341ef2013-03-26 09:03:27 -07002068 void handleAppCrashLocked(ProcessRecord app) {
2069 final int numStacks = mStacks.size();
2070 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2071 final ActivityStack stack = mStacks.get(stackNdx);
2072 stack.handleAppCrashLocked(app);
2073 }
2074 }
2075
Craig Mautnerde4ef022013-04-07 19:01:33 -07002076 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002077 // First the front stacks. In case any are not fullscreen and are in front of home.
2078 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002079 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002080 final ActivityStack stack = mStacks.get(stackNdx);
2081 if (isFrontStack(stack)) {
2082 showHomeBehindStack =
2083 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2084 }
2085 }
2086 // Now do back stacks.
2087 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2088 final ActivityStack stack = mStacks.get(stackNdx);
2089 if (!isFrontStack(stack)) {
2090 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2091 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002092 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002093 }
2094
2095 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2096 final int numStacks = mStacks.size();
2097 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2098 final ActivityStack stack = mStacks.get(stackNdx);
2099 stack.scheduleDestroyActivities(app, false, reason);
2100 }
2101 }
2102
2103 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner858d8a62013-04-23 17:08:34 -07002104 mUserStates.put(mCurrentUser, new UserState());
Craig Mautner2420ead2013-04-01 17:13:20 -07002105 mCurrentUser = userId;
Craig Mautner858d8a62013-04-23 17:08:34 -07002106 UserState userState = mUserStates.get(userId);
2107 if (userState != null) {
2108 userState.restore();
2109 mUserStates.delete(userId);
2110 } else {
2111 mFocusedStack = null;
Craig Mautner76ea2242013-05-15 11:40:05 -07002112 if (DEBUG_STACK) Slog.d(TAG, "switchUserLocked: mStackState=" +
2113 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautner858d8a62013-04-23 17:08:34 -07002114 mStackState = STACK_STATE_HOME_IN_FRONT;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002115 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002116
2117 mStartingUsers.add(uss);
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002118 boolean haveActivities = mHomeStack.switchUserLocked(userId);
Craig Mautner858d8a62013-04-23 17:08:34 -07002119
2120 resumeTopActivitiesLocked();
2121
Craig Mautner8d341ef2013-03-26 09:03:27 -07002122 return haveActivities;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002123 }
2124
Craig Mautnerde4ef022013-04-07 19:01:33 -07002125 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2126 int N = mStoppingActivities.size();
2127 if (N <= 0) return null;
2128
2129 ArrayList<ActivityRecord> stops = null;
2130
2131 final boolean nowVisible = allResumedActivitiesVisible();
2132 for (int i=0; i<N; i++) {
2133 ActivityRecord s = mStoppingActivities.get(i);
2134 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2135 + nowVisible + " waitingVisible=" + s.waitingVisible
2136 + " finishing=" + s.finishing);
2137 if (s.waitingVisible && nowVisible) {
2138 mWaitingVisibleActivities.remove(s);
2139 s.waitingVisible = false;
2140 if (s.finishing) {
2141 // If this activity is finishing, it is sitting on top of
2142 // everyone else but we now know it is no longer needed...
2143 // so get rid of it. Otherwise, we need to go through the
2144 // normal flow and hide it once we determine that it is
2145 // hidden by the activities in front of it.
2146 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002147 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002148 }
2149 }
2150 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2151 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2152 if (stops == null) {
2153 stops = new ArrayList<ActivityRecord>();
2154 }
2155 stops.add(s);
2156 mStoppingActivities.remove(i);
2157 N--;
2158 i--;
2159 }
2160 }
2161
2162 return stops;
2163 }
2164
Craig Mautnercf910b02013-04-23 11:23:27 -07002165 void validateTopActivitiesLocked() {
2166 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2167 final ActivityStack stack = mStacks.get(stackNdx);
2168 final ActivityRecord r = stack.topRunningActivityLocked(null);
2169 if (isFrontStack(stack)) {
2170 if (r == null) {
2171 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2172 } else {
2173 if (stack.mPausingActivity != null) {
2174 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2175 " state=" + r.state);
2176 }
2177 if (r.state != ActivityState.INITIALIZING &&
2178 r.state != ActivityState.RESUMED) {
2179 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2180 " state=" + r.state);
2181 }
2182 }
2183 } else {
2184 if (stack.mResumedActivity != null) {
2185 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2186 " state=" + r.state);
2187 }
2188 if (r != null && (r.state == ActivityState.INITIALIZING
2189 || r.state == ActivityState.RESUMED)) {
2190 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2191 " state=" + r.state);
2192 }
2193 }
2194 }
2195 }
2196
Craig Mautner76ea2242013-05-15 11:40:05 -07002197 private static String stackStateToString(int stackState) {
2198 switch (stackState) {
2199 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2200 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2201 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2202 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2203 default: return "Unknown stackState=" + stackState;
2204 }
2205 }
2206
Craig Mautner27084302013-03-25 08:05:25 -07002207 public void dump(PrintWriter pw, String prefix) {
2208 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2209 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002210 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Craig Mautner27084302013-03-25 08:05:25 -07002211 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002212
Craig Mautner20e72272013-04-01 13:45:53 -07002213 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002214 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002215 }
2216
Craig Mautner8d341ef2013-03-26 09:03:27 -07002217 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2218 boolean dumpClient, String dumpPackage) {
Craig Mautner76ea2242013-05-15 11:40:05 -07002219 pw.print(" mStackState="); pw.println(stackStateToString(mStackState));
Craig Mautner0eea92c2013-05-16 13:35:39 -07002220 if (mGoingToSleepActivities.size() > 0) {
2221 pw.println(" Activities waiting to sleep:");
2222 dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, false,
2223 dumpPackage);
2224 }
2225 if (dumpAll) {
2226 pw.println(" mSleepTimeout: " + mSleepTimeout);
2227 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002228 final int numStacks = mStacks.size();
2229 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2230 final ActivityStack stack = mStacks.get(stackNdx);
2231 pw.print(" Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":");
2232 stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
2233 pw.println(" ");
2234 pw.println(" Running activities (most recent first):");
2235 dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false,
2236 dumpPackage);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002237
Craig Mautner8d341ef2013-03-26 09:03:27 -07002238 pw.print(" Stack #"); pw.println(mStacks.indexOf(stack));
2239 if (stack.mPausingActivity != null) {
2240 pw.println(" mPausingActivity: " + stack.mPausingActivity);
2241 }
2242 pw.println(" mResumedActivity: " + stack.mResumedActivity);
2243 if (dumpAll) {
2244 pw.println(" mLastPausedActivity: " + stack.mLastPausedActivity);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002245 }
2246 }
2247
Craig Mautnerf3333272013-04-22 10:55:53 -07002248 if (mFinishingActivities.size() > 0) {
2249 pw.println(" ");
2250 pw.println(" Activities waiting to finish:");
2251 dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, false,
2252 dumpPackage);
2253 }
2254
Craig Mautnerde4ef022013-04-07 19:01:33 -07002255 if (mStoppingActivities.size() > 0) {
2256 pw.println(" ");
2257 pw.println(" Activities waiting to stop:");
2258 dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, false,
2259 dumpPackage);
2260 }
2261
2262 if (mWaitingVisibleActivities.size() > 0) {
2263 pw.println(" ");
2264 pw.println(" Activities waiting for another to become visible:");
2265 dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2266 false, dumpPackage);
2267 }
2268
Craig Mautner8d341ef2013-03-26 09:03:27 -07002269 if (dumpAll) {
2270 pw.println(" ");
2271 pw.println(" mCurTaskId: " + mCurTaskId);
2272 }
2273 return true;
2274 }
2275
Craig Mautner76ea2242013-05-15 11:40:05 -07002276 static void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002277 String prefix, String label, boolean complete, boolean brief, boolean client,
2278 String dumpPackage) {
2279 TaskRecord lastTask = null;
2280 boolean needNL = false;
2281 final String innerPrefix = prefix + " ";
2282 final String[] args = new String[0];
2283 for (int i=list.size()-1; i>=0; i--) {
2284 final ActivityRecord r = list.get(i);
2285 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2286 continue;
2287 }
2288 final boolean full = !brief && (complete || !r.isInHistory());
2289 if (needNL) {
2290 pw.println(" ");
2291 needNL = false;
2292 }
2293 if (lastTask != r.task) {
2294 lastTask = r.task;
2295 pw.print(prefix);
2296 pw.print(full ? "* " : " ");
2297 pw.println(lastTask);
2298 if (full) {
2299 lastTask.dump(pw, prefix + " ");
2300 } else if (complete) {
2301 // Complete + brief == give a summary. Isn't that obvious?!?
2302 if (lastTask.intent != null) {
2303 pw.print(prefix); pw.print(" ");
2304 pw.println(lastTask.intent.toInsecureStringWithClip());
2305 }
2306 }
2307 }
2308 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2309 pw.print(" #"); pw.print(i); pw.print(": ");
2310 pw.println(r);
2311 if (full) {
2312 r.dump(pw, innerPrefix);
2313 } else if (complete) {
2314 // Complete + brief == give a summary. Isn't that obvious?!?
2315 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2316 if (r.app != null) {
2317 pw.print(innerPrefix); pw.println(r.app);
2318 }
2319 }
2320 if (client && r.app != null && r.app.thread != null) {
2321 // flush anything that is already in the PrintWriter since the thread is going
2322 // to write to the file descriptor directly
2323 pw.flush();
2324 try {
2325 TransferPipe tp = new TransferPipe();
2326 try {
2327 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2328 r.appToken, innerPrefix, args);
2329 // Short timeout, since blocking here can
2330 // deadlock with the application.
2331 tp.go(fd, 2000);
2332 } finally {
2333 tp.kill();
2334 }
2335 } catch (IOException e) {
2336 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2337 } catch (RemoteException e) {
2338 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2339 }
2340 needNL = true;
2341 }
2342 }
2343 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002344
Craig Mautnerf3333272013-04-22 10:55:53 -07002345 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002346 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002347 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2348 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002349 }
2350
2351 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002352 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002353 }
2354
2355 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002356 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002357 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2358 }
2359
Craig Mautner05d29032013-05-03 13:40:13 -07002360 final void scheduleResumeTopActivities() {
2361 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2362 }
2363
Craig Mautner0eea92c2013-05-16 13:35:39 -07002364 void removeSleepTimeouts() {
2365 mSleepTimeout = false;
2366 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2367 }
2368
2369 final void scheduleSleepTimeout() {
2370 removeSleepTimeouts();
2371 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2372 }
2373
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002374 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002375
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002376 public ActivityStackSupervisorHandler(Looper looper) {
2377 super(looper);
2378 }
2379
Craig Mautnerf3333272013-04-22 10:55:53 -07002380 void activityIdleInternal(ActivityRecord r) {
2381 synchronized (mService) {
2382 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2383 }
2384 }
2385
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002386 @Override
2387 public void handleMessage(Message msg) {
2388 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002389 case IDLE_TIMEOUT_MSG: {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002390 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" +
2391 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002392 if (mService.mDidDexOpt) {
2393 mService.mDidDexOpt = false;
2394 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2395 nmsg.obj = msg.obj;
2396 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2397 return;
2398 }
2399 // We don't at this point know if the activity is fullscreen,
2400 // so we need to be conservative and assume it isn't.
2401 activityIdleInternal((ActivityRecord)msg.obj);
2402 } break;
2403 case IDLE_NOW_MSG: {
2404 activityIdleInternal((ActivityRecord)msg.obj);
2405 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002406 case RESUME_TOP_ACTIVITY_MSG: {
2407 synchronized (mService) {
2408 resumeTopActivitiesLocked();
2409 }
2410 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002411 case SLEEP_TIMEOUT_MSG: {
2412 synchronized (mService) {
2413 if (mService.isSleepingOrShuttingDown()) {
2414 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2415 mSleepTimeout = true;
2416 checkReadyForSleepLocked();
2417 }
2418 }
2419 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002420 }
2421 }
2422 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002423
2424 private final class UserState {
2425 final ActivityStack mSavedFocusedStack;
2426 final int mSavedStackState;
2427
2428 public UserState() {
2429 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2430 mSavedFocusedStack = supervisor.mFocusedStack;
2431 mSavedStackState = supervisor.mStackState;
2432 }
2433
2434 void restore() {
2435 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2436 supervisor.mFocusedStack = mSavedFocusedStack;
Craig Mautner76ea2242013-05-15 11:40:05 -07002437 if (DEBUG_STACK) Slog.d(TAG, "UserState.restore: mStackState old=" +
2438 stackStateToString(mSavedStackState));
Craig Mautner858d8a62013-04-23 17:08:34 -07002439 supervisor.mStackState = mSavedStackState;
2440 }
2441 }
Craig Mautner27084302013-03-25 08:05:25 -07002442}