blob: 219cb851adb83c5273b0b0a18790bb5ca751f445 [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 Mautner20e72272013-04-01 13:45:53 -0700551 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
552 final ActivityStack stack = mStacks.get(stackNdx);
553 final ActivityRecord ar =
554 stack.getTasksLocked(maxNum - list.size(), receiver, pending, list);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700555 if (isFrontStack(stack)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700556 r = ar;
557 }
558 }
559 return r;
560 }
561
Craig Mautner23ac33b2013-04-01 16:26:35 -0700562 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
563 String profileFile, ParcelFileDescriptor profileFd, int userId) {
564 // Collect information about the target of the Intent.
565 ActivityInfo aInfo;
566 try {
567 ResolveInfo rInfo =
568 AppGlobals.getPackageManager().resolveIntent(
569 intent, resolvedType,
570 PackageManager.MATCH_DEFAULT_ONLY
571 | ActivityManagerService.STOCK_PM_FLAGS, userId);
572 aInfo = rInfo != null ? rInfo.activityInfo : null;
573 } catch (RemoteException e) {
574 aInfo = null;
575 }
576
577 if (aInfo != null) {
578 // Store the found target back into the intent, because now that
579 // we have it we never want to do this again. For example, if the
580 // user navigates back to this point in the history, we should
581 // always restart the exact same activity.
582 intent.setComponent(new ComponentName(
583 aInfo.applicationInfo.packageName, aInfo.name));
584
585 // Don't debug things in the system process
586 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
587 if (!aInfo.processName.equals("system")) {
588 mService.setDebugApp(aInfo.processName, true, false);
589 }
590 }
591
592 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
593 if (!aInfo.processName.equals("system")) {
594 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
595 }
596 }
597
598 if (profileFile != null) {
599 if (!aInfo.processName.equals("system")) {
600 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
601 profileFile, profileFd,
602 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
603 }
604 }
605 }
606 return aInfo;
607 }
608
Craig Mautner2219a1b2013-03-25 09:44:30 -0700609 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700610 moveHomeStack(true);
Craig Mautner6170f732013-04-02 13:05:23 -0700611 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700612 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700613 }
614
Craig Mautner23ac33b2013-04-01 16:26:35 -0700615 final int startActivityMayWait(IApplicationThread caller, int callingUid,
616 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
617 String resultWho, int requestCode, int startFlags, String profileFile,
618 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
619 Bundle options, int userId) {
620 // Refuse possible leaked file descriptors
621 if (intent != null && intent.hasFileDescriptors()) {
622 throw new IllegalArgumentException("File descriptors passed in Intent");
623 }
624 boolean componentSpecified = intent.getComponent() != null;
625
626 // Don't modify the client's object!
627 intent = new Intent(intent);
628
629 // Collect information about the target of the Intent.
630 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
631 profileFile, profileFd, userId);
632
633 synchronized (mService) {
634 int callingPid;
635 if (callingUid >= 0) {
636 callingPid = -1;
637 } else if (caller == null) {
638 callingPid = Binder.getCallingPid();
639 callingUid = Binder.getCallingUid();
640 } else {
641 callingPid = callingUid = -1;
642 }
643
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700644 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700645 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700646 && mService.mConfiguration.diff(config) != 0;
647 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700648 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700649
650 final long origId = Binder.clearCallingIdentity();
651
652 if (aInfo != null &&
653 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
654 // This may be a heavy-weight process! Check to see if we already
655 // have another, different heavy-weight process running.
656 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
657 if (mService.mHeavyWeightProcess != null &&
658 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
659 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700660 int realCallingUid = callingUid;
661 if (caller != null) {
662 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
663 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700664 realCallingUid = callerApp.info.uid;
665 } else {
666 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700667 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700668 + intent.toString());
669 ActivityOptions.abort(options);
670 return ActivityManager.START_PERMISSION_DENIED;
671 }
672 }
673
674 IIntentSender target = mService.getIntentSenderLocked(
675 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
676 realCallingUid, userId, null, null, 0, new Intent[] { intent },
677 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
678 | PendingIntent.FLAG_ONE_SHOT, null);
679
680 Intent newIntent = new Intent();
681 if (requestCode >= 0) {
682 // Caller is requesting a result.
683 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
684 }
685 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
686 new IntentSender(target));
687 if (mService.mHeavyWeightProcess.activities.size() > 0) {
688 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
689 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
690 hist.packageName);
691 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
692 hist.task.taskId);
693 }
694 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
695 aInfo.packageName);
696 newIntent.setFlags(intent.getFlags());
697 newIntent.setClassName("android",
698 HeavyWeightSwitcherActivity.class.getName());
699 intent = newIntent;
700 resolvedType = null;
701 caller = null;
702 callingUid = Binder.getCallingUid();
703 callingPid = Binder.getCallingPid();
704 componentSpecified = true;
705 try {
706 ResolveInfo rInfo =
707 AppGlobals.getPackageManager().resolveIntent(
708 intent, null,
709 PackageManager.MATCH_DEFAULT_ONLY
710 | ActivityManagerService.STOCK_PM_FLAGS, userId);
711 aInfo = rInfo != null ? rInfo.activityInfo : null;
712 aInfo = mService.getActivityInfoForUser(aInfo, userId);
713 } catch (RemoteException e) {
714 aInfo = null;
715 }
716 }
717 }
718 }
719
Craig Mautner6170f732013-04-02 13:05:23 -0700720 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700721 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
722 callingPackage, startFlags, options, componentSpecified, null);
723
Craig Mautnerde4ef022013-04-07 19:01:33 -0700724 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700725 // If the caller also wants to switch to a new configuration,
726 // do so now. This allows a clean switch, as we are waiting
727 // for the current activity to pause (so we will not destroy
728 // it), and have not yet started the next activity.
729 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
730 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700731 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700732 if (DEBUG_CONFIGURATION) Slog.v(TAG,
733 "Updating to new configuration after starting activity.");
734 mService.updateConfigurationLocked(config, null, false, false);
735 }
736
737 Binder.restoreCallingIdentity(origId);
738
739 if (outResult != null) {
740 outResult.result = res;
741 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700742 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700743 do {
744 try {
745 mService.wait();
746 } catch (InterruptedException e) {
747 }
748 } while (!outResult.timeout && outResult.who == null);
749 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700750 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700751 if (r.nowVisible) {
752 outResult.timeout = false;
753 outResult.who = new ComponentName(r.info.packageName, r.info.name);
754 outResult.totalTime = 0;
755 outResult.thisTime = 0;
756 } else {
757 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700758 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700759 do {
760 try {
761 mService.wait();
762 } catch (InterruptedException e) {
763 }
764 } while (!outResult.timeout && outResult.who == null);
765 }
766 }
767 }
768
769 return res;
770 }
771 }
772
773 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
774 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
775 Bundle options, int userId) {
776 if (intents == null) {
777 throw new NullPointerException("intents is null");
778 }
779 if (resolvedTypes == null) {
780 throw new NullPointerException("resolvedTypes is null");
781 }
782 if (intents.length != resolvedTypes.length) {
783 throw new IllegalArgumentException("intents are length different than resolvedTypes");
784 }
785
Craig Mautner23ac33b2013-04-01 16:26:35 -0700786
787 int callingPid;
788 if (callingUid >= 0) {
789 callingPid = -1;
790 } else if (caller == null) {
791 callingPid = Binder.getCallingPid();
792 callingUid = Binder.getCallingUid();
793 } else {
794 callingPid = callingUid = -1;
795 }
796 final long origId = Binder.clearCallingIdentity();
797 try {
798 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700799 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700800 for (int i=0; i<intents.length; i++) {
801 Intent intent = intents[i];
802 if (intent == null) {
803 continue;
804 }
805
806 // Refuse possible leaked file descriptors
807 if (intent != null && intent.hasFileDescriptors()) {
808 throw new IllegalArgumentException("File descriptors passed in Intent");
809 }
810
811 boolean componentSpecified = intent.getComponent() != null;
812
813 // Don't modify the client's object!
814 intent = new Intent(intent);
815
816 // Collect information about the target of the Intent.
817 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
818 0, null, null, userId);
819 // TODO: New, check if this is correct
820 aInfo = mService.getActivityInfoForUser(aInfo, userId);
821
822 if (aInfo != null &&
823 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
824 != 0) {
825 throw new IllegalArgumentException(
826 "FLAG_CANT_SAVE_STATE not supported here");
827 }
828
829 Bundle theseOptions;
830 if (options != null && i == intents.length-1) {
831 theseOptions = options;
832 } else {
833 theseOptions = null;
834 }
Craig Mautner6170f732013-04-02 13:05:23 -0700835 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700836 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
837 0, theseOptions, componentSpecified, outActivity);
838 if (res < 0) {
839 return res;
840 }
841
842 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
843 }
844 }
845 } finally {
846 Binder.restoreCallingIdentity(origId);
847 }
848
849 return ActivityManager.START_SUCCESS;
850 }
851
Craig Mautner2420ead2013-04-01 17:13:20 -0700852 final boolean realStartActivityLocked(ActivityRecord r,
853 ProcessRecord app, boolean andResume, boolean checkConfig)
854 throws RemoteException {
855
856 r.startFreezingScreenLocked(app, 0);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700857 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700858
859 // schedule launch ticks to collect information about slow apps.
860 r.startLaunchTickingLocked();
861
862 // Have the window manager re-evaluate the orientation of
863 // the screen based on the new activity order. Note that
864 // as a result of this, it can call back into the activity
865 // manager with a new orientation. We don't care about that,
866 // because the activity is not currently running so we are
867 // just restarting it anyway.
868 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700869 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700870 mService.mConfiguration,
871 r.mayFreezeScreenLocked(app) ? r.appToken : null);
872 mService.updateConfigurationLocked(config, r, false, false);
873 }
874
875 r.app = app;
876 app.waitingToKill = null;
877 r.launchCount++;
878 r.lastLaunchTime = SystemClock.uptimeMillis();
879
880 if (localLOGV) Slog.v(TAG, "Launching: " + r);
881
882 int idx = app.activities.indexOf(r);
883 if (idx < 0) {
884 app.activities.add(r);
885 }
886 mService.updateLruProcessLocked(app, true);
887
888 final ActivityStack stack = r.task.stack;
889 try {
890 if (app.thread == null) {
891 throw new RemoteException();
892 }
893 List<ResultInfo> results = null;
894 List<Intent> newIntents = null;
895 if (andResume) {
896 results = r.results;
897 newIntents = r.newIntents;
898 }
899 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
900 + " icicle=" + r.icicle
901 + " with results=" + results + " newIntents=" + newIntents
902 + " andResume=" + andResume);
903 if (andResume) {
904 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
905 r.userId, System.identityHashCode(r),
906 r.task.taskId, r.shortComponentName);
907 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700908 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700909 // Home process is the root process of the task.
910 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700911 }
912 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
913 r.sleeping = false;
914 r.forceNewConfig = false;
915 mService.showAskCompatModeDialogLocked(r);
916 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
917 String profileFile = null;
918 ParcelFileDescriptor profileFd = null;
919 boolean profileAutoStop = false;
920 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
921 if (mService.mProfileProc == null || mService.mProfileProc == app) {
922 mService.mProfileProc = app;
923 profileFile = mService.mProfileFile;
924 profileFd = mService.mProfileFd;
925 profileAutoStop = mService.mAutoStopProfiler;
926 }
927 }
928 app.hasShownUi = true;
929 app.pendingUiClean = true;
930 if (profileFd != null) {
931 try {
932 profileFd = profileFd.dup();
933 } catch (IOException e) {
934 if (profileFd != null) {
935 try {
936 profileFd.close();
937 } catch (IOException o) {
938 }
939 profileFd = null;
940 }
941 }
942 }
Dianne Hackborna413dc02013-07-12 12:02:55 -0700943 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -0700944 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
945 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -0700946 new Configuration(mService.mConfiguration), r.compat,
947 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -0700948 mService.isNextTransitionForward(), profileFile, profileFd,
949 profileAutoStop);
950
951 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
952 // This may be a heavy-weight process! Note that the package
953 // manager will ensure that only activity can run in the main
954 // process of the .apk, which is the only thing that will be
955 // considered heavy-weight.
956 if (app.processName.equals(app.info.packageName)) {
957 if (mService.mHeavyWeightProcess != null
958 && mService.mHeavyWeightProcess != app) {
959 Slog.w(TAG, "Starting new heavy weight process " + app
960 + " when already running "
961 + mService.mHeavyWeightProcess);
962 }
963 mService.mHeavyWeightProcess = app;
964 Message msg = mService.mHandler.obtainMessage(
965 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
966 msg.obj = r;
967 mService.mHandler.sendMessage(msg);
968 }
969 }
970
971 } catch (RemoteException e) {
972 if (r.launchFailed) {
973 // This is the second time we failed -- finish activity
974 // and give up.
975 Slog.e(TAG, "Second failure launching "
976 + r.intent.getComponent().flattenToShortString()
977 + ", giving up", e);
978 mService.appDiedLocked(app, app.pid, app.thread);
979 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
980 "2nd-crash", false);
981 return false;
982 }
983
984 // This is the first time we failed -- restart process and
985 // retry.
986 app.activities.remove(r);
987 throw e;
988 }
989
990 r.launchFailed = false;
991 if (stack.updateLRUListLocked(r)) {
992 Slog.w(TAG, "Activity " + r
993 + " being launched, but already in LRU list");
994 }
995
996 if (andResume) {
997 // As part of the process of launching, ActivityThread also performs
998 // a resume.
999 stack.minimalResumeActivityLocked(r);
1000 } else {
1001 // This activity is not starting in the resumed state... which
1002 // should look like we asked it to pause+stop (but remain visible),
1003 // and it has done so and reported back the current icicle and
1004 // other state.
1005 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1006 + " (starting in stopped state)");
1007 r.state = ActivityState.STOPPED;
1008 r.stopped = true;
1009 }
1010
1011 // Launch the new version setup screen if needed. We do this -after-
1012 // launching the initial activity (that is, home), so that it can have
1013 // a chance to initialize itself while in the background, making the
1014 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001015 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001016 mService.startSetupActivityLocked();
1017 }
1018
1019 return true;
1020 }
1021
Craig Mautnere79d42682013-04-01 19:01:53 -07001022 void startSpecificActivityLocked(ActivityRecord r,
1023 boolean andResume, boolean checkConfig) {
1024 // Is this activity's application already running?
1025 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1026 r.info.applicationInfo.uid);
1027
1028 r.task.stack.setLaunchTime(r);
1029
1030 if (app != null && app.thread != null) {
1031 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001032 app.addPackage(r.info.packageName, mService.mProcessStats);
Craig Mautnere79d42682013-04-01 19:01:53 -07001033 realStartActivityLocked(r, app, andResume, checkConfig);
1034 return;
1035 } catch (RemoteException e) {
1036 Slog.w(TAG, "Exception when starting activity "
1037 + r.intent.getComponent().flattenToShortString(), e);
1038 }
1039
1040 // If a dead object exception was thrown -- fall through to
1041 // restart the application.
1042 }
1043
1044 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1045 "activity", r.intent.getComponent(), false, false);
1046 }
1047
Craig Mautner6170f732013-04-02 13:05:23 -07001048 final int startActivityLocked(IApplicationThread caller,
1049 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1050 String resultWho, int requestCode,
1051 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1052 boolean componentSpecified, ActivityRecord[] outActivity) {
1053 int err = ActivityManager.START_SUCCESS;
1054
1055 ProcessRecord callerApp = null;
1056 if (caller != null) {
1057 callerApp = mService.getRecordForAppLocked(caller);
1058 if (callerApp != null) {
1059 callingPid = callerApp.pid;
1060 callingUid = callerApp.info.uid;
1061 } else {
1062 Slog.w(TAG, "Unable to find app for caller " + caller
1063 + " (pid=" + callingPid + ") when starting: "
1064 + intent.toString());
1065 err = ActivityManager.START_PERMISSION_DENIED;
1066 }
1067 }
1068
1069 if (err == ActivityManager.START_SUCCESS) {
1070 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1071 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1072 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1073 }
1074
1075 ActivityRecord sourceRecord = null;
1076 ActivityRecord resultRecord = null;
1077 if (resultTo != null) {
1078 sourceRecord = isInAnyStackLocked(resultTo);
1079 if (DEBUG_RESULTS) Slog.v(
1080 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1081 if (sourceRecord != null) {
1082 if (requestCode >= 0 && !sourceRecord.finishing) {
1083 resultRecord = sourceRecord;
1084 }
1085 }
1086 }
1087 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1088
1089 int launchFlags = intent.getFlags();
1090
1091 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1092 && sourceRecord != null) {
1093 // Transfer the result target from the source activity to the new
1094 // one being started, including any failures.
1095 if (requestCode >= 0) {
1096 ActivityOptions.abort(options);
1097 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1098 }
1099 resultRecord = sourceRecord.resultTo;
1100 resultWho = sourceRecord.resultWho;
1101 requestCode = sourceRecord.requestCode;
1102 sourceRecord.resultTo = null;
1103 if (resultRecord != null) {
1104 resultRecord.removeResultsLocked(
1105 sourceRecord, resultWho, requestCode);
1106 }
1107 }
1108
1109 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1110 // We couldn't find a class that can handle the given Intent.
1111 // That's the end of that!
1112 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1113 }
1114
1115 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1116 // We couldn't find the specific class specified in the Intent.
1117 // Also the end of the line.
1118 err = ActivityManager.START_CLASS_NOT_FOUND;
1119 }
1120
1121 if (err != ActivityManager.START_SUCCESS) {
1122 if (resultRecord != null) {
1123 resultStack.sendActivityResultLocked(-1,
1124 resultRecord, resultWho, requestCode,
1125 Activity.RESULT_CANCELED, null);
1126 }
1127 setDismissKeyguard(false);
1128 ActivityOptions.abort(options);
1129 return err;
1130 }
1131
1132 final int startAnyPerm = mService.checkPermission(
1133 START_ANY_ACTIVITY, callingPid, callingUid);
1134 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1135 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1136 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1137 if (resultRecord != null) {
1138 resultStack.sendActivityResultLocked(-1,
1139 resultRecord, resultWho, requestCode,
1140 Activity.RESULT_CANCELED, null);
1141 }
1142 setDismissKeyguard(false);
1143 String msg;
1144 if (!aInfo.exported) {
1145 msg = "Permission Denial: starting " + intent.toString()
1146 + " from " + callerApp + " (pid=" + callingPid
1147 + ", uid=" + callingUid + ")"
1148 + " not exported from uid " + aInfo.applicationInfo.uid;
1149 } else {
1150 msg = "Permission Denial: starting " + intent.toString()
1151 + " from " + callerApp + " (pid=" + callingPid
1152 + ", uid=" + callingUid + ")"
1153 + " requires " + aInfo.permission;
1154 }
1155 Slog.w(TAG, msg);
1156 throw new SecurityException(msg);
1157 }
1158
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001159 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001160 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001161
Craig Mautner6170f732013-04-02 13:05:23 -07001162 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001163 try {
1164 // The Intent we give to the watcher has the extra data
1165 // stripped off, since it can contain private information.
1166 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001167 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001168 aInfo.applicationInfo.packageName);
1169 } catch (RemoteException e) {
1170 mService.mController = null;
1171 }
Ben Gruver5e207332013-04-03 17:41:37 -07001172 }
Craig Mautner6170f732013-04-02 13:05:23 -07001173
Ben Gruver5e207332013-04-03 17:41:37 -07001174 if (abort) {
1175 if (resultRecord != null) {
1176 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001177 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001178 }
Ben Gruver5e207332013-04-03 17:41:37 -07001179 // We pretend to the caller that it was really started, but
1180 // they will just get a cancel result.
1181 setDismissKeyguard(false);
1182 ActivityOptions.abort(options);
1183 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001184 }
1185
1186 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1187 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001188 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001189 if (outActivity != null) {
1190 outActivity[0] = r;
1191 }
1192
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001193 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001194 if (stack.mResumedActivity == null
1195 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001196 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1197 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001198 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001199 mService.mPendingActivityLaunches.add(pal);
1200 setDismissKeyguard(false);
1201 ActivityOptions.abort(options);
1202 return ActivityManager.START_SWITCHES_CANCELED;
1203 }
1204 }
1205
1206 if (mService.mDidAppSwitch) {
1207 // This is the second allowed switch since we stopped switches,
1208 // so now just generally allow switches. Use case: user presses
1209 // home (switches disabled, switch to home, mDidAppSwitch now true);
1210 // user taps a home icon (coming from home so allowed, we hit here
1211 // and now allow anyone to switch again).
1212 mService.mAppSwitchesAllowedTime = 0;
1213 } else {
1214 mService.mDidAppSwitch = true;
1215 }
1216
1217 mService.doPendingActivityLaunchesLocked(false);
1218
Craig Mautner8849a5e2013-04-02 16:41:03 -07001219 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001220 if (stack.mPausingActivity == null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001221 // Someone asked to have the keyguard dismissed on the next
1222 // activity start, but we are not actually doing an activity
1223 // switch... just dismiss the keyguard now, because we
1224 // probably want to see whatever is behind it.
1225 dismissKeyguard();
1226 }
1227 return err;
1228 }
1229
Craig Mautnerac6f8432013-07-17 13:24:59 -07001230 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001231 final TaskRecord task = r.task;
1232 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001233 if (task != null) {
1234 if (mFocusedStack != task.stack) {
1235 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1236 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
1237 mFocusedStack = task.stack;
1238 } else {
1239 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1240 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1241 }
1242 return mFocusedStack;
1243 }
1244
1245 if (mFocusedStack != null) {
1246 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1247 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1248 return mFocusedStack;
1249 }
1250
1251 for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1252 ActivityStack stack = mStacks.get(stackNdx);
1253 if (!stack.isHomeStack()) {
1254 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1255 "adjustStackFocus: Setting focused stack=" + stack);
1256 mFocusedStack = stack;
1257 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001258 }
1259 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001260
1261 // Time to create the first app stack for this user.
1262 int stackId = mService.createStack(-1, HOME_STACK_ID,
1263 StackBox.TASK_STACK_GOES_OVER, 1.0f);
1264 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1265 " stackId=" + stackId);
1266 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001267 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001268 }
1269 return mHomeStack;
1270 }
1271
Craig Mautner29219d92013-04-16 20:19:12 -07001272 void setFocusedStack(ActivityRecord r) {
1273 if (r == null) {
1274 return;
1275 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001276 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001277 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautnere7c58b62013-06-12 20:19:00 -07001278 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
Craig Mautner76ea2242013-05-15 11:40:05 -07001279 stackStateToString(mStackState) + " new=" +
1280 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1281 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001282 mStackState = STACK_STATE_HOME_TO_FRONT;
1283 }
1284 } else {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001285 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1286 "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
1287 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001288 mFocusedStack = r.task.stack;
1289 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001290 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1291 stackStateToString(mStackState) + " new=" +
1292 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1293 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001294 mStackState = STACK_STATE_HOME_TO_BACK;
1295 }
1296 }
1297 }
1298
Craig Mautner8849a5e2013-04-02 16:41:03 -07001299 final int startActivityUncheckedLocked(ActivityRecord r,
1300 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1301 Bundle options) {
1302 final Intent intent = r.intent;
1303 final int callingUid = r.launchedFromUid;
1304
1305 int launchFlags = intent.getFlags();
1306
Craig Mautner8849a5e2013-04-02 16:41:03 -07001307 // We'll invoke onUserLeaving before onPause only if the launching
1308 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001309 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1310 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001311
1312 // If the caller has asked not to resume at this point, we make note
1313 // of this in the record so that we can skip it when trying to find
1314 // the top running activity.
1315 if (!doResume) {
1316 r.delayedResume = true;
1317 }
1318
1319 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1320
1321 // If the onlyIfNeeded flag is set, then we can do this if the activity
1322 // being launched is the same as the one making the call... or, as
1323 // a special case, if we do not know the caller then we count the
1324 // current top activity as the caller.
1325 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1326 ActivityRecord checkedCaller = sourceRecord;
1327 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001328 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001329 }
1330 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1331 // Caller is not the same as launcher, so always needed.
1332 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1333 }
1334 }
1335
1336 if (sourceRecord == null) {
1337 // This activity is not being started from another... in this
1338 // case we -always- start a new task.
1339 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001340 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1341 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001342 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1343 }
1344 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1345 // The original activity who is starting us is running as a single
1346 // instance... this new activity it is starting must go on its
1347 // own task.
1348 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1349 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1350 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1351 // The activity being started is a single instance... it always
1352 // gets launched into its own task.
1353 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1354 }
1355
Craig Mautnerde4ef022013-04-07 19:01:33 -07001356 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001357 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001358 if (sourceRecord != null) {
1359 sourceTask = sourceRecord.task;
1360 sourceStack = sourceTask.stack;
1361 } else {
1362 sourceTask = null;
1363 sourceStack = null;
1364 }
1365
Craig Mautner8849a5e2013-04-02 16:41:03 -07001366 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1367 // For whatever reason this activity is being launched into a new
1368 // task... yet the caller has requested a result back. Well, that
1369 // is pretty messed up, so instead immediately send back a cancel
1370 // and let the new task continue launched as normal without a
1371 // dependency on its originator.
1372 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1373 r.resultTo.task.stack.sendActivityResultLocked(-1,
1374 r.resultTo, r.resultWho, r.requestCode,
1375 Activity.RESULT_CANCELED, null);
1376 r.resultTo = null;
1377 }
1378
1379 boolean addingToTask = false;
1380 boolean movedHome = false;
1381 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001382 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001383 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1384 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1385 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1386 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1387 // If bring to front is requested, and no result is requested, and
1388 // we can find a task that was started with this same
1389 // component, then instead of launching bring that one to the front.
1390 if (r.resultTo == null) {
1391 // See if there is a task to bring to the front. If this is
1392 // a SINGLE_INSTANCE activity, there can be one and only one
1393 // instance of it in the history, and it is always in its own
1394 // unique task, so we do a special search.
1395 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001396 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001397 : findActivityLocked(intent, r.info);
1398 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001399 if (r.task == null) {
1400 r.task = intentActivity.task;
1401 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001402 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001403 targetStack.mLastPausedActivity = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001404 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001405 if (intentActivity.task.intent == null) {
1406 // This task was started because of movement of
1407 // the activity based on affinity... now that we
1408 // are actually launching it, we can assign the
1409 // base intent.
1410 intentActivity.task.setIntent(intent, r.info);
1411 }
1412 // If the target task is not in the front, then we need
1413 // to bring it to the front... except... well, with
1414 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1415 // to have the same behavior as if a new instance was
1416 // being started, which means not bringing it to the front
1417 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001418 final ActivityStack lastStack = getLastStack();
1419 ActivityRecord curTop = lastStack == null?
1420 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001421 if (curTop != null && (curTop.task != intentActivity.task ||
1422 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001423 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001424 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1425 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001426 // We really do want to push this one into the
1427 // user's face, right now.
1428 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001429 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001430 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1431 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001432 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001433 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001434 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001435 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1436 options = null;
1437 }
1438 }
1439 // If the caller has requested that the target task be
1440 // reset, then do so.
1441 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1442 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1443 }
1444 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1445 // We don't need to start a new activity, and
1446 // the client said not to do anything if that
1447 // is the case, so this is it! And for paranoia, make
1448 // sure we have correctly resumed the top activity.
1449 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001450 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001451 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001452 } else {
1453 ActivityOptions.abort(options);
1454 }
Craig Mautner29219d92013-04-16 20:19:12 -07001455 if (r.task == null) Slog.v(TAG,
1456 "startActivityUncheckedLocked: task left null",
1457 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001458 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1459 }
1460 if ((launchFlags &
1461 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1462 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1463 // The caller has requested to completely replace any
1464 // existing task with its new activity. Well that should
1465 // not be too hard...
1466 reuseTask = intentActivity.task;
1467 reuseTask.performClearTaskLocked();
1468 reuseTask.setIntent(r.intent, r.info);
1469 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1470 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1471 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1472 // In this situation we want to remove all activities
1473 // from the task up to the one being started. In most
1474 // cases this means we are resetting the task to its
1475 // initial state.
1476 ActivityRecord top =
1477 intentActivity.task.performClearTaskLocked(r, launchFlags);
1478 if (top != null) {
1479 if (top.frontOfTask) {
1480 // Activity aliases may mean we use different
1481 // intents for the top activity, so make sure
1482 // the task now has the identity of the new
1483 // intent.
1484 top.task.setIntent(r.intent, r.info);
1485 }
1486 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1487 r, top.task);
1488 top.deliverNewIntentLocked(callingUid, r.intent);
1489 } else {
1490 // A special case: we need to
1491 // start the activity because it is not currently
1492 // running, and the caller has asked to clear the
1493 // current task to have this activity at the top.
1494 addingToTask = true;
1495 // Now pretend like this activity is being started
1496 // by the top of its task, so it is put in the
1497 // right place.
1498 sourceRecord = intentActivity;
1499 }
1500 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1501 // In this case the top activity on the task is the
1502 // same as the one being launched, so we take that
1503 // as a request to bring the task to the foreground.
1504 // If the top activity in the task is the root
1505 // activity, deliver this new intent to it if it
1506 // desires.
1507 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1508 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1509 && intentActivity.realActivity.equals(r.realActivity)) {
1510 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1511 intentActivity.task);
1512 if (intentActivity.frontOfTask) {
1513 intentActivity.task.setIntent(r.intent, r.info);
1514 }
1515 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1516 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1517 // In this case we are launching the root activity
1518 // of the task, but with a different intent. We
1519 // should start a new instance on top.
1520 addingToTask = true;
1521 sourceRecord = intentActivity;
1522 }
1523 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1524 // In this case an activity is being launched in to an
1525 // existing task, without resetting that task. This
1526 // is typically the situation of launching an activity
1527 // from a notification or shortcut. We want to place
1528 // the new activity on top of the current task.
1529 addingToTask = true;
1530 sourceRecord = intentActivity;
1531 } else if (!intentActivity.task.rootWasReset) {
1532 // In this case we are launching in to an existing task
1533 // that has not yet been started from its front door.
1534 // The current task has been brought to the front.
1535 // Ideally, we'd probably like to place this new task
1536 // at the bottom of its stack, but that's a little hard
1537 // to do with the current organization of the code so
1538 // for now we'll just drop it.
1539 intentActivity.task.setIntent(r.intent, r.info);
1540 }
1541 if (!addingToTask && reuseTask == null) {
1542 // We didn't do anything... but it was needed (a.k.a., client
1543 // don't use that intent!) And for paranoia, make
1544 // sure we have correctly resumed the top activity.
1545 if (doResume) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001546 // Reset flag so it gets correctly reevaluated.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001547 intentActivity.task.mOnTopOfHome = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001548 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1549 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001550 } else {
1551 ActivityOptions.abort(options);
1552 }
Craig Mautner29219d92013-04-16 20:19:12 -07001553 if (r.task == null) Slog.v(TAG,
1554 "startActivityUncheckedLocked: task left null",
1555 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001556 return ActivityManager.START_TASK_TO_FRONT;
1557 }
1558 }
1559 }
1560 }
1561
1562 //String uri = r.intent.toURI();
1563 //Intent intent2 = new Intent(uri);
1564 //Slog.i(TAG, "Given intent: " + r.intent);
1565 //Slog.i(TAG, "URI is: " + uri);
1566 //Slog.i(TAG, "To intent: " + intent2);
1567
1568 if (r.packageName != null) {
1569 // If the activity being launched is the same as the one currently
1570 // at the top, then we need to check if it should only be launched
1571 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001572 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001573 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001574 if (top != null && r.resultTo == null) {
1575 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1576 if (top.app != null && top.app.thread != null) {
1577 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1578 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1579 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1580 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1581 top.task);
1582 // For paranoia, make sure we have correctly
1583 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001584 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001585 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001586 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001587 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001588 }
1589 ActivityOptions.abort(options);
1590 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1591 // We don't need to start a new activity, and
1592 // the client said not to do anything if that
1593 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001594 if (r.task == null) Slog.v(TAG,
1595 "startActivityUncheckedLocked: task left null",
1596 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001597 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1598 }
1599 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001600 if (r.task == null) Slog.v(TAG,
1601 "startActivityUncheckedLocked: task left null",
1602 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001603 return ActivityManager.START_DELIVERED_TO_TOP;
1604 }
1605 }
1606 }
1607 }
1608
1609 } else {
1610 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001611 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1612 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001613 }
1614 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001615 if (r.task == null) Slog.v(TAG,
1616 "startActivityUncheckedLocked: task left null",
1617 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001618 return ActivityManager.START_CLASS_NOT_FOUND;
1619 }
1620
1621 boolean newTask = false;
1622 boolean keepCurTransition = false;
1623
1624 // Should this be considered a new task?
1625 if (r.resultTo == null && !addingToTask
1626 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001627 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001628 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001629 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001630 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1631 null, true);
1632 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1633 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001634 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001635 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001636 }
1637 newTask = true;
1638 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001639 if ((launchFlags &
1640 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1641 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1642 // Caller wants to appear on home activity, so before starting
1643 // their own activity we will bring home to the front.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001644 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001645 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001646 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001647 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001648 sourceTask = sourceRecord.task;
1649 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001650 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001651 if (!addingToTask &&
1652 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1653 // In this case, we are adding the activity to an existing
1654 // task, but the caller has asked to clear that task if the
1655 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001656 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001657 keepCurTransition = true;
1658 if (top != null) {
1659 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1660 top.deliverNewIntentLocked(callingUid, r.intent);
1661 // For paranoia, make sure we have correctly
1662 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001663 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001664 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001665 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001666 targetStack.resumeTopActivityLocked(null);
1667 }
1668 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001669 if (r.task == null) Slog.v(TAG,
1670 "startActivityUncheckedLocked: task left null",
1671 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001672 return ActivityManager.START_DELIVERED_TO_TOP;
1673 }
1674 } else if (!addingToTask &&
1675 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1676 // In this case, we are launching an activity in our own task
1677 // that may already be running somewhere in the history, and
1678 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001679 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001680 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001681 final TaskRecord task = top.task;
1682 task.moveActivityToFrontLocked(top);
1683 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001684 top.updateOptionsLocked(options);
1685 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001686 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001687 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001688 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001689 targetStack.resumeTopActivityLocked(null);
1690 }
1691 return ActivityManager.START_DELIVERED_TO_TOP;
1692 }
1693 }
1694 // An existing activity is starting this new activity, so we want
1695 // to keep the new one in the same task as the one that is starting
1696 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001697 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001698 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1699 + " in existing task " + r.task);
1700
1701 } else {
1702 // This not being started from an existing activity, and not part
1703 // of a new task... just put it in the top task, though these days
1704 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001705 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001706 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001707 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001708 r.setTask(prev != null ? prev.task
1709 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1710 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001711 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1712 + " in new guessed " + r.task);
1713 }
1714
1715 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1716 intent, r.getUriPermissionsLocked());
1717
1718 if (newTask) {
1719 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1720 }
1721 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001722 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
Craig Mautner0f922742013-08-06 08:44:42 -07001723 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001724 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001725 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001726 return ActivityManager.START_SUCCESS;
1727 }
1728
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001729 void acquireLaunchWakelock() {
1730 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1731 throw new IllegalStateException("Calling must be system uid");
1732 }
1733 mLaunchingActivity.acquire();
1734 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1735 // To be safe, don't allow the wake lock to be held for too long.
1736 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1737 }
1738 }
1739
Craig Mautnerf3333272013-04-22 10:55:53 -07001740 // Checked.
1741 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1742 Configuration config) {
1743 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1744
Craig Mautnerf3333272013-04-22 10:55:53 -07001745 ArrayList<ActivityRecord> stops = null;
1746 ArrayList<ActivityRecord> finishes = null;
1747 ArrayList<UserStartedState> startingUsers = null;
1748 int NS = 0;
1749 int NF = 0;
1750 IApplicationThread sendThumbnail = null;
1751 boolean booting = false;
1752 boolean enableScreen = false;
1753 boolean activityRemoved = false;
1754
1755 ActivityRecord r = ActivityRecord.forToken(token);
1756 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001757 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1758 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001759 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1760 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001761 if (fromTimeout) {
1762 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001763 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001764
1765 // This is a hack to semi-deal with a race condition
1766 // in the client where it can be constructed with a
1767 // newer configuration from when we asked it to launch.
1768 // We'll update with whatever configuration it now says
1769 // it used to launch.
1770 if (config != null) {
1771 r.configuration = config;
1772 }
1773
1774 // We are now idle. If someone is waiting for a thumbnail from
1775 // us, we can now deliver.
1776 r.idle = true;
1777
1778 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1779 sendThumbnail = r.app.thread;
1780 r.thumbnailNeeded = false;
1781 }
1782
1783 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1784 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1785 mService.mBooted = true;
1786 enableScreen = true;
1787 }
1788 }
1789
1790 if (allResumedActivitiesIdle()) {
1791 if (r != null) {
1792 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001793 }
1794
1795 if (mLaunchingActivity.isHeld()) {
1796 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1797 if (VALIDATE_WAKE_LOCK_CALLER &&
1798 Binder.getCallingUid() != Process.myUid()) {
1799 throw new IllegalStateException("Calling must be system uid");
1800 }
1801 mLaunchingActivity.release();
1802 }
1803 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001804 }
1805
1806 // Atomically retrieve all of the other things to do.
1807 stops = processStoppingActivitiesLocked(true);
1808 NS = stops != null ? stops.size() : 0;
1809 if ((NF=mFinishingActivities.size()) > 0) {
1810 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1811 mFinishingActivities.clear();
1812 }
1813
1814 final ArrayList<ActivityRecord> thumbnails;
1815 final int NT = mCancelledThumbnails.size();
1816 if (NT > 0) {
1817 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1818 mCancelledThumbnails.clear();
1819 } else {
1820 thumbnails = null;
1821 }
1822
1823 if (isFrontStack(mHomeStack)) {
1824 booting = mService.mBooting;
1825 mService.mBooting = false;
1826 }
1827
1828 if (mStartingUsers.size() > 0) {
1829 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1830 mStartingUsers.clear();
1831 }
1832
1833 // Perform the following actions from unsynchronized state.
1834 final IApplicationThread thumbnailThread = sendThumbnail;
1835 mHandler.post(new Runnable() {
1836 @Override
1837 public void run() {
1838 if (thumbnailThread != null) {
1839 try {
1840 thumbnailThread.requestThumbnail(token);
1841 } catch (Exception e) {
1842 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1843 mService.sendPendingThumbnail(null, token, null, null, true);
1844 }
1845 }
1846
1847 // Report back to any thumbnail receivers.
1848 for (int i = 0; i < NT; i++) {
1849 ActivityRecord r = thumbnails.get(i);
1850 mService.sendPendingThumbnail(r, null, null, null, true);
1851 }
1852 }
1853 });
1854
1855 // Stop any activities that are scheduled to do so but have been
1856 // waiting for the next one to start.
1857 for (int i = 0; i < NS; i++) {
1858 r = stops.get(i);
1859 final ActivityStack stack = r.task.stack;
1860 if (r.finishing) {
1861 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1862 } else {
1863 stack.stopActivityLocked(r);
1864 }
1865 }
1866
1867 // Finish any activities that are scheduled to do so but have been
1868 // waiting for the next one to start.
1869 for (int i = 0; i < NF; i++) {
1870 r = finishes.get(i);
1871 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1872 }
1873
1874 if (booting) {
1875 mService.finishBooting();
1876 } else if (startingUsers != null) {
1877 for (int i = 0; i < startingUsers.size(); i++) {
1878 mService.finishUserSwitch(startingUsers.get(i));
1879 }
1880 }
1881
1882 mService.trimApplications();
1883 //dump();
1884 //mWindowManager.dump();
1885
1886 if (enableScreen) {
1887 mService.enableScreenAfterBoot();
1888 }
1889
1890 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001891 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001892 }
1893
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001894 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001895 }
1896
Craig Mautner8d341ef2013-03-26 09:03:27 -07001897 void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1898 // Just in case.
1899 final int numStacks = mStacks.size();
1900 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001901 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
Craig Mautner8d341ef2013-03-26 09:03:27 -07001902 }
1903 }
1904
1905 void closeSystemDialogsLocked() {
1906 final int numStacks = mStacks.size();
1907 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1908 final ActivityStack stack = mStacks.get(stackNdx);
1909 stack.closeSystemDialogsLocked();
1910 }
1911 }
1912
1913 /**
1914 * @return true if some activity was finished (or would have finished if doit were true).
1915 */
1916 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1917 boolean didSomething = false;
1918 final int numStacks = mStacks.size();
1919 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1920 final ActivityStack stack = mStacks.get(stackNdx);
1921 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1922 didSomething = true;
1923 }
1924 }
1925 return didSomething;
1926 }
1927
Dianne Hackborna413dc02013-07-12 12:02:55 -07001928 void updatePreviousProcessLocked(ActivityRecord r) {
1929 // Now that this process has stopped, we may want to consider
1930 // it to be the previous app to try to keep around in case
1931 // the user wants to return to it.
1932
1933 // First, found out what is currently the foreground app, so that
1934 // we don't blow away the previous app if this activity is being
1935 // hosted by the process that is actually still the foreground.
1936 ProcessRecord fgApp = null;
1937 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1938 final ActivityStack stack = mStacks.get(stackNdx);
1939 if (isFrontStack(stack)) {
1940 if (stack.mResumedActivity != null) {
1941 fgApp = stack.mResumedActivity.app;
1942 } else if (stack.mPausingActivity != null) {
1943 fgApp = stack.mPausingActivity.app;
1944 }
1945 break;
1946 }
1947 }
1948
1949 // Now set this one as the previous process, only if that really
1950 // makes sense to.
1951 if (r.app != null && fgApp != null && r.app != fgApp
1952 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07001953 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07001954 mService.mPreviousProcess = r.app;
1955 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1956 }
1957 }
1958
Craig Mautner05d29032013-05-03 13:40:13 -07001959 boolean resumeTopActivitiesLocked() {
1960 return resumeTopActivitiesLocked(null, null, null);
1961 }
1962
1963 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1964 Bundle targetOptions) {
1965 if (targetStack == null) {
1966 targetStack = getFocusedStack();
1967 }
1968 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07001969 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001970 final ActivityStack stack = mStacks.get(stackNdx);
1971 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07001972 if (stack == targetStack) {
1973 result = stack.resumeTopActivityLocked(target, targetOptions);
1974 } else {
1975 stack.resumeTopActivityLocked(null);
1976 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07001977 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001978 }
Craig Mautner05d29032013-05-03 13:40:13 -07001979 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001980 }
1981
1982 void finishTopRunningActivityLocked(ProcessRecord app) {
1983 final int numStacks = mStacks.size();
1984 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1985 final ActivityStack stack = mStacks.get(stackNdx);
1986 stack.finishTopRunningActivityLocked(app);
1987 }
1988 }
1989
Craig Mautner8d341ef2013-03-26 09:03:27 -07001990 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
1991 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1992 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001993 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
Craig Mautner1d001b62013-06-18 16:52:43 -07001994 mStacks.get(stackNdx));
Craig Mautner8d341ef2013-03-26 09:03:27 -07001995 return;
1996 }
1997 }
1998 }
1999
Craig Mautner967212c2013-04-13 21:10:58 -07002000 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002001 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2002 final ActivityStack stack = mStacks.get(stackNdx);
2003 if (stack.getStackId() == stackId) {
2004 return stack;
2005 }
2006 }
2007 return null;
2008 }
2009
Craig Mautner967212c2013-04-13 21:10:58 -07002010 ArrayList<ActivityStack> getStacks() {
2011 return new ArrayList<ActivityStack>(mStacks);
2012 }
2013
2014 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002015 while (true) {
2016 if (++mLastStackId <= HOME_STACK_ID) {
2017 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002018 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002019 if (getStack(mLastStackId) == null) {
2020 break;
2021 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002022 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002023 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
2024 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002025 }
2026
2027 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002028 final TaskRecord task = anyTaskForIdLocked(taskId);
2029 if (task == null) {
2030 return;
2031 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002032 final ActivityStack stack = getStack(stackId);
2033 if (stack == null) {
2034 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2035 return;
2036 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002037 removeTask(task);
2038 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002039 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002040 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002041 }
2042
Craig Mautnerac6f8432013-07-17 13:24:59 -07002043 ActivityRecord findTaskLocked(ActivityRecord r) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07002044 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07002045 final ActivityStack stack = mStacks.get(stackNdx);
2046 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2047 continue;
2048 }
2049 final ActivityRecord ar = stack.findTaskLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07002050 if (ar != null) {
2051 return ar;
2052 }
2053 }
2054 return null;
2055 }
2056
2057 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2058 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2059 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
2060 if (ar != null) {
2061 return ar;
2062 }
2063 }
2064 return null;
2065 }
2066
Craig Mautner8d341ef2013-03-26 09:03:27 -07002067 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002068 scheduleSleepTimeout();
2069 if (!mGoingToSleep.isHeld()) {
2070 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002071 if (mLaunchingActivity.isHeld()) {
2072 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2073 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002074 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002075 mLaunchingActivity.release();
2076 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002077 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002078 }
2079 }
2080
2081 boolean shutdownLocked(int timeout) {
2082 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002083 goingToSleepLocked();
2084 checkReadyForSleepLocked();
2085
2086 final long endTime = System.currentTimeMillis() + timeout;
2087 while (true) {
2088 boolean cantShutdown = false;
2089 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2090 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2091 }
2092 if (cantShutdown) {
2093 long timeRemaining = endTime - System.currentTimeMillis();
2094 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002095 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002096 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002097 } catch (InterruptedException e) {
2098 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002099 } else {
2100 Slog.w(TAG, "Activity manager shutdown timed out");
2101 timedout = true;
2102 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002103 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002104 } else {
2105 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002106 }
2107 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002108
2109 // Force checkReadyForSleep to complete.
2110 mSleepTimeout = true;
2111 checkReadyForSleepLocked();
2112
Craig Mautner8d341ef2013-03-26 09:03:27 -07002113 return timedout;
2114 }
2115
2116 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002117 removeSleepTimeouts();
2118 if (mGoingToSleep.isHeld()) {
2119 mGoingToSleep.release();
2120 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002121 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002122 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002123 stack.awakeFromSleepingLocked();
2124 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07002125 resumeTopActivitiesLocked();
Craig Mautnerde4ef022013-04-07 19:01:33 -07002126 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002127 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002128 mGoingToSleepActivities.clear();
2129 }
2130
2131 void activitySleptLocked(ActivityRecord r) {
2132 mGoingToSleepActivities.remove(r);
2133 checkReadyForSleepLocked();
2134 }
2135
2136 void checkReadyForSleepLocked() {
2137 if (!mService.isSleepingOrShuttingDown()) {
2138 // Do not care.
2139 return;
2140 }
2141
2142 if (!mSleepTimeout) {
2143 boolean dontSleep = false;
2144 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2145 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2146 }
2147
2148 if (mStoppingActivities.size() > 0) {
2149 // Still need to tell some activities to stop; can't sleep yet.
2150 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2151 + mStoppingActivities.size() + " activities");
2152 scheduleIdleLocked();
2153 dontSleep = true;
2154 }
2155
2156 if (mGoingToSleepActivities.size() > 0) {
2157 // Still need to tell some activities to sleep; can't sleep yet.
2158 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2159 + mGoingToSleepActivities.size() + " activities");
2160 dontSleep = true;
2161 }
2162
2163 if (dontSleep) {
2164 return;
2165 }
2166 }
2167
2168 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2169 mStacks.get(stackNdx).goToSleep();
2170 }
2171
2172 removeSleepTimeouts();
2173
2174 if (mGoingToSleep.isHeld()) {
2175 mGoingToSleep.release();
2176 }
2177 if (mService.mShuttingDown) {
2178 mService.notifyAll();
2179 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002180 }
2181
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002182 boolean reportResumedActivityLocked(ActivityRecord r) {
2183 final ActivityStack stack = r.task.stack;
2184 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002185 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002186 }
2187 if (allResumedActivitiesComplete()) {
2188 ensureActivitiesVisibleLocked(null, 0);
2189 mWindowManager.executeAppTransition();
2190 return true;
2191 }
2192 return false;
2193 }
2194
Craig Mautner8d341ef2013-03-26 09:03:27 -07002195 void handleAppCrashLocked(ProcessRecord app) {
2196 final int numStacks = mStacks.size();
2197 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2198 final ActivityStack stack = mStacks.get(stackNdx);
2199 stack.handleAppCrashLocked(app);
2200 }
2201 }
2202
Craig Mautnerde4ef022013-04-07 19:01:33 -07002203 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002204 // First the front stacks. In case any are not fullscreen and are in front of home.
2205 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002206 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002207 final ActivityStack stack = mStacks.get(stackNdx);
2208 if (isFrontStack(stack)) {
2209 showHomeBehindStack =
2210 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2211 }
2212 }
2213 // Now do back stacks.
2214 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2215 final ActivityStack stack = mStacks.get(stackNdx);
2216 if (!isFrontStack(stack)) {
2217 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2218 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002219 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002220 }
2221
2222 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2223 final int numStacks = mStacks.size();
2224 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2225 final ActivityStack stack = mStacks.get(stackNdx);
2226 stack.scheduleDestroyActivities(app, false, reason);
2227 }
2228 }
2229
2230 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner2420ead2013-04-01 17:13:20 -07002231 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002232
2233 final String homePackageName = mService.getHomePackageName();
2234 if (homePackageName != null) {
2235 setHomePackageName(mCurrentUser, homePackageName);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002236 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002237
2238 mStartingUsers.add(uss);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002239 boolean haveActivities = false;
2240 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2241 haveActivities |= mStacks.get(stackNdx).switchUserLocked(userId);
2242 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002243
2244 resumeTopActivitiesLocked();
2245
Craig Mautner8d341ef2013-03-26 09:03:27 -07002246 return haveActivities;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002247 }
2248
Craig Mautnerde4ef022013-04-07 19:01:33 -07002249 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2250 int N = mStoppingActivities.size();
2251 if (N <= 0) return null;
2252
2253 ArrayList<ActivityRecord> stops = null;
2254
2255 final boolean nowVisible = allResumedActivitiesVisible();
2256 for (int i=0; i<N; i++) {
2257 ActivityRecord s = mStoppingActivities.get(i);
2258 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2259 + nowVisible + " waitingVisible=" + s.waitingVisible
2260 + " finishing=" + s.finishing);
2261 if (s.waitingVisible && nowVisible) {
2262 mWaitingVisibleActivities.remove(s);
2263 s.waitingVisible = false;
2264 if (s.finishing) {
2265 // If this activity is finishing, it is sitting on top of
2266 // everyone else but we now know it is no longer needed...
2267 // so get rid of it. Otherwise, we need to go through the
2268 // normal flow and hide it once we determine that it is
2269 // hidden by the activities in front of it.
2270 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002271 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002272 }
2273 }
2274 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2275 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2276 if (stops == null) {
2277 stops = new ArrayList<ActivityRecord>();
2278 }
2279 stops.add(s);
2280 mStoppingActivities.remove(i);
2281 N--;
2282 i--;
2283 }
2284 }
2285
2286 return stops;
2287 }
2288
Craig Mautnercf910b02013-04-23 11:23:27 -07002289 void validateTopActivitiesLocked() {
2290 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2291 final ActivityStack stack = mStacks.get(stackNdx);
2292 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002293 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002294 if (isFrontStack(stack)) {
2295 if (r == null) {
2296 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2297 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002298 final ActivityRecord pausing = stack.mPausingActivity;
2299 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002300 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002301 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002302 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002303 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002304 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002305 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002306 }
2307 }
2308 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002309 final ActivityRecord resumed = stack.mResumedActivity;
2310 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002311 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002312 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002313 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002314 if (r != null && (state == ActivityState.INITIALIZING
2315 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002316 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002317 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002318 }
2319 }
2320 }
2321 }
2322
Craig Mautner76ea2242013-05-15 11:40:05 -07002323 private static String stackStateToString(int stackState) {
2324 switch (stackState) {
2325 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2326 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2327 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2328 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2329 default: return "Unknown stackState=" + stackState;
2330 }
2331 }
2332
Craig Mautner27084302013-03-25 08:05:25 -07002333 public void dump(PrintWriter pw, String prefix) {
2334 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2335 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002336 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002337 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2338 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002339 pw.print(prefix); pw.print("mHomePackageNames:");
2340 for (int i = 0; i < mHomePackageNames.size(); ++i) {
2341 pw.print(" ("); pw.print(mHomePackageNames.keyAt(i)); pw.print(",");
2342 pw.print(mHomePackageNames.valueAt(i)); pw.print(")");
2343 }
2344 pw.println();
Craig Mautner27084302013-03-25 08:05:25 -07002345 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002346
Craig Mautner20e72272013-04-01 13:45:53 -07002347 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002348 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002349 }
2350
Dianne Hackborn390517b2013-05-30 15:03:32 -07002351 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2352 boolean needSep, String prefix) {
2353 if (activity != null) {
2354 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2355 if (needSep) {
2356 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002357 }
2358 pw.print(prefix);
2359 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002360 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002361 }
2362 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002363 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002364 }
2365
Craig Mautner8d341ef2013-03-26 09:03:27 -07002366 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2367 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002368 boolean printed = false;
2369 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002370 final int numStacks = mStacks.size();
2371 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2372 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002373 StringBuilder stackHeader = new StringBuilder(128);
2374 stackHeader.append(" Stack #");
2375 stackHeader.append(mStacks.indexOf(stack));
2376 stackHeader.append(":");
2377 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2378 stackHeader.toString());
2379 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2380 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002381
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002382 needSep = printed;
2383 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002384 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002385 if (pr) {
2386 printed = true;
2387 needSep = false;
2388 }
2389 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002390 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002391 if (pr) {
2392 printed = true;
2393 needSep = false;
2394 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002395 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002396 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002397 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002398 if (pr) {
2399 printed = true;
Craig Mautner0f922742013-08-06 08:44:42 -07002400 needSep = true;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002401 }
Craig Mautner0f922742013-08-06 08:44:42 -07002402 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2403 needSep, " mLastNoHistoryActivity: ");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002404 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002405 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002406 }
2407
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002408 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2409 false, dumpPackage, true, " Activities waiting to finish:", null);
2410 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2411 false, dumpPackage, true, " Activities waiting to stop:", null);
2412 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2413 false, dumpPackage, true, " Activities waiting for another to become visible:",
2414 null);
2415 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2416 false, dumpPackage, true, " Activities waiting to sleep:", null);
2417 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2418 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002419
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002420 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002421 }
2422
Dianne Hackborn390517b2013-05-30 15:03:32 -07002423 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002424 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002425 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002426 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002427 String innerPrefix = null;
2428 String[] args = null;
2429 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002430 for (int i=list.size()-1; i>=0; i--) {
2431 final ActivityRecord r = list.get(i);
2432 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2433 continue;
2434 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002435 if (innerPrefix == null) {
2436 innerPrefix = prefix + " ";
2437 args = new String[0];
2438 }
2439 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002440 final boolean full = !brief && (complete || !r.isInHistory());
2441 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002442 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002443 needNL = false;
2444 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002445 if (header1 != null) {
2446 pw.println(header1);
2447 header1 = null;
2448 }
2449 if (header2 != null) {
2450 pw.println(header2);
2451 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002452 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002453 if (lastTask != r.task) {
2454 lastTask = r.task;
2455 pw.print(prefix);
2456 pw.print(full ? "* " : " ");
2457 pw.println(lastTask);
2458 if (full) {
2459 lastTask.dump(pw, prefix + " ");
2460 } else if (complete) {
2461 // Complete + brief == give a summary. Isn't that obvious?!?
2462 if (lastTask.intent != null) {
2463 pw.print(prefix); pw.print(" ");
2464 pw.println(lastTask.intent.toInsecureStringWithClip());
2465 }
2466 }
2467 }
2468 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2469 pw.print(" #"); pw.print(i); pw.print(": ");
2470 pw.println(r);
2471 if (full) {
2472 r.dump(pw, innerPrefix);
2473 } else if (complete) {
2474 // Complete + brief == give a summary. Isn't that obvious?!?
2475 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2476 if (r.app != null) {
2477 pw.print(innerPrefix); pw.println(r.app);
2478 }
2479 }
2480 if (client && r.app != null && r.app.thread != null) {
2481 // flush anything that is already in the PrintWriter since the thread is going
2482 // to write to the file descriptor directly
2483 pw.flush();
2484 try {
2485 TransferPipe tp = new TransferPipe();
2486 try {
2487 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2488 r.appToken, innerPrefix, args);
2489 // Short timeout, since blocking here can
2490 // deadlock with the application.
2491 tp.go(fd, 2000);
2492 } finally {
2493 tp.kill();
2494 }
2495 } catch (IOException e) {
2496 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2497 } catch (RemoteException e) {
2498 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2499 }
2500 needNL = true;
2501 }
2502 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002503 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002504 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002505
Craig Mautnerf3333272013-04-22 10:55:53 -07002506 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002507 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002508 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2509 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002510 }
2511
2512 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002513 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002514 }
2515
2516 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002517 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002518 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2519 }
2520
Craig Mautner05d29032013-05-03 13:40:13 -07002521 final void scheduleResumeTopActivities() {
2522 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2523 }
2524
Craig Mautner0eea92c2013-05-16 13:35:39 -07002525 void removeSleepTimeouts() {
2526 mSleepTimeout = false;
2527 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2528 }
2529
2530 final void scheduleSleepTimeout() {
2531 removeSleepTimeouts();
2532 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2533 }
2534
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002535 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002536
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002537 public ActivityStackSupervisorHandler(Looper looper) {
2538 super(looper);
2539 }
2540
Craig Mautnerf3333272013-04-22 10:55:53 -07002541 void activityIdleInternal(ActivityRecord r) {
2542 synchronized (mService) {
2543 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2544 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002545 }
2546
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002547 @Override
2548 public void handleMessage(Message msg) {
2549 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002550 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002551 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002552 if (mService.mDidDexOpt) {
2553 mService.mDidDexOpt = false;
2554 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2555 nmsg.obj = msg.obj;
2556 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2557 return;
2558 }
2559 // We don't at this point know if the activity is fullscreen,
2560 // so we need to be conservative and assume it isn't.
2561 activityIdleInternal((ActivityRecord)msg.obj);
2562 } break;
2563 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002564 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002565 activityIdleInternal((ActivityRecord)msg.obj);
2566 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002567 case RESUME_TOP_ACTIVITY_MSG: {
2568 synchronized (mService) {
2569 resumeTopActivitiesLocked();
2570 }
2571 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002572 case SLEEP_TIMEOUT_MSG: {
2573 synchronized (mService) {
2574 if (mService.isSleepingOrShuttingDown()) {
2575 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2576 mSleepTimeout = true;
2577 checkReadyForSleepLocked();
2578 }
2579 }
2580 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002581 case LAUNCH_TIMEOUT_MSG: {
2582 if (mService.mDidDexOpt) {
2583 mService.mDidDexOpt = false;
2584 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2585 return;
2586 }
2587 synchronized (mService) {
2588 if (mLaunchingActivity.isHeld()) {
2589 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2590 if (VALIDATE_WAKE_LOCK_CALLER
2591 && Binder.getCallingUid() != Process.myUid()) {
2592 throw new IllegalStateException("Calling must be system uid");
2593 }
2594 mLaunchingActivity.release();
2595 }
2596 }
2597 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002598 }
2599 }
2600 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002601
Craig Mautnerac6f8432013-07-17 13:24:59 -07002602 String getHomePackageName() {
2603 return mHomePackageNames.get(mCurrentUser);
2604 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002605
Craig Mautnerac6f8432013-07-17 13:24:59 -07002606 void setHomePackageName(int userId, String homePackageName) {
2607 if (DEBUG_SWITCH) Slog.d(TAG, "setHomePackageName: user=" + userId + " package="
2608 + homePackageName);
2609 mHomePackageNames.put(userId, homePackageName);
Craig Mautner858d8a62013-04-23 17:08:34 -07002610 }
Craig Mautner27084302013-03-25 08:05:25 -07002611}