blob: 4c65a8ab1272b4ded4e9cd8b182d2b9c6ceaef0e [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
37import android.app.ActivityOptions;
38import android.app.AppGlobals;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070039import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070040import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070041import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070042import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070043import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070044import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070045import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070046import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070047import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070048import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070049import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070050import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070051import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070052import android.content.pm.ApplicationInfo;
53import android.content.pm.PackageManager;
54import android.content.pm.ResolveInfo;
55import android.content.res.Configuration;
56import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070057import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070058import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070059import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070060import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070061import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070062import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070063import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070064import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070065import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070066import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070067import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070068import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070069import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070070import android.util.Slog;
Craig Mautner858d8a62013-04-23 17:08:34 -070071import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070072
Craig 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? */
125 private boolean mDismissKeyguardOnNextActivity = false;
126
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 Mautnerac6f8432013-07-17 13:24:59 -0700206 /**
207 * The name of the current home activity for each user.
208 * TODO: Remove entries when user is deleted.
209 */
210 final SparseArray<String> mHomePackageNames = new SparseArray<String>();
211
Craig Mautner2219a1b2013-03-25 09:44:30 -0700212 public ActivityStackSupervisor(ActivityManagerService service, Context context,
213 Looper looper) {
Craig Mautner27084302013-03-25 08:05:25 -0700214 mService = service;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700215 mContext = context;
216 mLooper = looper;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700217 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
218 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700219 mHandler = new ActivityStackSupervisorHandler(looper);
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700220 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
221 throw new IllegalStateException("Calling must be system uid");
222 }
223 mLaunchingActivity =
224 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
225 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700226 }
227
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700228 void setWindowManager(WindowManagerService wm) {
229 mWindowManager = wm;
230 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700231 mStacks.add(mHomeStack);
Craig Mautner27084302013-03-25 08:05:25 -0700232 }
233
234 void dismissKeyguard() {
235 if (mDismissKeyguardOnNextActivity) {
236 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700237 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700238 }
239 }
240
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700241 ActivityStack getFocusedStack() {
Craig Mautnerf88c50f2013-04-18 19:25:12 -0700242 if (mFocusedStack == null) {
243 return mHomeStack;
244 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700245 switch (mStackState) {
246 case STACK_STATE_HOME_IN_FRONT:
247 case STACK_STATE_HOME_TO_FRONT:
248 return mHomeStack;
249 case STACK_STATE_HOME_IN_BACK:
250 case STACK_STATE_HOME_TO_BACK:
251 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700252 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700253 }
Craig Mautner20e72272013-04-01 13:45:53 -0700254 }
255
Craig Mautnerde4ef022013-04-07 19:01:33 -0700256 ActivityStack getLastStack() {
257 switch (mStackState) {
258 case STACK_STATE_HOME_IN_FRONT:
259 case STACK_STATE_HOME_TO_BACK:
260 return mHomeStack;
261 case STACK_STATE_HOME_TO_FRONT:
262 case STACK_STATE_HOME_IN_BACK:
263 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700264 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700265 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700266 }
267
Craig Mautnerde4ef022013-04-07 19:01:33 -0700268 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700269 return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
Craig Mautner20e72272013-04-01 13:45:53 -0700270 }
271
Craig Mautnerde4ef022013-04-07 19:01:33 -0700272 void moveHomeStack(boolean toFront) {
273 final boolean homeInFront = isFrontStack(mHomeStack);
274 if (homeInFront ^ toFront) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700275 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
276 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
277 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700278 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
279 }
280 }
281
Craig Mautner69ada552013-04-18 13:51:51 -0700282 boolean resumeHomeActivity(ActivityRecord prev) {
283 moveHomeStack(true);
284 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700285 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700286 }
Craig Mautnera82aa092013-09-13 15:34:08 -0700287 mHomeStack.moveHomeTaskToTop();
Craig Mautnera8a90e02013-06-28 15:24:50 -0700288 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
289 if (r != null) {
290 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700291 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700292 }
293 return mService.startHomeActivityLocked(mCurrentUser);
294 }
295
Craig Mautnerde4ef022013-04-07 19:01:33 -0700296 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r,
297 ActivityStack stack) {
298 if (stack == mHomeStack) {
299 return;
300 }
301 if ((sourceRecord == null && getLastStack() == mHomeStack) ||
Craig Mautner86d67a42013-05-14 10:34:38 -0700302 (sourceRecord != null && sourceRecord.isHomeActivity())) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700303 if (r == null) {
304 r = stack.topRunningActivityLocked(null);
305 }
Craig Mautner86d67a42013-05-14 10:34:38 -0700306 if (r != null && !r.isHomeActivity() && r.isRootActivity()) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700307 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700308 }
309 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700310 }
311
Craig Mautner27084302013-03-25 08:05:25 -0700312 void setDismissKeyguard(boolean dismiss) {
313 mDismissKeyguardOnNextActivity = dismiss;
314 }
315
Craig Mautner8d341ef2013-03-26 09:03:27 -0700316 TaskRecord anyTaskForIdLocked(int id) {
317 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
318 ActivityStack stack = mStacks.get(stackNdx);
319 TaskRecord task = stack.taskForIdLocked(id);
320 if (task != null) {
321 return task;
322 }
323 }
324 return null;
325 }
326
Craig Mautner6170f732013-04-02 13:05:23 -0700327 ActivityRecord isInAnyStackLocked(IBinder token) {
328 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
329 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
330 if (r != null) {
331 return r;
332 }
333 }
334 return null;
335 }
336
Craig Mautner8d341ef2013-03-26 09:03:27 -0700337 int getNextTaskId() {
338 do {
339 mCurTaskId++;
340 if (mCurTaskId <= 0) {
341 mCurTaskId = 1;
342 }
343 } while (anyTaskForIdLocked(mCurTaskId) != null);
344 return mCurTaskId;
345 }
346
Craig Mautnerde4ef022013-04-07 19:01:33 -0700347 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700348 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700349 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700350 final ActivityRecord r = stack.mResumedActivity;
351 if (r != null && r.task == task) {
352 stack.mResumedActivity = null;
353 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700354 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700355 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700356 mStacks.remove(stack);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700357 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700358 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700359 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Craig Mautnerac6f8432013-07-17 13:24:59 -0700360 if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700361 // If this is the last app stack, set mFocusedStack to null.
Craig Mautner29219d92013-04-16 20:19:12 -0700362 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700363 }
364 }
365 }
366
367 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700368 ActivityStack stack = getFocusedStack();
369 if (stack == null) {
370 return null;
371 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700372 ActivityRecord resumedActivity = stack.mResumedActivity;
373 if (resumedActivity == null || resumedActivity.app == null) {
374 resumedActivity = stack.mPausingActivity;
375 if (resumedActivity == null || resumedActivity.app == null) {
376 resumedActivity = stack.topRunningActivityLocked(null);
377 }
378 }
379 return resumedActivity;
380 }
381
Craig Mautner20e72272013-04-01 13:45:53 -0700382 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
383 boolean didSomething = false;
384 final String processName = app.processName;
385 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
386 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner858d8a62013-04-23 17:08:34 -0700387 if (!isFrontStack(stack)) {
388 continue;
389 }
Craig Mautner20e72272013-04-01 13:45:53 -0700390 ActivityRecord hr = stack.topRunningActivityLocked(null);
391 if (hr != null) {
392 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
393 && processName.equals(hr.processName)) {
394 try {
395 if (headless) {
396 Slog.e(TAG, "Starting activities not supported on headless device: "
397 + hr);
Craig Mautner2420ead2013-04-01 17:13:20 -0700398 } else if (realStartActivityLocked(hr, app, true, true)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700399 didSomething = true;
400 }
401 } catch (Exception e) {
402 Slog.w(TAG, "Exception in new application when starting activity "
403 + hr.intent.getComponent().flattenToShortString(), e);
404 throw e;
405 }
Craig Mautner20e72272013-04-01 13:45:53 -0700406 }
407 }
408 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700409 if (!didSomething) {
410 ensureActivitiesVisibleLocked(null, 0);
411 }
Craig Mautner20e72272013-04-01 13:45:53 -0700412 return didSomething;
413 }
414
415 boolean allResumedActivitiesIdle() {
416 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700417 final ActivityStack stack = mStacks.get(stackNdx);
418 if (!isFrontStack(stack)) {
419 continue;
420 }
421 final ActivityRecord resumedActivity = stack.mResumedActivity;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -0700422 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner20e72272013-04-01 13:45:53 -0700423 return false;
424 }
425 }
426 return true;
427 }
428
Craig Mautnerde4ef022013-04-07 19:01:33 -0700429 boolean allResumedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700430 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
431 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner967212c2013-04-13 21:10:58 -0700432 if (isFrontStack(stack)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700433 final ActivityRecord r = stack.mResumedActivity;
434 if (r != null && r.state != ActivityState.RESUMED) {
435 return false;
436 }
437 }
438 }
439 // TODO: Not sure if this should check if all Paused are complete too.
440 switch (mStackState) {
441 case STACK_STATE_HOME_TO_BACK:
Craig Mautner76ea2242013-05-15 11:40:05 -0700442 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
443 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
444 stackStateToString(STACK_STATE_HOME_IN_BACK));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700445 mStackState = STACK_STATE_HOME_IN_BACK;
446 break;
447 case STACK_STATE_HOME_TO_FRONT:
Craig Mautner76ea2242013-05-15 11:40:05 -0700448 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
449 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
450 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700451 mStackState = STACK_STATE_HOME_IN_FRONT;
452 break;
453 }
454 return true;
455 }
456
457 boolean allResumedActivitiesVisible() {
458 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
459 final ActivityStack stack = mStacks.get(stackNdx);
460 final ActivityRecord r = stack.mResumedActivity;
461 if (r != null && (!r.nowVisible || r.waitingVisible)) {
462 return false;
463 }
464 }
465 return true;
466 }
467
Craig Mautnercf910b02013-04-23 11:23:27 -0700468 boolean pauseBackStacks(boolean userLeaving) {
469 boolean someActivityPaused = false;
470 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
471 final ActivityStack stack = mStacks.get(stackNdx);
472 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700473 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
474 " mResumedActivity=" + stack.mResumedActivity);
Craig Mautnercf910b02013-04-23 11:23:27 -0700475 stack.startPausingLocked(userLeaving, false);
476 someActivityPaused = true;
477 }
478 }
479 return someActivityPaused;
480 }
481
Craig Mautnerde4ef022013-04-07 19:01:33 -0700482 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700483 boolean pausing = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700484 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
485 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner69ada552013-04-18 13:51:51 -0700486 final ActivityRecord r = stack.mPausingActivity;
487 if (r != null && r.state != ActivityState.PAUSED
488 && r.state != ActivityState.STOPPED
489 && r.state != ActivityState.STOPPING) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700490 if (DEBUG_STATES) {
491 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
492 pausing = false;
493 } else {
494 return false;
495 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700496 }
497 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700498 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700499 }
500
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700501 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700502 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700503 WaitResult w = mWaitingActivityVisible.get(i);
504 w.timeout = false;
505 if (r != null) {
506 w.who = new ComponentName(r.info.packageName, r.info.name);
507 }
508 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
509 w.thisTime = w.totalTime;
510 }
511 mService.notifyAll();
512 dismissKeyguard();
513 }
514
515 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
516 long thisTime, long totalTime) {
517 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700518 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700519 w.timeout = timeout;
520 if (r != null) {
521 w.who = new ComponentName(r.info.packageName, r.info.name);
522 }
523 w.thisTime = thisTime;
524 w.totalTime = totalTime;
525 }
526 mService.notifyAll();
527 }
528
Craig Mautner29219d92013-04-16 20:19:12 -0700529 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700530 final ActivityStack focusedStack = getFocusedStack();
531 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
532 if (r != null) {
533 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700534 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700535
Craig Mautner29219d92013-04-16 20:19:12 -0700536 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
537 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700538 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700539 r = stack.topRunningActivityLocked(null);
540 if (r != null) {
541 return r;
542 }
543 }
544 }
545 return null;
546 }
547
Craig Mautner20e72272013-04-01 13:45:53 -0700548 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
549 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
550 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700551
552 // Gather all of the running tasks for each stack into runningTaskLists.
553 final int numStacks = mStacks.size();
554 ArrayList<RunningTaskInfo>[] runningTaskLists = new ArrayList[numStacks];
555 for (int stackNdx = numStacks - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner20e72272013-04-01 13:45:53 -0700556 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700557 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
558 runningTaskLists[stackNdx] = stackTaskList;
559 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700560 if (isFrontStack(stack)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700561 r = ar;
562 }
563 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700564
565 // The lists are already sorted from most recent to oldest. Just pull the most recent off
566 // each list and add it to list. Stop when all lists are empty or maxNum reached.
567 while (maxNum > 0) {
568 long mostRecentActiveTime = Long.MIN_VALUE;
569 ArrayList<RunningTaskInfo> selectedStackList = null;
570 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
571 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists[stackNdx];
572 if (!stackTaskList.isEmpty()) {
573 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
574 if (lastActiveTime > mostRecentActiveTime) {
575 mostRecentActiveTime = lastActiveTime;
576 selectedStackList = stackTaskList;
577 }
578 }
579 }
580 if (selectedStackList != null) {
581 list.add(selectedStackList.remove(0));
582 --maxNum;
583 } else {
584 break;
585 }
586 }
587
Craig Mautner20e72272013-04-01 13:45:53 -0700588 return r;
589 }
590
Craig Mautner23ac33b2013-04-01 16:26:35 -0700591 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
592 String profileFile, ParcelFileDescriptor profileFd, int userId) {
593 // Collect information about the target of the Intent.
594 ActivityInfo aInfo;
595 try {
596 ResolveInfo rInfo =
597 AppGlobals.getPackageManager().resolveIntent(
598 intent, resolvedType,
599 PackageManager.MATCH_DEFAULT_ONLY
600 | ActivityManagerService.STOCK_PM_FLAGS, userId);
601 aInfo = rInfo != null ? rInfo.activityInfo : null;
602 } catch (RemoteException e) {
603 aInfo = null;
604 }
605
606 if (aInfo != null) {
607 // Store the found target back into the intent, because now that
608 // we have it we never want to do this again. For example, if the
609 // user navigates back to this point in the history, we should
610 // always restart the exact same activity.
611 intent.setComponent(new ComponentName(
612 aInfo.applicationInfo.packageName, aInfo.name));
613
614 // Don't debug things in the system process
615 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
616 if (!aInfo.processName.equals("system")) {
617 mService.setDebugApp(aInfo.processName, true, false);
618 }
619 }
620
621 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
622 if (!aInfo.processName.equals("system")) {
623 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
624 }
625 }
626
627 if (profileFile != null) {
628 if (!aInfo.processName.equals("system")) {
629 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
630 profileFile, profileFd,
631 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
632 }
633 }
634 }
635 return aInfo;
636 }
637
Craig Mautner2219a1b2013-03-25 09:44:30 -0700638 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700639 moveHomeStack(true);
Craig Mautner6170f732013-04-02 13:05:23 -0700640 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700641 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700642 }
643
Craig Mautner23ac33b2013-04-01 16:26:35 -0700644 final int startActivityMayWait(IApplicationThread caller, int callingUid,
645 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
646 String resultWho, int requestCode, int startFlags, String profileFile,
647 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
648 Bundle options, int userId) {
649 // Refuse possible leaked file descriptors
650 if (intent != null && intent.hasFileDescriptors()) {
651 throw new IllegalArgumentException("File descriptors passed in Intent");
652 }
653 boolean componentSpecified = intent.getComponent() != null;
654
655 // Don't modify the client's object!
656 intent = new Intent(intent);
657
658 // Collect information about the target of the Intent.
659 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
660 profileFile, profileFd, userId);
661
662 synchronized (mService) {
663 int callingPid;
664 if (callingUid >= 0) {
665 callingPid = -1;
666 } else if (caller == null) {
667 callingPid = Binder.getCallingPid();
668 callingUid = Binder.getCallingUid();
669 } else {
670 callingPid = callingUid = -1;
671 }
672
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700673 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700674 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700675 && mService.mConfiguration.diff(config) != 0;
676 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700677 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700678
679 final long origId = Binder.clearCallingIdentity();
680
681 if (aInfo != null &&
682 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
683 // This may be a heavy-weight process! Check to see if we already
684 // have another, different heavy-weight process running.
685 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
686 if (mService.mHeavyWeightProcess != null &&
687 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
688 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700689 int realCallingUid = callingUid;
690 if (caller != null) {
691 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
692 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700693 realCallingUid = callerApp.info.uid;
694 } else {
695 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700696 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700697 + intent.toString());
698 ActivityOptions.abort(options);
699 return ActivityManager.START_PERMISSION_DENIED;
700 }
701 }
702
703 IIntentSender target = mService.getIntentSenderLocked(
704 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
705 realCallingUid, userId, null, null, 0, new Intent[] { intent },
706 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
707 | PendingIntent.FLAG_ONE_SHOT, null);
708
709 Intent newIntent = new Intent();
710 if (requestCode >= 0) {
711 // Caller is requesting a result.
712 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
713 }
714 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
715 new IntentSender(target));
716 if (mService.mHeavyWeightProcess.activities.size() > 0) {
717 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
718 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
719 hist.packageName);
720 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
721 hist.task.taskId);
722 }
723 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
724 aInfo.packageName);
725 newIntent.setFlags(intent.getFlags());
726 newIntent.setClassName("android",
727 HeavyWeightSwitcherActivity.class.getName());
728 intent = newIntent;
729 resolvedType = null;
730 caller = null;
731 callingUid = Binder.getCallingUid();
732 callingPid = Binder.getCallingPid();
733 componentSpecified = true;
734 try {
735 ResolveInfo rInfo =
736 AppGlobals.getPackageManager().resolveIntent(
737 intent, null,
738 PackageManager.MATCH_DEFAULT_ONLY
739 | ActivityManagerService.STOCK_PM_FLAGS, userId);
740 aInfo = rInfo != null ? rInfo.activityInfo : null;
741 aInfo = mService.getActivityInfoForUser(aInfo, userId);
742 } catch (RemoteException e) {
743 aInfo = null;
744 }
745 }
746 }
747 }
748
Craig Mautner6170f732013-04-02 13:05:23 -0700749 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700750 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
751 callingPackage, startFlags, options, componentSpecified, null);
752
Craig Mautnerde4ef022013-04-07 19:01:33 -0700753 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700754 // If the caller also wants to switch to a new configuration,
755 // do so now. This allows a clean switch, as we are waiting
756 // for the current activity to pause (so we will not destroy
757 // it), and have not yet started the next activity.
758 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
759 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700760 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700761 if (DEBUG_CONFIGURATION) Slog.v(TAG,
762 "Updating to new configuration after starting activity.");
763 mService.updateConfigurationLocked(config, null, false, false);
764 }
765
766 Binder.restoreCallingIdentity(origId);
767
768 if (outResult != null) {
769 outResult.result = res;
770 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700771 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700772 do {
773 try {
774 mService.wait();
775 } catch (InterruptedException e) {
776 }
777 } while (!outResult.timeout && outResult.who == null);
778 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700779 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700780 if (r.nowVisible) {
781 outResult.timeout = false;
782 outResult.who = new ComponentName(r.info.packageName, r.info.name);
783 outResult.totalTime = 0;
784 outResult.thisTime = 0;
785 } else {
786 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700787 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700788 do {
789 try {
790 mService.wait();
791 } catch (InterruptedException e) {
792 }
793 } while (!outResult.timeout && outResult.who == null);
794 }
795 }
796 }
797
798 return res;
799 }
800 }
801
802 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
803 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
804 Bundle options, int userId) {
805 if (intents == null) {
806 throw new NullPointerException("intents is null");
807 }
808 if (resolvedTypes == null) {
809 throw new NullPointerException("resolvedTypes is null");
810 }
811 if (intents.length != resolvedTypes.length) {
812 throw new IllegalArgumentException("intents are length different than resolvedTypes");
813 }
814
Craig Mautner23ac33b2013-04-01 16:26:35 -0700815
816 int callingPid;
817 if (callingUid >= 0) {
818 callingPid = -1;
819 } else if (caller == null) {
820 callingPid = Binder.getCallingPid();
821 callingUid = Binder.getCallingUid();
822 } else {
823 callingPid = callingUid = -1;
824 }
825 final long origId = Binder.clearCallingIdentity();
826 try {
827 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700828 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700829 for (int i=0; i<intents.length; i++) {
830 Intent intent = intents[i];
831 if (intent == null) {
832 continue;
833 }
834
835 // Refuse possible leaked file descriptors
836 if (intent != null && intent.hasFileDescriptors()) {
837 throw new IllegalArgumentException("File descriptors passed in Intent");
838 }
839
840 boolean componentSpecified = intent.getComponent() != null;
841
842 // Don't modify the client's object!
843 intent = new Intent(intent);
844
845 // Collect information about the target of the Intent.
846 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
847 0, null, null, userId);
848 // TODO: New, check if this is correct
849 aInfo = mService.getActivityInfoForUser(aInfo, userId);
850
851 if (aInfo != null &&
852 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
853 != 0) {
854 throw new IllegalArgumentException(
855 "FLAG_CANT_SAVE_STATE not supported here");
856 }
857
858 Bundle theseOptions;
859 if (options != null && i == intents.length-1) {
860 theseOptions = options;
861 } else {
862 theseOptions = null;
863 }
Craig Mautner6170f732013-04-02 13:05:23 -0700864 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700865 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
866 0, theseOptions, componentSpecified, outActivity);
867 if (res < 0) {
868 return res;
869 }
870
871 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
872 }
873 }
874 } finally {
875 Binder.restoreCallingIdentity(origId);
876 }
877
878 return ActivityManager.START_SUCCESS;
879 }
880
Craig Mautner2420ead2013-04-01 17:13:20 -0700881 final boolean realStartActivityLocked(ActivityRecord r,
882 ProcessRecord app, boolean andResume, boolean checkConfig)
883 throws RemoteException {
884
885 r.startFreezingScreenLocked(app, 0);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700886 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700887
888 // schedule launch ticks to collect information about slow apps.
889 r.startLaunchTickingLocked();
890
891 // Have the window manager re-evaluate the orientation of
892 // the screen based on the new activity order. Note that
893 // as a result of this, it can call back into the activity
894 // manager with a new orientation. We don't care about that,
895 // because the activity is not currently running so we are
896 // just restarting it anyway.
897 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700898 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700899 mService.mConfiguration,
900 r.mayFreezeScreenLocked(app) ? r.appToken : null);
901 mService.updateConfigurationLocked(config, r, false, false);
902 }
903
904 r.app = app;
905 app.waitingToKill = null;
906 r.launchCount++;
907 r.lastLaunchTime = SystemClock.uptimeMillis();
908
909 if (localLOGV) Slog.v(TAG, "Launching: " + r);
910
911 int idx = app.activities.indexOf(r);
912 if (idx < 0) {
913 app.activities.add(r);
914 }
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700915 mService.updateLruProcessLocked(app, true, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700916
917 final ActivityStack stack = r.task.stack;
918 try {
919 if (app.thread == null) {
920 throw new RemoteException();
921 }
922 List<ResultInfo> results = null;
923 List<Intent> newIntents = null;
924 if (andResume) {
925 results = r.results;
926 newIntents = r.newIntents;
927 }
928 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
929 + " icicle=" + r.icicle
930 + " with results=" + results + " newIntents=" + newIntents
931 + " andResume=" + andResume);
932 if (andResume) {
933 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
934 r.userId, System.identityHashCode(r),
935 r.task.taskId, r.shortComponentName);
936 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700937 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700938 // Home process is the root process of the task.
939 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700940 }
941 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
942 r.sleeping = false;
943 r.forceNewConfig = false;
944 mService.showAskCompatModeDialogLocked(r);
945 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
946 String profileFile = null;
947 ParcelFileDescriptor profileFd = null;
948 boolean profileAutoStop = false;
949 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
950 if (mService.mProfileProc == null || mService.mProfileProc == app) {
951 mService.mProfileProc = app;
952 profileFile = mService.mProfileFile;
953 profileFd = mService.mProfileFd;
954 profileAutoStop = mService.mAutoStopProfiler;
955 }
956 }
957 app.hasShownUi = true;
958 app.pendingUiClean = true;
959 if (profileFd != null) {
960 try {
961 profileFd = profileFd.dup();
962 } catch (IOException e) {
963 if (profileFd != null) {
964 try {
965 profileFd.close();
966 } catch (IOException o) {
967 }
968 profileFd = null;
969 }
970 }
971 }
Dianne Hackborna413dc02013-07-12 12:02:55 -0700972 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -0700973 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
974 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -0700975 new Configuration(mService.mConfiguration), r.compat,
976 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -0700977 mService.isNextTransitionForward(), profileFile, profileFd,
978 profileAutoStop);
979
980 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
981 // This may be a heavy-weight process! Note that the package
982 // manager will ensure that only activity can run in the main
983 // process of the .apk, which is the only thing that will be
984 // considered heavy-weight.
985 if (app.processName.equals(app.info.packageName)) {
986 if (mService.mHeavyWeightProcess != null
987 && mService.mHeavyWeightProcess != app) {
988 Slog.w(TAG, "Starting new heavy weight process " + app
989 + " when already running "
990 + mService.mHeavyWeightProcess);
991 }
992 mService.mHeavyWeightProcess = app;
993 Message msg = mService.mHandler.obtainMessage(
994 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
995 msg.obj = r;
996 mService.mHandler.sendMessage(msg);
997 }
998 }
999
1000 } catch (RemoteException e) {
1001 if (r.launchFailed) {
1002 // This is the second time we failed -- finish activity
1003 // and give up.
1004 Slog.e(TAG, "Second failure launching "
1005 + r.intent.getComponent().flattenToShortString()
1006 + ", giving up", e);
1007 mService.appDiedLocked(app, app.pid, app.thread);
1008 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1009 "2nd-crash", false);
1010 return false;
1011 }
1012
1013 // This is the first time we failed -- restart process and
1014 // retry.
1015 app.activities.remove(r);
1016 throw e;
1017 }
1018
1019 r.launchFailed = false;
1020 if (stack.updateLRUListLocked(r)) {
1021 Slog.w(TAG, "Activity " + r
1022 + " being launched, but already in LRU list");
1023 }
1024
1025 if (andResume) {
1026 // As part of the process of launching, ActivityThread also performs
1027 // a resume.
1028 stack.minimalResumeActivityLocked(r);
1029 } else {
1030 // This activity is not starting in the resumed state... which
1031 // should look like we asked it to pause+stop (but remain visible),
1032 // and it has done so and reported back the current icicle and
1033 // other state.
1034 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1035 + " (starting in stopped state)");
1036 r.state = ActivityState.STOPPED;
1037 r.stopped = true;
1038 }
1039
1040 // Launch the new version setup screen if needed. We do this -after-
1041 // launching the initial activity (that is, home), so that it can have
1042 // a chance to initialize itself while in the background, making the
1043 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001044 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001045 mService.startSetupActivityLocked();
1046 }
1047
1048 return true;
1049 }
1050
Craig Mautnere79d42682013-04-01 19:01:53 -07001051 void startSpecificActivityLocked(ActivityRecord r,
1052 boolean andResume, boolean checkConfig) {
1053 // Is this activity's application already running?
1054 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001055 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001056
1057 r.task.stack.setLaunchTime(r);
1058
1059 if (app != null && app.thread != null) {
1060 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001061 app.addPackage(r.info.packageName, mService.mProcessStats);
Craig Mautnere79d42682013-04-01 19:01:53 -07001062 realStartActivityLocked(r, app, andResume, checkConfig);
1063 return;
1064 } catch (RemoteException e) {
1065 Slog.w(TAG, "Exception when starting activity "
1066 + r.intent.getComponent().flattenToShortString(), e);
1067 }
1068
1069 // If a dead object exception was thrown -- fall through to
1070 // restart the application.
1071 }
1072
1073 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001074 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001075 }
1076
Craig Mautner6170f732013-04-02 13:05:23 -07001077 final int startActivityLocked(IApplicationThread caller,
1078 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1079 String resultWho, int requestCode,
1080 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1081 boolean componentSpecified, ActivityRecord[] outActivity) {
1082 int err = ActivityManager.START_SUCCESS;
1083
1084 ProcessRecord callerApp = null;
1085 if (caller != null) {
1086 callerApp = mService.getRecordForAppLocked(caller);
1087 if (callerApp != null) {
1088 callingPid = callerApp.pid;
1089 callingUid = callerApp.info.uid;
1090 } else {
1091 Slog.w(TAG, "Unable to find app for caller " + caller
1092 + " (pid=" + callingPid + ") when starting: "
1093 + intent.toString());
1094 err = ActivityManager.START_PERMISSION_DENIED;
1095 }
1096 }
1097
1098 if (err == ActivityManager.START_SUCCESS) {
1099 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1100 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1101 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1102 }
1103
1104 ActivityRecord sourceRecord = null;
1105 ActivityRecord resultRecord = null;
1106 if (resultTo != null) {
1107 sourceRecord = isInAnyStackLocked(resultTo);
1108 if (DEBUG_RESULTS) Slog.v(
1109 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1110 if (sourceRecord != null) {
1111 if (requestCode >= 0 && !sourceRecord.finishing) {
1112 resultRecord = sourceRecord;
1113 }
1114 }
1115 }
1116 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1117
1118 int launchFlags = intent.getFlags();
1119
1120 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1121 && sourceRecord != null) {
1122 // Transfer the result target from the source activity to the new
1123 // one being started, including any failures.
1124 if (requestCode >= 0) {
1125 ActivityOptions.abort(options);
1126 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1127 }
1128 resultRecord = sourceRecord.resultTo;
1129 resultWho = sourceRecord.resultWho;
1130 requestCode = sourceRecord.requestCode;
1131 sourceRecord.resultTo = null;
1132 if (resultRecord != null) {
1133 resultRecord.removeResultsLocked(
1134 sourceRecord, resultWho, requestCode);
1135 }
1136 }
1137
1138 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1139 // We couldn't find a class that can handle the given Intent.
1140 // That's the end of that!
1141 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1142 }
1143
1144 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1145 // We couldn't find the specific class specified in the Intent.
1146 // Also the end of the line.
1147 err = ActivityManager.START_CLASS_NOT_FOUND;
1148 }
1149
1150 if (err != ActivityManager.START_SUCCESS) {
1151 if (resultRecord != null) {
1152 resultStack.sendActivityResultLocked(-1,
1153 resultRecord, resultWho, requestCode,
1154 Activity.RESULT_CANCELED, null);
1155 }
1156 setDismissKeyguard(false);
1157 ActivityOptions.abort(options);
1158 return err;
1159 }
1160
1161 final int startAnyPerm = mService.checkPermission(
1162 START_ANY_ACTIVITY, callingPid, callingUid);
1163 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1164 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1165 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1166 if (resultRecord != null) {
1167 resultStack.sendActivityResultLocked(-1,
1168 resultRecord, resultWho, requestCode,
1169 Activity.RESULT_CANCELED, null);
1170 }
1171 setDismissKeyguard(false);
1172 String msg;
1173 if (!aInfo.exported) {
1174 msg = "Permission Denial: starting " + intent.toString()
1175 + " from " + callerApp + " (pid=" + callingPid
1176 + ", uid=" + callingUid + ")"
1177 + " not exported from uid " + aInfo.applicationInfo.uid;
1178 } else {
1179 msg = "Permission Denial: starting " + intent.toString()
1180 + " from " + callerApp + " (pid=" + callingPid
1181 + ", uid=" + callingUid + ")"
1182 + " requires " + aInfo.permission;
1183 }
1184 Slog.w(TAG, msg);
1185 throw new SecurityException(msg);
1186 }
1187
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001188 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001189 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001190
Craig Mautner6170f732013-04-02 13:05:23 -07001191 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001192 try {
1193 // The Intent we give to the watcher has the extra data
1194 // stripped off, since it can contain private information.
1195 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001196 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001197 aInfo.applicationInfo.packageName);
1198 } catch (RemoteException e) {
1199 mService.mController = null;
1200 }
Ben Gruver5e207332013-04-03 17:41:37 -07001201 }
Craig Mautner6170f732013-04-02 13:05:23 -07001202
Ben Gruver5e207332013-04-03 17:41:37 -07001203 if (abort) {
1204 if (resultRecord != null) {
1205 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001206 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001207 }
Ben Gruver5e207332013-04-03 17:41:37 -07001208 // We pretend to the caller that it was really started, but
1209 // they will just get a cancel result.
1210 setDismissKeyguard(false);
1211 ActivityOptions.abort(options);
1212 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001213 }
1214
1215 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1216 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001217 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001218 if (outActivity != null) {
1219 outActivity[0] = r;
1220 }
1221
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001222 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001223 if (stack.mResumedActivity == null
1224 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001225 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1226 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001227 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001228 mService.mPendingActivityLaunches.add(pal);
1229 setDismissKeyguard(false);
1230 ActivityOptions.abort(options);
1231 return ActivityManager.START_SWITCHES_CANCELED;
1232 }
1233 }
1234
1235 if (mService.mDidAppSwitch) {
1236 // This is the second allowed switch since we stopped switches,
1237 // so now just generally allow switches. Use case: user presses
1238 // home (switches disabled, switch to home, mDidAppSwitch now true);
1239 // user taps a home icon (coming from home so allowed, we hit here
1240 // and now allow anyone to switch again).
1241 mService.mAppSwitchesAllowedTime = 0;
1242 } else {
1243 mService.mDidAppSwitch = true;
1244 }
1245
1246 mService.doPendingActivityLaunchesLocked(false);
1247
Craig Mautner8849a5e2013-04-02 16:41:03 -07001248 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001249
1250 if (allPausedActivitiesComplete()) {
1251 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001252 // activity start, but we are not actually doing an activity
1253 // switch... just dismiss the keyguard now, because we
1254 // probably want to see whatever is behind it.
1255 dismissKeyguard();
1256 }
1257 return err;
1258 }
1259
Craig Mautnerac6f8432013-07-17 13:24:59 -07001260 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001261 final TaskRecord task = r.task;
1262 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001263 if (task != null) {
1264 if (mFocusedStack != task.stack) {
1265 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1266 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
1267 mFocusedStack = task.stack;
1268 } else {
1269 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1270 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1271 }
1272 return mFocusedStack;
1273 }
1274
1275 if (mFocusedStack != null) {
1276 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1277 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1278 return mFocusedStack;
1279 }
1280
1281 for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1282 ActivityStack stack = mStacks.get(stackNdx);
1283 if (!stack.isHomeStack()) {
1284 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1285 "adjustStackFocus: Setting focused stack=" + stack);
1286 mFocusedStack = stack;
1287 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001288 }
1289 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001290
1291 // Time to create the first app stack for this user.
1292 int stackId = mService.createStack(-1, HOME_STACK_ID,
1293 StackBox.TASK_STACK_GOES_OVER, 1.0f);
1294 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1295 " stackId=" + stackId);
1296 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001297 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001298 }
1299 return mHomeStack;
1300 }
1301
Craig Mautner29219d92013-04-16 20:19:12 -07001302 void setFocusedStack(ActivityRecord r) {
1303 if (r == null) {
1304 return;
1305 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001306 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001307 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautnere7c58b62013-06-12 20:19:00 -07001308 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
Craig Mautner76ea2242013-05-15 11:40:05 -07001309 stackStateToString(mStackState) + " new=" +
1310 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1311 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001312 mStackState = STACK_STATE_HOME_TO_FRONT;
1313 }
1314 } else {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001315 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1316 "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
1317 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001318 mFocusedStack = r.task.stack;
1319 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001320 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1321 stackStateToString(mStackState) + " new=" +
1322 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1323 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001324 mStackState = STACK_STATE_HOME_TO_BACK;
1325 }
1326 }
1327 }
1328
Craig Mautner8849a5e2013-04-02 16:41:03 -07001329 final int startActivityUncheckedLocked(ActivityRecord r,
1330 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1331 Bundle options) {
1332 final Intent intent = r.intent;
1333 final int callingUid = r.launchedFromUid;
1334
1335 int launchFlags = intent.getFlags();
1336
Craig Mautner8849a5e2013-04-02 16:41:03 -07001337 // We'll invoke onUserLeaving before onPause only if the launching
1338 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001339 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1340 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001341
1342 // If the caller has asked not to resume at this point, we make note
1343 // of this in the record so that we can skip it when trying to find
1344 // the top running activity.
1345 if (!doResume) {
1346 r.delayedResume = true;
1347 }
1348
1349 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1350
1351 // If the onlyIfNeeded flag is set, then we can do this if the activity
1352 // being launched is the same as the one making the call... or, as
1353 // a special case, if we do not know the caller then we count the
1354 // current top activity as the caller.
1355 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1356 ActivityRecord checkedCaller = sourceRecord;
1357 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001358 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001359 }
1360 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1361 // Caller is not the same as launcher, so always needed.
1362 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1363 }
1364 }
1365
1366 if (sourceRecord == null) {
1367 // This activity is not being started from another... in this
1368 // case we -always- start a new task.
1369 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001370 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1371 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001372 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1373 }
1374 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1375 // The original activity who is starting us is running as a single
1376 // instance... this new activity it is starting must go on its
1377 // own task.
1378 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1379 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1380 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1381 // The activity being started is a single instance... it always
1382 // gets launched into its own task.
1383 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1384 }
1385
Craig Mautnerde4ef022013-04-07 19:01:33 -07001386 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001387 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001388 if (sourceRecord != null) {
1389 sourceTask = sourceRecord.task;
1390 sourceStack = sourceTask.stack;
1391 } else {
1392 sourceTask = null;
1393 sourceStack = null;
1394 }
1395
Craig Mautner8849a5e2013-04-02 16:41:03 -07001396 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1397 // For whatever reason this activity is being launched into a new
1398 // task... yet the caller has requested a result back. Well, that
1399 // is pretty messed up, so instead immediately send back a cancel
1400 // and let the new task continue launched as normal without a
1401 // dependency on its originator.
1402 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1403 r.resultTo.task.stack.sendActivityResultLocked(-1,
1404 r.resultTo, r.resultWho, r.requestCode,
1405 Activity.RESULT_CANCELED, null);
1406 r.resultTo = null;
1407 }
1408
1409 boolean addingToTask = false;
1410 boolean movedHome = false;
1411 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001412 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001413 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1414 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1415 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1416 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1417 // If bring to front is requested, and no result is requested, and
1418 // we can find a task that was started with this same
1419 // component, then instead of launching bring that one to the front.
1420 if (r.resultTo == null) {
1421 // See if there is a task to bring to the front. If this is
1422 // a SINGLE_INSTANCE activity, there can be one and only one
1423 // instance of it in the history, and it is always in its own
1424 // unique task, so we do a special search.
1425 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001426 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001427 : findActivityLocked(intent, r.info);
1428 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001429 if (r.task == null) {
1430 r.task = intentActivity.task;
1431 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001432 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001433 targetStack.mLastPausedActivity = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001434 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001435 if (intentActivity.task.intent == null) {
1436 // This task was started because of movement of
1437 // the activity based on affinity... now that we
1438 // are actually launching it, we can assign the
1439 // base intent.
1440 intentActivity.task.setIntent(intent, r.info);
1441 }
1442 // If the target task is not in the front, then we need
1443 // to bring it to the front... except... well, with
1444 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1445 // to have the same behavior as if a new instance was
1446 // being started, which means not bringing it to the front
1447 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001448 final ActivityStack lastStack = getLastStack();
1449 ActivityRecord curTop = lastStack == null?
1450 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001451 if (curTop != null && (curTop.task != intentActivity.task ||
1452 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001453 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001454 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1455 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001456 // We really do want to push this one into the
1457 // user's face, right now.
1458 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001459 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001460 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1461 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001462 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001463 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001464 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001465 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1466 options = null;
1467 }
1468 }
1469 // If the caller has requested that the target task be
1470 // reset, then do so.
1471 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1472 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1473 }
1474 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1475 // We don't need to start a new activity, and
1476 // the client said not to do anything if that
1477 // is the case, so this is it! And for paranoia, make
1478 // sure we have correctly resumed the top activity.
1479 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001480 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001481 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001482 } else {
1483 ActivityOptions.abort(options);
1484 }
Craig Mautner29219d92013-04-16 20:19:12 -07001485 if (r.task == null) Slog.v(TAG,
1486 "startActivityUncheckedLocked: task left null",
1487 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001488 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1489 }
1490 if ((launchFlags &
1491 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1492 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1493 // The caller has requested to completely replace any
1494 // existing task with its new activity. Well that should
1495 // not be too hard...
1496 reuseTask = intentActivity.task;
1497 reuseTask.performClearTaskLocked();
1498 reuseTask.setIntent(r.intent, r.info);
1499 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1500 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1501 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1502 // In this situation we want to remove all activities
1503 // from the task up to the one being started. In most
1504 // cases this means we are resetting the task to its
1505 // initial state.
1506 ActivityRecord top =
1507 intentActivity.task.performClearTaskLocked(r, launchFlags);
1508 if (top != null) {
1509 if (top.frontOfTask) {
1510 // Activity aliases may mean we use different
1511 // intents for the top activity, so make sure
1512 // the task now has the identity of the new
1513 // intent.
1514 top.task.setIntent(r.intent, r.info);
1515 }
1516 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1517 r, top.task);
1518 top.deliverNewIntentLocked(callingUid, r.intent);
1519 } else {
1520 // A special case: we need to
1521 // start the activity because it is not currently
1522 // running, and the caller has asked to clear the
1523 // current task to have this activity at the top.
1524 addingToTask = true;
1525 // Now pretend like this activity is being started
1526 // by the top of its task, so it is put in the
1527 // right place.
1528 sourceRecord = intentActivity;
1529 }
1530 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1531 // In this case the top activity on the task is the
1532 // same as the one being launched, so we take that
1533 // as a request to bring the task to the foreground.
1534 // If the top activity in the task is the root
1535 // activity, deliver this new intent to it if it
1536 // desires.
1537 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1538 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1539 && intentActivity.realActivity.equals(r.realActivity)) {
1540 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1541 intentActivity.task);
1542 if (intentActivity.frontOfTask) {
1543 intentActivity.task.setIntent(r.intent, r.info);
1544 }
1545 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1546 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1547 // In this case we are launching the root activity
1548 // of the task, but with a different intent. We
1549 // should start a new instance on top.
1550 addingToTask = true;
1551 sourceRecord = intentActivity;
1552 }
1553 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1554 // In this case an activity is being launched in to an
1555 // existing task, without resetting that task. This
1556 // is typically the situation of launching an activity
1557 // from a notification or shortcut. We want to place
1558 // the new activity on top of the current task.
1559 addingToTask = true;
1560 sourceRecord = intentActivity;
1561 } else if (!intentActivity.task.rootWasReset) {
1562 // In this case we are launching in to an existing task
1563 // that has not yet been started from its front door.
1564 // The current task has been brought to the front.
1565 // Ideally, we'd probably like to place this new task
1566 // at the bottom of its stack, but that's a little hard
1567 // to do with the current organization of the code so
1568 // for now we'll just drop it.
1569 intentActivity.task.setIntent(r.intent, r.info);
1570 }
1571 if (!addingToTask && reuseTask == null) {
1572 // We didn't do anything... but it was needed (a.k.a., client
1573 // don't use that intent!) And for paranoia, make
1574 // sure we have correctly resumed the top activity.
1575 if (doResume) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001576 // Reset flag so it gets correctly reevaluated.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001577 intentActivity.task.mOnTopOfHome = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001578 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1579 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001580 } else {
1581 ActivityOptions.abort(options);
1582 }
Craig Mautner29219d92013-04-16 20:19:12 -07001583 if (r.task == null) Slog.v(TAG,
1584 "startActivityUncheckedLocked: task left null",
1585 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001586 return ActivityManager.START_TASK_TO_FRONT;
1587 }
1588 }
1589 }
1590 }
1591
1592 //String uri = r.intent.toURI();
1593 //Intent intent2 = new Intent(uri);
1594 //Slog.i(TAG, "Given intent: " + r.intent);
1595 //Slog.i(TAG, "URI is: " + uri);
1596 //Slog.i(TAG, "To intent: " + intent2);
1597
1598 if (r.packageName != null) {
1599 // If the activity being launched is the same as the one currently
1600 // at the top, then we need to check if it should only be launched
1601 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001602 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001603 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001604 if (top != null && r.resultTo == null) {
1605 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1606 if (top.app != null && top.app.thread != null) {
1607 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1608 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1609 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1610 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1611 top.task);
1612 // For paranoia, make sure we have correctly
1613 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001614 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001615 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001616 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001617 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001618 }
1619 ActivityOptions.abort(options);
1620 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1621 // We don't need to start a new activity, and
1622 // the client said not to do anything if that
1623 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001624 if (r.task == null) Slog.v(TAG,
1625 "startActivityUncheckedLocked: task left null",
1626 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001627 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1628 }
1629 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001630 if (r.task == null) Slog.v(TAG,
1631 "startActivityUncheckedLocked: task left null",
1632 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001633 return ActivityManager.START_DELIVERED_TO_TOP;
1634 }
1635 }
1636 }
1637 }
1638
1639 } else {
1640 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001641 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1642 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001643 }
1644 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001645 if (r.task == null) Slog.v(TAG,
1646 "startActivityUncheckedLocked: task left null",
1647 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001648 return ActivityManager.START_CLASS_NOT_FOUND;
1649 }
1650
1651 boolean newTask = false;
1652 boolean keepCurTransition = false;
1653
1654 // Should this be considered a new task?
1655 if (r.resultTo == null && !addingToTask
1656 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001657 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001658 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001659 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001660 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1661 null, true);
1662 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1663 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001664 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001665 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001666 }
1667 newTask = true;
1668 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001669 if ((launchFlags &
1670 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1671 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1672 // Caller wants to appear on home activity, so before starting
1673 // their own activity we will bring home to the front.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001674 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001675 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001676 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001677 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001678 sourceTask = sourceRecord.task;
1679 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001680 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001681 if (!addingToTask &&
1682 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1683 // In this case, we are adding the activity to an existing
1684 // task, but the caller has asked to clear that task if the
1685 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001686 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001687 keepCurTransition = true;
1688 if (top != null) {
1689 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1690 top.deliverNewIntentLocked(callingUid, r.intent);
1691 // For paranoia, make sure we have correctly
1692 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001693 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001694 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001695 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001696 targetStack.resumeTopActivityLocked(null);
1697 }
1698 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001699 if (r.task == null) Slog.v(TAG,
1700 "startActivityUncheckedLocked: task left null",
1701 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001702 return ActivityManager.START_DELIVERED_TO_TOP;
1703 }
1704 } else if (!addingToTask &&
1705 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1706 // In this case, we are launching an activity in our own task
1707 // that may already be running somewhere in the history, and
1708 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001709 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001710 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001711 final TaskRecord task = top.task;
1712 task.moveActivityToFrontLocked(top);
1713 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001714 top.updateOptionsLocked(options);
1715 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001716 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001717 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001718 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001719 targetStack.resumeTopActivityLocked(null);
1720 }
1721 return ActivityManager.START_DELIVERED_TO_TOP;
1722 }
1723 }
1724 // An existing activity is starting this new activity, so we want
1725 // to keep the new one in the same task as the one that is starting
1726 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001727 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001728 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1729 + " in existing task " + r.task);
1730
1731 } else {
1732 // This not being started from an existing activity, and not part
1733 // of a new task... just put it in the top task, though these days
1734 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001735 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001736 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001737 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001738 r.setTask(prev != null ? prev.task
1739 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1740 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001741 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1742 + " in new guessed " + r.task);
1743 }
1744
1745 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1746 intent, r.getUriPermissionsLocked());
1747
1748 if (newTask) {
1749 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1750 }
1751 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001752 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
Craig Mautner0f922742013-08-06 08:44:42 -07001753 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001754 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001755 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001756 return ActivityManager.START_SUCCESS;
1757 }
1758
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001759 void acquireLaunchWakelock() {
1760 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1761 throw new IllegalStateException("Calling must be system uid");
1762 }
1763 mLaunchingActivity.acquire();
1764 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1765 // To be safe, don't allow the wake lock to be held for too long.
1766 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1767 }
1768 }
1769
Craig Mautnerf3333272013-04-22 10:55:53 -07001770 // Checked.
1771 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1772 Configuration config) {
1773 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1774
Craig Mautnerf3333272013-04-22 10:55:53 -07001775 ArrayList<ActivityRecord> stops = null;
1776 ArrayList<ActivityRecord> finishes = null;
1777 ArrayList<UserStartedState> startingUsers = null;
1778 int NS = 0;
1779 int NF = 0;
1780 IApplicationThread sendThumbnail = null;
1781 boolean booting = false;
1782 boolean enableScreen = false;
1783 boolean activityRemoved = false;
1784
1785 ActivityRecord r = ActivityRecord.forToken(token);
1786 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001787 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1788 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001789 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1790 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001791 if (fromTimeout) {
1792 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001793 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001794
1795 // This is a hack to semi-deal with a race condition
1796 // in the client where it can be constructed with a
1797 // newer configuration from when we asked it to launch.
1798 // We'll update with whatever configuration it now says
1799 // it used to launch.
1800 if (config != null) {
1801 r.configuration = config;
1802 }
1803
1804 // We are now idle. If someone is waiting for a thumbnail from
1805 // us, we can now deliver.
1806 r.idle = true;
1807
1808 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1809 sendThumbnail = r.app.thread;
1810 r.thumbnailNeeded = false;
1811 }
1812
1813 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1814 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1815 mService.mBooted = true;
1816 enableScreen = true;
1817 }
1818 }
1819
1820 if (allResumedActivitiesIdle()) {
1821 if (r != null) {
1822 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001823 }
1824
1825 if (mLaunchingActivity.isHeld()) {
1826 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1827 if (VALIDATE_WAKE_LOCK_CALLER &&
1828 Binder.getCallingUid() != Process.myUid()) {
1829 throw new IllegalStateException("Calling must be system uid");
1830 }
1831 mLaunchingActivity.release();
1832 }
1833 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001834 }
1835
1836 // Atomically retrieve all of the other things to do.
1837 stops = processStoppingActivitiesLocked(true);
1838 NS = stops != null ? stops.size() : 0;
1839 if ((NF=mFinishingActivities.size()) > 0) {
1840 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1841 mFinishingActivities.clear();
1842 }
1843
1844 final ArrayList<ActivityRecord> thumbnails;
1845 final int NT = mCancelledThumbnails.size();
1846 if (NT > 0) {
1847 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1848 mCancelledThumbnails.clear();
1849 } else {
1850 thumbnails = null;
1851 }
1852
1853 if (isFrontStack(mHomeStack)) {
1854 booting = mService.mBooting;
1855 mService.mBooting = false;
1856 }
1857
1858 if (mStartingUsers.size() > 0) {
1859 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1860 mStartingUsers.clear();
1861 }
1862
1863 // Perform the following actions from unsynchronized state.
1864 final IApplicationThread thumbnailThread = sendThumbnail;
1865 mHandler.post(new Runnable() {
1866 @Override
1867 public void run() {
1868 if (thumbnailThread != null) {
1869 try {
1870 thumbnailThread.requestThumbnail(token);
1871 } catch (Exception e) {
1872 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1873 mService.sendPendingThumbnail(null, token, null, null, true);
1874 }
1875 }
1876
1877 // Report back to any thumbnail receivers.
1878 for (int i = 0; i < NT; i++) {
1879 ActivityRecord r = thumbnails.get(i);
1880 mService.sendPendingThumbnail(r, null, null, null, true);
1881 }
1882 }
1883 });
1884
1885 // Stop any activities that are scheduled to do so but have been
1886 // waiting for the next one to start.
1887 for (int i = 0; i < NS; i++) {
1888 r = stops.get(i);
1889 final ActivityStack stack = r.task.stack;
1890 if (r.finishing) {
1891 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1892 } else {
1893 stack.stopActivityLocked(r);
1894 }
1895 }
1896
1897 // Finish any activities that are scheduled to do so but have been
1898 // waiting for the next one to start.
1899 for (int i = 0; i < NF; i++) {
1900 r = finishes.get(i);
1901 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1902 }
1903
1904 if (booting) {
1905 mService.finishBooting();
1906 } else if (startingUsers != null) {
1907 for (int i = 0; i < startingUsers.size(); i++) {
1908 mService.finishUserSwitch(startingUsers.get(i));
1909 }
1910 }
1911
1912 mService.trimApplications();
1913 //dump();
1914 //mWindowManager.dump();
1915
1916 if (enableScreen) {
1917 mService.enableScreenAfterBoot();
1918 }
1919
1920 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001921 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001922 }
1923
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001924 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001925 }
1926
Craig Mautner8d341ef2013-03-26 09:03:27 -07001927 void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1928 // Just in case.
1929 final int numStacks = mStacks.size();
1930 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001931 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001932 }
1933 }
1934
1935 void closeSystemDialogsLocked() {
1936 final int numStacks = mStacks.size();
1937 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1938 final ActivityStack stack = mStacks.get(stackNdx);
1939 stack.closeSystemDialogsLocked();
1940 }
1941 }
1942
1943 /**
1944 * @return true if some activity was finished (or would have finished if doit were true).
1945 */
1946 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1947 boolean didSomething = false;
1948 final int numStacks = mStacks.size();
1949 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1950 final ActivityStack stack = mStacks.get(stackNdx);
1951 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1952 didSomething = true;
1953 }
1954 }
1955 return didSomething;
1956 }
1957
Dianne Hackborna413dc02013-07-12 12:02:55 -07001958 void updatePreviousProcessLocked(ActivityRecord r) {
1959 // Now that this process has stopped, we may want to consider
1960 // it to be the previous app to try to keep around in case
1961 // the user wants to return to it.
1962
1963 // First, found out what is currently the foreground app, so that
1964 // we don't blow away the previous app if this activity is being
1965 // hosted by the process that is actually still the foreground.
1966 ProcessRecord fgApp = null;
1967 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1968 final ActivityStack stack = mStacks.get(stackNdx);
1969 if (isFrontStack(stack)) {
1970 if (stack.mResumedActivity != null) {
1971 fgApp = stack.mResumedActivity.app;
1972 } else if (stack.mPausingActivity != null) {
1973 fgApp = stack.mPausingActivity.app;
1974 }
1975 break;
1976 }
1977 }
1978
1979 // Now set this one as the previous process, only if that really
1980 // makes sense to.
1981 if (r.app != null && fgApp != null && r.app != fgApp
1982 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07001983 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07001984 mService.mPreviousProcess = r.app;
1985 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1986 }
1987 }
1988
Craig Mautner05d29032013-05-03 13:40:13 -07001989 boolean resumeTopActivitiesLocked() {
1990 return resumeTopActivitiesLocked(null, null, null);
1991 }
1992
1993 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1994 Bundle targetOptions) {
1995 if (targetStack == null) {
1996 targetStack = getFocusedStack();
1997 }
1998 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001999 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002000 final ActivityStack stack = mStacks.get(stackNdx);
2001 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07002002 if (stack == targetStack) {
2003 result = stack.resumeTopActivityLocked(target, targetOptions);
2004 } else {
2005 stack.resumeTopActivityLocked(null);
2006 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002007 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002008 }
Craig Mautner05d29032013-05-03 13:40:13 -07002009 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002010 }
2011
2012 void finishTopRunningActivityLocked(ProcessRecord app) {
2013 final int numStacks = mStacks.size();
2014 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2015 final ActivityStack stack = mStacks.get(stackNdx);
2016 stack.finishTopRunningActivityLocked(app);
2017 }
2018 }
2019
Craig Mautner8d341ef2013-03-26 09:03:27 -07002020 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2021 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2022 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002023 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
Craig Mautner1d001b62013-06-18 16:52:43 -07002024 mStacks.get(stackNdx));
Craig Mautner8d341ef2013-03-26 09:03:27 -07002025 return;
2026 }
2027 }
2028 }
2029
Craig Mautner967212c2013-04-13 21:10:58 -07002030 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002031 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2032 final ActivityStack stack = mStacks.get(stackNdx);
2033 if (stack.getStackId() == stackId) {
2034 return stack;
2035 }
2036 }
2037 return null;
2038 }
2039
Craig Mautner967212c2013-04-13 21:10:58 -07002040 ArrayList<ActivityStack> getStacks() {
2041 return new ArrayList<ActivityStack>(mStacks);
2042 }
2043
2044 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002045 while (true) {
2046 if (++mLastStackId <= HOME_STACK_ID) {
2047 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002048 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002049 if (getStack(mLastStackId) == null) {
2050 break;
2051 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002052 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002053 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
2054 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002055 }
2056
2057 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002058 final TaskRecord task = anyTaskForIdLocked(taskId);
2059 if (task == null) {
2060 return;
2061 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002062 final ActivityStack stack = getStack(stackId);
2063 if (stack == null) {
2064 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2065 return;
2066 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002067 removeTask(task);
2068 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002069 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002070 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002071 }
2072
Craig Mautnerac6f8432013-07-17 13:24:59 -07002073 ActivityRecord findTaskLocked(ActivityRecord r) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07002074 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07002075 final ActivityStack stack = mStacks.get(stackNdx);
2076 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2077 continue;
2078 }
2079 final ActivityRecord ar = stack.findTaskLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07002080 if (ar != null) {
2081 return ar;
2082 }
2083 }
2084 return null;
2085 }
2086
2087 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2088 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2089 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
2090 if (ar != null) {
2091 return ar;
2092 }
2093 }
2094 return null;
2095 }
2096
Craig Mautner8d341ef2013-03-26 09:03:27 -07002097 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002098 scheduleSleepTimeout();
2099 if (!mGoingToSleep.isHeld()) {
2100 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002101 if (mLaunchingActivity.isHeld()) {
2102 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2103 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002104 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002105 mLaunchingActivity.release();
2106 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002107 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002108 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002109 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002110 }
2111
2112 boolean shutdownLocked(int timeout) {
2113 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002114 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002115
2116 final long endTime = System.currentTimeMillis() + timeout;
2117 while (true) {
2118 boolean cantShutdown = false;
2119 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2120 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2121 }
2122 if (cantShutdown) {
2123 long timeRemaining = endTime - System.currentTimeMillis();
2124 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002125 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002126 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002127 } catch (InterruptedException e) {
2128 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002129 } else {
2130 Slog.w(TAG, "Activity manager shutdown timed out");
2131 timedout = true;
2132 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002133 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002134 } else {
2135 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002136 }
2137 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002138
2139 // Force checkReadyForSleep to complete.
2140 mSleepTimeout = true;
2141 checkReadyForSleepLocked();
2142
Craig Mautner8d341ef2013-03-26 09:03:27 -07002143 return timedout;
2144 }
2145
2146 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002147 removeSleepTimeouts();
2148 if (mGoingToSleep.isHeld()) {
2149 mGoingToSleep.release();
2150 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002151 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002152 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002153 stack.awakeFromSleepingLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002154 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002155 mGoingToSleepActivities.clear();
2156 }
2157
2158 void activitySleptLocked(ActivityRecord r) {
2159 mGoingToSleepActivities.remove(r);
2160 checkReadyForSleepLocked();
2161 }
2162
2163 void checkReadyForSleepLocked() {
2164 if (!mService.isSleepingOrShuttingDown()) {
2165 // Do not care.
2166 return;
2167 }
2168
2169 if (!mSleepTimeout) {
2170 boolean dontSleep = false;
2171 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2172 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2173 }
2174
2175 if (mStoppingActivities.size() > 0) {
2176 // Still need to tell some activities to stop; can't sleep yet.
2177 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2178 + mStoppingActivities.size() + " activities");
2179 scheduleIdleLocked();
2180 dontSleep = true;
2181 }
2182
2183 if (mGoingToSleepActivities.size() > 0) {
2184 // Still need to tell some activities to sleep; can't sleep yet.
2185 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2186 + mGoingToSleepActivities.size() + " activities");
2187 dontSleep = true;
2188 }
2189
2190 if (dontSleep) {
2191 return;
2192 }
2193 }
2194
2195 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2196 mStacks.get(stackNdx).goToSleep();
2197 }
2198
2199 removeSleepTimeouts();
2200
2201 if (mGoingToSleep.isHeld()) {
2202 mGoingToSleep.release();
2203 }
2204 if (mService.mShuttingDown) {
2205 mService.notifyAll();
2206 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002207 }
2208
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002209 boolean reportResumedActivityLocked(ActivityRecord r) {
2210 final ActivityStack stack = r.task.stack;
2211 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002212 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002213 }
2214 if (allResumedActivitiesComplete()) {
2215 ensureActivitiesVisibleLocked(null, 0);
2216 mWindowManager.executeAppTransition();
2217 return true;
2218 }
2219 return false;
2220 }
2221
Craig Mautner8d341ef2013-03-26 09:03:27 -07002222 void handleAppCrashLocked(ProcessRecord app) {
2223 final int numStacks = mStacks.size();
2224 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2225 final ActivityStack stack = mStacks.get(stackNdx);
2226 stack.handleAppCrashLocked(app);
2227 }
2228 }
2229
Craig Mautnerde4ef022013-04-07 19:01:33 -07002230 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002231 // First the front stacks. In case any are not fullscreen and are in front of home.
2232 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002233 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002234 final ActivityStack stack = mStacks.get(stackNdx);
2235 if (isFrontStack(stack)) {
2236 showHomeBehindStack =
2237 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2238 }
2239 }
2240 // Now do back stacks.
2241 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2242 final ActivityStack stack = mStacks.get(stackNdx);
2243 if (!isFrontStack(stack)) {
2244 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2245 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002246 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002247 }
2248
2249 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2250 final int numStacks = mStacks.size();
2251 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2252 final ActivityStack stack = mStacks.get(stackNdx);
2253 stack.scheduleDestroyActivities(app, false, reason);
2254 }
2255 }
2256
2257 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner2420ead2013-04-01 17:13:20 -07002258 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002259
2260 final String homePackageName = mService.getHomePackageName();
2261 if (homePackageName != null) {
2262 setHomePackageName(mCurrentUser, homePackageName);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002263 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002264
2265 mStartingUsers.add(uss);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002266 boolean haveActivities = false;
2267 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2268 haveActivities |= mStacks.get(stackNdx).switchUserLocked(userId);
2269 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002270
2271 resumeTopActivitiesLocked();
2272
Craig Mautner8d341ef2013-03-26 09:03:27 -07002273 return haveActivities;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002274 }
2275
Craig Mautnerde4ef022013-04-07 19:01:33 -07002276 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2277 int N = mStoppingActivities.size();
2278 if (N <= 0) return null;
2279
2280 ArrayList<ActivityRecord> stops = null;
2281
2282 final boolean nowVisible = allResumedActivitiesVisible();
2283 for (int i=0; i<N; i++) {
2284 ActivityRecord s = mStoppingActivities.get(i);
2285 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2286 + nowVisible + " waitingVisible=" + s.waitingVisible
2287 + " finishing=" + s.finishing);
2288 if (s.waitingVisible && nowVisible) {
2289 mWaitingVisibleActivities.remove(s);
2290 s.waitingVisible = false;
2291 if (s.finishing) {
2292 // If this activity is finishing, it is sitting on top of
2293 // everyone else but we now know it is no longer needed...
2294 // so get rid of it. Otherwise, we need to go through the
2295 // normal flow and hide it once we determine that it is
2296 // hidden by the activities in front of it.
2297 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002298 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002299 }
2300 }
2301 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2302 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2303 if (stops == null) {
2304 stops = new ArrayList<ActivityRecord>();
2305 }
2306 stops.add(s);
2307 mStoppingActivities.remove(i);
2308 N--;
2309 i--;
2310 }
2311 }
2312
2313 return stops;
2314 }
2315
Craig Mautnercf910b02013-04-23 11:23:27 -07002316 void validateTopActivitiesLocked() {
2317 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2318 final ActivityStack stack = mStacks.get(stackNdx);
2319 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002320 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002321 if (isFrontStack(stack)) {
2322 if (r == null) {
2323 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2324 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002325 final ActivityRecord pausing = stack.mPausingActivity;
2326 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002327 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002328 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002329 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002330 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002331 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002332 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002333 }
2334 }
2335 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002336 final ActivityRecord resumed = stack.mResumedActivity;
2337 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002338 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002339 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002340 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002341 if (r != null && (state == ActivityState.INITIALIZING
2342 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002343 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002344 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002345 }
2346 }
2347 }
2348 }
2349
Craig Mautner76ea2242013-05-15 11:40:05 -07002350 private static String stackStateToString(int stackState) {
2351 switch (stackState) {
2352 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2353 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2354 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2355 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2356 default: return "Unknown stackState=" + stackState;
2357 }
2358 }
2359
Craig Mautner27084302013-03-25 08:05:25 -07002360 public void dump(PrintWriter pw, String prefix) {
2361 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2362 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002363 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002364 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2365 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002366 pw.print(prefix); pw.print("mHomePackageNames:");
2367 for (int i = 0; i < mHomePackageNames.size(); ++i) {
2368 pw.print(" ("); pw.print(mHomePackageNames.keyAt(i)); pw.print(",");
2369 pw.print(mHomePackageNames.valueAt(i)); pw.print(")");
2370 }
2371 pw.println();
Craig Mautner27084302013-03-25 08:05:25 -07002372 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002373
Craig Mautner20e72272013-04-01 13:45:53 -07002374 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002375 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002376 }
2377
Dianne Hackborn390517b2013-05-30 15:03:32 -07002378 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2379 boolean needSep, String prefix) {
2380 if (activity != null) {
2381 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2382 if (needSep) {
2383 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002384 }
2385 pw.print(prefix);
2386 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002387 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002388 }
2389 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002390 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002391 }
2392
Craig Mautner8d341ef2013-03-26 09:03:27 -07002393 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2394 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002395 boolean printed = false;
2396 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002397 final int numStacks = mStacks.size();
2398 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2399 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002400 StringBuilder stackHeader = new StringBuilder(128);
2401 stackHeader.append(" Stack #");
2402 stackHeader.append(mStacks.indexOf(stack));
2403 stackHeader.append(":");
2404 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2405 stackHeader.toString());
2406 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2407 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002408
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002409 needSep = printed;
2410 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002411 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002412 if (pr) {
2413 printed = true;
2414 needSep = false;
2415 }
2416 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002417 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002418 if (pr) {
2419 printed = true;
2420 needSep = false;
2421 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002422 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002423 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002424 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002425 if (pr) {
2426 printed = true;
Craig Mautner0f922742013-08-06 08:44:42 -07002427 needSep = true;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002428 }
Craig Mautner0f922742013-08-06 08:44:42 -07002429 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2430 needSep, " mLastNoHistoryActivity: ");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002431 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002432 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002433 }
2434
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002435 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2436 false, dumpPackage, true, " Activities waiting to finish:", null);
2437 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2438 false, dumpPackage, true, " Activities waiting to stop:", null);
2439 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2440 false, dumpPackage, true, " Activities waiting for another to become visible:",
2441 null);
2442 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2443 false, dumpPackage, true, " Activities waiting to sleep:", null);
2444 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2445 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002446
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002447 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002448 }
2449
Dianne Hackborn390517b2013-05-30 15:03:32 -07002450 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002451 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002452 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002453 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002454 String innerPrefix = null;
2455 String[] args = null;
2456 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002457 for (int i=list.size()-1; i>=0; i--) {
2458 final ActivityRecord r = list.get(i);
2459 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2460 continue;
2461 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002462 if (innerPrefix == null) {
2463 innerPrefix = prefix + " ";
2464 args = new String[0];
2465 }
2466 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002467 final boolean full = !brief && (complete || !r.isInHistory());
2468 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002469 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002470 needNL = false;
2471 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002472 if (header1 != null) {
2473 pw.println(header1);
2474 header1 = null;
2475 }
2476 if (header2 != null) {
2477 pw.println(header2);
2478 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002479 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002480 if (lastTask != r.task) {
2481 lastTask = r.task;
2482 pw.print(prefix);
2483 pw.print(full ? "* " : " ");
2484 pw.println(lastTask);
2485 if (full) {
2486 lastTask.dump(pw, prefix + " ");
2487 } else if (complete) {
2488 // Complete + brief == give a summary. Isn't that obvious?!?
2489 if (lastTask.intent != null) {
2490 pw.print(prefix); pw.print(" ");
2491 pw.println(lastTask.intent.toInsecureStringWithClip());
2492 }
2493 }
2494 }
2495 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2496 pw.print(" #"); pw.print(i); pw.print(": ");
2497 pw.println(r);
2498 if (full) {
2499 r.dump(pw, innerPrefix);
2500 } else if (complete) {
2501 // Complete + brief == give a summary. Isn't that obvious?!?
2502 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2503 if (r.app != null) {
2504 pw.print(innerPrefix); pw.println(r.app);
2505 }
2506 }
2507 if (client && r.app != null && r.app.thread != null) {
2508 // flush anything that is already in the PrintWriter since the thread is going
2509 // to write to the file descriptor directly
2510 pw.flush();
2511 try {
2512 TransferPipe tp = new TransferPipe();
2513 try {
2514 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2515 r.appToken, innerPrefix, args);
2516 // Short timeout, since blocking here can
2517 // deadlock with the application.
2518 tp.go(fd, 2000);
2519 } finally {
2520 tp.kill();
2521 }
2522 } catch (IOException e) {
2523 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2524 } catch (RemoteException e) {
2525 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2526 }
2527 needNL = true;
2528 }
2529 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002530 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002531 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002532
Craig Mautnerf3333272013-04-22 10:55:53 -07002533 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002534 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002535 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2536 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002537 }
2538
2539 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002540 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002541 }
2542
2543 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002544 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002545 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2546 }
2547
Craig Mautner05d29032013-05-03 13:40:13 -07002548 final void scheduleResumeTopActivities() {
2549 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2550 }
2551
Craig Mautner0eea92c2013-05-16 13:35:39 -07002552 void removeSleepTimeouts() {
2553 mSleepTimeout = false;
2554 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2555 }
2556
2557 final void scheduleSleepTimeout() {
2558 removeSleepTimeouts();
2559 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2560 }
2561
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002562 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002563
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002564 public ActivityStackSupervisorHandler(Looper looper) {
2565 super(looper);
2566 }
2567
Craig Mautnerf3333272013-04-22 10:55:53 -07002568 void activityIdleInternal(ActivityRecord r) {
2569 synchronized (mService) {
2570 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2571 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002572 }
2573
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002574 @Override
2575 public void handleMessage(Message msg) {
2576 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002577 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002578 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002579 if (mService.mDidDexOpt) {
2580 mService.mDidDexOpt = false;
2581 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2582 nmsg.obj = msg.obj;
2583 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2584 return;
2585 }
2586 // We don't at this point know if the activity is fullscreen,
2587 // so we need to be conservative and assume it isn't.
2588 activityIdleInternal((ActivityRecord)msg.obj);
2589 } break;
2590 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002591 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002592 activityIdleInternal((ActivityRecord)msg.obj);
2593 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002594 case RESUME_TOP_ACTIVITY_MSG: {
2595 synchronized (mService) {
2596 resumeTopActivitiesLocked();
2597 }
2598 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002599 case SLEEP_TIMEOUT_MSG: {
2600 synchronized (mService) {
2601 if (mService.isSleepingOrShuttingDown()) {
2602 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2603 mSleepTimeout = true;
2604 checkReadyForSleepLocked();
2605 }
2606 }
2607 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002608 case LAUNCH_TIMEOUT_MSG: {
2609 if (mService.mDidDexOpt) {
2610 mService.mDidDexOpt = false;
2611 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2612 return;
2613 }
2614 synchronized (mService) {
2615 if (mLaunchingActivity.isHeld()) {
2616 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2617 if (VALIDATE_WAKE_LOCK_CALLER
2618 && Binder.getCallingUid() != Process.myUid()) {
2619 throw new IllegalStateException("Calling must be system uid");
2620 }
2621 mLaunchingActivity.release();
2622 }
2623 }
2624 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002625 }
2626 }
2627 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002628
Craig Mautnerac6f8432013-07-17 13:24:59 -07002629 String getHomePackageName() {
2630 return mHomePackageNames.get(mCurrentUser);
2631 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002632
Craig Mautnerac6f8432013-07-17 13:24:59 -07002633 void setHomePackageName(int userId, String homePackageName) {
2634 if (DEBUG_SWITCH) Slog.d(TAG, "setHomePackageName: user=" + userId + " package="
2635 + homePackageName);
2636 mHomePackageNames.put(userId, homePackageName);
Craig Mautner858d8a62013-04-23 17:08:34 -07002637 }
Craig Mautner27084302013-03-25 08:05:25 -07002638}