blob: 95a35ded167f31d5e90d763f2e08300fb97ecc50 [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;
91 static final boolean DEBUG_STATES = DEBUG || false;
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 }
915 mService.updateLruProcessLocked(app, true);
916
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 Mautnere428a7f2013-08-17 17:04:56 -0700938 mService.mHomeProcess.add(app);
Craig Mautner2420ead2013-04-01 17:13:20 -0700939 }
940 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
941 r.sleeping = false;
942 r.forceNewConfig = false;
943 mService.showAskCompatModeDialogLocked(r);
944 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
945 String profileFile = null;
946 ParcelFileDescriptor profileFd = null;
947 boolean profileAutoStop = false;
948 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
949 if (mService.mProfileProc == null || mService.mProfileProc == app) {
950 mService.mProfileProc = app;
951 profileFile = mService.mProfileFile;
952 profileFd = mService.mProfileFd;
953 profileAutoStop = mService.mAutoStopProfiler;
954 }
955 }
956 app.hasShownUi = true;
957 app.pendingUiClean = true;
958 if (profileFd != null) {
959 try {
960 profileFd = profileFd.dup();
961 } catch (IOException e) {
962 if (profileFd != null) {
963 try {
964 profileFd.close();
965 } catch (IOException o) {
966 }
967 profileFd = null;
968 }
969 }
970 }
Dianne Hackborna413dc02013-07-12 12:02:55 -0700971 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -0700972 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
973 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -0700974 new Configuration(mService.mConfiguration), r.compat,
975 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -0700976 mService.isNextTransitionForward(), profileFile, profileFd,
977 profileAutoStop);
978
979 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
980 // This may be a heavy-weight process! Note that the package
981 // manager will ensure that only activity can run in the main
982 // process of the .apk, which is the only thing that will be
983 // considered heavy-weight.
984 if (app.processName.equals(app.info.packageName)) {
985 if (mService.mHeavyWeightProcess != null
986 && mService.mHeavyWeightProcess != app) {
987 Slog.w(TAG, "Starting new heavy weight process " + app
988 + " when already running "
989 + mService.mHeavyWeightProcess);
990 }
991 mService.mHeavyWeightProcess = app;
992 Message msg = mService.mHandler.obtainMessage(
993 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
994 msg.obj = r;
995 mService.mHandler.sendMessage(msg);
996 }
997 }
998
999 } catch (RemoteException e) {
1000 if (r.launchFailed) {
1001 // This is the second time we failed -- finish activity
1002 // and give up.
1003 Slog.e(TAG, "Second failure launching "
1004 + r.intent.getComponent().flattenToShortString()
1005 + ", giving up", e);
1006 mService.appDiedLocked(app, app.pid, app.thread);
1007 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1008 "2nd-crash", false);
1009 return false;
1010 }
1011
1012 // This is the first time we failed -- restart process and
1013 // retry.
1014 app.activities.remove(r);
1015 throw e;
1016 }
1017
1018 r.launchFailed = false;
1019 if (stack.updateLRUListLocked(r)) {
1020 Slog.w(TAG, "Activity " + r
1021 + " being launched, but already in LRU list");
1022 }
1023
1024 if (andResume) {
1025 // As part of the process of launching, ActivityThread also performs
1026 // a resume.
1027 stack.minimalResumeActivityLocked(r);
1028 } else {
1029 // This activity is not starting in the resumed state... which
1030 // should look like we asked it to pause+stop (but remain visible),
1031 // and it has done so and reported back the current icicle and
1032 // other state.
1033 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1034 + " (starting in stopped state)");
1035 r.state = ActivityState.STOPPED;
1036 r.stopped = true;
1037 }
1038
1039 // Launch the new version setup screen if needed. We do this -after-
1040 // launching the initial activity (that is, home), so that it can have
1041 // a chance to initialize itself while in the background, making the
1042 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001043 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001044 mService.startSetupActivityLocked();
1045 }
1046
1047 return true;
1048 }
1049
Craig Mautnere79d42682013-04-01 19:01:53 -07001050 void startSpecificActivityLocked(ActivityRecord r,
1051 boolean andResume, boolean checkConfig) {
1052 // Is this activity's application already running?
1053 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1054 r.info.applicationInfo.uid);
1055
1056 r.task.stack.setLaunchTime(r);
1057
1058 if (app != null && app.thread != null) {
1059 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001060 app.addPackage(r.info.packageName, mService.mProcessStats);
Craig Mautnere79d42682013-04-01 19:01:53 -07001061 realStartActivityLocked(r, app, andResume, checkConfig);
1062 return;
1063 } catch (RemoteException e) {
1064 Slog.w(TAG, "Exception when starting activity "
1065 + r.intent.getComponent().flattenToShortString(), e);
1066 }
1067
1068 // If a dead object exception was thrown -- fall through to
1069 // restart the application.
1070 }
1071
1072 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1073 "activity", r.intent.getComponent(), false, false);
1074 }
1075
Craig Mautner6170f732013-04-02 13:05:23 -07001076 final int startActivityLocked(IApplicationThread caller,
1077 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1078 String resultWho, int requestCode,
1079 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1080 boolean componentSpecified, ActivityRecord[] outActivity) {
1081 int err = ActivityManager.START_SUCCESS;
1082
1083 ProcessRecord callerApp = null;
1084 if (caller != null) {
1085 callerApp = mService.getRecordForAppLocked(caller);
1086 if (callerApp != null) {
1087 callingPid = callerApp.pid;
1088 callingUid = callerApp.info.uid;
1089 } else {
1090 Slog.w(TAG, "Unable to find app for caller " + caller
1091 + " (pid=" + callingPid + ") when starting: "
1092 + intent.toString());
1093 err = ActivityManager.START_PERMISSION_DENIED;
1094 }
1095 }
1096
1097 if (err == ActivityManager.START_SUCCESS) {
1098 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1099 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1100 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1101 }
1102
1103 ActivityRecord sourceRecord = null;
1104 ActivityRecord resultRecord = null;
1105 if (resultTo != null) {
1106 sourceRecord = isInAnyStackLocked(resultTo);
1107 if (DEBUG_RESULTS) Slog.v(
1108 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1109 if (sourceRecord != null) {
1110 if (requestCode >= 0 && !sourceRecord.finishing) {
1111 resultRecord = sourceRecord;
1112 }
1113 }
1114 }
1115 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1116
1117 int launchFlags = intent.getFlags();
1118
1119 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1120 && sourceRecord != null) {
1121 // Transfer the result target from the source activity to the new
1122 // one being started, including any failures.
1123 if (requestCode >= 0) {
1124 ActivityOptions.abort(options);
1125 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1126 }
1127 resultRecord = sourceRecord.resultTo;
1128 resultWho = sourceRecord.resultWho;
1129 requestCode = sourceRecord.requestCode;
1130 sourceRecord.resultTo = null;
1131 if (resultRecord != null) {
1132 resultRecord.removeResultsLocked(
1133 sourceRecord, resultWho, requestCode);
1134 }
1135 }
1136
1137 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1138 // We couldn't find a class that can handle the given Intent.
1139 // That's the end of that!
1140 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1141 }
1142
1143 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1144 // We couldn't find the specific class specified in the Intent.
1145 // Also the end of the line.
1146 err = ActivityManager.START_CLASS_NOT_FOUND;
1147 }
1148
1149 if (err != ActivityManager.START_SUCCESS) {
1150 if (resultRecord != null) {
1151 resultStack.sendActivityResultLocked(-1,
1152 resultRecord, resultWho, requestCode,
1153 Activity.RESULT_CANCELED, null);
1154 }
1155 setDismissKeyguard(false);
1156 ActivityOptions.abort(options);
1157 return err;
1158 }
1159
1160 final int startAnyPerm = mService.checkPermission(
1161 START_ANY_ACTIVITY, callingPid, callingUid);
1162 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1163 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1164 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1165 if (resultRecord != null) {
1166 resultStack.sendActivityResultLocked(-1,
1167 resultRecord, resultWho, requestCode,
1168 Activity.RESULT_CANCELED, null);
1169 }
1170 setDismissKeyguard(false);
1171 String msg;
1172 if (!aInfo.exported) {
1173 msg = "Permission Denial: starting " + intent.toString()
1174 + " from " + callerApp + " (pid=" + callingPid
1175 + ", uid=" + callingUid + ")"
1176 + " not exported from uid " + aInfo.applicationInfo.uid;
1177 } else {
1178 msg = "Permission Denial: starting " + intent.toString()
1179 + " from " + callerApp + " (pid=" + callingPid
1180 + ", uid=" + callingUid + ")"
1181 + " requires " + aInfo.permission;
1182 }
1183 Slog.w(TAG, msg);
1184 throw new SecurityException(msg);
1185 }
1186
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001187 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001188 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001189
Craig Mautner6170f732013-04-02 13:05:23 -07001190 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001191 try {
1192 // The Intent we give to the watcher has the extra data
1193 // stripped off, since it can contain private information.
1194 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001195 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001196 aInfo.applicationInfo.packageName);
1197 } catch (RemoteException e) {
1198 mService.mController = null;
1199 }
Ben Gruver5e207332013-04-03 17:41:37 -07001200 }
Craig Mautner6170f732013-04-02 13:05:23 -07001201
Ben Gruver5e207332013-04-03 17:41:37 -07001202 if (abort) {
1203 if (resultRecord != null) {
1204 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001205 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001206 }
Ben Gruver5e207332013-04-03 17:41:37 -07001207 // We pretend to the caller that it was really started, but
1208 // they will just get a cancel result.
1209 setDismissKeyguard(false);
1210 ActivityOptions.abort(options);
1211 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001212 }
1213
1214 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1215 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001216 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001217 if (outActivity != null) {
1218 outActivity[0] = r;
1219 }
1220
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001221 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001222 if (stack.mResumedActivity == null
1223 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001224 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1225 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001226 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001227 mService.mPendingActivityLaunches.add(pal);
1228 setDismissKeyguard(false);
1229 ActivityOptions.abort(options);
1230 return ActivityManager.START_SWITCHES_CANCELED;
1231 }
1232 }
1233
1234 if (mService.mDidAppSwitch) {
1235 // This is the second allowed switch since we stopped switches,
1236 // so now just generally allow switches. Use case: user presses
1237 // home (switches disabled, switch to home, mDidAppSwitch now true);
1238 // user taps a home icon (coming from home so allowed, we hit here
1239 // and now allow anyone to switch again).
1240 mService.mAppSwitchesAllowedTime = 0;
1241 } else {
1242 mService.mDidAppSwitch = true;
1243 }
1244
1245 mService.doPendingActivityLaunchesLocked(false);
1246
Craig Mautner8849a5e2013-04-02 16:41:03 -07001247 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001248 if (stack.mPausingActivity == null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001249 // Someone asked to have the keyguard dismissed on the next
1250 // activity start, but we are not actually doing an activity
1251 // switch... just dismiss the keyguard now, because we
1252 // probably want to see whatever is behind it.
1253 dismissKeyguard();
1254 }
1255 return err;
1256 }
1257
Craig Mautnerac6f8432013-07-17 13:24:59 -07001258 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001259 final TaskRecord task = r.task;
1260 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001261 if (task != null) {
1262 if (mFocusedStack != task.stack) {
1263 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1264 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
1265 mFocusedStack = task.stack;
1266 } else {
1267 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1268 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1269 }
1270 return mFocusedStack;
1271 }
1272
1273 if (mFocusedStack != null) {
1274 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1275 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1276 return mFocusedStack;
1277 }
1278
1279 for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1280 ActivityStack stack = mStacks.get(stackNdx);
1281 if (!stack.isHomeStack()) {
1282 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1283 "adjustStackFocus: Setting focused stack=" + stack);
1284 mFocusedStack = stack;
1285 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001286 }
1287 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001288
1289 // Time to create the first app stack for this user.
1290 int stackId = mService.createStack(-1, HOME_STACK_ID,
1291 StackBox.TASK_STACK_GOES_OVER, 1.0f);
1292 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1293 " stackId=" + stackId);
1294 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001295 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001296 }
1297 return mHomeStack;
1298 }
1299
Craig Mautner29219d92013-04-16 20:19:12 -07001300 void setFocusedStack(ActivityRecord r) {
1301 if (r == null) {
1302 return;
1303 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001304 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001305 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautnere7c58b62013-06-12 20:19:00 -07001306 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
Craig Mautner76ea2242013-05-15 11:40:05 -07001307 stackStateToString(mStackState) + " new=" +
1308 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1309 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001310 mStackState = STACK_STATE_HOME_TO_FRONT;
1311 }
1312 } else {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001313 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1314 "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
1315 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001316 mFocusedStack = r.task.stack;
1317 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001318 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1319 stackStateToString(mStackState) + " new=" +
1320 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1321 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001322 mStackState = STACK_STATE_HOME_TO_BACK;
1323 }
1324 }
1325 }
1326
Craig Mautner8849a5e2013-04-02 16:41:03 -07001327 final int startActivityUncheckedLocked(ActivityRecord r,
1328 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1329 Bundle options) {
1330 final Intent intent = r.intent;
1331 final int callingUid = r.launchedFromUid;
1332
1333 int launchFlags = intent.getFlags();
1334
Craig Mautner8849a5e2013-04-02 16:41:03 -07001335 // We'll invoke onUserLeaving before onPause only if the launching
1336 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001337 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1338 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001339
1340 // If the caller has asked not to resume at this point, we make note
1341 // of this in the record so that we can skip it when trying to find
1342 // the top running activity.
1343 if (!doResume) {
1344 r.delayedResume = true;
1345 }
1346
1347 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1348
1349 // If the onlyIfNeeded flag is set, then we can do this if the activity
1350 // being launched is the same as the one making the call... or, as
1351 // a special case, if we do not know the caller then we count the
1352 // current top activity as the caller.
1353 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1354 ActivityRecord checkedCaller = sourceRecord;
1355 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001356 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001357 }
1358 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1359 // Caller is not the same as launcher, so always needed.
1360 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1361 }
1362 }
1363
1364 if (sourceRecord == null) {
1365 // This activity is not being started from another... in this
1366 // case we -always- start a new task.
1367 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001368 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1369 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001370 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1371 }
1372 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1373 // The original activity who is starting us is running as a single
1374 // instance... this new activity it is starting must go on its
1375 // own task.
1376 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1377 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1378 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1379 // The activity being started is a single instance... it always
1380 // gets launched into its own task.
1381 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1382 }
1383
Craig Mautnerde4ef022013-04-07 19:01:33 -07001384 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001385 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001386 if (sourceRecord != null) {
1387 sourceTask = sourceRecord.task;
1388 sourceStack = sourceTask.stack;
1389 } else {
1390 sourceTask = null;
1391 sourceStack = null;
1392 }
1393
Craig Mautner8849a5e2013-04-02 16:41:03 -07001394 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1395 // For whatever reason this activity is being launched into a new
1396 // task... yet the caller has requested a result back. Well, that
1397 // is pretty messed up, so instead immediately send back a cancel
1398 // and let the new task continue launched as normal without a
1399 // dependency on its originator.
1400 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1401 r.resultTo.task.stack.sendActivityResultLocked(-1,
1402 r.resultTo, r.resultWho, r.requestCode,
1403 Activity.RESULT_CANCELED, null);
1404 r.resultTo = null;
1405 }
1406
1407 boolean addingToTask = false;
1408 boolean movedHome = false;
1409 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001410 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001411 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1412 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1413 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1414 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1415 // If bring to front is requested, and no result is requested, and
1416 // we can find a task that was started with this same
1417 // component, then instead of launching bring that one to the front.
1418 if (r.resultTo == null) {
1419 // See if there is a task to bring to the front. If this is
1420 // a SINGLE_INSTANCE activity, there can be one and only one
1421 // instance of it in the history, and it is always in its own
1422 // unique task, so we do a special search.
1423 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001424 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001425 : findActivityLocked(intent, r.info);
1426 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001427 if (r.task == null) {
1428 r.task = intentActivity.task;
1429 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001430 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001431 targetStack.mLastPausedActivity = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001432 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001433 if (intentActivity.task.intent == null) {
1434 // This task was started because of movement of
1435 // the activity based on affinity... now that we
1436 // are actually launching it, we can assign the
1437 // base intent.
1438 intentActivity.task.setIntent(intent, r.info);
1439 }
1440 // If the target task is not in the front, then we need
1441 // to bring it to the front... except... well, with
1442 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1443 // to have the same behavior as if a new instance was
1444 // being started, which means not bringing it to the front
1445 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001446 final ActivityStack lastStack = getLastStack();
1447 ActivityRecord curTop = lastStack == null?
1448 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001449 if (curTop != null && (curTop.task != intentActivity.task ||
1450 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001451 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001452 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1453 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001454 // We really do want to push this one into the
1455 // user's face, right now.
1456 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001457 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001458 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1459 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001460 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001461 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001462 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001463 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1464 options = null;
1465 }
1466 }
1467 // If the caller has requested that the target task be
1468 // reset, then do so.
1469 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1470 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1471 }
1472 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1473 // We don't need to start a new activity, and
1474 // the client said not to do anything if that
1475 // is the case, so this is it! And for paranoia, make
1476 // sure we have correctly resumed the top activity.
1477 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001478 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001479 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001480 } else {
1481 ActivityOptions.abort(options);
1482 }
Craig Mautner29219d92013-04-16 20:19:12 -07001483 if (r.task == null) Slog.v(TAG,
1484 "startActivityUncheckedLocked: task left null",
1485 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001486 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1487 }
1488 if ((launchFlags &
1489 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1490 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1491 // The caller has requested to completely replace any
1492 // existing task with its new activity. Well that should
1493 // not be too hard...
1494 reuseTask = intentActivity.task;
1495 reuseTask.performClearTaskLocked();
1496 reuseTask.setIntent(r.intent, r.info);
1497 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1498 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1499 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1500 // In this situation we want to remove all activities
1501 // from the task up to the one being started. In most
1502 // cases this means we are resetting the task to its
1503 // initial state.
1504 ActivityRecord top =
1505 intentActivity.task.performClearTaskLocked(r, launchFlags);
1506 if (top != null) {
1507 if (top.frontOfTask) {
1508 // Activity aliases may mean we use different
1509 // intents for the top activity, so make sure
1510 // the task now has the identity of the new
1511 // intent.
1512 top.task.setIntent(r.intent, r.info);
1513 }
1514 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1515 r, top.task);
1516 top.deliverNewIntentLocked(callingUid, r.intent);
1517 } else {
1518 // A special case: we need to
1519 // start the activity because it is not currently
1520 // running, and the caller has asked to clear the
1521 // current task to have this activity at the top.
1522 addingToTask = true;
1523 // Now pretend like this activity is being started
1524 // by the top of its task, so it is put in the
1525 // right place.
1526 sourceRecord = intentActivity;
1527 }
1528 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1529 // In this case the top activity on the task is the
1530 // same as the one being launched, so we take that
1531 // as a request to bring the task to the foreground.
1532 // If the top activity in the task is the root
1533 // activity, deliver this new intent to it if it
1534 // desires.
1535 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1536 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1537 && intentActivity.realActivity.equals(r.realActivity)) {
1538 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1539 intentActivity.task);
1540 if (intentActivity.frontOfTask) {
1541 intentActivity.task.setIntent(r.intent, r.info);
1542 }
1543 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1544 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1545 // In this case we are launching the root activity
1546 // of the task, but with a different intent. We
1547 // should start a new instance on top.
1548 addingToTask = true;
1549 sourceRecord = intentActivity;
1550 }
1551 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1552 // In this case an activity is being launched in to an
1553 // existing task, without resetting that task. This
1554 // is typically the situation of launching an activity
1555 // from a notification or shortcut. We want to place
1556 // the new activity on top of the current task.
1557 addingToTask = true;
1558 sourceRecord = intentActivity;
1559 } else if (!intentActivity.task.rootWasReset) {
1560 // In this case we are launching in to an existing task
1561 // that has not yet been started from its front door.
1562 // The current task has been brought to the front.
1563 // Ideally, we'd probably like to place this new task
1564 // at the bottom of its stack, but that's a little hard
1565 // to do with the current organization of the code so
1566 // for now we'll just drop it.
1567 intentActivity.task.setIntent(r.intent, r.info);
1568 }
1569 if (!addingToTask && reuseTask == null) {
1570 // We didn't do anything... but it was needed (a.k.a., client
1571 // don't use that intent!) And for paranoia, make
1572 // sure we have correctly resumed the top activity.
1573 if (doResume) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001574 // Reset flag so it gets correctly reevaluated.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001575 intentActivity.task.mOnTopOfHome = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001576 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1577 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001578 } else {
1579 ActivityOptions.abort(options);
1580 }
Craig Mautner29219d92013-04-16 20:19:12 -07001581 if (r.task == null) Slog.v(TAG,
1582 "startActivityUncheckedLocked: task left null",
1583 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001584 return ActivityManager.START_TASK_TO_FRONT;
1585 }
1586 }
1587 }
1588 }
1589
1590 //String uri = r.intent.toURI();
1591 //Intent intent2 = new Intent(uri);
1592 //Slog.i(TAG, "Given intent: " + r.intent);
1593 //Slog.i(TAG, "URI is: " + uri);
1594 //Slog.i(TAG, "To intent: " + intent2);
1595
1596 if (r.packageName != null) {
1597 // If the activity being launched is the same as the one currently
1598 // at the top, then we need to check if it should only be launched
1599 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001600 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001601 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001602 if (top != null && r.resultTo == null) {
1603 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1604 if (top.app != null && top.app.thread != null) {
1605 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1606 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1607 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1608 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1609 top.task);
1610 // For paranoia, make sure we have correctly
1611 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001612 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001613 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001614 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001615 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001616 }
1617 ActivityOptions.abort(options);
1618 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1619 // We don't need to start a new activity, and
1620 // the client said not to do anything if that
1621 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001622 if (r.task == null) Slog.v(TAG,
1623 "startActivityUncheckedLocked: task left null",
1624 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001625 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1626 }
1627 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001628 if (r.task == null) Slog.v(TAG,
1629 "startActivityUncheckedLocked: task left null",
1630 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001631 return ActivityManager.START_DELIVERED_TO_TOP;
1632 }
1633 }
1634 }
1635 }
1636
1637 } else {
1638 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001639 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1640 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001641 }
1642 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001643 if (r.task == null) Slog.v(TAG,
1644 "startActivityUncheckedLocked: task left null",
1645 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001646 return ActivityManager.START_CLASS_NOT_FOUND;
1647 }
1648
1649 boolean newTask = false;
1650 boolean keepCurTransition = false;
1651
1652 // Should this be considered a new task?
1653 if (r.resultTo == null && !addingToTask
1654 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001655 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001656 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001657 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001658 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1659 null, true);
1660 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1661 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001662 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001663 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001664 }
1665 newTask = true;
1666 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001667 if ((launchFlags &
1668 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1669 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1670 // Caller wants to appear on home activity, so before starting
1671 // their own activity we will bring home to the front.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001672 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001673 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001674 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001675 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001676 sourceTask = sourceRecord.task;
1677 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001678 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001679 if (!addingToTask &&
1680 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1681 // In this case, we are adding the activity to an existing
1682 // task, but the caller has asked to clear that task if the
1683 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001684 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001685 keepCurTransition = true;
1686 if (top != null) {
1687 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1688 top.deliverNewIntentLocked(callingUid, r.intent);
1689 // For paranoia, make sure we have correctly
1690 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001691 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001692 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001693 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001694 targetStack.resumeTopActivityLocked(null);
1695 }
1696 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001697 if (r.task == null) Slog.v(TAG,
1698 "startActivityUncheckedLocked: task left null",
1699 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001700 return ActivityManager.START_DELIVERED_TO_TOP;
1701 }
1702 } else if (!addingToTask &&
1703 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1704 // In this case, we are launching an activity in our own task
1705 // that may already be running somewhere in the history, and
1706 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001707 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001708 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001709 final TaskRecord task = top.task;
1710 task.moveActivityToFrontLocked(top);
1711 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001712 top.updateOptionsLocked(options);
1713 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001714 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001715 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001716 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001717 targetStack.resumeTopActivityLocked(null);
1718 }
1719 return ActivityManager.START_DELIVERED_TO_TOP;
1720 }
1721 }
1722 // An existing activity is starting this new activity, so we want
1723 // to keep the new one in the same task as the one that is starting
1724 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001725 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001726 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1727 + " in existing task " + r.task);
1728
1729 } else {
1730 // This not being started from an existing activity, and not part
1731 // of a new task... just put it in the top task, though these days
1732 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001733 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001734 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001735 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001736 r.setTask(prev != null ? prev.task
1737 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1738 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001739 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1740 + " in new guessed " + r.task);
1741 }
1742
1743 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1744 intent, r.getUriPermissionsLocked());
1745
1746 if (newTask) {
1747 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1748 }
1749 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001750 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
Craig Mautner0f922742013-08-06 08:44:42 -07001751 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001752 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001753 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001754 return ActivityManager.START_SUCCESS;
1755 }
1756
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001757 void acquireLaunchWakelock() {
1758 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1759 throw new IllegalStateException("Calling must be system uid");
1760 }
1761 mLaunchingActivity.acquire();
1762 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1763 // To be safe, don't allow the wake lock to be held for too long.
1764 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1765 }
1766 }
1767
Craig Mautnerf3333272013-04-22 10:55:53 -07001768 // Checked.
1769 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1770 Configuration config) {
1771 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1772
Craig Mautnerf3333272013-04-22 10:55:53 -07001773 ArrayList<ActivityRecord> stops = null;
1774 ArrayList<ActivityRecord> finishes = null;
1775 ArrayList<UserStartedState> startingUsers = null;
1776 int NS = 0;
1777 int NF = 0;
1778 IApplicationThread sendThumbnail = null;
1779 boolean booting = false;
1780 boolean enableScreen = false;
1781 boolean activityRemoved = false;
1782
1783 ActivityRecord r = ActivityRecord.forToken(token);
1784 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001785 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1786 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001787 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1788 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001789 if (fromTimeout) {
1790 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001791 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001792
1793 // This is a hack to semi-deal with a race condition
1794 // in the client where it can be constructed with a
1795 // newer configuration from when we asked it to launch.
1796 // We'll update with whatever configuration it now says
1797 // it used to launch.
1798 if (config != null) {
1799 r.configuration = config;
1800 }
1801
1802 // We are now idle. If someone is waiting for a thumbnail from
1803 // us, we can now deliver.
1804 r.idle = true;
1805
1806 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1807 sendThumbnail = r.app.thread;
1808 r.thumbnailNeeded = false;
1809 }
1810
1811 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1812 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1813 mService.mBooted = true;
1814 enableScreen = true;
1815 }
1816 }
1817
1818 if (allResumedActivitiesIdle()) {
1819 if (r != null) {
1820 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001821 }
1822
1823 if (mLaunchingActivity.isHeld()) {
1824 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1825 if (VALIDATE_WAKE_LOCK_CALLER &&
1826 Binder.getCallingUid() != Process.myUid()) {
1827 throw new IllegalStateException("Calling must be system uid");
1828 }
1829 mLaunchingActivity.release();
1830 }
1831 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001832 }
1833
1834 // Atomically retrieve all of the other things to do.
1835 stops = processStoppingActivitiesLocked(true);
1836 NS = stops != null ? stops.size() : 0;
1837 if ((NF=mFinishingActivities.size()) > 0) {
1838 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1839 mFinishingActivities.clear();
1840 }
1841
1842 final ArrayList<ActivityRecord> thumbnails;
1843 final int NT = mCancelledThumbnails.size();
1844 if (NT > 0) {
1845 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1846 mCancelledThumbnails.clear();
1847 } else {
1848 thumbnails = null;
1849 }
1850
1851 if (isFrontStack(mHomeStack)) {
1852 booting = mService.mBooting;
1853 mService.mBooting = false;
1854 }
1855
1856 if (mStartingUsers.size() > 0) {
1857 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1858 mStartingUsers.clear();
1859 }
1860
1861 // Perform the following actions from unsynchronized state.
1862 final IApplicationThread thumbnailThread = sendThumbnail;
1863 mHandler.post(new Runnable() {
1864 @Override
1865 public void run() {
1866 if (thumbnailThread != null) {
1867 try {
1868 thumbnailThread.requestThumbnail(token);
1869 } catch (Exception e) {
1870 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1871 mService.sendPendingThumbnail(null, token, null, null, true);
1872 }
1873 }
1874
1875 // Report back to any thumbnail receivers.
1876 for (int i = 0; i < NT; i++) {
1877 ActivityRecord r = thumbnails.get(i);
1878 mService.sendPendingThumbnail(r, null, null, null, true);
1879 }
1880 }
1881 });
1882
1883 // Stop any activities that are scheduled to do so but have been
1884 // waiting for the next one to start.
1885 for (int i = 0; i < NS; i++) {
1886 r = stops.get(i);
1887 final ActivityStack stack = r.task.stack;
1888 if (r.finishing) {
1889 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1890 } else {
1891 stack.stopActivityLocked(r);
1892 }
1893 }
1894
1895 // Finish any activities that are scheduled to do so but have been
1896 // waiting for the next one to start.
1897 for (int i = 0; i < NF; i++) {
1898 r = finishes.get(i);
1899 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1900 }
1901
1902 if (booting) {
1903 mService.finishBooting();
1904 } else if (startingUsers != null) {
1905 for (int i = 0; i < startingUsers.size(); i++) {
1906 mService.finishUserSwitch(startingUsers.get(i));
1907 }
1908 }
1909
1910 mService.trimApplications();
1911 //dump();
1912 //mWindowManager.dump();
1913
1914 if (enableScreen) {
1915 mService.enableScreenAfterBoot();
1916 }
1917
1918 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001919 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001920 }
1921
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001922 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001923 }
1924
Craig Mautner8d341ef2013-03-26 09:03:27 -07001925 void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1926 // Just in case.
1927 final int numStacks = mStacks.size();
1928 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001929 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001930 }
1931 }
1932
1933 void closeSystemDialogsLocked() {
1934 final int numStacks = mStacks.size();
1935 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1936 final ActivityStack stack = mStacks.get(stackNdx);
1937 stack.closeSystemDialogsLocked();
1938 }
1939 }
1940
1941 /**
1942 * @return true if some activity was finished (or would have finished if doit were true).
1943 */
1944 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1945 boolean didSomething = false;
1946 final int numStacks = mStacks.size();
1947 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1948 final ActivityStack stack = mStacks.get(stackNdx);
1949 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1950 didSomething = true;
1951 }
1952 }
1953 return didSomething;
1954 }
1955
Dianne Hackborna413dc02013-07-12 12:02:55 -07001956 void updatePreviousProcessLocked(ActivityRecord r) {
1957 // Now that this process has stopped, we may want to consider
1958 // it to be the previous app to try to keep around in case
1959 // the user wants to return to it.
1960
1961 // First, found out what is currently the foreground app, so that
1962 // we don't blow away the previous app if this activity is being
1963 // hosted by the process that is actually still the foreground.
1964 ProcessRecord fgApp = null;
1965 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1966 final ActivityStack stack = mStacks.get(stackNdx);
1967 if (isFrontStack(stack)) {
1968 if (stack.mResumedActivity != null) {
1969 fgApp = stack.mResumedActivity.app;
1970 } else if (stack.mPausingActivity != null) {
1971 fgApp = stack.mPausingActivity.app;
1972 }
1973 break;
1974 }
1975 }
1976
1977 // Now set this one as the previous process, only if that really
1978 // makes sense to.
1979 if (r.app != null && fgApp != null && r.app != fgApp
1980 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautnere428a7f2013-08-17 17:04:56 -07001981 && !mService.mHomeProcess.contains(r.app)) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07001982 mService.mPreviousProcess = r.app;
1983 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1984 }
1985 }
1986
Craig Mautner05d29032013-05-03 13:40:13 -07001987 boolean resumeTopActivitiesLocked() {
1988 return resumeTopActivitiesLocked(null, null, null);
1989 }
1990
1991 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1992 Bundle targetOptions) {
1993 if (targetStack == null) {
1994 targetStack = getFocusedStack();
1995 }
1996 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001997 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001998 final ActivityStack stack = mStacks.get(stackNdx);
1999 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07002000 if (stack == targetStack) {
2001 result = stack.resumeTopActivityLocked(target, targetOptions);
2002 } else {
2003 stack.resumeTopActivityLocked(null);
2004 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002005 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002006 }
Craig Mautner05d29032013-05-03 13:40:13 -07002007 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002008 }
2009
2010 void finishTopRunningActivityLocked(ProcessRecord app) {
2011 final int numStacks = mStacks.size();
2012 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2013 final ActivityStack stack = mStacks.get(stackNdx);
2014 stack.finishTopRunningActivityLocked(app);
2015 }
2016 }
2017
Craig Mautner8d341ef2013-03-26 09:03:27 -07002018 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2019 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2020 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002021 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
Craig Mautner1d001b62013-06-18 16:52:43 -07002022 mStacks.get(stackNdx));
Craig Mautner8d341ef2013-03-26 09:03:27 -07002023 return;
2024 }
2025 }
2026 }
2027
Craig Mautner967212c2013-04-13 21:10:58 -07002028 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002029 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2030 final ActivityStack stack = mStacks.get(stackNdx);
2031 if (stack.getStackId() == stackId) {
2032 return stack;
2033 }
2034 }
2035 return null;
2036 }
2037
Craig Mautner967212c2013-04-13 21:10:58 -07002038 ArrayList<ActivityStack> getStacks() {
2039 return new ArrayList<ActivityStack>(mStacks);
2040 }
2041
2042 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002043 while (true) {
2044 if (++mLastStackId <= HOME_STACK_ID) {
2045 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002046 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002047 if (getStack(mLastStackId) == null) {
2048 break;
2049 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002050 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002051 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
2052 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002053 }
2054
2055 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002056 final TaskRecord task = anyTaskForIdLocked(taskId);
2057 if (task == null) {
2058 return;
2059 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002060 final ActivityStack stack = getStack(stackId);
2061 if (stack == null) {
2062 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2063 return;
2064 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002065 removeTask(task);
2066 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002067 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002068 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002069 }
2070
Craig Mautnerac6f8432013-07-17 13:24:59 -07002071 ActivityRecord findTaskLocked(ActivityRecord r) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07002072 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07002073 final ActivityStack stack = mStacks.get(stackNdx);
2074 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2075 continue;
2076 }
2077 final ActivityRecord ar = stack.findTaskLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07002078 if (ar != null) {
2079 return ar;
2080 }
2081 }
2082 return null;
2083 }
2084
2085 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2086 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2087 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
2088 if (ar != null) {
2089 return ar;
2090 }
2091 }
2092 return null;
2093 }
2094
Craig Mautner8d341ef2013-03-26 09:03:27 -07002095 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002096 scheduleSleepTimeout();
2097 if (!mGoingToSleep.isHeld()) {
2098 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002099 if (mLaunchingActivity.isHeld()) {
2100 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2101 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002102 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002103 mLaunchingActivity.release();
2104 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002105 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002106 }
2107 }
2108
2109 boolean shutdownLocked(int timeout) {
2110 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002111 goingToSleepLocked();
2112 checkReadyForSleepLocked();
2113
2114 final long endTime = System.currentTimeMillis() + timeout;
2115 while (true) {
2116 boolean cantShutdown = false;
2117 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2118 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2119 }
2120 if (cantShutdown) {
2121 long timeRemaining = endTime - System.currentTimeMillis();
2122 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002123 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002124 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002125 } catch (InterruptedException e) {
2126 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002127 } else {
2128 Slog.w(TAG, "Activity manager shutdown timed out");
2129 timedout = true;
2130 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002131 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002132 } else {
2133 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002134 }
2135 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002136
2137 // Force checkReadyForSleep to complete.
2138 mSleepTimeout = true;
2139 checkReadyForSleepLocked();
2140
Craig Mautner8d341ef2013-03-26 09:03:27 -07002141 return timedout;
2142 }
2143
2144 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002145 removeSleepTimeouts();
2146 if (mGoingToSleep.isHeld()) {
2147 mGoingToSleep.release();
2148 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002149 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002150 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002151 stack.awakeFromSleepingLocked();
2152 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07002153 resumeTopActivitiesLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -07002154 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002155 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002156 mGoingToSleepActivities.clear();
2157 }
2158
2159 void activitySleptLocked(ActivityRecord r) {
2160 mGoingToSleepActivities.remove(r);
2161 checkReadyForSleepLocked();
2162 }
2163
2164 void checkReadyForSleepLocked() {
2165 if (!mService.isSleepingOrShuttingDown()) {
2166 // Do not care.
2167 return;
2168 }
2169
2170 if (!mSleepTimeout) {
2171 boolean dontSleep = false;
2172 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2173 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2174 }
2175
2176 if (mStoppingActivities.size() > 0) {
2177 // Still need to tell some activities to stop; can't sleep yet.
2178 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2179 + mStoppingActivities.size() + " activities");
2180 scheduleIdleLocked();
2181 dontSleep = true;
2182 }
2183
2184 if (mGoingToSleepActivities.size() > 0) {
2185 // Still need to tell some activities to sleep; can't sleep yet.
2186 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2187 + mGoingToSleepActivities.size() + " activities");
2188 dontSleep = true;
2189 }
2190
2191 if (dontSleep) {
2192 return;
2193 }
2194 }
2195
2196 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2197 mStacks.get(stackNdx).goToSleep();
2198 }
2199
2200 removeSleepTimeouts();
2201
2202 if (mGoingToSleep.isHeld()) {
2203 mGoingToSleep.release();
2204 }
2205 if (mService.mShuttingDown) {
2206 mService.notifyAll();
2207 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002208 }
2209
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002210 boolean reportResumedActivityLocked(ActivityRecord r) {
2211 final ActivityStack stack = r.task.stack;
2212 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002213 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002214 }
2215 if (allResumedActivitiesComplete()) {
2216 ensureActivitiesVisibleLocked(null, 0);
2217 mWindowManager.executeAppTransition();
2218 return true;
2219 }
2220 return false;
2221 }
2222
Craig Mautner8d341ef2013-03-26 09:03:27 -07002223 void handleAppCrashLocked(ProcessRecord app) {
2224 final int numStacks = mStacks.size();
2225 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2226 final ActivityStack stack = mStacks.get(stackNdx);
2227 stack.handleAppCrashLocked(app);
2228 }
2229 }
2230
Craig Mautnerde4ef022013-04-07 19:01:33 -07002231 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002232 // First the front stacks. In case any are not fullscreen and are in front of home.
2233 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002234 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002235 final ActivityStack stack = mStacks.get(stackNdx);
2236 if (isFrontStack(stack)) {
2237 showHomeBehindStack =
2238 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2239 }
2240 }
2241 // Now do back stacks.
2242 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2243 final ActivityStack stack = mStacks.get(stackNdx);
2244 if (!isFrontStack(stack)) {
2245 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2246 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002247 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002248 }
2249
2250 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2251 final int numStacks = mStacks.size();
2252 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2253 final ActivityStack stack = mStacks.get(stackNdx);
2254 stack.scheduleDestroyActivities(app, false, reason);
2255 }
2256 }
2257
2258 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner2420ead2013-04-01 17:13:20 -07002259 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002260
2261 final String homePackageName = mService.getHomePackageName();
2262 if (homePackageName != null) {
2263 setHomePackageName(mCurrentUser, homePackageName);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002264 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002265
2266 mStartingUsers.add(uss);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002267 boolean haveActivities = false;
2268 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2269 haveActivities |= mStacks.get(stackNdx).switchUserLocked(userId);
2270 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002271
2272 resumeTopActivitiesLocked();
2273
Craig Mautner8d341ef2013-03-26 09:03:27 -07002274 return haveActivities;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002275 }
2276
Craig Mautnerde4ef022013-04-07 19:01:33 -07002277 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2278 int N = mStoppingActivities.size();
2279 if (N <= 0) return null;
2280
2281 ArrayList<ActivityRecord> stops = null;
2282
2283 final boolean nowVisible = allResumedActivitiesVisible();
2284 for (int i=0; i<N; i++) {
2285 ActivityRecord s = mStoppingActivities.get(i);
2286 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2287 + nowVisible + " waitingVisible=" + s.waitingVisible
2288 + " finishing=" + s.finishing);
2289 if (s.waitingVisible && nowVisible) {
2290 mWaitingVisibleActivities.remove(s);
2291 s.waitingVisible = false;
2292 if (s.finishing) {
2293 // If this activity is finishing, it is sitting on top of
2294 // everyone else but we now know it is no longer needed...
2295 // so get rid of it. Otherwise, we need to go through the
2296 // normal flow and hide it once we determine that it is
2297 // hidden by the activities in front of it.
2298 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002299 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002300 }
2301 }
2302 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2303 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2304 if (stops == null) {
2305 stops = new ArrayList<ActivityRecord>();
2306 }
2307 stops.add(s);
2308 mStoppingActivities.remove(i);
2309 N--;
2310 i--;
2311 }
2312 }
2313
2314 return stops;
2315 }
2316
Craig Mautnercf910b02013-04-23 11:23:27 -07002317 void validateTopActivitiesLocked() {
2318 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2319 final ActivityStack stack = mStacks.get(stackNdx);
2320 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002321 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002322 if (isFrontStack(stack)) {
2323 if (r == null) {
2324 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2325 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002326 final ActivityRecord pausing = stack.mPausingActivity;
2327 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002328 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002329 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002330 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002331 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002332 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002333 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002334 }
2335 }
2336 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002337 final ActivityRecord resumed = stack.mResumedActivity;
2338 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002339 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002340 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002341 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002342 if (r != null && (state == ActivityState.INITIALIZING
2343 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002344 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002345 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002346 }
2347 }
2348 }
2349 }
2350
Craig Mautner76ea2242013-05-15 11:40:05 -07002351 private static String stackStateToString(int stackState) {
2352 switch (stackState) {
2353 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2354 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2355 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2356 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2357 default: return "Unknown stackState=" + stackState;
2358 }
2359 }
2360
Craig Mautner27084302013-03-25 08:05:25 -07002361 public void dump(PrintWriter pw, String prefix) {
2362 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2363 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002364 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002365 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2366 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002367 pw.print(prefix); pw.print("mHomePackageNames:");
2368 for (int i = 0; i < mHomePackageNames.size(); ++i) {
2369 pw.print(" ("); pw.print(mHomePackageNames.keyAt(i)); pw.print(",");
2370 pw.print(mHomePackageNames.valueAt(i)); pw.print(")");
2371 }
2372 pw.println();
Craig Mautner27084302013-03-25 08:05:25 -07002373 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002374
Craig Mautner20e72272013-04-01 13:45:53 -07002375 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002376 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002377 }
2378
Dianne Hackborn390517b2013-05-30 15:03:32 -07002379 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2380 boolean needSep, String prefix) {
2381 if (activity != null) {
2382 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2383 if (needSep) {
2384 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002385 }
2386 pw.print(prefix);
2387 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002388 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002389 }
2390 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002391 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002392 }
2393
Craig Mautner8d341ef2013-03-26 09:03:27 -07002394 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2395 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002396 boolean printed = false;
2397 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002398 final int numStacks = mStacks.size();
2399 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2400 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002401 StringBuilder stackHeader = new StringBuilder(128);
2402 stackHeader.append(" Stack #");
2403 stackHeader.append(mStacks.indexOf(stack));
2404 stackHeader.append(":");
2405 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2406 stackHeader.toString());
2407 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2408 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002409
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002410 needSep = printed;
2411 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002412 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002413 if (pr) {
2414 printed = true;
2415 needSep = false;
2416 }
2417 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002418 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002419 if (pr) {
2420 printed = true;
2421 needSep = false;
2422 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002423 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002424 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002425 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002426 if (pr) {
2427 printed = true;
Craig Mautner0f922742013-08-06 08:44:42 -07002428 needSep = true;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002429 }
Craig Mautner0f922742013-08-06 08:44:42 -07002430 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2431 needSep, " mLastNoHistoryActivity: ");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002432 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002433 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002434 }
2435
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002436 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2437 false, dumpPackage, true, " Activities waiting to finish:", null);
2438 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2439 false, dumpPackage, true, " Activities waiting to stop:", null);
2440 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2441 false, dumpPackage, true, " Activities waiting for another to become visible:",
2442 null);
2443 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2444 false, dumpPackage, true, " Activities waiting to sleep:", null);
2445 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2446 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002447
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002448 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002449 }
2450
Dianne Hackborn390517b2013-05-30 15:03:32 -07002451 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002452 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002453 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002454 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002455 String innerPrefix = null;
2456 String[] args = null;
2457 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002458 for (int i=list.size()-1; i>=0; i--) {
2459 final ActivityRecord r = list.get(i);
2460 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2461 continue;
2462 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002463 if (innerPrefix == null) {
2464 innerPrefix = prefix + " ";
2465 args = new String[0];
2466 }
2467 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002468 final boolean full = !brief && (complete || !r.isInHistory());
2469 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002470 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002471 needNL = false;
2472 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002473 if (header1 != null) {
2474 pw.println(header1);
2475 header1 = null;
2476 }
2477 if (header2 != null) {
2478 pw.println(header2);
2479 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002480 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002481 if (lastTask != r.task) {
2482 lastTask = r.task;
2483 pw.print(prefix);
2484 pw.print(full ? "* " : " ");
2485 pw.println(lastTask);
2486 if (full) {
2487 lastTask.dump(pw, prefix + " ");
2488 } else if (complete) {
2489 // Complete + brief == give a summary. Isn't that obvious?!?
2490 if (lastTask.intent != null) {
2491 pw.print(prefix); pw.print(" ");
2492 pw.println(lastTask.intent.toInsecureStringWithClip());
2493 }
2494 }
2495 }
2496 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2497 pw.print(" #"); pw.print(i); pw.print(": ");
2498 pw.println(r);
2499 if (full) {
2500 r.dump(pw, innerPrefix);
2501 } else if (complete) {
2502 // Complete + brief == give a summary. Isn't that obvious?!?
2503 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2504 if (r.app != null) {
2505 pw.print(innerPrefix); pw.println(r.app);
2506 }
2507 }
2508 if (client && r.app != null && r.app.thread != null) {
2509 // flush anything that is already in the PrintWriter since the thread is going
2510 // to write to the file descriptor directly
2511 pw.flush();
2512 try {
2513 TransferPipe tp = new TransferPipe();
2514 try {
2515 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2516 r.appToken, innerPrefix, args);
2517 // Short timeout, since blocking here can
2518 // deadlock with the application.
2519 tp.go(fd, 2000);
2520 } finally {
2521 tp.kill();
2522 }
2523 } catch (IOException e) {
2524 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2525 } catch (RemoteException e) {
2526 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2527 }
2528 needNL = true;
2529 }
2530 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002531 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002532 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002533
Craig Mautnerf3333272013-04-22 10:55:53 -07002534 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002535 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002536 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2537 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002538 }
2539
2540 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002541 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002542 }
2543
2544 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002545 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002546 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2547 }
2548
Craig Mautner05d29032013-05-03 13:40:13 -07002549 final void scheduleResumeTopActivities() {
2550 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2551 }
2552
Craig Mautner0eea92c2013-05-16 13:35:39 -07002553 void removeSleepTimeouts() {
2554 mSleepTimeout = false;
2555 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2556 }
2557
2558 final void scheduleSleepTimeout() {
2559 removeSleepTimeouts();
2560 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2561 }
2562
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002563 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002564
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002565 public ActivityStackSupervisorHandler(Looper looper) {
2566 super(looper);
2567 }
2568
Craig Mautnerf3333272013-04-22 10:55:53 -07002569 void activityIdleInternal(ActivityRecord r) {
2570 synchronized (mService) {
2571 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2572 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002573 }
2574
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002575 @Override
2576 public void handleMessage(Message msg) {
2577 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002578 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002579 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002580 if (mService.mDidDexOpt) {
2581 mService.mDidDexOpt = false;
2582 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2583 nmsg.obj = msg.obj;
2584 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2585 return;
2586 }
2587 // We don't at this point know if the activity is fullscreen,
2588 // so we need to be conservative and assume it isn't.
2589 activityIdleInternal((ActivityRecord)msg.obj);
2590 } break;
2591 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002592 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002593 activityIdleInternal((ActivityRecord)msg.obj);
2594 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002595 case RESUME_TOP_ACTIVITY_MSG: {
2596 synchronized (mService) {
2597 resumeTopActivitiesLocked();
2598 }
2599 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002600 case SLEEP_TIMEOUT_MSG: {
2601 synchronized (mService) {
2602 if (mService.isSleepingOrShuttingDown()) {
2603 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2604 mSleepTimeout = true;
2605 checkReadyForSleepLocked();
2606 }
2607 }
2608 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002609 case LAUNCH_TIMEOUT_MSG: {
2610 if (mService.mDidDexOpt) {
2611 mService.mDidDexOpt = false;
2612 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2613 return;
2614 }
2615 synchronized (mService) {
2616 if (mLaunchingActivity.isHeld()) {
2617 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2618 if (VALIDATE_WAKE_LOCK_CALLER
2619 && Binder.getCallingUid() != Process.myUid()) {
2620 throw new IllegalStateException("Calling must be system uid");
2621 }
2622 mLaunchingActivity.release();
2623 }
2624 }
2625 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002626 }
2627 }
2628 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002629
Craig Mautnerac6f8432013-07-17 13:24:59 -07002630 String getHomePackageName() {
2631 return mHomePackageNames.get(mCurrentUser);
2632 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002633
Craig Mautnerac6f8432013-07-17 13:24:59 -07002634 void setHomePackageName(int userId, String homePackageName) {
2635 if (DEBUG_SWITCH) Slog.d(TAG, "setHomePackageName: user=" + userId + " package="
2636 + homePackageName);
2637 mHomePackageNames.put(userId, homePackageName);
Craig Mautner858d8a62013-04-23 17:08:34 -07002638 }
Craig Mautner27084302013-03-25 08:05:25 -07002639}