blob: 040f0ac5581a6cba6a30fd5e57e34893ab8472fe [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 Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
37import android.app.ActivityOptions;
38import android.app.AppGlobals;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070039import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070040import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070041import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070042import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070043import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070044import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070045import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070046import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070047import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070048import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070049import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070050import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070051import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070052import android.content.pm.ApplicationInfo;
53import android.content.pm.PackageManager;
54import android.content.pm.ResolveInfo;
55import android.content.res.Configuration;
56import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070057import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070058import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070059import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070060import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070061import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070062import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070063import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070064import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070065import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070066import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070067import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070068import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070069import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070070import android.util.Slog;
Craig Mautner858d8a62013-04-23 17:08:34 -070071import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070072
Craig Mautner93529a42013-10-04 15:03:13 -070073import android.util.SparseBooleanArray;
Craig Mautner23ac33b2013-04-01 16:26:35 -070074import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070075import com.android.internal.os.TransferPipe;
Craig Mautner6170f732013-04-02 13:05:23 -070076import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070077import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerde4ef022013-04-07 19:01:33 -070078import com.android.server.wm.StackBox;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070079import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070080
Craig Mautner8d341ef2013-03-26 09:03:27 -070081import java.io.FileDescriptor;
82import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070083import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070084import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070085import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070086
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070087public final class ActivityStackSupervisor {
Craig Mautnerde4ef022013-04-07 19:01:33 -070088 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
89 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
90 static final boolean DEBUG_APP = DEBUG || false;
91 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnerb3370ce2013-09-19 12:02:09 -070092 static final boolean DEBUG_STATES = DEBUG || true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070093 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -070094
Craig Mautner2219a1b2013-03-25 09:44:30 -070095 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -070096
Craig Mautnerf3333272013-04-22 10:55:53 -070097 /** How long we wait until giving up on the last activity telling us it is idle. */
98 static final int IDLE_TIMEOUT = 10*1000;
99
Craig Mautner0eea92c2013-05-16 13:35:39 -0700100 /** How long we can hold the sleep wake lock before giving up. */
101 static final int SLEEP_TIMEOUT = 5*1000;
102
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700103 // How long we can hold the launch wake lock before giving up.
104 static final int LAUNCH_TIMEOUT = 10*1000;
105
Craig Mautner05d29032013-05-03 13:40:13 -0700106 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
107 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
108 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700109 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700110 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
111
112 // For debugging to make sure the caller when acquiring/releasing our
113 // wake lock is the system process.
114 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700115
Craig Mautner27084302013-03-25 08:05:25 -0700116 final ActivityManagerService mService;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700117 final Context mContext;
118 final Looper mLooper;
Craig Mautner27084302013-03-25 08:05:25 -0700119
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700120 final ActivityStackSupervisorHandler mHandler;
121
122 /** Short cut */
123 WindowManagerService mWindowManager;
124
Craig Mautner27084302013-03-25 08:05:25 -0700125 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700126 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700127
Craig Mautner8d341ef2013-03-26 09:03:27 -0700128 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700129 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700130
131 /** Task identifier that activities are currently being started in. Incremented each time a
132 * new task is created. */
133 private int mCurTaskId = 0;
134
Craig Mautner2420ead2013-04-01 17:13:20 -0700135 /** The current user */
136 private int mCurrentUser;
137
Craig Mautner8d341ef2013-03-26 09:03:27 -0700138 /** The stack containing the launcher app */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700139 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700140
Craig Mautnerde4ef022013-04-07 19:01:33 -0700141 /** The non-home stack currently receiving input or launching the next activity. If home is
Craig Mautner41c0f352013-05-28 08:39:25 -0700142 * in front then mHomeStack overrides mFocusedStack.
143 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
Craig Mautner29219d92013-04-16 20:19:12 -0700144 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700145
146 /** All the non-launcher stacks */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700147 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
148
Craig Mautnerde4ef022013-04-07 19:01:33 -0700149 private static final int STACK_STATE_HOME_IN_FRONT = 0;
150 private static final int STACK_STATE_HOME_TO_BACK = 1;
151 private static final int STACK_STATE_HOME_IN_BACK = 2;
152 private static final int STACK_STATE_HOME_TO_FRONT = 3;
153 private int mStackState = STACK_STATE_HOME_IN_FRONT;
154
155 /** List of activities that are waiting for a new activity to become visible before completing
156 * whatever operation they are supposed to do. */
157 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
158
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700159 /** List of processes waiting to find out about the next visible activity. */
160 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
161 new ArrayList<IActivityManager.WaitResult>();
162
163 /** List of processes waiting to find out about the next launched activity. */
164 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
165 new ArrayList<IActivityManager.WaitResult>();
166
Craig Mautnerde4ef022013-04-07 19:01:33 -0700167 /** List of activities that are ready to be stopped, but waiting for the next activity to
168 * settle down before doing so. */
169 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
170
Craig Mautnerf3333272013-04-22 10:55:53 -0700171 /** List of activities that are ready to be finished, but waiting for the previous activity to
172 * settle down before doing so. It contains ActivityRecord objects. */
173 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
174
Craig Mautner0eea92c2013-05-16 13:35:39 -0700175 /** List of activities that are in the process of going to sleep. */
176 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
177
Craig Mautnerf3333272013-04-22 10:55:53 -0700178 /** List of ActivityRecord objects that have been finished and must still report back to a
179 * pending thumbnail receiver. */
180 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
181
182 /** Used on user changes */
183 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
184
Craig Mautnerde4ef022013-04-07 19:01:33 -0700185 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
186 * is being brought in front of us. */
187 boolean mUserLeaving = false;
188
Craig Mautner0eea92c2013-05-16 13:35:39 -0700189 /** Set when we have taken too long waiting to go to sleep. */
190 boolean mSleepTimeout = false;
191
192 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700193 * We don't want to allow the device to go to sleep while in the process
194 * of launching an activity. This is primarily to allow alarm intent
195 * receivers to launch an activity and get that to run before the device
196 * goes back to sleep.
197 */
198 final PowerManager.WakeLock mLaunchingActivity;
199
200 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700201 * Set when the system is going to sleep, until we have
202 * successfully paused the current activity and released our wake lock.
203 * At that point the system is allowed to actually sleep.
204 */
205 final PowerManager.WakeLock mGoingToSleep;
206
Craig Mautner93529a42013-10-04 15:03:13 -0700207 /** State of the stacks when user switched, indexed by userId. */
208 SparseBooleanArray mUserHomeInFront = new SparseBooleanArray(2);
209
Craig Mautner2219a1b2013-03-25 09:44:30 -0700210 public ActivityStackSupervisor(ActivityManagerService service, Context context,
211 Looper looper) {
Craig Mautner27084302013-03-25 08:05:25 -0700212 mService = service;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700213 mContext = context;
214 mLooper = looper;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700215 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
216 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700217 mHandler = new ActivityStackSupervisorHandler(looper);
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700218 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
219 throw new IllegalStateException("Calling must be system uid");
220 }
221 mLaunchingActivity =
222 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
223 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700224 }
225
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700226 void setWindowManager(WindowManagerService wm) {
227 mWindowManager = wm;
228 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700229 mStacks.add(mHomeStack);
Craig Mautner27084302013-03-25 08:05:25 -0700230 }
231
232 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700233 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700234 if (mDismissKeyguardOnNextActivity) {
235 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700236 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700237 }
238 }
239
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700240 ActivityStack getFocusedStack() {
Craig Mautnerf88c50f2013-04-18 19:25:12 -0700241 if (mFocusedStack == null) {
242 return mHomeStack;
243 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700244 switch (mStackState) {
245 case STACK_STATE_HOME_IN_FRONT:
246 case STACK_STATE_HOME_TO_FRONT:
247 return mHomeStack;
248 case STACK_STATE_HOME_IN_BACK:
249 case STACK_STATE_HOME_TO_BACK:
250 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700251 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700252 }
Craig Mautner20e72272013-04-01 13:45:53 -0700253 }
254
Craig Mautnerde4ef022013-04-07 19:01:33 -0700255 ActivityStack getLastStack() {
256 switch (mStackState) {
257 case STACK_STATE_HOME_IN_FRONT:
258 case STACK_STATE_HOME_TO_BACK:
259 return mHomeStack;
260 case STACK_STATE_HOME_TO_FRONT:
261 case STACK_STATE_HOME_IN_BACK:
262 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700263 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700264 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700265 }
266
Craig Mautnerde4ef022013-04-07 19:01:33 -0700267 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700268 return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
Craig Mautner20e72272013-04-01 13:45:53 -0700269 }
270
Craig Mautnerde4ef022013-04-07 19:01:33 -0700271 void moveHomeStack(boolean toFront) {
272 final boolean homeInFront = isFrontStack(mHomeStack);
273 if (homeInFront ^ toFront) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700274 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
275 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
276 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700277 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
278 }
279 }
280
Craig Mautner8e569572013-10-11 17:36:59 -0700281 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700282 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700283 mHomeStack.moveHomeTaskToTop();
284 }
285
286 boolean resumeHomeActivity(ActivityRecord prev) {
287 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700288 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700289 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700290 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700291 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700292 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700293 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700294 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700295 }
296 return mService.startHomeActivityLocked(mCurrentUser);
297 }
298
Craig Mautner27084302013-03-25 08:05:25 -0700299 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700300 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700301 mDismissKeyguardOnNextActivity = dismiss;
302 }
303
Craig Mautner8d341ef2013-03-26 09:03:27 -0700304 TaskRecord anyTaskForIdLocked(int id) {
305 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
306 ActivityStack stack = mStacks.get(stackNdx);
307 TaskRecord task = stack.taskForIdLocked(id);
308 if (task != null) {
309 return task;
310 }
311 }
312 return null;
313 }
314
Craig Mautner6170f732013-04-02 13:05:23 -0700315 ActivityRecord isInAnyStackLocked(IBinder token) {
316 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
317 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
318 if (r != null) {
319 return r;
320 }
321 }
322 return null;
323 }
324
Craig Mautner8d341ef2013-03-26 09:03:27 -0700325 int getNextTaskId() {
326 do {
327 mCurTaskId++;
328 if (mCurTaskId <= 0) {
329 mCurTaskId = 1;
330 }
331 } while (anyTaskForIdLocked(mCurTaskId) != null);
332 return mCurTaskId;
333 }
334
Craig Mautnerde4ef022013-04-07 19:01:33 -0700335 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700336 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700337 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700338 final ActivityRecord r = stack.mResumedActivity;
339 if (r != null && r.task == task) {
340 stack.mResumedActivity = null;
341 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700342 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700343 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700344 mStacks.remove(stack);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700345 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700346 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700347 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Craig Mautnerac6f8432013-07-17 13:24:59 -0700348 if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700349 // If this is the last app stack, set mFocusedStack to null.
Craig Mautner29219d92013-04-16 20:19:12 -0700350 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700351 }
352 }
353 }
354
355 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700356 ActivityStack stack = getFocusedStack();
357 if (stack == null) {
358 return null;
359 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700360 ActivityRecord resumedActivity = stack.mResumedActivity;
361 if (resumedActivity == null || resumedActivity.app == null) {
362 resumedActivity = stack.mPausingActivity;
363 if (resumedActivity == null || resumedActivity.app == null) {
364 resumedActivity = stack.topRunningActivityLocked(null);
365 }
366 }
367 return resumedActivity;
368 }
369
Craig Mautner20e72272013-04-01 13:45:53 -0700370 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
371 boolean didSomething = false;
372 final String processName = app.processName;
373 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
374 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner858d8a62013-04-23 17:08:34 -0700375 if (!isFrontStack(stack)) {
376 continue;
377 }
Craig Mautner20e72272013-04-01 13:45:53 -0700378 ActivityRecord hr = stack.topRunningActivityLocked(null);
379 if (hr != null) {
380 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
381 && processName.equals(hr.processName)) {
382 try {
383 if (headless) {
384 Slog.e(TAG, "Starting activities not supported on headless device: "
385 + hr);
Craig Mautner2420ead2013-04-01 17:13:20 -0700386 } else if (realStartActivityLocked(hr, app, true, true)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700387 didSomething = true;
388 }
389 } catch (Exception e) {
390 Slog.w(TAG, "Exception in new application when starting activity "
391 + hr.intent.getComponent().flattenToShortString(), e);
392 throw e;
393 }
Craig Mautner20e72272013-04-01 13:45:53 -0700394 }
395 }
396 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700397 if (!didSomething) {
398 ensureActivitiesVisibleLocked(null, 0);
399 }
Craig Mautner20e72272013-04-01 13:45:53 -0700400 return didSomething;
401 }
402
403 boolean allResumedActivitiesIdle() {
404 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700405 final ActivityStack stack = mStacks.get(stackNdx);
406 if (!isFrontStack(stack)) {
407 continue;
408 }
409 final ActivityRecord resumedActivity = stack.mResumedActivity;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -0700410 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner20e72272013-04-01 13:45:53 -0700411 return false;
412 }
413 }
414 return true;
415 }
416
Craig Mautnerde4ef022013-04-07 19:01:33 -0700417 boolean allResumedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700418 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
419 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner967212c2013-04-13 21:10:58 -0700420 if (isFrontStack(stack)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700421 final ActivityRecord r = stack.mResumedActivity;
422 if (r != null && r.state != ActivityState.RESUMED) {
423 return false;
424 }
425 }
426 }
427 // TODO: Not sure if this should check if all Paused are complete too.
428 switch (mStackState) {
429 case STACK_STATE_HOME_TO_BACK:
Craig Mautner76ea2242013-05-15 11:40:05 -0700430 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
431 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
432 stackStateToString(STACK_STATE_HOME_IN_BACK));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700433 mStackState = STACK_STATE_HOME_IN_BACK;
434 break;
435 case STACK_STATE_HOME_TO_FRONT:
Craig Mautner76ea2242013-05-15 11:40:05 -0700436 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
437 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
438 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700439 mStackState = STACK_STATE_HOME_IN_FRONT;
440 break;
441 }
442 return true;
443 }
444
445 boolean allResumedActivitiesVisible() {
446 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
447 final ActivityStack stack = mStacks.get(stackNdx);
448 final ActivityRecord r = stack.mResumedActivity;
449 if (r != null && (!r.nowVisible || r.waitingVisible)) {
450 return false;
451 }
452 }
453 return true;
454 }
455
Craig Mautner2acc3892013-09-23 10:28:14 -0700456 /**
457 * Pause all activities in either all of the stacks or just the back stacks.
458 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700459 * @return true if any activity was paused as a result of this call.
460 */
Craig Mautner5314a402013-09-26 12:40:16 -0700461 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700462 boolean someActivityPaused = false;
463 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
464 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner5314a402013-09-26 12:40:16 -0700465 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
466 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
Craig Mautnerac6f8432013-07-17 13:24:59 -0700467 " mResumedActivity=" + stack.mResumedActivity);
Craig Mautnercf910b02013-04-23 11:23:27 -0700468 stack.startPausingLocked(userLeaving, false);
469 someActivityPaused = true;
470 }
471 }
472 return someActivityPaused;
473 }
474
Craig Mautnerde4ef022013-04-07 19:01:33 -0700475 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700476 boolean pausing = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700477 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
478 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner69ada552013-04-18 13:51:51 -0700479 final ActivityRecord r = stack.mPausingActivity;
480 if (r != null && r.state != ActivityState.PAUSED
481 && r.state != ActivityState.STOPPED
482 && r.state != ActivityState.STOPPING) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700483 if (DEBUG_STATES) {
484 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
485 pausing = false;
486 } else {
487 return false;
488 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700489 }
490 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700491 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700492 }
493
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700494 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700495 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700496 WaitResult w = mWaitingActivityVisible.get(i);
497 w.timeout = false;
498 if (r != null) {
499 w.who = new ComponentName(r.info.packageName, r.info.name);
500 }
501 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
502 w.thisTime = w.totalTime;
503 }
504 mService.notifyAll();
505 dismissKeyguard();
506 }
507
508 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
509 long thisTime, long totalTime) {
510 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700511 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700512 w.timeout = timeout;
513 if (r != null) {
514 w.who = new ComponentName(r.info.packageName, r.info.name);
515 }
516 w.thisTime = thisTime;
517 w.totalTime = totalTime;
518 }
519 mService.notifyAll();
520 }
521
Craig Mautner29219d92013-04-16 20:19:12 -0700522 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700523 final ActivityStack focusedStack = getFocusedStack();
524 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
525 if (r != null) {
526 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700527 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700528
Craig Mautner29219d92013-04-16 20:19:12 -0700529 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
530 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700531 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700532 r = stack.topRunningActivityLocked(null);
533 if (r != null) {
534 return r;
535 }
536 }
537 }
538 return null;
539 }
540
Craig Mautner20e72272013-04-01 13:45:53 -0700541 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
542 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
543 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700544
545 // Gather all of the running tasks for each stack into runningTaskLists.
546 final int numStacks = mStacks.size();
547 ArrayList<RunningTaskInfo>[] runningTaskLists = new ArrayList[numStacks];
548 for (int stackNdx = numStacks - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner20e72272013-04-01 13:45:53 -0700549 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700550 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
551 runningTaskLists[stackNdx] = stackTaskList;
552 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700553 if (isFrontStack(stack)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700554 r = ar;
555 }
556 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700557
558 // The lists are already sorted from most recent to oldest. Just pull the most recent off
559 // each list and add it to list. Stop when all lists are empty or maxNum reached.
560 while (maxNum > 0) {
561 long mostRecentActiveTime = Long.MIN_VALUE;
562 ArrayList<RunningTaskInfo> selectedStackList = null;
563 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
564 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists[stackNdx];
565 if (!stackTaskList.isEmpty()) {
566 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
567 if (lastActiveTime > mostRecentActiveTime) {
568 mostRecentActiveTime = lastActiveTime;
569 selectedStackList = stackTaskList;
570 }
571 }
572 }
573 if (selectedStackList != null) {
574 list.add(selectedStackList.remove(0));
575 --maxNum;
576 } else {
577 break;
578 }
579 }
580
Craig Mautner20e72272013-04-01 13:45:53 -0700581 return r;
582 }
583
Craig Mautner23ac33b2013-04-01 16:26:35 -0700584 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
585 String profileFile, ParcelFileDescriptor profileFd, int userId) {
586 // Collect information about the target of the Intent.
587 ActivityInfo aInfo;
588 try {
589 ResolveInfo rInfo =
590 AppGlobals.getPackageManager().resolveIntent(
591 intent, resolvedType,
592 PackageManager.MATCH_DEFAULT_ONLY
593 | ActivityManagerService.STOCK_PM_FLAGS, userId);
594 aInfo = rInfo != null ? rInfo.activityInfo : null;
595 } catch (RemoteException e) {
596 aInfo = null;
597 }
598
599 if (aInfo != null) {
600 // Store the found target back into the intent, because now that
601 // we have it we never want to do this again. For example, if the
602 // user navigates back to this point in the history, we should
603 // always restart the exact same activity.
604 intent.setComponent(new ComponentName(
605 aInfo.applicationInfo.packageName, aInfo.name));
606
607 // Don't debug things in the system process
608 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
609 if (!aInfo.processName.equals("system")) {
610 mService.setDebugApp(aInfo.processName, true, false);
611 }
612 }
613
614 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
615 if (!aInfo.processName.equals("system")) {
616 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
617 }
618 }
619
620 if (profileFile != null) {
621 if (!aInfo.processName.equals("system")) {
622 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
623 profileFile, profileFd,
624 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
625 }
626 }
627 }
628 return aInfo;
629 }
630
Craig Mautner2219a1b2013-03-25 09:44:30 -0700631 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700632 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700633 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700634 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700635 }
636
Craig Mautner23ac33b2013-04-01 16:26:35 -0700637 final int startActivityMayWait(IApplicationThread caller, int callingUid,
638 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
639 String resultWho, int requestCode, int startFlags, String profileFile,
640 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
641 Bundle options, int userId) {
642 // Refuse possible leaked file descriptors
643 if (intent != null && intent.hasFileDescriptors()) {
644 throw new IllegalArgumentException("File descriptors passed in Intent");
645 }
646 boolean componentSpecified = intent.getComponent() != null;
647
648 // Don't modify the client's object!
649 intent = new Intent(intent);
650
651 // Collect information about the target of the Intent.
652 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
653 profileFile, profileFd, userId);
654
655 synchronized (mService) {
656 int callingPid;
657 if (callingUid >= 0) {
658 callingPid = -1;
659 } else if (caller == null) {
660 callingPid = Binder.getCallingPid();
661 callingUid = Binder.getCallingUid();
662 } else {
663 callingPid = callingUid = -1;
664 }
665
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700666 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700667 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700668 && mService.mConfiguration.diff(config) != 0;
669 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700670 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700671
672 final long origId = Binder.clearCallingIdentity();
673
674 if (aInfo != null &&
675 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
676 // This may be a heavy-weight process! Check to see if we already
677 // have another, different heavy-weight process running.
678 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
679 if (mService.mHeavyWeightProcess != null &&
680 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
681 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700682 int realCallingUid = callingUid;
683 if (caller != null) {
684 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
685 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700686 realCallingUid = callerApp.info.uid;
687 } else {
688 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700689 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700690 + intent.toString());
691 ActivityOptions.abort(options);
692 return ActivityManager.START_PERMISSION_DENIED;
693 }
694 }
695
696 IIntentSender target = mService.getIntentSenderLocked(
697 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
698 realCallingUid, userId, null, null, 0, new Intent[] { intent },
699 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
700 | PendingIntent.FLAG_ONE_SHOT, null);
701
702 Intent newIntent = new Intent();
703 if (requestCode >= 0) {
704 // Caller is requesting a result.
705 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
706 }
707 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
708 new IntentSender(target));
709 if (mService.mHeavyWeightProcess.activities.size() > 0) {
710 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
711 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
712 hist.packageName);
713 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
714 hist.task.taskId);
715 }
716 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
717 aInfo.packageName);
718 newIntent.setFlags(intent.getFlags());
719 newIntent.setClassName("android",
720 HeavyWeightSwitcherActivity.class.getName());
721 intent = newIntent;
722 resolvedType = null;
723 caller = null;
724 callingUid = Binder.getCallingUid();
725 callingPid = Binder.getCallingPid();
726 componentSpecified = true;
727 try {
728 ResolveInfo rInfo =
729 AppGlobals.getPackageManager().resolveIntent(
730 intent, null,
731 PackageManager.MATCH_DEFAULT_ONLY
732 | ActivityManagerService.STOCK_PM_FLAGS, userId);
733 aInfo = rInfo != null ? rInfo.activityInfo : null;
734 aInfo = mService.getActivityInfoForUser(aInfo, userId);
735 } catch (RemoteException e) {
736 aInfo = null;
737 }
738 }
739 }
740 }
741
Craig Mautner6170f732013-04-02 13:05:23 -0700742 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700743 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
744 callingPackage, startFlags, options, componentSpecified, null);
745
Craig Mautnerde4ef022013-04-07 19:01:33 -0700746 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700747 // If the caller also wants to switch to a new configuration,
748 // do so now. This allows a clean switch, as we are waiting
749 // for the current activity to pause (so we will not destroy
750 // it), and have not yet started the next activity.
751 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
752 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700753 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700754 if (DEBUG_CONFIGURATION) Slog.v(TAG,
755 "Updating to new configuration after starting activity.");
756 mService.updateConfigurationLocked(config, null, false, false);
757 }
758
759 Binder.restoreCallingIdentity(origId);
760
761 if (outResult != null) {
762 outResult.result = res;
763 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700764 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700765 do {
766 try {
767 mService.wait();
768 } catch (InterruptedException e) {
769 }
770 } while (!outResult.timeout && outResult.who == null);
771 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700772 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700773 if (r.nowVisible) {
774 outResult.timeout = false;
775 outResult.who = new ComponentName(r.info.packageName, r.info.name);
776 outResult.totalTime = 0;
777 outResult.thisTime = 0;
778 } else {
779 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700780 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700781 do {
782 try {
783 mService.wait();
784 } catch (InterruptedException e) {
785 }
786 } while (!outResult.timeout && outResult.who == null);
787 }
788 }
789 }
790
791 return res;
792 }
793 }
794
795 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
796 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
797 Bundle options, int userId) {
798 if (intents == null) {
799 throw new NullPointerException("intents is null");
800 }
801 if (resolvedTypes == null) {
802 throw new NullPointerException("resolvedTypes is null");
803 }
804 if (intents.length != resolvedTypes.length) {
805 throw new IllegalArgumentException("intents are length different than resolvedTypes");
806 }
807
Craig Mautner23ac33b2013-04-01 16:26:35 -0700808
809 int callingPid;
810 if (callingUid >= 0) {
811 callingPid = -1;
812 } else if (caller == null) {
813 callingPid = Binder.getCallingPid();
814 callingUid = Binder.getCallingUid();
815 } else {
816 callingPid = callingUid = -1;
817 }
818 final long origId = Binder.clearCallingIdentity();
819 try {
820 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700821 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700822 for (int i=0; i<intents.length; i++) {
823 Intent intent = intents[i];
824 if (intent == null) {
825 continue;
826 }
827
828 // Refuse possible leaked file descriptors
829 if (intent != null && intent.hasFileDescriptors()) {
830 throw new IllegalArgumentException("File descriptors passed in Intent");
831 }
832
833 boolean componentSpecified = intent.getComponent() != null;
834
835 // Don't modify the client's object!
836 intent = new Intent(intent);
837
838 // Collect information about the target of the Intent.
839 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
840 0, null, null, userId);
841 // TODO: New, check if this is correct
842 aInfo = mService.getActivityInfoForUser(aInfo, userId);
843
844 if (aInfo != null &&
845 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
846 != 0) {
847 throw new IllegalArgumentException(
848 "FLAG_CANT_SAVE_STATE not supported here");
849 }
850
851 Bundle theseOptions;
852 if (options != null && i == intents.length-1) {
853 theseOptions = options;
854 } else {
855 theseOptions = null;
856 }
Craig Mautner6170f732013-04-02 13:05:23 -0700857 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700858 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
859 0, theseOptions, componentSpecified, outActivity);
860 if (res < 0) {
861 return res;
862 }
863
864 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
865 }
866 }
867 } finally {
868 Binder.restoreCallingIdentity(origId);
869 }
870
871 return ActivityManager.START_SUCCESS;
872 }
873
Craig Mautner2420ead2013-04-01 17:13:20 -0700874 final boolean realStartActivityLocked(ActivityRecord r,
875 ProcessRecord app, boolean andResume, boolean checkConfig)
876 throws RemoteException {
877
878 r.startFreezingScreenLocked(app, 0);
Craig Mautner323f7802013-10-01 21:16:22 -0700879 if (true) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700880 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700881
882 // schedule launch ticks to collect information about slow apps.
883 r.startLaunchTickingLocked();
884
885 // Have the window manager re-evaluate the orientation of
886 // the screen based on the new activity order. Note that
887 // as a result of this, it can call back into the activity
888 // manager with a new orientation. We don't care about that,
889 // because the activity is not currently running so we are
890 // just restarting it anyway.
891 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700892 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700893 mService.mConfiguration,
894 r.mayFreezeScreenLocked(app) ? r.appToken : null);
895 mService.updateConfigurationLocked(config, r, false, false);
896 }
897
898 r.app = app;
899 app.waitingToKill = null;
900 r.launchCount++;
901 r.lastLaunchTime = SystemClock.uptimeMillis();
902
903 if (localLOGV) Slog.v(TAG, "Launching: " + r);
904
905 int idx = app.activities.indexOf(r);
906 if (idx < 0) {
907 app.activities.add(r);
908 }
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700909 mService.updateLruProcessLocked(app, true, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700910
911 final ActivityStack stack = r.task.stack;
912 try {
913 if (app.thread == null) {
914 throw new RemoteException();
915 }
916 List<ResultInfo> results = null;
917 List<Intent> newIntents = null;
918 if (andResume) {
919 results = r.results;
920 newIntents = r.newIntents;
921 }
922 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
923 + " icicle=" + r.icicle
924 + " with results=" + results + " newIntents=" + newIntents
925 + " andResume=" + andResume);
926 if (andResume) {
927 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
928 r.userId, System.identityHashCode(r),
929 r.task.taskId, r.shortComponentName);
930 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700931 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700932 // Home process is the root process of the task.
933 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700934 }
935 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
936 r.sleeping = false;
937 r.forceNewConfig = false;
938 mService.showAskCompatModeDialogLocked(r);
939 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
940 String profileFile = null;
941 ParcelFileDescriptor profileFd = null;
942 boolean profileAutoStop = false;
943 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
944 if (mService.mProfileProc == null || mService.mProfileProc == app) {
945 mService.mProfileProc = app;
946 profileFile = mService.mProfileFile;
947 profileFd = mService.mProfileFd;
948 profileAutoStop = mService.mAutoStopProfiler;
949 }
950 }
951 app.hasShownUi = true;
952 app.pendingUiClean = true;
953 if (profileFd != null) {
954 try {
955 profileFd = profileFd.dup();
956 } catch (IOException e) {
957 if (profileFd != null) {
958 try {
959 profileFd.close();
960 } catch (IOException o) {
961 }
962 profileFd = null;
963 }
964 }
965 }
Dianne Hackborna413dc02013-07-12 12:02:55 -0700966 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -0700967 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
968 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -0700969 new Configuration(mService.mConfiguration), r.compat,
970 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -0700971 mService.isNextTransitionForward(), profileFile, profileFd,
972 profileAutoStop);
973
974 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
975 // This may be a heavy-weight process! Note that the package
976 // manager will ensure that only activity can run in the main
977 // process of the .apk, which is the only thing that will be
978 // considered heavy-weight.
979 if (app.processName.equals(app.info.packageName)) {
980 if (mService.mHeavyWeightProcess != null
981 && mService.mHeavyWeightProcess != app) {
982 Slog.w(TAG, "Starting new heavy weight process " + app
983 + " when already running "
984 + mService.mHeavyWeightProcess);
985 }
986 mService.mHeavyWeightProcess = app;
987 Message msg = mService.mHandler.obtainMessage(
988 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
989 msg.obj = r;
990 mService.mHandler.sendMessage(msg);
991 }
992 }
993
994 } catch (RemoteException e) {
995 if (r.launchFailed) {
996 // This is the second time we failed -- finish activity
997 // and give up.
998 Slog.e(TAG, "Second failure launching "
999 + r.intent.getComponent().flattenToShortString()
1000 + ", giving up", e);
1001 mService.appDiedLocked(app, app.pid, app.thread);
1002 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1003 "2nd-crash", false);
1004 return false;
1005 }
1006
1007 // This is the first time we failed -- restart process and
1008 // retry.
1009 app.activities.remove(r);
1010 throw e;
1011 }
1012
1013 r.launchFailed = false;
1014 if (stack.updateLRUListLocked(r)) {
1015 Slog.w(TAG, "Activity " + r
1016 + " being launched, but already in LRU list");
1017 }
1018
1019 if (andResume) {
1020 // As part of the process of launching, ActivityThread also performs
1021 // a resume.
1022 stack.minimalResumeActivityLocked(r);
1023 } else {
1024 // This activity is not starting in the resumed state... which
1025 // should look like we asked it to pause+stop (but remain visible),
1026 // and it has done so and reported back the current icicle and
1027 // other state.
1028 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1029 + " (starting in stopped state)");
1030 r.state = ActivityState.STOPPED;
1031 r.stopped = true;
1032 }
1033
1034 // Launch the new version setup screen if needed. We do this -after-
1035 // launching the initial activity (that is, home), so that it can have
1036 // a chance to initialize itself while in the background, making the
1037 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001038 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001039 mService.startSetupActivityLocked();
1040 }
1041
1042 return true;
1043 }
1044
Craig Mautnere79d42682013-04-01 19:01:53 -07001045 void startSpecificActivityLocked(ActivityRecord r,
1046 boolean andResume, boolean checkConfig) {
1047 // Is this activity's application already running?
1048 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001049 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001050
1051 r.task.stack.setLaunchTime(r);
1052
1053 if (app != null && app.thread != null) {
1054 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001055 app.addPackage(r.info.packageName, mService.mProcessStats);
Craig Mautnere79d42682013-04-01 19:01:53 -07001056 realStartActivityLocked(r, app, andResume, checkConfig);
1057 return;
1058 } catch (RemoteException e) {
1059 Slog.w(TAG, "Exception when starting activity "
1060 + r.intent.getComponent().flattenToShortString(), e);
1061 }
1062
1063 // If a dead object exception was thrown -- fall through to
1064 // restart the application.
1065 }
1066
1067 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001068 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001069 }
1070
Craig Mautner6170f732013-04-02 13:05:23 -07001071 final int startActivityLocked(IApplicationThread caller,
1072 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1073 String resultWho, int requestCode,
1074 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1075 boolean componentSpecified, ActivityRecord[] outActivity) {
1076 int err = ActivityManager.START_SUCCESS;
1077
1078 ProcessRecord callerApp = null;
1079 if (caller != null) {
1080 callerApp = mService.getRecordForAppLocked(caller);
1081 if (callerApp != null) {
1082 callingPid = callerApp.pid;
1083 callingUid = callerApp.info.uid;
1084 } else {
1085 Slog.w(TAG, "Unable to find app for caller " + caller
1086 + " (pid=" + callingPid + ") when starting: "
1087 + intent.toString());
1088 err = ActivityManager.START_PERMISSION_DENIED;
1089 }
1090 }
1091
1092 if (err == ActivityManager.START_SUCCESS) {
1093 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1094 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1095 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1096 }
1097
1098 ActivityRecord sourceRecord = null;
1099 ActivityRecord resultRecord = null;
1100 if (resultTo != null) {
1101 sourceRecord = isInAnyStackLocked(resultTo);
1102 if (DEBUG_RESULTS) Slog.v(
1103 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1104 if (sourceRecord != null) {
1105 if (requestCode >= 0 && !sourceRecord.finishing) {
1106 resultRecord = sourceRecord;
1107 }
1108 }
1109 }
1110 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1111
1112 int launchFlags = intent.getFlags();
1113
1114 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1115 && sourceRecord != null) {
1116 // Transfer the result target from the source activity to the new
1117 // one being started, including any failures.
1118 if (requestCode >= 0) {
1119 ActivityOptions.abort(options);
1120 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1121 }
1122 resultRecord = sourceRecord.resultTo;
1123 resultWho = sourceRecord.resultWho;
1124 requestCode = sourceRecord.requestCode;
1125 sourceRecord.resultTo = null;
1126 if (resultRecord != null) {
1127 resultRecord.removeResultsLocked(
1128 sourceRecord, resultWho, requestCode);
1129 }
1130 }
1131
1132 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1133 // We couldn't find a class that can handle the given Intent.
1134 // That's the end of that!
1135 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1136 }
1137
1138 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1139 // We couldn't find the specific class specified in the Intent.
1140 // Also the end of the line.
1141 err = ActivityManager.START_CLASS_NOT_FOUND;
1142 }
1143
1144 if (err != ActivityManager.START_SUCCESS) {
1145 if (resultRecord != null) {
1146 resultStack.sendActivityResultLocked(-1,
1147 resultRecord, resultWho, requestCode,
1148 Activity.RESULT_CANCELED, null);
1149 }
1150 setDismissKeyguard(false);
1151 ActivityOptions.abort(options);
1152 return err;
1153 }
1154
1155 final int startAnyPerm = mService.checkPermission(
1156 START_ANY_ACTIVITY, callingPid, callingUid);
1157 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1158 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1159 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1160 if (resultRecord != null) {
1161 resultStack.sendActivityResultLocked(-1,
1162 resultRecord, resultWho, requestCode,
1163 Activity.RESULT_CANCELED, null);
1164 }
1165 setDismissKeyguard(false);
1166 String msg;
1167 if (!aInfo.exported) {
1168 msg = "Permission Denial: starting " + intent.toString()
1169 + " from " + callerApp + " (pid=" + callingPid
1170 + ", uid=" + callingUid + ")"
1171 + " not exported from uid " + aInfo.applicationInfo.uid;
1172 } else {
1173 msg = "Permission Denial: starting " + intent.toString()
1174 + " from " + callerApp + " (pid=" + callingPid
1175 + ", uid=" + callingUid + ")"
1176 + " requires " + aInfo.permission;
1177 }
1178 Slog.w(TAG, msg);
1179 throw new SecurityException(msg);
1180 }
1181
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001182 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001183 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001184
Craig Mautner6170f732013-04-02 13:05:23 -07001185 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001186 try {
1187 // The Intent we give to the watcher has the extra data
1188 // stripped off, since it can contain private information.
1189 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001190 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001191 aInfo.applicationInfo.packageName);
1192 } catch (RemoteException e) {
1193 mService.mController = null;
1194 }
Ben Gruver5e207332013-04-03 17:41:37 -07001195 }
Craig Mautner6170f732013-04-02 13:05:23 -07001196
Ben Gruver5e207332013-04-03 17:41:37 -07001197 if (abort) {
1198 if (resultRecord != null) {
1199 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001200 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001201 }
Ben Gruver5e207332013-04-03 17:41:37 -07001202 // We pretend to the caller that it was really started, but
1203 // they will just get a cancel result.
1204 setDismissKeyguard(false);
1205 ActivityOptions.abort(options);
1206 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001207 }
1208
1209 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1210 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001211 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001212 if (outActivity != null) {
1213 outActivity[0] = r;
1214 }
1215
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001216 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001217 if (stack.mResumedActivity == null
1218 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001219 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1220 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001221 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001222 mService.mPendingActivityLaunches.add(pal);
1223 setDismissKeyguard(false);
1224 ActivityOptions.abort(options);
1225 return ActivityManager.START_SWITCHES_CANCELED;
1226 }
1227 }
1228
1229 if (mService.mDidAppSwitch) {
1230 // This is the second allowed switch since we stopped switches,
1231 // so now just generally allow switches. Use case: user presses
1232 // home (switches disabled, switch to home, mDidAppSwitch now true);
1233 // user taps a home icon (coming from home so allowed, we hit here
1234 // and now allow anyone to switch again).
1235 mService.mAppSwitchesAllowedTime = 0;
1236 } else {
1237 mService.mDidAppSwitch = true;
1238 }
1239
1240 mService.doPendingActivityLaunchesLocked(false);
1241
Craig Mautner8849a5e2013-04-02 16:41:03 -07001242 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001243
1244 if (allPausedActivitiesComplete()) {
1245 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001246 // activity start, but we are not actually doing an activity
1247 // switch... just dismiss the keyguard now, because we
1248 // probably want to see whatever is behind it.
1249 dismissKeyguard();
1250 }
1251 return err;
1252 }
1253
Craig Mautnerac6f8432013-07-17 13:24:59 -07001254 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001255 final TaskRecord task = r.task;
1256 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001257 if (task != null) {
1258 if (mFocusedStack != task.stack) {
1259 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1260 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
1261 mFocusedStack = task.stack;
1262 } else {
1263 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1264 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1265 }
1266 return mFocusedStack;
1267 }
1268
1269 if (mFocusedStack != null) {
1270 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1271 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1272 return mFocusedStack;
1273 }
1274
1275 for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1276 ActivityStack stack = mStacks.get(stackNdx);
1277 if (!stack.isHomeStack()) {
1278 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1279 "adjustStackFocus: Setting focused stack=" + stack);
1280 mFocusedStack = stack;
1281 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001282 }
1283 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001284
1285 // Time to create the first app stack for this user.
1286 int stackId = mService.createStack(-1, HOME_STACK_ID,
1287 StackBox.TASK_STACK_GOES_OVER, 1.0f);
1288 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1289 " stackId=" + stackId);
1290 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001291 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001292 }
1293 return mHomeStack;
1294 }
1295
Craig Mautner29219d92013-04-16 20:19:12 -07001296 void setFocusedStack(ActivityRecord r) {
1297 if (r == null) {
1298 return;
1299 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001300 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001301 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautnere7c58b62013-06-12 20:19:00 -07001302 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
Craig Mautner76ea2242013-05-15 11:40:05 -07001303 stackStateToString(mStackState) + " new=" +
1304 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1305 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001306 mStackState = STACK_STATE_HOME_TO_FRONT;
1307 }
1308 } else {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001309 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1310 "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
1311 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001312 mFocusedStack = r.task.stack;
1313 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001314 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1315 stackStateToString(mStackState) + " new=" +
1316 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1317 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001318 mStackState = STACK_STATE_HOME_TO_BACK;
1319 }
1320 }
1321 }
1322
Craig Mautner8849a5e2013-04-02 16:41:03 -07001323 final int startActivityUncheckedLocked(ActivityRecord r,
1324 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1325 Bundle options) {
1326 final Intent intent = r.intent;
1327 final int callingUid = r.launchedFromUid;
1328
1329 int launchFlags = intent.getFlags();
1330
Craig Mautner8849a5e2013-04-02 16:41:03 -07001331 // We'll invoke onUserLeaving before onPause only if the launching
1332 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001333 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1334 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001335
1336 // If the caller has asked not to resume at this point, we make note
1337 // of this in the record so that we can skip it when trying to find
1338 // the top running activity.
1339 if (!doResume) {
1340 r.delayedResume = true;
1341 }
1342
1343 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1344
1345 // If the onlyIfNeeded flag is set, then we can do this if the activity
1346 // being launched is the same as the one making the call... or, as
1347 // a special case, if we do not know the caller then we count the
1348 // current top activity as the caller.
1349 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1350 ActivityRecord checkedCaller = sourceRecord;
1351 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001352 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001353 }
1354 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1355 // Caller is not the same as launcher, so always needed.
1356 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1357 }
1358 }
1359
1360 if (sourceRecord == null) {
1361 // This activity is not being started from another... in this
1362 // case we -always- start a new task.
1363 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001364 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1365 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001366 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1367 }
1368 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1369 // The original activity who is starting us is running as a single
1370 // instance... this new activity it is starting must go on its
1371 // own task.
1372 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1373 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1374 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1375 // The activity being started is a single instance... it always
1376 // gets launched into its own task.
1377 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1378 }
1379
Craig Mautnerde4ef022013-04-07 19:01:33 -07001380 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001381 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001382 if (sourceRecord != null) {
1383 sourceTask = sourceRecord.task;
1384 sourceStack = sourceTask.stack;
1385 } else {
1386 sourceTask = null;
1387 sourceStack = null;
1388 }
1389
Craig Mautner8849a5e2013-04-02 16:41:03 -07001390 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1391 // For whatever reason this activity is being launched into a new
1392 // task... yet the caller has requested a result back. Well, that
1393 // is pretty messed up, so instead immediately send back a cancel
1394 // and let the new task continue launched as normal without a
1395 // dependency on its originator.
1396 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1397 r.resultTo.task.stack.sendActivityResultLocked(-1,
1398 r.resultTo, r.resultWho, r.requestCode,
1399 Activity.RESULT_CANCELED, null);
1400 r.resultTo = null;
1401 }
1402
1403 boolean addingToTask = false;
1404 boolean movedHome = false;
1405 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001406 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001407 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1408 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1409 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1410 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1411 // If bring to front is requested, and no result is requested, and
1412 // we can find a task that was started with this same
1413 // component, then instead of launching bring that one to the front.
1414 if (r.resultTo == null) {
1415 // See if there is a task to bring to the front. If this is
1416 // a SINGLE_INSTANCE activity, there can be one and only one
1417 // instance of it in the history, and it is always in its own
1418 // unique task, so we do a special search.
1419 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001420 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001421 : findActivityLocked(intent, r.info);
1422 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001423 if (r.task == null) {
1424 r.task = intentActivity.task;
1425 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001426 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001427 targetStack.mLastPausedActivity = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001428 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001429 if (intentActivity.task.intent == null) {
1430 // This task was started because of movement of
1431 // the activity based on affinity... now that we
1432 // are actually launching it, we can assign the
1433 // base intent.
1434 intentActivity.task.setIntent(intent, r.info);
1435 }
1436 // If the target task is not in the front, then we need
1437 // to bring it to the front... except... well, with
1438 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1439 // to have the same behavior as if a new instance was
1440 // being started, which means not bringing it to the front
1441 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001442 final ActivityStack lastStack = getLastStack();
1443 ActivityRecord curTop = lastStack == null?
1444 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001445 if (curTop != null && (curTop.task != intentActivity.task ||
1446 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001447 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001448 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1449 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001450 // We really do want to push this one into the
1451 // user's face, right now.
1452 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001453 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001454 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1455 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001456 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001457 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001458 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001459 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1460 options = null;
1461 }
1462 }
1463 // If the caller has requested that the target task be
1464 // reset, then do so.
1465 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1466 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1467 }
1468 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1469 // We don't need to start a new activity, and
1470 // the client said not to do anything if that
1471 // is the case, so this is it! And for paranoia, make
1472 // sure we have correctly resumed the top activity.
1473 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001474 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001475 } else {
1476 ActivityOptions.abort(options);
1477 }
Craig Mautner29219d92013-04-16 20:19:12 -07001478 if (r.task == null) Slog.v(TAG,
1479 "startActivityUncheckedLocked: task left null",
1480 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001481 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1482 }
1483 if ((launchFlags &
1484 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1485 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1486 // The caller has requested to completely replace any
1487 // existing task with its new activity. Well that should
1488 // not be too hard...
1489 reuseTask = intentActivity.task;
1490 reuseTask.performClearTaskLocked();
1491 reuseTask.setIntent(r.intent, r.info);
1492 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1493 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1494 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1495 // In this situation we want to remove all activities
1496 // from the task up to the one being started. In most
1497 // cases this means we are resetting the task to its
1498 // initial state.
1499 ActivityRecord top =
1500 intentActivity.task.performClearTaskLocked(r, launchFlags);
1501 if (top != null) {
1502 if (top.frontOfTask) {
1503 // Activity aliases may mean we use different
1504 // intents for the top activity, so make sure
1505 // the task now has the identity of the new
1506 // intent.
1507 top.task.setIntent(r.intent, r.info);
1508 }
1509 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1510 r, top.task);
1511 top.deliverNewIntentLocked(callingUid, r.intent);
1512 } else {
1513 // A special case: we need to
1514 // start the activity because it is not currently
1515 // running, and the caller has asked to clear the
1516 // current task to have this activity at the top.
1517 addingToTask = true;
1518 // Now pretend like this activity is being started
1519 // by the top of its task, so it is put in the
1520 // right place.
1521 sourceRecord = intentActivity;
1522 }
1523 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1524 // In this case the top activity on the task is the
1525 // same as the one being launched, so we take that
1526 // as a request to bring the task to the foreground.
1527 // If the top activity in the task is the root
1528 // activity, deliver this new intent to it if it
1529 // desires.
1530 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1531 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1532 && intentActivity.realActivity.equals(r.realActivity)) {
1533 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1534 intentActivity.task);
1535 if (intentActivity.frontOfTask) {
1536 intentActivity.task.setIntent(r.intent, r.info);
1537 }
1538 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1539 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1540 // In this case we are launching the root activity
1541 // of the task, but with a different intent. We
1542 // should start a new instance on top.
1543 addingToTask = true;
1544 sourceRecord = intentActivity;
1545 }
1546 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1547 // In this case an activity is being launched in to an
1548 // existing task, without resetting that task. This
1549 // is typically the situation of launching an activity
1550 // from a notification or shortcut. We want to place
1551 // the new activity on top of the current task.
1552 addingToTask = true;
1553 sourceRecord = intentActivity;
1554 } else if (!intentActivity.task.rootWasReset) {
1555 // In this case we are launching in to an existing task
1556 // that has not yet been started from its front door.
1557 // The current task has been brought to the front.
1558 // Ideally, we'd probably like to place this new task
1559 // at the bottom of its stack, but that's a little hard
1560 // to do with the current organization of the code so
1561 // for now we'll just drop it.
1562 intentActivity.task.setIntent(r.intent, r.info);
1563 }
1564 if (!addingToTask && reuseTask == null) {
1565 // We didn't do anything... but it was needed (a.k.a., client
1566 // don't use that intent!) And for paranoia, make
1567 // sure we have correctly resumed the top activity.
1568 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001569 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001570 } else {
1571 ActivityOptions.abort(options);
1572 }
Craig Mautner29219d92013-04-16 20:19:12 -07001573 if (r.task == null) Slog.v(TAG,
1574 "startActivityUncheckedLocked: task left null",
1575 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001576 return ActivityManager.START_TASK_TO_FRONT;
1577 }
1578 }
1579 }
1580 }
1581
1582 //String uri = r.intent.toURI();
1583 //Intent intent2 = new Intent(uri);
1584 //Slog.i(TAG, "Given intent: " + r.intent);
1585 //Slog.i(TAG, "URI is: " + uri);
1586 //Slog.i(TAG, "To intent: " + intent2);
1587
1588 if (r.packageName != null) {
1589 // If the activity being launched is the same as the one currently
1590 // at the top, then we need to check if it should only be launched
1591 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001592 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001593 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001594 if (top != null && r.resultTo == null) {
1595 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1596 if (top.app != null && top.app.thread != null) {
1597 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1598 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1599 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1600 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1601 top.task);
1602 // For paranoia, make sure we have correctly
1603 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001604 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001605 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001606 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001607 }
1608 ActivityOptions.abort(options);
1609 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1610 // We don't need to start a new activity, and
1611 // the client said not to do anything if that
1612 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001613 if (r.task == null) Slog.v(TAG,
1614 "startActivityUncheckedLocked: task left null",
1615 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001616 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1617 }
1618 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001619 if (r.task == null) Slog.v(TAG,
1620 "startActivityUncheckedLocked: task left null",
1621 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001622 return ActivityManager.START_DELIVERED_TO_TOP;
1623 }
1624 }
1625 }
1626 }
1627
1628 } else {
1629 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001630 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1631 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001632 }
1633 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001634 if (r.task == null) Slog.v(TAG,
1635 "startActivityUncheckedLocked: task left null",
1636 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001637 return ActivityManager.START_CLASS_NOT_FOUND;
1638 }
1639
1640 boolean newTask = false;
1641 boolean keepCurTransition = false;
1642
1643 // Should this be considered a new task?
1644 if (r.resultTo == null && !addingToTask
1645 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001646 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001647 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001648 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001649 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1650 null, true);
1651 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1652 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001653 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001654 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001655 }
1656 newTask = true;
1657 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001658 if ((launchFlags &
1659 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1660 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1661 // Caller wants to appear on home activity, so before starting
1662 // their own activity we will bring home to the front.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001663 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001664 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001665 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001666 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001667 sourceTask = sourceRecord.task;
1668 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001669 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001670 if (!addingToTask &&
1671 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1672 // In this case, we are adding the activity to an existing
1673 // task, but the caller has asked to clear that task if the
1674 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001675 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001676 keepCurTransition = true;
1677 if (top != null) {
1678 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1679 top.deliverNewIntentLocked(callingUid, r.intent);
1680 // For paranoia, make sure we have correctly
1681 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001682 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001683 if (doResume) {
1684 targetStack.resumeTopActivityLocked(null);
1685 }
1686 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001687 if (r.task == null) Slog.v(TAG,
1688 "startActivityUncheckedLocked: task left null",
1689 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001690 return ActivityManager.START_DELIVERED_TO_TOP;
1691 }
1692 } else if (!addingToTask &&
1693 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1694 // In this case, we are launching an activity in our own task
1695 // that may already be running somewhere in the history, and
1696 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001697 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001698 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001699 final TaskRecord task = top.task;
1700 task.moveActivityToFrontLocked(top);
1701 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001702 top.updateOptionsLocked(options);
1703 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001704 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001705 if (doResume) {
1706 targetStack.resumeTopActivityLocked(null);
1707 }
1708 return ActivityManager.START_DELIVERED_TO_TOP;
1709 }
1710 }
1711 // An existing activity is starting this new activity, so we want
1712 // to keep the new one in the same task as the one that is starting
1713 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001714 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001715 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1716 + " in existing task " + r.task);
1717
1718 } else {
1719 // This not being started from an existing activity, and not part
1720 // of a new task... just put it in the top task, though these days
1721 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001722 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001723 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001724 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001725 r.setTask(prev != null ? prev.task
1726 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1727 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001728 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1729 + " in new guessed " + r.task);
1730 }
1731
1732 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1733 intent, r.getUriPermissionsLocked());
1734
1735 if (newTask) {
1736 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1737 }
1738 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001739 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001740 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001741 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001742 return ActivityManager.START_SUCCESS;
1743 }
1744
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001745 void acquireLaunchWakelock() {
1746 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1747 throw new IllegalStateException("Calling must be system uid");
1748 }
1749 mLaunchingActivity.acquire();
1750 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1751 // To be safe, don't allow the wake lock to be held for too long.
1752 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1753 }
1754 }
1755
Craig Mautnerf3333272013-04-22 10:55:53 -07001756 // Checked.
1757 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1758 Configuration config) {
1759 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1760
Craig Mautnerf3333272013-04-22 10:55:53 -07001761 ArrayList<ActivityRecord> stops = null;
1762 ArrayList<ActivityRecord> finishes = null;
1763 ArrayList<UserStartedState> startingUsers = null;
1764 int NS = 0;
1765 int NF = 0;
1766 IApplicationThread sendThumbnail = null;
1767 boolean booting = false;
1768 boolean enableScreen = false;
1769 boolean activityRemoved = false;
1770
1771 ActivityRecord r = ActivityRecord.forToken(token);
1772 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001773 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1774 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001775 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1776 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001777 if (fromTimeout) {
1778 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001779 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001780
1781 // This is a hack to semi-deal with a race condition
1782 // in the client where it can be constructed with a
1783 // newer configuration from when we asked it to launch.
1784 // We'll update with whatever configuration it now says
1785 // it used to launch.
1786 if (config != null) {
1787 r.configuration = config;
1788 }
1789
1790 // We are now idle. If someone is waiting for a thumbnail from
1791 // us, we can now deliver.
1792 r.idle = true;
1793
1794 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1795 sendThumbnail = r.app.thread;
1796 r.thumbnailNeeded = false;
1797 }
1798
1799 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1800 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1801 mService.mBooted = true;
1802 enableScreen = true;
1803 }
1804 }
1805
1806 if (allResumedActivitiesIdle()) {
1807 if (r != null) {
1808 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001809 }
1810
1811 if (mLaunchingActivity.isHeld()) {
1812 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1813 if (VALIDATE_WAKE_LOCK_CALLER &&
1814 Binder.getCallingUid() != Process.myUid()) {
1815 throw new IllegalStateException("Calling must be system uid");
1816 }
1817 mLaunchingActivity.release();
1818 }
1819 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001820 }
1821
1822 // Atomically retrieve all of the other things to do.
1823 stops = processStoppingActivitiesLocked(true);
1824 NS = stops != null ? stops.size() : 0;
1825 if ((NF=mFinishingActivities.size()) > 0) {
1826 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1827 mFinishingActivities.clear();
1828 }
1829
1830 final ArrayList<ActivityRecord> thumbnails;
1831 final int NT = mCancelledThumbnails.size();
1832 if (NT > 0) {
1833 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1834 mCancelledThumbnails.clear();
1835 } else {
1836 thumbnails = null;
1837 }
1838
1839 if (isFrontStack(mHomeStack)) {
1840 booting = mService.mBooting;
1841 mService.mBooting = false;
1842 }
1843
1844 if (mStartingUsers.size() > 0) {
1845 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1846 mStartingUsers.clear();
1847 }
1848
1849 // Perform the following actions from unsynchronized state.
1850 final IApplicationThread thumbnailThread = sendThumbnail;
1851 mHandler.post(new Runnable() {
1852 @Override
1853 public void run() {
1854 if (thumbnailThread != null) {
1855 try {
1856 thumbnailThread.requestThumbnail(token);
1857 } catch (Exception e) {
1858 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1859 mService.sendPendingThumbnail(null, token, null, null, true);
1860 }
1861 }
1862
1863 // Report back to any thumbnail receivers.
1864 for (int i = 0; i < NT; i++) {
1865 ActivityRecord r = thumbnails.get(i);
1866 mService.sendPendingThumbnail(r, null, null, null, true);
1867 }
1868 }
1869 });
1870
1871 // Stop any activities that are scheduled to do so but have been
1872 // waiting for the next one to start.
1873 for (int i = 0; i < NS; i++) {
1874 r = stops.get(i);
1875 final ActivityStack stack = r.task.stack;
1876 if (r.finishing) {
1877 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1878 } else {
1879 stack.stopActivityLocked(r);
1880 }
1881 }
1882
1883 // Finish any activities that are scheduled to do so but have been
1884 // waiting for the next one to start.
1885 for (int i = 0; i < NF; i++) {
1886 r = finishes.get(i);
1887 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1888 }
1889
1890 if (booting) {
1891 mService.finishBooting();
1892 } else if (startingUsers != null) {
1893 for (int i = 0; i < startingUsers.size(); i++) {
1894 mService.finishUserSwitch(startingUsers.get(i));
1895 }
1896 }
1897
1898 mService.trimApplications();
1899 //dump();
1900 //mWindowManager.dump();
1901
1902 if (enableScreen) {
1903 mService.enableScreenAfterBoot();
1904 }
1905
1906 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001907 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001908 }
1909
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001910 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001911 }
1912
Craig Mautner8e569572013-10-11 17:36:59 -07001913 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001914 boolean hasVisibleActivities = false;
1915 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1916 hasVisibleActivities |= mStacks.get(stackNdx).handleAppDiedLocked(app);
Craig Mautner6b74cb52013-09-27 17:02:21 -07001917 }
Craig Mautner19091252013-10-05 00:03:53 -07001918 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001919 }
1920
1921 void closeSystemDialogsLocked() {
1922 final int numStacks = mStacks.size();
1923 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1924 final ActivityStack stack = mStacks.get(stackNdx);
1925 stack.closeSystemDialogsLocked();
1926 }
1927 }
1928
Craig Mautner93529a42013-10-04 15:03:13 -07001929 void removeUserLocked(int userId) {
1930 mUserHomeInFront.delete(userId);
1931 }
1932
Craig Mautner8d341ef2013-03-26 09:03:27 -07001933 /**
1934 * @return true if some activity was finished (or would have finished if doit were true).
1935 */
1936 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1937 boolean didSomething = false;
1938 final int numStacks = mStacks.size();
1939 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1940 final ActivityStack stack = mStacks.get(stackNdx);
1941 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1942 didSomething = true;
1943 }
1944 }
1945 return didSomething;
1946 }
1947
Dianne Hackborna413dc02013-07-12 12:02:55 -07001948 void updatePreviousProcessLocked(ActivityRecord r) {
1949 // Now that this process has stopped, we may want to consider
1950 // it to be the previous app to try to keep around in case
1951 // the user wants to return to it.
1952
1953 // First, found out what is currently the foreground app, so that
1954 // we don't blow away the previous app if this activity is being
1955 // hosted by the process that is actually still the foreground.
1956 ProcessRecord fgApp = null;
1957 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1958 final ActivityStack stack = mStacks.get(stackNdx);
1959 if (isFrontStack(stack)) {
1960 if (stack.mResumedActivity != null) {
1961 fgApp = stack.mResumedActivity.app;
1962 } else if (stack.mPausingActivity != null) {
1963 fgApp = stack.mPausingActivity.app;
1964 }
1965 break;
1966 }
1967 }
1968
1969 // Now set this one as the previous process, only if that really
1970 // makes sense to.
1971 if (r.app != null && fgApp != null && r.app != fgApp
1972 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07001973 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07001974 mService.mPreviousProcess = r.app;
1975 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1976 }
1977 }
1978
Craig Mautner05d29032013-05-03 13:40:13 -07001979 boolean resumeTopActivitiesLocked() {
1980 return resumeTopActivitiesLocked(null, null, null);
1981 }
1982
1983 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1984 Bundle targetOptions) {
1985 if (targetStack == null) {
1986 targetStack = getFocusedStack();
1987 }
1988 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001989 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001990 final ActivityStack stack = mStacks.get(stackNdx);
1991 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001992 if (stack == targetStack) {
1993 result = stack.resumeTopActivityLocked(target, targetOptions);
1994 } else {
1995 stack.resumeTopActivityLocked(null);
1996 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001997 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001998 }
Craig Mautner05d29032013-05-03 13:40:13 -07001999 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002000 }
2001
2002 void finishTopRunningActivityLocked(ProcessRecord app) {
2003 final int numStacks = mStacks.size();
2004 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2005 final ActivityStack stack = mStacks.get(stackNdx);
2006 stack.finishTopRunningActivityLocked(app);
2007 }
2008 }
2009
Craig Mautner8d341ef2013-03-26 09:03:27 -07002010 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2011 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2012 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002013 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
Craig Mautner1d001b62013-06-18 16:52:43 -07002014 mStacks.get(stackNdx));
Craig Mautner8d341ef2013-03-26 09:03:27 -07002015 return;
2016 }
2017 }
2018 }
2019
Craig Mautner967212c2013-04-13 21:10:58 -07002020 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002021 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2022 final ActivityStack stack = mStacks.get(stackNdx);
2023 if (stack.getStackId() == stackId) {
2024 return stack;
2025 }
2026 }
2027 return null;
2028 }
2029
Craig Mautner967212c2013-04-13 21:10:58 -07002030 ArrayList<ActivityStack> getStacks() {
2031 return new ArrayList<ActivityStack>(mStacks);
2032 }
2033
2034 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002035 while (true) {
2036 if (++mLastStackId <= HOME_STACK_ID) {
2037 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002038 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002039 if (getStack(mLastStackId) == null) {
2040 break;
2041 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002042 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002043 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
2044 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002045 }
2046
2047 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002048 final TaskRecord task = anyTaskForIdLocked(taskId);
2049 if (task == null) {
2050 return;
2051 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002052 final ActivityStack stack = getStack(stackId);
2053 if (stack == null) {
2054 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2055 return;
2056 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002057 removeTask(task);
2058 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002059 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002060 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002061 }
2062
Craig Mautnerac6f8432013-07-17 13:24:59 -07002063 ActivityRecord findTaskLocked(ActivityRecord r) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07002064 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07002065 final ActivityStack stack = mStacks.get(stackNdx);
2066 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2067 continue;
2068 }
2069 final ActivityRecord ar = stack.findTaskLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07002070 if (ar != null) {
2071 return ar;
2072 }
2073 }
2074 return null;
2075 }
2076
2077 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2078 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2079 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
2080 if (ar != null) {
2081 return ar;
2082 }
2083 }
2084 return null;
2085 }
2086
Craig Mautner8d341ef2013-03-26 09:03:27 -07002087 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002088 scheduleSleepTimeout();
2089 if (!mGoingToSleep.isHeld()) {
2090 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002091 if (mLaunchingActivity.isHeld()) {
2092 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2093 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002094 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002095 mLaunchingActivity.release();
2096 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002097 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002098 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002099 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002100 }
2101
2102 boolean shutdownLocked(int timeout) {
2103 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002104 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002105
2106 final long endTime = System.currentTimeMillis() + timeout;
2107 while (true) {
2108 boolean cantShutdown = false;
2109 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2110 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2111 }
2112 if (cantShutdown) {
2113 long timeRemaining = endTime - System.currentTimeMillis();
2114 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002115 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002116 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002117 } catch (InterruptedException e) {
2118 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002119 } else {
2120 Slog.w(TAG, "Activity manager shutdown timed out");
2121 timedout = true;
2122 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002123 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002124 } else {
2125 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002126 }
2127 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002128
2129 // Force checkReadyForSleep to complete.
2130 mSleepTimeout = true;
2131 checkReadyForSleepLocked();
2132
Craig Mautner8d341ef2013-03-26 09:03:27 -07002133 return timedout;
2134 }
2135
2136 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002137 removeSleepTimeouts();
2138 if (mGoingToSleep.isHeld()) {
2139 mGoingToSleep.release();
2140 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002141 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002142 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002143 stack.awakeFromSleepingLocked();
Craig Mautner5314a402013-09-26 12:40:16 -07002144 if (isFrontStack(stack)) {
2145 resumeTopActivitiesLocked();
2146 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002147 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002148 mGoingToSleepActivities.clear();
2149 }
2150
2151 void activitySleptLocked(ActivityRecord r) {
2152 mGoingToSleepActivities.remove(r);
2153 checkReadyForSleepLocked();
2154 }
2155
2156 void checkReadyForSleepLocked() {
2157 if (!mService.isSleepingOrShuttingDown()) {
2158 // Do not care.
2159 return;
2160 }
2161
2162 if (!mSleepTimeout) {
2163 boolean dontSleep = false;
2164 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2165 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2166 }
2167
2168 if (mStoppingActivities.size() > 0) {
2169 // Still need to tell some activities to stop; can't sleep yet.
2170 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2171 + mStoppingActivities.size() + " activities");
2172 scheduleIdleLocked();
2173 dontSleep = true;
2174 }
2175
2176 if (mGoingToSleepActivities.size() > 0) {
2177 // Still need to tell some activities to sleep; can't sleep yet.
2178 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2179 + mGoingToSleepActivities.size() + " activities");
2180 dontSleep = true;
2181 }
2182
2183 if (dontSleep) {
2184 return;
2185 }
2186 }
2187
2188 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2189 mStacks.get(stackNdx).goToSleep();
2190 }
2191
2192 removeSleepTimeouts();
2193
2194 if (mGoingToSleep.isHeld()) {
2195 mGoingToSleep.release();
2196 }
2197 if (mService.mShuttingDown) {
2198 mService.notifyAll();
2199 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002200 }
2201
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002202 boolean reportResumedActivityLocked(ActivityRecord r) {
2203 final ActivityStack stack = r.task.stack;
2204 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002205 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002206 }
2207 if (allResumedActivitiesComplete()) {
2208 ensureActivitiesVisibleLocked(null, 0);
2209 mWindowManager.executeAppTransition();
2210 return true;
2211 }
2212 return false;
2213 }
2214
Craig Mautner8d341ef2013-03-26 09:03:27 -07002215 void handleAppCrashLocked(ProcessRecord app) {
2216 final int numStacks = mStacks.size();
2217 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2218 final ActivityStack stack = mStacks.get(stackNdx);
2219 stack.handleAppCrashLocked(app);
2220 }
2221 }
2222
Craig Mautnerde4ef022013-04-07 19:01:33 -07002223 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002224 // First the front stacks. In case any are not fullscreen and are in front of home.
2225 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002226 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002227 final ActivityStack stack = mStacks.get(stackNdx);
2228 if (isFrontStack(stack)) {
2229 showHomeBehindStack =
2230 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2231 }
2232 }
2233 // Now do back stacks.
2234 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2235 final ActivityStack stack = mStacks.get(stackNdx);
2236 if (!isFrontStack(stack)) {
2237 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2238 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002239 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002240 }
2241
2242 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2243 final int numStacks = mStacks.size();
2244 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2245 final ActivityStack stack = mStacks.get(stackNdx);
2246 stack.scheduleDestroyActivities(app, false, reason);
2247 }
2248 }
2249
2250 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner93529a42013-10-04 15:03:13 -07002251 mUserHomeInFront.put(mCurrentUser, isFrontStack(mHomeStack));
2252 final boolean homeInFront = mUserHomeInFront.get(userId, true);
Craig Mautner2420ead2013-04-01 17:13:20 -07002253 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002254
Craig Mautner858d8a62013-04-23 17:08:34 -07002255 mStartingUsers.add(uss);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002256 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner93529a42013-10-04 15:03:13 -07002257 mStacks.get(stackNdx).switchUserLocked(userId);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002258 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002259
Craig Mautner93529a42013-10-04 15:03:13 -07002260 moveHomeStack(homeInFront);
2261 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002262 }
2263
Craig Mautnerde4ef022013-04-07 19:01:33 -07002264 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2265 int N = mStoppingActivities.size();
2266 if (N <= 0) return null;
2267
2268 ArrayList<ActivityRecord> stops = null;
2269
2270 final boolean nowVisible = allResumedActivitiesVisible();
2271 for (int i=0; i<N; i++) {
2272 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautner323f7802013-10-01 21:16:22 -07002273 if (true || localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002274 + nowVisible + " waitingVisible=" + s.waitingVisible
2275 + " finishing=" + s.finishing);
2276 if (s.waitingVisible && nowVisible) {
2277 mWaitingVisibleActivities.remove(s);
2278 s.waitingVisible = false;
2279 if (s.finishing) {
2280 // If this activity is finishing, it is sitting on top of
2281 // everyone else but we now know it is no longer needed...
2282 // so get rid of it. Otherwise, we need to go through the
2283 // normal flow and hide it once we determine that it is
2284 // hidden by the activities in front of it.
2285 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002286 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002287 }
2288 }
2289 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2290 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2291 if (stops == null) {
2292 stops = new ArrayList<ActivityRecord>();
2293 }
2294 stops.add(s);
2295 mStoppingActivities.remove(i);
2296 N--;
2297 i--;
2298 }
2299 }
2300
2301 return stops;
2302 }
2303
Craig Mautnercf910b02013-04-23 11:23:27 -07002304 void validateTopActivitiesLocked() {
2305 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2306 final ActivityStack stack = mStacks.get(stackNdx);
2307 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002308 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002309 if (isFrontStack(stack)) {
2310 if (r == null) {
2311 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2312 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002313 final ActivityRecord pausing = stack.mPausingActivity;
2314 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002315 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002316 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002317 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002318 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002319 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002320 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002321 }
2322 }
2323 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002324 final ActivityRecord resumed = stack.mResumedActivity;
2325 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002326 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002327 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002328 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002329 if (r != null && (state == ActivityState.INITIALIZING
2330 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002331 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002332 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002333 }
2334 }
2335 }
2336 }
2337
Craig Mautner76ea2242013-05-15 11:40:05 -07002338 private static String stackStateToString(int stackState) {
2339 switch (stackState) {
2340 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2341 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2342 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2343 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2344 default: return "Unknown stackState=" + stackState;
2345 }
2346 }
2347
Craig Mautner27084302013-03-25 08:05:25 -07002348 public void dump(PrintWriter pw, String prefix) {
2349 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2350 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002351 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002352 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2353 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautner93529a42013-10-04 15:03:13 -07002354 pw.print(prefix); pw.println("mUserHomeInFront: " + mUserHomeInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002355 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002356
Craig Mautner20e72272013-04-01 13:45:53 -07002357 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002358 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002359 }
2360
Dianne Hackborn390517b2013-05-30 15:03:32 -07002361 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2362 boolean needSep, String prefix) {
2363 if (activity != null) {
2364 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2365 if (needSep) {
2366 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002367 }
2368 pw.print(prefix);
2369 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002370 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002371 }
2372 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002373 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002374 }
2375
Craig Mautner8d341ef2013-03-26 09:03:27 -07002376 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2377 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002378 boolean printed = false;
2379 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002380 final int numStacks = mStacks.size();
2381 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2382 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002383 StringBuilder stackHeader = new StringBuilder(128);
2384 stackHeader.append(" Stack #");
2385 stackHeader.append(mStacks.indexOf(stack));
2386 stackHeader.append(":");
2387 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2388 stackHeader.toString());
2389 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2390 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002391
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002392 needSep = printed;
2393 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002394 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002395 if (pr) {
2396 printed = true;
2397 needSep = false;
2398 }
2399 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002400 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002401 if (pr) {
2402 printed = true;
2403 needSep = false;
2404 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002405 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002406 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002407 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002408 if (pr) {
2409 printed = true;
Craig Mautner0f922742013-08-06 08:44:42 -07002410 needSep = true;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002411 }
Craig Mautner0f922742013-08-06 08:44:42 -07002412 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2413 needSep, " mLastNoHistoryActivity: ");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002414 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002415 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002416 }
2417
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002418 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2419 false, dumpPackage, true, " Activities waiting to finish:", null);
2420 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2421 false, dumpPackage, true, " Activities waiting to stop:", null);
2422 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2423 false, dumpPackage, true, " Activities waiting for another to become visible:",
2424 null);
2425 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2426 false, dumpPackage, true, " Activities waiting to sleep:", null);
2427 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2428 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002429
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002430 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002431 }
2432
Dianne Hackborn390517b2013-05-30 15:03:32 -07002433 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002434 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002435 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002436 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002437 String innerPrefix = null;
2438 String[] args = null;
2439 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002440 for (int i=list.size()-1; i>=0; i--) {
2441 final ActivityRecord r = list.get(i);
2442 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2443 continue;
2444 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002445 if (innerPrefix == null) {
2446 innerPrefix = prefix + " ";
2447 args = new String[0];
2448 }
2449 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002450 final boolean full = !brief && (complete || !r.isInHistory());
2451 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002452 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002453 needNL = false;
2454 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002455 if (header1 != null) {
2456 pw.println(header1);
2457 header1 = null;
2458 }
2459 if (header2 != null) {
2460 pw.println(header2);
2461 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002462 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002463 if (lastTask != r.task) {
2464 lastTask = r.task;
2465 pw.print(prefix);
2466 pw.print(full ? "* " : " ");
2467 pw.println(lastTask);
2468 if (full) {
2469 lastTask.dump(pw, prefix + " ");
2470 } else if (complete) {
2471 // Complete + brief == give a summary. Isn't that obvious?!?
2472 if (lastTask.intent != null) {
2473 pw.print(prefix); pw.print(" ");
2474 pw.println(lastTask.intent.toInsecureStringWithClip());
2475 }
2476 }
2477 }
2478 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2479 pw.print(" #"); pw.print(i); pw.print(": ");
2480 pw.println(r);
2481 if (full) {
2482 r.dump(pw, innerPrefix);
2483 } else if (complete) {
2484 // Complete + brief == give a summary. Isn't that obvious?!?
2485 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2486 if (r.app != null) {
2487 pw.print(innerPrefix); pw.println(r.app);
2488 }
2489 }
2490 if (client && r.app != null && r.app.thread != null) {
2491 // flush anything that is already in the PrintWriter since the thread is going
2492 // to write to the file descriptor directly
2493 pw.flush();
2494 try {
2495 TransferPipe tp = new TransferPipe();
2496 try {
2497 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2498 r.appToken, innerPrefix, args);
2499 // Short timeout, since blocking here can
2500 // deadlock with the application.
2501 tp.go(fd, 2000);
2502 } finally {
2503 tp.kill();
2504 }
2505 } catch (IOException e) {
2506 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2507 } catch (RemoteException e) {
2508 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2509 }
2510 needNL = true;
2511 }
2512 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002513 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002514 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002515
Craig Mautnerf3333272013-04-22 10:55:53 -07002516 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002517 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002518 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2519 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002520 }
2521
2522 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002523 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002524 }
2525
2526 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002527 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002528 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2529 }
2530
Craig Mautner05d29032013-05-03 13:40:13 -07002531 final void scheduleResumeTopActivities() {
2532 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2533 }
2534
Craig Mautner0eea92c2013-05-16 13:35:39 -07002535 void removeSleepTimeouts() {
2536 mSleepTimeout = false;
2537 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2538 }
2539
2540 final void scheduleSleepTimeout() {
2541 removeSleepTimeouts();
2542 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2543 }
2544
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002545 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002546
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002547 public ActivityStackSupervisorHandler(Looper looper) {
2548 super(looper);
2549 }
2550
Craig Mautnerf3333272013-04-22 10:55:53 -07002551 void activityIdleInternal(ActivityRecord r) {
2552 synchronized (mService) {
2553 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2554 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002555 }
2556
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002557 @Override
2558 public void handleMessage(Message msg) {
2559 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002560 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002561 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002562 if (mService.mDidDexOpt) {
2563 mService.mDidDexOpt = false;
2564 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2565 nmsg.obj = msg.obj;
2566 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2567 return;
2568 }
2569 // We don't at this point know if the activity is fullscreen,
2570 // so we need to be conservative and assume it isn't.
2571 activityIdleInternal((ActivityRecord)msg.obj);
2572 } break;
2573 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002574 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002575 activityIdleInternal((ActivityRecord)msg.obj);
2576 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002577 case RESUME_TOP_ACTIVITY_MSG: {
2578 synchronized (mService) {
2579 resumeTopActivitiesLocked();
2580 }
2581 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002582 case SLEEP_TIMEOUT_MSG: {
2583 synchronized (mService) {
2584 if (mService.isSleepingOrShuttingDown()) {
2585 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2586 mSleepTimeout = true;
2587 checkReadyForSleepLocked();
2588 }
2589 }
2590 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002591 case LAUNCH_TIMEOUT_MSG: {
2592 if (mService.mDidDexOpt) {
2593 mService.mDidDexOpt = false;
2594 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2595 return;
2596 }
2597 synchronized (mService) {
2598 if (mLaunchingActivity.isHeld()) {
2599 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2600 if (VALIDATE_WAKE_LOCK_CALLER
2601 && Binder.getCallingUid() != Process.myUid()) {
2602 throw new IllegalStateException("Calling must be system uid");
2603 }
2604 mLaunchingActivity.release();
2605 }
2606 }
2607 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002608 }
2609 }
2610 }
Craig Mautner27084302013-03-25 08:05:25 -07002611}