blob: da9c4e8277a150e05bda099d81b856507bf257d3 [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 Mautner4f1df4f2013-10-15 15:44:14 -070071import android.util.SparseIntArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070072
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070074import com.android.internal.os.TransferPipe;
Craig Mautner6170f732013-04-02 13:05:23 -070075import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070076import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerde4ef022013-04-07 19:01:33 -070077import com.android.server.wm.StackBox;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070078import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070079
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import java.io.FileDescriptor;
81import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070082import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070083import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070084import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070085
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070086public final class ActivityStackSupervisor {
Craig Mautnerde4ef022013-04-07 19:01:33 -070087 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
88 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
89 static final boolean DEBUG_APP = DEBUG || false;
90 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnerb3370ce2013-09-19 12:02:09 -070091 static final boolean DEBUG_STATES = DEBUG || true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070092 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -070093
Craig Mautner2219a1b2013-03-25 09:44:30 -070094 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -070095
Craig Mautnerf3333272013-04-22 10:55:53 -070096 /** How long we wait until giving up on the last activity telling us it is idle. */
97 static final int IDLE_TIMEOUT = 10*1000;
98
Craig Mautner0eea92c2013-05-16 13:35:39 -070099 /** How long we can hold the sleep wake lock before giving up. */
100 static final int SLEEP_TIMEOUT = 5*1000;
101
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700102 // How long we can hold the launch wake lock before giving up.
103 static final int LAUNCH_TIMEOUT = 10*1000;
104
Craig Mautner05d29032013-05-03 13:40:13 -0700105 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
106 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
107 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700108 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700109 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
110
111 // For debugging to make sure the caller when acquiring/releasing our
112 // wake lock is the system process.
113 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700114
Craig Mautner27084302013-03-25 08:05:25 -0700115 final ActivityManagerService mService;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700116 final Context mContext;
117 final Looper mLooper;
Craig Mautner27084302013-03-25 08:05:25 -0700118
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700119 final ActivityStackSupervisorHandler mHandler;
120
121 /** Short cut */
122 WindowManagerService mWindowManager;
123
Craig Mautner27084302013-03-25 08:05:25 -0700124 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700125 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700126
Craig Mautner8d341ef2013-03-26 09:03:27 -0700127 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700128 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700129
130 /** Task identifier that activities are currently being started in. Incremented each time a
131 * new task is created. */
132 private int mCurTaskId = 0;
133
Craig Mautner2420ead2013-04-01 17:13:20 -0700134 /** The current user */
135 private int mCurrentUser;
136
Craig Mautner8d341ef2013-03-26 09:03:27 -0700137 /** The stack containing the launcher app */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700138 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700139
Craig Mautnerde4ef022013-04-07 19:01:33 -0700140 /** The non-home stack currently receiving input or launching the next activity. If home is
Craig Mautner41c0f352013-05-28 08:39:25 -0700141 * in front then mHomeStack overrides mFocusedStack.
142 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
Craig Mautner29219d92013-04-16 20:19:12 -0700143 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700144
145 /** All the non-launcher stacks */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700146 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
147
Craig Mautnerde4ef022013-04-07 19:01:33 -0700148 private static final int STACK_STATE_HOME_IN_FRONT = 0;
149 private static final int STACK_STATE_HOME_TO_BACK = 1;
150 private static final int STACK_STATE_HOME_IN_BACK = 2;
151 private static final int STACK_STATE_HOME_TO_FRONT = 3;
152 private int mStackState = STACK_STATE_HOME_IN_FRONT;
153
154 /** List of activities that are waiting for a new activity to become visible before completing
155 * whatever operation they are supposed to do. */
156 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
157
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700158 /** List of processes waiting to find out about the next visible activity. */
159 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
160 new ArrayList<IActivityManager.WaitResult>();
161
162 /** List of processes waiting to find out about the next launched activity. */
163 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
164 new ArrayList<IActivityManager.WaitResult>();
165
Craig Mautnerde4ef022013-04-07 19:01:33 -0700166 /** List of activities that are ready to be stopped, but waiting for the next activity to
167 * settle down before doing so. */
168 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
169
Craig Mautnerf3333272013-04-22 10:55:53 -0700170 /** List of activities that are ready to be finished, but waiting for the previous activity to
171 * settle down before doing so. It contains ActivityRecord objects. */
172 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
173
Craig Mautner0eea92c2013-05-16 13:35:39 -0700174 /** List of activities that are in the process of going to sleep. */
175 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
176
Craig Mautnerf3333272013-04-22 10:55:53 -0700177 /** List of ActivityRecord objects that have been finished and must still report back to a
178 * pending thumbnail receiver. */
179 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
180
181 /** Used on user changes */
182 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
183
Craig Mautnerde4ef022013-04-07 19:01:33 -0700184 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
185 * is being brought in front of us. */
186 boolean mUserLeaving = false;
187
Craig Mautner0eea92c2013-05-16 13:35:39 -0700188 /** Set when we have taken too long waiting to go to sleep. */
189 boolean mSleepTimeout = false;
190
191 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700192 * We don't want to allow the device to go to sleep while in the process
193 * of launching an activity. This is primarily to allow alarm intent
194 * receivers to launch an activity and get that to run before the device
195 * goes back to sleep.
196 */
197 final PowerManager.WakeLock mLaunchingActivity;
198
199 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700200 * Set when the system is going to sleep, until we have
201 * successfully paused the current activity and released our wake lock.
202 * At that point the system is allowed to actually sleep.
203 */
204 final PowerManager.WakeLock mGoingToSleep;
205
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700206 /** Stack id of the front stack when user switched, indexed by userId. */
207 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700208
Craig Mautner2219a1b2013-03-25 09:44:30 -0700209 public ActivityStackSupervisor(ActivityManagerService service, Context context,
210 Looper looper) {
Craig Mautner27084302013-03-25 08:05:25 -0700211 mService = service;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700212 mContext = context;
213 mLooper = looper;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700214 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
215 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700216 mHandler = new ActivityStackSupervisorHandler(looper);
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700217 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
218 throw new IllegalStateException("Calling must be system uid");
219 }
220 mLaunchingActivity =
221 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
222 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700223 }
224
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700225 void setWindowManager(WindowManagerService wm) {
226 mWindowManager = wm;
227 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700228 mStacks.add(mHomeStack);
Craig Mautner27084302013-03-25 08:05:25 -0700229 }
230
231 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700232 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700233 if (mDismissKeyguardOnNextActivity) {
234 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700235 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700236 }
237 }
238
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700239 ActivityStack getFocusedStack() {
Craig Mautnerf88c50f2013-04-18 19:25:12 -0700240 if (mFocusedStack == null) {
241 return mHomeStack;
242 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700243 switch (mStackState) {
244 case STACK_STATE_HOME_IN_FRONT:
245 case STACK_STATE_HOME_TO_FRONT:
246 return mHomeStack;
247 case STACK_STATE_HOME_IN_BACK:
248 case STACK_STATE_HOME_TO_BACK:
249 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700250 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700251 }
Craig Mautner20e72272013-04-01 13:45:53 -0700252 }
253
Craig Mautnerde4ef022013-04-07 19:01:33 -0700254 ActivityStack getLastStack() {
255 switch (mStackState) {
256 case STACK_STATE_HOME_IN_FRONT:
257 case STACK_STATE_HOME_TO_BACK:
258 return mHomeStack;
259 case STACK_STATE_HOME_TO_FRONT:
260 case STACK_STATE_HOME_IN_BACK:
261 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700262 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700263 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700264 }
265
Craig Mautnerde4ef022013-04-07 19:01:33 -0700266 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700267 return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
Craig Mautner20e72272013-04-01 13:45:53 -0700268 }
269
Craig Mautnerde4ef022013-04-07 19:01:33 -0700270 void moveHomeStack(boolean toFront) {
271 final boolean homeInFront = isFrontStack(mHomeStack);
272 if (homeInFront ^ toFront) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700273 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
274 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
275 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700276 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
277 }
278 }
279
Craig Mautner8e569572013-10-11 17:36:59 -0700280 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700281 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700282 mHomeStack.moveHomeTaskToTop();
283 }
284
285 boolean resumeHomeActivity(ActivityRecord prev) {
286 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700287 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700288 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700289 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700290 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700291 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700292 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700293 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700294 }
295 return mService.startHomeActivityLocked(mCurrentUser);
296 }
297
Craig Mautner27084302013-03-25 08:05:25 -0700298 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700299 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700300 mDismissKeyguardOnNextActivity = dismiss;
301 }
302
Craig Mautner8d341ef2013-03-26 09:03:27 -0700303 TaskRecord anyTaskForIdLocked(int id) {
304 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
305 ActivityStack stack = mStacks.get(stackNdx);
306 TaskRecord task = stack.taskForIdLocked(id);
307 if (task != null) {
308 return task;
309 }
310 }
311 return null;
312 }
313
Craig Mautner6170f732013-04-02 13:05:23 -0700314 ActivityRecord isInAnyStackLocked(IBinder token) {
315 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
316 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
317 if (r != null) {
318 return r;
319 }
320 }
321 return null;
322 }
323
Craig Mautner8d341ef2013-03-26 09:03:27 -0700324 int getNextTaskId() {
325 do {
326 mCurTaskId++;
327 if (mCurTaskId <= 0) {
328 mCurTaskId = 1;
329 }
330 } while (anyTaskForIdLocked(mCurTaskId) != null);
331 return mCurTaskId;
332 }
333
Craig Mautnerde4ef022013-04-07 19:01:33 -0700334 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700335 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700336 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700337 final ActivityRecord r = stack.mResumedActivity;
338 if (r != null && r.task == task) {
339 stack.mResumedActivity = null;
340 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700341 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700342 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700343 mStacks.remove(stack);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700344 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700345 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700346 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Craig Mautnerac6f8432013-07-17 13:24:59 -0700347 if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700348 // If this is the last app stack, set mFocusedStack to null.
Craig Mautner29219d92013-04-16 20:19:12 -0700349 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700350 }
351 }
352 }
353
354 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700355 ActivityStack stack = getFocusedStack();
356 if (stack == null) {
357 return null;
358 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700359 ActivityRecord resumedActivity = stack.mResumedActivity;
360 if (resumedActivity == null || resumedActivity.app == null) {
361 resumedActivity = stack.mPausingActivity;
362 if (resumedActivity == null || resumedActivity.app == null) {
363 resumedActivity = stack.topRunningActivityLocked(null);
364 }
365 }
366 return resumedActivity;
367 }
368
Craig Mautner20e72272013-04-01 13:45:53 -0700369 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
370 boolean didSomething = false;
371 final String processName = app.processName;
372 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
373 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner858d8a62013-04-23 17:08:34 -0700374 if (!isFrontStack(stack)) {
375 continue;
376 }
Craig Mautner20e72272013-04-01 13:45:53 -0700377 ActivityRecord hr = stack.topRunningActivityLocked(null);
378 if (hr != null) {
379 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
380 && processName.equals(hr.processName)) {
381 try {
382 if (headless) {
383 Slog.e(TAG, "Starting activities not supported on headless device: "
384 + hr);
Craig Mautner2420ead2013-04-01 17:13:20 -0700385 } else if (realStartActivityLocked(hr, app, true, true)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700386 didSomething = true;
387 }
388 } catch (Exception e) {
389 Slog.w(TAG, "Exception in new application when starting activity "
390 + hr.intent.getComponent().flattenToShortString(), e);
391 throw e;
392 }
Craig Mautner20e72272013-04-01 13:45:53 -0700393 }
394 }
395 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700396 if (!didSomething) {
397 ensureActivitiesVisibleLocked(null, 0);
398 }
Craig Mautner20e72272013-04-01 13:45:53 -0700399 return didSomething;
400 }
401
402 boolean allResumedActivitiesIdle() {
403 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700404 final ActivityStack stack = mStacks.get(stackNdx);
405 if (!isFrontStack(stack)) {
406 continue;
407 }
408 final ActivityRecord resumedActivity = stack.mResumedActivity;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -0700409 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner20e72272013-04-01 13:45:53 -0700410 return false;
411 }
412 }
413 return true;
414 }
415
Craig Mautnerde4ef022013-04-07 19:01:33 -0700416 boolean allResumedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700417 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
418 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner967212c2013-04-13 21:10:58 -0700419 if (isFrontStack(stack)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700420 final ActivityRecord r = stack.mResumedActivity;
421 if (r != null && r.state != ActivityState.RESUMED) {
422 return false;
423 }
424 }
425 }
426 // TODO: Not sure if this should check if all Paused are complete too.
427 switch (mStackState) {
428 case STACK_STATE_HOME_TO_BACK:
Craig Mautner76ea2242013-05-15 11:40:05 -0700429 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
430 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
431 stackStateToString(STACK_STATE_HOME_IN_BACK));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700432 mStackState = STACK_STATE_HOME_IN_BACK;
433 break;
434 case STACK_STATE_HOME_TO_FRONT:
Craig Mautner76ea2242013-05-15 11:40:05 -0700435 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
436 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
437 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700438 mStackState = STACK_STATE_HOME_IN_FRONT;
439 break;
440 }
441 return true;
442 }
443
444 boolean allResumedActivitiesVisible() {
445 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
446 final ActivityStack stack = mStacks.get(stackNdx);
447 final ActivityRecord r = stack.mResumedActivity;
448 if (r != null && (!r.nowVisible || r.waitingVisible)) {
449 return false;
450 }
451 }
452 return true;
453 }
454
Craig Mautner2acc3892013-09-23 10:28:14 -0700455 /**
456 * Pause all activities in either all of the stacks or just the back stacks.
457 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700458 * @return true if any activity was paused as a result of this call.
459 */
Craig Mautner5314a402013-09-26 12:40:16 -0700460 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700461 boolean someActivityPaused = false;
462 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
463 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner5314a402013-09-26 12:40:16 -0700464 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
465 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
Craig Mautnerac6f8432013-07-17 13:24:59 -0700466 " mResumedActivity=" + stack.mResumedActivity);
Craig Mautnercf910b02013-04-23 11:23:27 -0700467 stack.startPausingLocked(userLeaving, false);
468 someActivityPaused = true;
469 }
470 }
471 return someActivityPaused;
472 }
473
Craig Mautnerde4ef022013-04-07 19:01:33 -0700474 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700475 boolean pausing = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700476 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
477 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner69ada552013-04-18 13:51:51 -0700478 final ActivityRecord r = stack.mPausingActivity;
479 if (r != null && r.state != ActivityState.PAUSED
480 && r.state != ActivityState.STOPPED
481 && r.state != ActivityState.STOPPING) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700482 if (DEBUG_STATES) {
483 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
484 pausing = false;
485 } else {
486 return false;
487 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700488 }
489 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700490 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700491 }
492
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700493 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700494 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700495 WaitResult w = mWaitingActivityVisible.get(i);
496 w.timeout = false;
497 if (r != null) {
498 w.who = new ComponentName(r.info.packageName, r.info.name);
499 }
500 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
501 w.thisTime = w.totalTime;
502 }
503 mService.notifyAll();
504 dismissKeyguard();
505 }
506
507 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
508 long thisTime, long totalTime) {
509 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700510 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700511 w.timeout = timeout;
512 if (r != null) {
513 w.who = new ComponentName(r.info.packageName, r.info.name);
514 }
515 w.thisTime = thisTime;
516 w.totalTime = totalTime;
517 }
518 mService.notifyAll();
519 }
520
Craig Mautner29219d92013-04-16 20:19:12 -0700521 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700522 final ActivityStack focusedStack = getFocusedStack();
523 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
524 if (r != null) {
525 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700526 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700527
Craig Mautner29219d92013-04-16 20:19:12 -0700528 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
529 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700530 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700531 r = stack.topRunningActivityLocked(null);
532 if (r != null) {
533 return r;
534 }
535 }
536 }
537 return null;
538 }
539
Craig Mautner20e72272013-04-01 13:45:53 -0700540 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
541 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
542 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700543
544 // Gather all of the running tasks for each stack into runningTaskLists.
545 final int numStacks = mStacks.size();
546 ArrayList<RunningTaskInfo>[] runningTaskLists = new ArrayList[numStacks];
547 for (int stackNdx = numStacks - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner20e72272013-04-01 13:45:53 -0700548 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700549 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
550 runningTaskLists[stackNdx] = stackTaskList;
551 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700552 if (isFrontStack(stack)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700553 r = ar;
554 }
555 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700556
557 // The lists are already sorted from most recent to oldest. Just pull the most recent off
558 // each list and add it to list. Stop when all lists are empty or maxNum reached.
559 while (maxNum > 0) {
560 long mostRecentActiveTime = Long.MIN_VALUE;
561 ArrayList<RunningTaskInfo> selectedStackList = null;
562 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
563 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists[stackNdx];
564 if (!stackTaskList.isEmpty()) {
565 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
566 if (lastActiveTime > mostRecentActiveTime) {
567 mostRecentActiveTime = lastActiveTime;
568 selectedStackList = stackTaskList;
569 }
570 }
571 }
572 if (selectedStackList != null) {
573 list.add(selectedStackList.remove(0));
574 --maxNum;
575 } else {
576 break;
577 }
578 }
579
Craig Mautner20e72272013-04-01 13:45:53 -0700580 return r;
581 }
582
Craig Mautner23ac33b2013-04-01 16:26:35 -0700583 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
584 String profileFile, ParcelFileDescriptor profileFd, int userId) {
585 // Collect information about the target of the Intent.
586 ActivityInfo aInfo;
587 try {
588 ResolveInfo rInfo =
589 AppGlobals.getPackageManager().resolveIntent(
590 intent, resolvedType,
591 PackageManager.MATCH_DEFAULT_ONLY
592 | ActivityManagerService.STOCK_PM_FLAGS, userId);
593 aInfo = rInfo != null ? rInfo.activityInfo : null;
594 } catch (RemoteException e) {
595 aInfo = null;
596 }
597
598 if (aInfo != null) {
599 // Store the found target back into the intent, because now that
600 // we have it we never want to do this again. For example, if the
601 // user navigates back to this point in the history, we should
602 // always restart the exact same activity.
603 intent.setComponent(new ComponentName(
604 aInfo.applicationInfo.packageName, aInfo.name));
605
606 // Don't debug things in the system process
607 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
608 if (!aInfo.processName.equals("system")) {
609 mService.setDebugApp(aInfo.processName, true, false);
610 }
611 }
612
613 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
614 if (!aInfo.processName.equals("system")) {
615 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
616 }
617 }
618
619 if (profileFile != null) {
620 if (!aInfo.processName.equals("system")) {
621 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
622 profileFile, profileFd,
623 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
624 }
625 }
626 }
627 return aInfo;
628 }
629
Craig Mautner2219a1b2013-03-25 09:44:30 -0700630 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700631 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700632 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700633 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700634 }
635
Craig Mautner23ac33b2013-04-01 16:26:35 -0700636 final int startActivityMayWait(IApplicationThread caller, int callingUid,
637 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
638 String resultWho, int requestCode, int startFlags, String profileFile,
639 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
640 Bundle options, int userId) {
641 // Refuse possible leaked file descriptors
642 if (intent != null && intent.hasFileDescriptors()) {
643 throw new IllegalArgumentException("File descriptors passed in Intent");
644 }
645 boolean componentSpecified = intent.getComponent() != null;
646
647 // Don't modify the client's object!
648 intent = new Intent(intent);
649
650 // Collect information about the target of the Intent.
651 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
652 profileFile, profileFd, userId);
653
654 synchronized (mService) {
655 int callingPid;
656 if (callingUid >= 0) {
657 callingPid = -1;
658 } else if (caller == null) {
659 callingPid = Binder.getCallingPid();
660 callingUid = Binder.getCallingUid();
661 } else {
662 callingPid = callingUid = -1;
663 }
664
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700665 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700666 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700667 && mService.mConfiguration.diff(config) != 0;
668 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700669 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700670
671 final long origId = Binder.clearCallingIdentity();
672
673 if (aInfo != null &&
674 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
675 // This may be a heavy-weight process! Check to see if we already
676 // have another, different heavy-weight process running.
677 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
678 if (mService.mHeavyWeightProcess != null &&
679 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
680 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700681 int realCallingUid = callingUid;
682 if (caller != null) {
683 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
684 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700685 realCallingUid = callerApp.info.uid;
686 } else {
687 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700688 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700689 + intent.toString());
690 ActivityOptions.abort(options);
691 return ActivityManager.START_PERMISSION_DENIED;
692 }
693 }
694
695 IIntentSender target = mService.getIntentSenderLocked(
696 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
697 realCallingUid, userId, null, null, 0, new Intent[] { intent },
698 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
699 | PendingIntent.FLAG_ONE_SHOT, null);
700
701 Intent newIntent = new Intent();
702 if (requestCode >= 0) {
703 // Caller is requesting a result.
704 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
705 }
706 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
707 new IntentSender(target));
708 if (mService.mHeavyWeightProcess.activities.size() > 0) {
709 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
710 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
711 hist.packageName);
712 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
713 hist.task.taskId);
714 }
715 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
716 aInfo.packageName);
717 newIntent.setFlags(intent.getFlags());
718 newIntent.setClassName("android",
719 HeavyWeightSwitcherActivity.class.getName());
720 intent = newIntent;
721 resolvedType = null;
722 caller = null;
723 callingUid = Binder.getCallingUid();
724 callingPid = Binder.getCallingPid();
725 componentSpecified = true;
726 try {
727 ResolveInfo rInfo =
728 AppGlobals.getPackageManager().resolveIntent(
729 intent, null,
730 PackageManager.MATCH_DEFAULT_ONLY
731 | ActivityManagerService.STOCK_PM_FLAGS, userId);
732 aInfo = rInfo != null ? rInfo.activityInfo : null;
733 aInfo = mService.getActivityInfoForUser(aInfo, userId);
734 } catch (RemoteException e) {
735 aInfo = null;
736 }
737 }
738 }
739 }
740
Craig Mautner6170f732013-04-02 13:05:23 -0700741 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700742 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
743 callingPackage, startFlags, options, componentSpecified, null);
744
Craig Mautnerde4ef022013-04-07 19:01:33 -0700745 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700746 // If the caller also wants to switch to a new configuration,
747 // do so now. This allows a clean switch, as we are waiting
748 // for the current activity to pause (so we will not destroy
749 // it), and have not yet started the next activity.
750 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
751 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700752 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700753 if (DEBUG_CONFIGURATION) Slog.v(TAG,
754 "Updating to new configuration after starting activity.");
755 mService.updateConfigurationLocked(config, null, false, false);
756 }
757
758 Binder.restoreCallingIdentity(origId);
759
760 if (outResult != null) {
761 outResult.result = res;
762 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700763 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700764 do {
765 try {
766 mService.wait();
767 } catch (InterruptedException e) {
768 }
769 } while (!outResult.timeout && outResult.who == null);
770 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700771 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700772 if (r.nowVisible) {
773 outResult.timeout = false;
774 outResult.who = new ComponentName(r.info.packageName, r.info.name);
775 outResult.totalTime = 0;
776 outResult.thisTime = 0;
777 } else {
778 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700779 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700780 do {
781 try {
782 mService.wait();
783 } catch (InterruptedException e) {
784 }
785 } while (!outResult.timeout && outResult.who == null);
786 }
787 }
788 }
789
790 return res;
791 }
792 }
793
794 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
795 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
796 Bundle options, int userId) {
797 if (intents == null) {
798 throw new NullPointerException("intents is null");
799 }
800 if (resolvedTypes == null) {
801 throw new NullPointerException("resolvedTypes is null");
802 }
803 if (intents.length != resolvedTypes.length) {
804 throw new IllegalArgumentException("intents are length different than resolvedTypes");
805 }
806
Craig Mautner23ac33b2013-04-01 16:26:35 -0700807
808 int callingPid;
809 if (callingUid >= 0) {
810 callingPid = -1;
811 } else if (caller == null) {
812 callingPid = Binder.getCallingPid();
813 callingUid = Binder.getCallingUid();
814 } else {
815 callingPid = callingUid = -1;
816 }
817 final long origId = Binder.clearCallingIdentity();
818 try {
819 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700820 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700821 for (int i=0; i<intents.length; i++) {
822 Intent intent = intents[i];
823 if (intent == null) {
824 continue;
825 }
826
827 // Refuse possible leaked file descriptors
828 if (intent != null && intent.hasFileDescriptors()) {
829 throw new IllegalArgumentException("File descriptors passed in Intent");
830 }
831
832 boolean componentSpecified = intent.getComponent() != null;
833
834 // Don't modify the client's object!
835 intent = new Intent(intent);
836
837 // Collect information about the target of the Intent.
838 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
839 0, null, null, userId);
840 // TODO: New, check if this is correct
841 aInfo = mService.getActivityInfoForUser(aInfo, userId);
842
843 if (aInfo != null &&
844 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
845 != 0) {
846 throw new IllegalArgumentException(
847 "FLAG_CANT_SAVE_STATE not supported here");
848 }
849
850 Bundle theseOptions;
851 if (options != null && i == intents.length-1) {
852 theseOptions = options;
853 } else {
854 theseOptions = null;
855 }
Craig Mautner6170f732013-04-02 13:05:23 -0700856 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700857 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
858 0, theseOptions, componentSpecified, outActivity);
859 if (res < 0) {
860 return res;
861 }
862
863 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
864 }
865 }
866 } finally {
867 Binder.restoreCallingIdentity(origId);
868 }
869
870 return ActivityManager.START_SUCCESS;
871 }
872
Craig Mautner2420ead2013-04-01 17:13:20 -0700873 final boolean realStartActivityLocked(ActivityRecord r,
874 ProcessRecord app, boolean andResume, boolean checkConfig)
875 throws RemoteException {
876
877 r.startFreezingScreenLocked(app, 0);
Craig Mautner323f7802013-10-01 21:16:22 -0700878 if (true) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700879 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700880
881 // schedule launch ticks to collect information about slow apps.
882 r.startLaunchTickingLocked();
883
884 // Have the window manager re-evaluate the orientation of
885 // the screen based on the new activity order. Note that
886 // as a result of this, it can call back into the activity
887 // manager with a new orientation. We don't care about that,
888 // because the activity is not currently running so we are
889 // just restarting it anyway.
890 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700891 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700892 mService.mConfiguration,
893 r.mayFreezeScreenLocked(app) ? r.appToken : null);
894 mService.updateConfigurationLocked(config, r, false, false);
895 }
896
897 r.app = app;
898 app.waitingToKill = null;
899 r.launchCount++;
900 r.lastLaunchTime = SystemClock.uptimeMillis();
901
902 if (localLOGV) Slog.v(TAG, "Launching: " + r);
903
904 int idx = app.activities.indexOf(r);
905 if (idx < 0) {
906 app.activities.add(r);
907 }
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700908 mService.updateLruProcessLocked(app, true, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700909
910 final ActivityStack stack = r.task.stack;
911 try {
912 if (app.thread == null) {
913 throw new RemoteException();
914 }
915 List<ResultInfo> results = null;
916 List<Intent> newIntents = null;
917 if (andResume) {
918 results = r.results;
919 newIntents = r.newIntents;
920 }
921 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
922 + " icicle=" + r.icicle
923 + " with results=" + results + " newIntents=" + newIntents
924 + " andResume=" + andResume);
925 if (andResume) {
926 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
927 r.userId, System.identityHashCode(r),
928 r.task.taskId, r.shortComponentName);
929 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700930 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700931 // Home process is the root process of the task.
932 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700933 }
934 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
935 r.sleeping = false;
936 r.forceNewConfig = false;
937 mService.showAskCompatModeDialogLocked(r);
938 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
939 String profileFile = null;
940 ParcelFileDescriptor profileFd = null;
941 boolean profileAutoStop = false;
942 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
943 if (mService.mProfileProc == null || mService.mProfileProc == app) {
944 mService.mProfileProc = app;
945 profileFile = mService.mProfileFile;
946 profileFd = mService.mProfileFd;
947 profileAutoStop = mService.mAutoStopProfiler;
948 }
949 }
950 app.hasShownUi = true;
951 app.pendingUiClean = true;
952 if (profileFd != null) {
953 try {
954 profileFd = profileFd.dup();
955 } catch (IOException e) {
956 if (profileFd != null) {
957 try {
958 profileFd.close();
959 } catch (IOException o) {
960 }
961 profileFd = null;
962 }
963 }
964 }
Dianne Hackborna413dc02013-07-12 12:02:55 -0700965 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -0700966 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
967 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -0700968 new Configuration(mService.mConfiguration), r.compat,
969 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -0700970 mService.isNextTransitionForward(), profileFile, profileFd,
971 profileAutoStop);
972
973 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
974 // This may be a heavy-weight process! Note that the package
975 // manager will ensure that only activity can run in the main
976 // process of the .apk, which is the only thing that will be
977 // considered heavy-weight.
978 if (app.processName.equals(app.info.packageName)) {
979 if (mService.mHeavyWeightProcess != null
980 && mService.mHeavyWeightProcess != app) {
981 Slog.w(TAG, "Starting new heavy weight process " + app
982 + " when already running "
983 + mService.mHeavyWeightProcess);
984 }
985 mService.mHeavyWeightProcess = app;
986 Message msg = mService.mHandler.obtainMessage(
987 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
988 msg.obj = r;
989 mService.mHandler.sendMessage(msg);
990 }
991 }
992
993 } catch (RemoteException e) {
994 if (r.launchFailed) {
995 // This is the second time we failed -- finish activity
996 // and give up.
997 Slog.e(TAG, "Second failure launching "
998 + r.intent.getComponent().flattenToShortString()
999 + ", giving up", e);
1000 mService.appDiedLocked(app, app.pid, app.thread);
1001 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1002 "2nd-crash", false);
1003 return false;
1004 }
1005
1006 // This is the first time we failed -- restart process and
1007 // retry.
1008 app.activities.remove(r);
1009 throw e;
1010 }
1011
1012 r.launchFailed = false;
1013 if (stack.updateLRUListLocked(r)) {
1014 Slog.w(TAG, "Activity " + r
1015 + " being launched, but already in LRU list");
1016 }
1017
1018 if (andResume) {
1019 // As part of the process of launching, ActivityThread also performs
1020 // a resume.
1021 stack.minimalResumeActivityLocked(r);
1022 } else {
1023 // This activity is not starting in the resumed state... which
1024 // should look like we asked it to pause+stop (but remain visible),
1025 // and it has done so and reported back the current icicle and
1026 // other state.
1027 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1028 + " (starting in stopped state)");
1029 r.state = ActivityState.STOPPED;
1030 r.stopped = true;
1031 }
1032
1033 // Launch the new version setup screen if needed. We do this -after-
1034 // launching the initial activity (that is, home), so that it can have
1035 // a chance to initialize itself while in the background, making the
1036 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001037 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001038 mService.startSetupActivityLocked();
1039 }
1040
1041 return true;
1042 }
1043
Craig Mautnere79d42682013-04-01 19:01:53 -07001044 void startSpecificActivityLocked(ActivityRecord r,
1045 boolean andResume, boolean checkConfig) {
1046 // Is this activity's application already running?
1047 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001048 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001049
1050 r.task.stack.setLaunchTime(r);
1051
1052 if (app != null && app.thread != null) {
1053 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001054 app.addPackage(r.info.packageName, mService.mProcessStats);
Craig Mautnere79d42682013-04-01 19:01:53 -07001055 realStartActivityLocked(r, app, andResume, checkConfig);
1056 return;
1057 } catch (RemoteException e) {
1058 Slog.w(TAG, "Exception when starting activity "
1059 + r.intent.getComponent().flattenToShortString(), e);
1060 }
1061
1062 // If a dead object exception was thrown -- fall through to
1063 // restart the application.
1064 }
1065
1066 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001067 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001068 }
1069
Craig Mautner6170f732013-04-02 13:05:23 -07001070 final int startActivityLocked(IApplicationThread caller,
1071 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1072 String resultWho, int requestCode,
1073 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1074 boolean componentSpecified, ActivityRecord[] outActivity) {
1075 int err = ActivityManager.START_SUCCESS;
1076
1077 ProcessRecord callerApp = null;
1078 if (caller != null) {
1079 callerApp = mService.getRecordForAppLocked(caller);
1080 if (callerApp != null) {
1081 callingPid = callerApp.pid;
1082 callingUid = callerApp.info.uid;
1083 } else {
1084 Slog.w(TAG, "Unable to find app for caller " + caller
1085 + " (pid=" + callingPid + ") when starting: "
1086 + intent.toString());
1087 err = ActivityManager.START_PERMISSION_DENIED;
1088 }
1089 }
1090
1091 if (err == ActivityManager.START_SUCCESS) {
1092 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1093 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1094 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1095 }
1096
1097 ActivityRecord sourceRecord = null;
1098 ActivityRecord resultRecord = null;
1099 if (resultTo != null) {
1100 sourceRecord = isInAnyStackLocked(resultTo);
1101 if (DEBUG_RESULTS) Slog.v(
1102 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1103 if (sourceRecord != null) {
1104 if (requestCode >= 0 && !sourceRecord.finishing) {
1105 resultRecord = sourceRecord;
1106 }
1107 }
1108 }
1109 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1110
1111 int launchFlags = intent.getFlags();
1112
1113 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1114 && sourceRecord != null) {
1115 // Transfer the result target from the source activity to the new
1116 // one being started, including any failures.
1117 if (requestCode >= 0) {
1118 ActivityOptions.abort(options);
1119 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1120 }
1121 resultRecord = sourceRecord.resultTo;
1122 resultWho = sourceRecord.resultWho;
1123 requestCode = sourceRecord.requestCode;
1124 sourceRecord.resultTo = null;
1125 if (resultRecord != null) {
1126 resultRecord.removeResultsLocked(
1127 sourceRecord, resultWho, requestCode);
1128 }
1129 }
1130
1131 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1132 // We couldn't find a class that can handle the given Intent.
1133 // That's the end of that!
1134 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1135 }
1136
1137 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1138 // We couldn't find the specific class specified in the Intent.
1139 // Also the end of the line.
1140 err = ActivityManager.START_CLASS_NOT_FOUND;
1141 }
1142
1143 if (err != ActivityManager.START_SUCCESS) {
1144 if (resultRecord != null) {
1145 resultStack.sendActivityResultLocked(-1,
1146 resultRecord, resultWho, requestCode,
1147 Activity.RESULT_CANCELED, null);
1148 }
1149 setDismissKeyguard(false);
1150 ActivityOptions.abort(options);
1151 return err;
1152 }
1153
1154 final int startAnyPerm = mService.checkPermission(
1155 START_ANY_ACTIVITY, callingPid, callingUid);
1156 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1157 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1158 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1159 if (resultRecord != null) {
1160 resultStack.sendActivityResultLocked(-1,
1161 resultRecord, resultWho, requestCode,
1162 Activity.RESULT_CANCELED, null);
1163 }
1164 setDismissKeyguard(false);
1165 String msg;
1166 if (!aInfo.exported) {
1167 msg = "Permission Denial: starting " + intent.toString()
1168 + " from " + callerApp + " (pid=" + callingPid
1169 + ", uid=" + callingUid + ")"
1170 + " not exported from uid " + aInfo.applicationInfo.uid;
1171 } else {
1172 msg = "Permission Denial: starting " + intent.toString()
1173 + " from " + callerApp + " (pid=" + callingPid
1174 + ", uid=" + callingUid + ")"
1175 + " requires " + aInfo.permission;
1176 }
1177 Slog.w(TAG, msg);
1178 throw new SecurityException(msg);
1179 }
1180
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001181 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001182 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001183
Craig Mautner6170f732013-04-02 13:05:23 -07001184 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001185 try {
1186 // The Intent we give to the watcher has the extra data
1187 // stripped off, since it can contain private information.
1188 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001189 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001190 aInfo.applicationInfo.packageName);
1191 } catch (RemoteException e) {
1192 mService.mController = null;
1193 }
Ben Gruver5e207332013-04-03 17:41:37 -07001194 }
Craig Mautner6170f732013-04-02 13:05:23 -07001195
Ben Gruver5e207332013-04-03 17:41:37 -07001196 if (abort) {
1197 if (resultRecord != null) {
1198 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001199 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001200 }
Ben Gruver5e207332013-04-03 17:41:37 -07001201 // We pretend to the caller that it was really started, but
1202 // they will just get a cancel result.
1203 setDismissKeyguard(false);
1204 ActivityOptions.abort(options);
1205 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001206 }
1207
1208 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1209 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001210 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001211 if (outActivity != null) {
1212 outActivity[0] = r;
1213 }
1214
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001215 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001216 if (stack.mResumedActivity == null
1217 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001218 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1219 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001220 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001221 mService.mPendingActivityLaunches.add(pal);
1222 setDismissKeyguard(false);
1223 ActivityOptions.abort(options);
1224 return ActivityManager.START_SWITCHES_CANCELED;
1225 }
1226 }
1227
1228 if (mService.mDidAppSwitch) {
1229 // This is the second allowed switch since we stopped switches,
1230 // so now just generally allow switches. Use case: user presses
1231 // home (switches disabled, switch to home, mDidAppSwitch now true);
1232 // user taps a home icon (coming from home so allowed, we hit here
1233 // and now allow anyone to switch again).
1234 mService.mAppSwitchesAllowedTime = 0;
1235 } else {
1236 mService.mDidAppSwitch = true;
1237 }
1238
1239 mService.doPendingActivityLaunchesLocked(false);
1240
Craig Mautner8849a5e2013-04-02 16:41:03 -07001241 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001242
1243 if (allPausedActivitiesComplete()) {
1244 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001245 // activity start, but we are not actually doing an activity
1246 // switch... just dismiss the keyguard now, because we
1247 // probably want to see whatever is behind it.
1248 dismissKeyguard();
1249 }
1250 return err;
1251 }
1252
Craig Mautnerac6f8432013-07-17 13:24:59 -07001253 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001254 final TaskRecord task = r.task;
1255 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001256 if (task != null) {
1257 if (mFocusedStack != task.stack) {
1258 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1259 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
1260 mFocusedStack = task.stack;
1261 } else {
1262 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1263 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1264 }
1265 return mFocusedStack;
1266 }
1267
1268 if (mFocusedStack != null) {
1269 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1270 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1271 return mFocusedStack;
1272 }
1273
1274 for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1275 ActivityStack stack = mStacks.get(stackNdx);
1276 if (!stack.isHomeStack()) {
1277 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1278 "adjustStackFocus: Setting focused stack=" + stack);
1279 mFocusedStack = stack;
1280 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001281 }
1282 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001283
1284 // Time to create the first app stack for this user.
1285 int stackId = mService.createStack(-1, HOME_STACK_ID,
1286 StackBox.TASK_STACK_GOES_OVER, 1.0f);
1287 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1288 " stackId=" + stackId);
1289 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001290 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001291 }
1292 return mHomeStack;
1293 }
1294
Craig Mautner29219d92013-04-16 20:19:12 -07001295 void setFocusedStack(ActivityRecord r) {
1296 if (r == null) {
1297 return;
1298 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001299 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001300 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautnere7c58b62013-06-12 20:19:00 -07001301 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
Craig Mautner76ea2242013-05-15 11:40:05 -07001302 stackStateToString(mStackState) + " new=" +
1303 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1304 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001305 mStackState = STACK_STATE_HOME_TO_FRONT;
1306 }
1307 } else {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001308 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1309 "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
1310 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001311 mFocusedStack = r.task.stack;
1312 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001313 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1314 stackStateToString(mStackState) + " new=" +
1315 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1316 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001317 mStackState = STACK_STATE_HOME_TO_BACK;
1318 }
1319 }
1320 }
1321
Craig Mautner8849a5e2013-04-02 16:41:03 -07001322 final int startActivityUncheckedLocked(ActivityRecord r,
1323 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1324 Bundle options) {
1325 final Intent intent = r.intent;
1326 final int callingUid = r.launchedFromUid;
1327
1328 int launchFlags = intent.getFlags();
1329
Craig Mautner8849a5e2013-04-02 16:41:03 -07001330 // We'll invoke onUserLeaving before onPause only if the launching
1331 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001332 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1333 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001334
1335 // If the caller has asked not to resume at this point, we make note
1336 // of this in the record so that we can skip it when trying to find
1337 // the top running activity.
1338 if (!doResume) {
1339 r.delayedResume = true;
1340 }
1341
1342 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1343
1344 // If the onlyIfNeeded flag is set, then we can do this if the activity
1345 // being launched is the same as the one making the call... or, as
1346 // a special case, if we do not know the caller then we count the
1347 // current top activity as the caller.
1348 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1349 ActivityRecord checkedCaller = sourceRecord;
1350 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001351 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001352 }
1353 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1354 // Caller is not the same as launcher, so always needed.
1355 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1356 }
1357 }
1358
1359 if (sourceRecord == null) {
1360 // This activity is not being started from another... in this
1361 // case we -always- start a new task.
1362 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001363 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1364 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001365 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1366 }
1367 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1368 // The original activity who is starting us is running as a single
1369 // instance... this new activity it is starting must go on its
1370 // own task.
1371 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1372 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1373 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1374 // The activity being started is a single instance... it always
1375 // gets launched into its own task.
1376 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1377 }
1378
Craig Mautnerde4ef022013-04-07 19:01:33 -07001379 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001380 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001381 if (sourceRecord != null) {
1382 sourceTask = sourceRecord.task;
1383 sourceStack = sourceTask.stack;
1384 } else {
1385 sourceTask = null;
1386 sourceStack = null;
1387 }
1388
Craig Mautner8849a5e2013-04-02 16:41:03 -07001389 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1390 // For whatever reason this activity is being launched into a new
1391 // task... yet the caller has requested a result back. Well, that
1392 // is pretty messed up, so instead immediately send back a cancel
1393 // and let the new task continue launched as normal without a
1394 // dependency on its originator.
1395 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1396 r.resultTo.task.stack.sendActivityResultLocked(-1,
1397 r.resultTo, r.resultWho, r.requestCode,
1398 Activity.RESULT_CANCELED, null);
1399 r.resultTo = null;
1400 }
1401
1402 boolean addingToTask = false;
1403 boolean movedHome = false;
1404 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001405 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001406 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1407 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1408 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1409 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1410 // If bring to front is requested, and no result is requested, and
1411 // we can find a task that was started with this same
1412 // component, then instead of launching bring that one to the front.
1413 if (r.resultTo == null) {
1414 // See if there is a task to bring to the front. If this is
1415 // a SINGLE_INSTANCE activity, there can be one and only one
1416 // instance of it in the history, and it is always in its own
1417 // unique task, so we do a special search.
1418 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001419 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001420 : findActivityLocked(intent, r.info);
1421 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001422 if (r.task == null) {
1423 r.task = intentActivity.task;
1424 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001425 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001426 targetStack.mLastPausedActivity = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001427 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001428 if (intentActivity.task.intent == null) {
1429 // This task was started because of movement of
1430 // the activity based on affinity... now that we
1431 // are actually launching it, we can assign the
1432 // base intent.
1433 intentActivity.task.setIntent(intent, r.info);
1434 }
1435 // If the target task is not in the front, then we need
1436 // to bring it to the front... except... well, with
1437 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1438 // to have the same behavior as if a new instance was
1439 // being started, which means not bringing it to the front
1440 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001441 final ActivityStack lastStack = getLastStack();
1442 ActivityRecord curTop = lastStack == null?
1443 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001444 if (curTop != null && (curTop.task != intentActivity.task ||
1445 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001446 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001447 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1448 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001449 // We really do want to push this one into the
1450 // user's face, right now.
1451 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001452 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001453 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1454 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001455 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001456 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001457 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001458 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1459 options = null;
1460 }
1461 }
1462 // If the caller has requested that the target task be
1463 // reset, then do so.
1464 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1465 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1466 }
1467 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1468 // We don't need to start a new activity, and
1469 // the client said not to do anything if that
1470 // is the case, so this is it! And for paranoia, make
1471 // sure we have correctly resumed the top activity.
1472 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001473 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001474 } else {
1475 ActivityOptions.abort(options);
1476 }
Craig Mautner29219d92013-04-16 20:19:12 -07001477 if (r.task == null) Slog.v(TAG,
1478 "startActivityUncheckedLocked: task left null",
1479 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001480 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1481 }
1482 if ((launchFlags &
1483 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1484 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1485 // The caller has requested to completely replace any
1486 // existing task with its new activity. Well that should
1487 // not be too hard...
1488 reuseTask = intentActivity.task;
1489 reuseTask.performClearTaskLocked();
1490 reuseTask.setIntent(r.intent, r.info);
1491 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1492 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1493 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1494 // In this situation we want to remove all activities
1495 // from the task up to the one being started. In most
1496 // cases this means we are resetting the task to its
1497 // initial state.
1498 ActivityRecord top =
1499 intentActivity.task.performClearTaskLocked(r, launchFlags);
1500 if (top != null) {
1501 if (top.frontOfTask) {
1502 // Activity aliases may mean we use different
1503 // intents for the top activity, so make sure
1504 // the task now has the identity of the new
1505 // intent.
1506 top.task.setIntent(r.intent, r.info);
1507 }
1508 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1509 r, top.task);
1510 top.deliverNewIntentLocked(callingUid, r.intent);
1511 } else {
1512 // A special case: we need to
1513 // start the activity because it is not currently
1514 // running, and the caller has asked to clear the
1515 // current task to have this activity at the top.
1516 addingToTask = true;
1517 // Now pretend like this activity is being started
1518 // by the top of its task, so it is put in the
1519 // right place.
1520 sourceRecord = intentActivity;
1521 }
1522 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1523 // In this case the top activity on the task is the
1524 // same as the one being launched, so we take that
1525 // as a request to bring the task to the foreground.
1526 // If the top activity in the task is the root
1527 // activity, deliver this new intent to it if it
1528 // desires.
1529 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1530 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1531 && intentActivity.realActivity.equals(r.realActivity)) {
1532 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1533 intentActivity.task);
1534 if (intentActivity.frontOfTask) {
1535 intentActivity.task.setIntent(r.intent, r.info);
1536 }
1537 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1538 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1539 // In this case we are launching the root activity
1540 // of the task, but with a different intent. We
1541 // should start a new instance on top.
1542 addingToTask = true;
1543 sourceRecord = intentActivity;
1544 }
1545 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1546 // In this case an activity is being launched in to an
1547 // existing task, without resetting that task. This
1548 // is typically the situation of launching an activity
1549 // from a notification or shortcut. We want to place
1550 // the new activity on top of the current task.
1551 addingToTask = true;
1552 sourceRecord = intentActivity;
1553 } else if (!intentActivity.task.rootWasReset) {
1554 // In this case we are launching in to an existing task
1555 // that has not yet been started from its front door.
1556 // The current task has been brought to the front.
1557 // Ideally, we'd probably like to place this new task
1558 // at the bottom of its stack, but that's a little hard
1559 // to do with the current organization of the code so
1560 // for now we'll just drop it.
1561 intentActivity.task.setIntent(r.intent, r.info);
1562 }
1563 if (!addingToTask && reuseTask == null) {
1564 // We didn't do anything... but it was needed (a.k.a., client
1565 // don't use that intent!) And for paranoia, make
1566 // sure we have correctly resumed the top activity.
1567 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001568 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001569 } else {
1570 ActivityOptions.abort(options);
1571 }
Craig Mautner29219d92013-04-16 20:19:12 -07001572 if (r.task == null) Slog.v(TAG,
1573 "startActivityUncheckedLocked: task left null",
1574 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001575 return ActivityManager.START_TASK_TO_FRONT;
1576 }
1577 }
1578 }
1579 }
1580
1581 //String uri = r.intent.toURI();
1582 //Intent intent2 = new Intent(uri);
1583 //Slog.i(TAG, "Given intent: " + r.intent);
1584 //Slog.i(TAG, "URI is: " + uri);
1585 //Slog.i(TAG, "To intent: " + intent2);
1586
1587 if (r.packageName != null) {
1588 // If the activity being launched is the same as the one currently
1589 // at the top, then we need to check if it should only be launched
1590 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001591 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001592 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001593 if (top != null && r.resultTo == null) {
1594 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1595 if (top.app != null && top.app.thread != null) {
1596 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1597 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1598 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1599 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1600 top.task);
1601 // For paranoia, make sure we have correctly
1602 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001603 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001604 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001605 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001606 }
1607 ActivityOptions.abort(options);
1608 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1609 // We don't need to start a new activity, and
1610 // the client said not to do anything if that
1611 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001612 if (r.task == null) Slog.v(TAG,
1613 "startActivityUncheckedLocked: task left null",
1614 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001615 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1616 }
1617 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001618 if (r.task == null) Slog.v(TAG,
1619 "startActivityUncheckedLocked: task left null",
1620 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001621 return ActivityManager.START_DELIVERED_TO_TOP;
1622 }
1623 }
1624 }
1625 }
1626
1627 } else {
1628 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001629 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1630 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001631 }
1632 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001633 if (r.task == null) Slog.v(TAG,
1634 "startActivityUncheckedLocked: task left null",
1635 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001636 return ActivityManager.START_CLASS_NOT_FOUND;
1637 }
1638
1639 boolean newTask = false;
1640 boolean keepCurTransition = false;
1641
1642 // Should this be considered a new task?
1643 if (r.resultTo == null && !addingToTask
1644 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001645 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001646 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001647 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001648 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1649 null, true);
1650 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1651 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001652 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001653 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001654 }
1655 newTask = true;
1656 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001657 if ((launchFlags &
1658 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1659 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1660 // Caller wants to appear on home activity, so before starting
1661 // their own activity we will bring home to the front.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001662 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001663 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001664 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001665 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001666 sourceTask = sourceRecord.task;
1667 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001668 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001669 if (!addingToTask &&
1670 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1671 // In this case, we are adding the activity to an existing
1672 // task, but the caller has asked to clear that task if the
1673 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001674 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001675 keepCurTransition = true;
1676 if (top != null) {
1677 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1678 top.deliverNewIntentLocked(callingUid, r.intent);
1679 // For paranoia, make sure we have correctly
1680 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001681 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001682 if (doResume) {
1683 targetStack.resumeTopActivityLocked(null);
1684 }
1685 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001686 if (r.task == null) Slog.v(TAG,
1687 "startActivityUncheckedLocked: task left null",
1688 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001689 return ActivityManager.START_DELIVERED_TO_TOP;
1690 }
1691 } else if (!addingToTask &&
1692 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1693 // In this case, we are launching an activity in our own task
1694 // that may already be running somewhere in the history, and
1695 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001696 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001697 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001698 final TaskRecord task = top.task;
1699 task.moveActivityToFrontLocked(top);
1700 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001701 top.updateOptionsLocked(options);
1702 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001703 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001704 if (doResume) {
1705 targetStack.resumeTopActivityLocked(null);
1706 }
1707 return ActivityManager.START_DELIVERED_TO_TOP;
1708 }
1709 }
1710 // An existing activity is starting this new activity, so we want
1711 // to keep the new one in the same task as the one that is starting
1712 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001713 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001714 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1715 + " in existing task " + r.task);
1716
1717 } else {
1718 // This not being started from an existing activity, and not part
1719 // of a new task... just put it in the top task, though these days
1720 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001721 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001722 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001723 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001724 r.setTask(prev != null ? prev.task
1725 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1726 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001727 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1728 + " in new guessed " + r.task);
1729 }
1730
1731 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1732 intent, r.getUriPermissionsLocked());
1733
1734 if (newTask) {
1735 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1736 }
1737 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001738 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001739 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001740 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001741 return ActivityManager.START_SUCCESS;
1742 }
1743
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001744 void acquireLaunchWakelock() {
1745 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1746 throw new IllegalStateException("Calling must be system uid");
1747 }
1748 mLaunchingActivity.acquire();
1749 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1750 // To be safe, don't allow the wake lock to be held for too long.
1751 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1752 }
1753 }
1754
Craig Mautnerf3333272013-04-22 10:55:53 -07001755 // Checked.
1756 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1757 Configuration config) {
1758 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1759
Craig Mautnerf3333272013-04-22 10:55:53 -07001760 ArrayList<ActivityRecord> stops = null;
1761 ArrayList<ActivityRecord> finishes = null;
1762 ArrayList<UserStartedState> startingUsers = null;
1763 int NS = 0;
1764 int NF = 0;
1765 IApplicationThread sendThumbnail = null;
1766 boolean booting = false;
1767 boolean enableScreen = false;
1768 boolean activityRemoved = false;
1769
1770 ActivityRecord r = ActivityRecord.forToken(token);
1771 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001772 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1773 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001774 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1775 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001776 if (fromTimeout) {
1777 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001778 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001779
1780 // This is a hack to semi-deal with a race condition
1781 // in the client where it can be constructed with a
1782 // newer configuration from when we asked it to launch.
1783 // We'll update with whatever configuration it now says
1784 // it used to launch.
1785 if (config != null) {
1786 r.configuration = config;
1787 }
1788
1789 // We are now idle. If someone is waiting for a thumbnail from
1790 // us, we can now deliver.
1791 r.idle = true;
1792
1793 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1794 sendThumbnail = r.app.thread;
1795 r.thumbnailNeeded = false;
1796 }
1797
1798 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1799 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1800 mService.mBooted = true;
1801 enableScreen = true;
1802 }
1803 }
1804
1805 if (allResumedActivitiesIdle()) {
1806 if (r != null) {
1807 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001808 }
1809
1810 if (mLaunchingActivity.isHeld()) {
1811 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1812 if (VALIDATE_WAKE_LOCK_CALLER &&
1813 Binder.getCallingUid() != Process.myUid()) {
1814 throw new IllegalStateException("Calling must be system uid");
1815 }
1816 mLaunchingActivity.release();
1817 }
1818 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001819 }
1820
1821 // Atomically retrieve all of the other things to do.
1822 stops = processStoppingActivitiesLocked(true);
1823 NS = stops != null ? stops.size() : 0;
1824 if ((NF=mFinishingActivities.size()) > 0) {
1825 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1826 mFinishingActivities.clear();
1827 }
1828
1829 final ArrayList<ActivityRecord> thumbnails;
1830 final int NT = mCancelledThumbnails.size();
1831 if (NT > 0) {
1832 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1833 mCancelledThumbnails.clear();
1834 } else {
1835 thumbnails = null;
1836 }
1837
1838 if (isFrontStack(mHomeStack)) {
1839 booting = mService.mBooting;
1840 mService.mBooting = false;
1841 }
1842
1843 if (mStartingUsers.size() > 0) {
1844 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1845 mStartingUsers.clear();
1846 }
1847
1848 // Perform the following actions from unsynchronized state.
1849 final IApplicationThread thumbnailThread = sendThumbnail;
1850 mHandler.post(new Runnable() {
1851 @Override
1852 public void run() {
1853 if (thumbnailThread != null) {
1854 try {
1855 thumbnailThread.requestThumbnail(token);
1856 } catch (Exception e) {
1857 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1858 mService.sendPendingThumbnail(null, token, null, null, true);
1859 }
1860 }
1861
1862 // Report back to any thumbnail receivers.
1863 for (int i = 0; i < NT; i++) {
1864 ActivityRecord r = thumbnails.get(i);
1865 mService.sendPendingThumbnail(r, null, null, null, true);
1866 }
1867 }
1868 });
1869
1870 // Stop any activities that are scheduled to do so but have been
1871 // waiting for the next one to start.
1872 for (int i = 0; i < NS; i++) {
1873 r = stops.get(i);
1874 final ActivityStack stack = r.task.stack;
1875 if (r.finishing) {
1876 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1877 } else {
1878 stack.stopActivityLocked(r);
1879 }
1880 }
1881
1882 // Finish any activities that are scheduled to do so but have been
1883 // waiting for the next one to start.
1884 for (int i = 0; i < NF; i++) {
1885 r = finishes.get(i);
1886 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1887 }
1888
1889 if (booting) {
1890 mService.finishBooting();
1891 } else if (startingUsers != null) {
1892 for (int i = 0; i < startingUsers.size(); i++) {
1893 mService.finishUserSwitch(startingUsers.get(i));
1894 }
1895 }
1896
1897 mService.trimApplications();
1898 //dump();
1899 //mWindowManager.dump();
1900
1901 if (enableScreen) {
1902 mService.enableScreenAfterBoot();
1903 }
1904
1905 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001906 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001907 }
1908
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001909 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001910 }
1911
Craig Mautner8e569572013-10-11 17:36:59 -07001912 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001913 boolean hasVisibleActivities = false;
1914 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1915 hasVisibleActivities |= mStacks.get(stackNdx).handleAppDiedLocked(app);
Craig Mautner6b74cb52013-09-27 17:02:21 -07001916 }
Craig Mautner19091252013-10-05 00:03:53 -07001917 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001918 }
1919
1920 void closeSystemDialogsLocked() {
1921 final int numStacks = mStacks.size();
1922 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1923 final ActivityStack stack = mStacks.get(stackNdx);
1924 stack.closeSystemDialogsLocked();
1925 }
1926 }
1927
Craig Mautner93529a42013-10-04 15:03:13 -07001928 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07001929 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07001930 }
1931
Craig Mautner8d341ef2013-03-26 09:03:27 -07001932 /**
1933 * @return true if some activity was finished (or would have finished if doit were true).
1934 */
1935 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1936 boolean didSomething = false;
1937 final int numStacks = mStacks.size();
1938 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1939 final ActivityStack stack = mStacks.get(stackNdx);
1940 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1941 didSomething = true;
1942 }
1943 }
1944 return didSomething;
1945 }
1946
Dianne Hackborna413dc02013-07-12 12:02:55 -07001947 void updatePreviousProcessLocked(ActivityRecord r) {
1948 // Now that this process has stopped, we may want to consider
1949 // it to be the previous app to try to keep around in case
1950 // the user wants to return to it.
1951
1952 // First, found out what is currently the foreground app, so that
1953 // we don't blow away the previous app if this activity is being
1954 // hosted by the process that is actually still the foreground.
1955 ProcessRecord fgApp = null;
1956 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1957 final ActivityStack stack = mStacks.get(stackNdx);
1958 if (isFrontStack(stack)) {
1959 if (stack.mResumedActivity != null) {
1960 fgApp = stack.mResumedActivity.app;
1961 } else if (stack.mPausingActivity != null) {
1962 fgApp = stack.mPausingActivity.app;
1963 }
1964 break;
1965 }
1966 }
1967
1968 // Now set this one as the previous process, only if that really
1969 // makes sense to.
1970 if (r.app != null && fgApp != null && r.app != fgApp
1971 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07001972 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07001973 mService.mPreviousProcess = r.app;
1974 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1975 }
1976 }
1977
Craig Mautner05d29032013-05-03 13:40:13 -07001978 boolean resumeTopActivitiesLocked() {
1979 return resumeTopActivitiesLocked(null, null, null);
1980 }
1981
1982 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1983 Bundle targetOptions) {
1984 if (targetStack == null) {
1985 targetStack = getFocusedStack();
1986 }
1987 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001988 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001989 final ActivityStack stack = mStacks.get(stackNdx);
1990 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001991 if (stack == targetStack) {
1992 result = stack.resumeTopActivityLocked(target, targetOptions);
1993 } else {
1994 stack.resumeTopActivityLocked(null);
1995 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001996 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001997 }
Craig Mautner05d29032013-05-03 13:40:13 -07001998 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001999 }
2000
2001 void finishTopRunningActivityLocked(ProcessRecord app) {
2002 final int numStacks = mStacks.size();
2003 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2004 final ActivityStack stack = mStacks.get(stackNdx);
2005 stack.finishTopRunningActivityLocked(app);
2006 }
2007 }
2008
Craig Mautner8d341ef2013-03-26 09:03:27 -07002009 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2010 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2011 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002012 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
Craig Mautner1d001b62013-06-18 16:52:43 -07002013 mStacks.get(stackNdx));
Craig Mautner8d341ef2013-03-26 09:03:27 -07002014 return;
2015 }
2016 }
2017 }
2018
Craig Mautner967212c2013-04-13 21:10:58 -07002019 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002020 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2021 final ActivityStack stack = mStacks.get(stackNdx);
2022 if (stack.getStackId() == stackId) {
2023 return stack;
2024 }
2025 }
2026 return null;
2027 }
2028
Craig Mautner967212c2013-04-13 21:10:58 -07002029 ArrayList<ActivityStack> getStacks() {
2030 return new ArrayList<ActivityStack>(mStacks);
2031 }
2032
2033 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002034 while (true) {
2035 if (++mLastStackId <= HOME_STACK_ID) {
2036 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002037 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002038 if (getStack(mLastStackId) == null) {
2039 break;
2040 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002041 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002042 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
2043 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002044 }
2045
2046 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002047 final TaskRecord task = anyTaskForIdLocked(taskId);
2048 if (task == null) {
2049 return;
2050 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002051 final ActivityStack stack = getStack(stackId);
2052 if (stack == null) {
2053 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2054 return;
2055 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002056 removeTask(task);
2057 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002058 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002059 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002060 }
2061
Craig Mautnerac6f8432013-07-17 13:24:59 -07002062 ActivityRecord findTaskLocked(ActivityRecord r) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07002063 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07002064 final ActivityStack stack = mStacks.get(stackNdx);
2065 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2066 continue;
2067 }
2068 final ActivityRecord ar = stack.findTaskLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07002069 if (ar != null) {
2070 return ar;
2071 }
2072 }
2073 return null;
2074 }
2075
2076 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2077 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2078 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
2079 if (ar != null) {
2080 return ar;
2081 }
2082 }
2083 return null;
2084 }
2085
Craig Mautner8d341ef2013-03-26 09:03:27 -07002086 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002087 scheduleSleepTimeout();
2088 if (!mGoingToSleep.isHeld()) {
2089 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002090 if (mLaunchingActivity.isHeld()) {
2091 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2092 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002093 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002094 mLaunchingActivity.release();
2095 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002096 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002097 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002098 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002099 }
2100
2101 boolean shutdownLocked(int timeout) {
2102 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002103 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002104
2105 final long endTime = System.currentTimeMillis() + timeout;
2106 while (true) {
2107 boolean cantShutdown = false;
2108 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2109 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2110 }
2111 if (cantShutdown) {
2112 long timeRemaining = endTime - System.currentTimeMillis();
2113 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002114 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002115 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002116 } catch (InterruptedException e) {
2117 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002118 } else {
2119 Slog.w(TAG, "Activity manager shutdown timed out");
2120 timedout = true;
2121 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002122 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002123 } else {
2124 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002125 }
2126 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002127
2128 // Force checkReadyForSleep to complete.
2129 mSleepTimeout = true;
2130 checkReadyForSleepLocked();
2131
Craig Mautner8d341ef2013-03-26 09:03:27 -07002132 return timedout;
2133 }
2134
2135 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002136 removeSleepTimeouts();
2137 if (mGoingToSleep.isHeld()) {
2138 mGoingToSleep.release();
2139 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002140 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002141 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002142 stack.awakeFromSleepingLocked();
Craig Mautner5314a402013-09-26 12:40:16 -07002143 if (isFrontStack(stack)) {
2144 resumeTopActivitiesLocked();
2145 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002146 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002147 mGoingToSleepActivities.clear();
2148 }
2149
2150 void activitySleptLocked(ActivityRecord r) {
2151 mGoingToSleepActivities.remove(r);
2152 checkReadyForSleepLocked();
2153 }
2154
2155 void checkReadyForSleepLocked() {
2156 if (!mService.isSleepingOrShuttingDown()) {
2157 // Do not care.
2158 return;
2159 }
2160
2161 if (!mSleepTimeout) {
2162 boolean dontSleep = false;
2163 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2164 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2165 }
2166
2167 if (mStoppingActivities.size() > 0) {
2168 // Still need to tell some activities to stop; can't sleep yet.
2169 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2170 + mStoppingActivities.size() + " activities");
2171 scheduleIdleLocked();
2172 dontSleep = true;
2173 }
2174
2175 if (mGoingToSleepActivities.size() > 0) {
2176 // Still need to tell some activities to sleep; can't sleep yet.
2177 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2178 + mGoingToSleepActivities.size() + " activities");
2179 dontSleep = true;
2180 }
2181
2182 if (dontSleep) {
2183 return;
2184 }
2185 }
2186
2187 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2188 mStacks.get(stackNdx).goToSleep();
2189 }
2190
2191 removeSleepTimeouts();
2192
2193 if (mGoingToSleep.isHeld()) {
2194 mGoingToSleep.release();
2195 }
2196 if (mService.mShuttingDown) {
2197 mService.notifyAll();
2198 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002199 }
2200
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002201 boolean reportResumedActivityLocked(ActivityRecord r) {
2202 final ActivityStack stack = r.task.stack;
2203 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002204 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002205 }
2206 if (allResumedActivitiesComplete()) {
2207 ensureActivitiesVisibleLocked(null, 0);
2208 mWindowManager.executeAppTransition();
2209 return true;
2210 }
2211 return false;
2212 }
2213
Craig Mautner8d341ef2013-03-26 09:03:27 -07002214 void handleAppCrashLocked(ProcessRecord app) {
2215 final int numStacks = mStacks.size();
2216 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2217 final ActivityStack stack = mStacks.get(stackNdx);
2218 stack.handleAppCrashLocked(app);
2219 }
2220 }
2221
Craig Mautnerde4ef022013-04-07 19:01:33 -07002222 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002223 // First the front stacks. In case any are not fullscreen and are in front of home.
2224 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002225 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002226 final ActivityStack stack = mStacks.get(stackNdx);
2227 if (isFrontStack(stack)) {
2228 showHomeBehindStack =
2229 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2230 }
2231 }
2232 // Now do back stacks.
2233 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2234 final ActivityStack stack = mStacks.get(stackNdx);
2235 if (!isFrontStack(stack)) {
2236 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2237 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002238 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002239 }
2240
2241 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2242 final int numStacks = mStacks.size();
2243 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2244 final ActivityStack stack = mStacks.get(stackNdx);
2245 stack.scheduleDestroyActivities(app, false, reason);
2246 }
2247 }
2248
2249 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002250 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2251 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002252 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002253
Craig Mautner858d8a62013-04-23 17:08:34 -07002254 mStartingUsers.add(uss);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002255 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner93529a42013-10-04 15:03:13 -07002256 mStacks.get(stackNdx).switchUserLocked(userId);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002257 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002258
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002259 ActivityStack stack = getStack(restoreStackId);
2260 if (stack == null) {
2261 stack = mHomeStack;
2262 }
2263 final boolean homeInFront = stack.isHomeStack();
Craig Mautner93529a42013-10-04 15:03:13 -07002264 moveHomeStack(homeInFront);
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002265 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner93529a42013-10-04 15:03:13 -07002266 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002267 }
2268
Craig Mautnerde4ef022013-04-07 19:01:33 -07002269 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2270 int N = mStoppingActivities.size();
2271 if (N <= 0) return null;
2272
2273 ArrayList<ActivityRecord> stops = null;
2274
2275 final boolean nowVisible = allResumedActivitiesVisible();
2276 for (int i=0; i<N; i++) {
2277 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautner323f7802013-10-01 21:16:22 -07002278 if (true || localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002279 + nowVisible + " waitingVisible=" + s.waitingVisible
2280 + " finishing=" + s.finishing);
2281 if (s.waitingVisible && nowVisible) {
2282 mWaitingVisibleActivities.remove(s);
2283 s.waitingVisible = false;
2284 if (s.finishing) {
2285 // If this activity is finishing, it is sitting on top of
2286 // everyone else but we now know it is no longer needed...
2287 // so get rid of it. Otherwise, we need to go through the
2288 // normal flow and hide it once we determine that it is
2289 // hidden by the activities in front of it.
2290 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002291 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002292 }
2293 }
2294 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2295 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2296 if (stops == null) {
2297 stops = new ArrayList<ActivityRecord>();
2298 }
2299 stops.add(s);
2300 mStoppingActivities.remove(i);
2301 N--;
2302 i--;
2303 }
2304 }
2305
2306 return stops;
2307 }
2308
Craig Mautnercf910b02013-04-23 11:23:27 -07002309 void validateTopActivitiesLocked() {
2310 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2311 final ActivityStack stack = mStacks.get(stackNdx);
2312 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002313 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002314 if (isFrontStack(stack)) {
2315 if (r == null) {
2316 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2317 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002318 final ActivityRecord pausing = stack.mPausingActivity;
2319 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002320 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002321 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002322 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002323 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002324 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002325 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002326 }
2327 }
2328 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002329 final ActivityRecord resumed = stack.mResumedActivity;
2330 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002331 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002332 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002333 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002334 if (r != null && (state == ActivityState.INITIALIZING
2335 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002336 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002337 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002338 }
2339 }
2340 }
2341 }
2342
Craig Mautner76ea2242013-05-15 11:40:05 -07002343 private static String stackStateToString(int stackState) {
2344 switch (stackState) {
2345 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2346 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2347 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2348 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2349 default: return "Unknown stackState=" + stackState;
2350 }
2351 }
2352
Craig Mautner27084302013-03-25 08:05:25 -07002353 public void dump(PrintWriter pw, String prefix) {
2354 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2355 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002356 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002357 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2358 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002359 pw.print(prefix); pw.println("mUserStackInFront: " + mUserStackInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002360 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002361
Craig Mautner20e72272013-04-01 13:45:53 -07002362 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002363 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002364 }
2365
Dianne Hackborn390517b2013-05-30 15:03:32 -07002366 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2367 boolean needSep, String prefix) {
2368 if (activity != null) {
2369 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2370 if (needSep) {
2371 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002372 }
2373 pw.print(prefix);
2374 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002375 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002376 }
2377 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002378 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002379 }
2380
Craig Mautner8d341ef2013-03-26 09:03:27 -07002381 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2382 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002383 boolean printed = false;
2384 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002385 final int numStacks = mStacks.size();
2386 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2387 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002388 StringBuilder stackHeader = new StringBuilder(128);
2389 stackHeader.append(" Stack #");
2390 stackHeader.append(mStacks.indexOf(stack));
2391 stackHeader.append(":");
2392 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2393 stackHeader.toString());
2394 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2395 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002396
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002397 needSep = printed;
2398 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002399 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002400 if (pr) {
2401 printed = true;
2402 needSep = false;
2403 }
2404 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002405 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002406 if (pr) {
2407 printed = true;
2408 needSep = false;
2409 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002410 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002411 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002412 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002413 if (pr) {
2414 printed = true;
Craig Mautner0f922742013-08-06 08:44:42 -07002415 needSep = true;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002416 }
Craig Mautner0f922742013-08-06 08:44:42 -07002417 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2418 needSep, " mLastNoHistoryActivity: ");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002419 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002420 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002421 }
2422
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002423 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2424 false, dumpPackage, true, " Activities waiting to finish:", null);
2425 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2426 false, dumpPackage, true, " Activities waiting to stop:", null);
2427 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2428 false, dumpPackage, true, " Activities waiting for another to become visible:",
2429 null);
2430 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2431 false, dumpPackage, true, " Activities waiting to sleep:", null);
2432 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2433 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002434
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002435 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002436 }
2437
Dianne Hackborn390517b2013-05-30 15:03:32 -07002438 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002439 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002440 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002441 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002442 String innerPrefix = null;
2443 String[] args = null;
2444 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002445 for (int i=list.size()-1; i>=0; i--) {
2446 final ActivityRecord r = list.get(i);
2447 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2448 continue;
2449 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002450 if (innerPrefix == null) {
2451 innerPrefix = prefix + " ";
2452 args = new String[0];
2453 }
2454 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002455 final boolean full = !brief && (complete || !r.isInHistory());
2456 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002457 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002458 needNL = false;
2459 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002460 if (header1 != null) {
2461 pw.println(header1);
2462 header1 = null;
2463 }
2464 if (header2 != null) {
2465 pw.println(header2);
2466 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002467 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002468 if (lastTask != r.task) {
2469 lastTask = r.task;
2470 pw.print(prefix);
2471 pw.print(full ? "* " : " ");
2472 pw.println(lastTask);
2473 if (full) {
2474 lastTask.dump(pw, prefix + " ");
2475 } else if (complete) {
2476 // Complete + brief == give a summary. Isn't that obvious?!?
2477 if (lastTask.intent != null) {
2478 pw.print(prefix); pw.print(" ");
2479 pw.println(lastTask.intent.toInsecureStringWithClip());
2480 }
2481 }
2482 }
2483 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2484 pw.print(" #"); pw.print(i); pw.print(": ");
2485 pw.println(r);
2486 if (full) {
2487 r.dump(pw, innerPrefix);
2488 } else if (complete) {
2489 // Complete + brief == give a summary. Isn't that obvious?!?
2490 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2491 if (r.app != null) {
2492 pw.print(innerPrefix); pw.println(r.app);
2493 }
2494 }
2495 if (client && r.app != null && r.app.thread != null) {
2496 // flush anything that is already in the PrintWriter since the thread is going
2497 // to write to the file descriptor directly
2498 pw.flush();
2499 try {
2500 TransferPipe tp = new TransferPipe();
2501 try {
2502 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2503 r.appToken, innerPrefix, args);
2504 // Short timeout, since blocking here can
2505 // deadlock with the application.
2506 tp.go(fd, 2000);
2507 } finally {
2508 tp.kill();
2509 }
2510 } catch (IOException e) {
2511 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2512 } catch (RemoteException e) {
2513 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2514 }
2515 needNL = true;
2516 }
2517 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002518 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002519 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002520
Craig Mautnerf3333272013-04-22 10:55:53 -07002521 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002522 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002523 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2524 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002525 }
2526
2527 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002528 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002529 }
2530
2531 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002532 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002533 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2534 }
2535
Craig Mautner05d29032013-05-03 13:40:13 -07002536 final void scheduleResumeTopActivities() {
2537 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2538 }
2539
Craig Mautner0eea92c2013-05-16 13:35:39 -07002540 void removeSleepTimeouts() {
2541 mSleepTimeout = false;
2542 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2543 }
2544
2545 final void scheduleSleepTimeout() {
2546 removeSleepTimeouts();
2547 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2548 }
2549
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002550 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002551
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002552 public ActivityStackSupervisorHandler(Looper looper) {
2553 super(looper);
2554 }
2555
Craig Mautnerf3333272013-04-22 10:55:53 -07002556 void activityIdleInternal(ActivityRecord r) {
2557 synchronized (mService) {
2558 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2559 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002560 }
2561
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002562 @Override
2563 public void handleMessage(Message msg) {
2564 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002565 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002566 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002567 if (mService.mDidDexOpt) {
2568 mService.mDidDexOpt = false;
2569 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2570 nmsg.obj = msg.obj;
2571 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2572 return;
2573 }
2574 // We don't at this point know if the activity is fullscreen,
2575 // so we need to be conservative and assume it isn't.
2576 activityIdleInternal((ActivityRecord)msg.obj);
2577 } break;
2578 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002579 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002580 activityIdleInternal((ActivityRecord)msg.obj);
2581 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002582 case RESUME_TOP_ACTIVITY_MSG: {
2583 synchronized (mService) {
2584 resumeTopActivitiesLocked();
2585 }
2586 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002587 case SLEEP_TIMEOUT_MSG: {
2588 synchronized (mService) {
2589 if (mService.isSleepingOrShuttingDown()) {
2590 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2591 mSleepTimeout = true;
2592 checkReadyForSleepLocked();
2593 }
2594 }
2595 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002596 case LAUNCH_TIMEOUT_MSG: {
2597 if (mService.mDidDexOpt) {
2598 mService.mDidDexOpt = false;
2599 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2600 return;
2601 }
2602 synchronized (mService) {
2603 if (mLaunchingActivity.isHeld()) {
2604 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2605 if (VALIDATE_WAKE_LOCK_CALLER
2606 && Binder.getCallingUid() != Process.myUid()) {
2607 throw new IllegalStateException("Calling must be system uid");
2608 }
2609 mLaunchingActivity.release();
2610 }
2611 }
2612 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002613 }
2614 }
2615 }
Craig Mautner27084302013-03-25 08:05:25 -07002616}