blob: 75f3ce2f0d0b4efb9c82a93eb20eacff0fd7e8fb [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
37import android.app.ActivityOptions;
38import android.app.AppGlobals;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070039import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070040import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070041import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070042import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070043import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070044import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070045import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070046import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070047import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070048import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070049import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070050import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070051import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070052import android.content.pm.ApplicationInfo;
53import android.content.pm.PackageManager;
54import android.content.pm.ResolveInfo;
55import android.content.res.Configuration;
56import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070057import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070058import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070059import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070060import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070061import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070062import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070063import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070064import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070065import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070066import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070067import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070068import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070069import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070070import android.util.Slog;
Craig Mautner858d8a62013-04-23 17:08:34 -070071import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070072
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070074import com.android.internal.os.TransferPipe;
Craig Mautner6170f732013-04-02 13:05:23 -070075import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070076import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerde4ef022013-04-07 19:01:33 -070077import com.android.server.wm.StackBox;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070078import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070079
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import java.io.FileDescriptor;
81import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070082import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070083import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070084import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070085
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070086public final class ActivityStackSupervisor {
Craig Mautnerde4ef022013-04-07 19:01:33 -070087 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
88 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
89 static final boolean DEBUG_APP = DEBUG || false;
90 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnerb3370ce2013-09-19 12:02:09 -070091 static final boolean DEBUG_STATES = DEBUG || true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070092 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -070093
Craig Mautner2219a1b2013-03-25 09:44:30 -070094 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -070095
Craig Mautnerf3333272013-04-22 10:55:53 -070096 /** How long we wait until giving up on the last activity telling us it is idle. */
97 static final int IDLE_TIMEOUT = 10*1000;
98
Craig Mautner0eea92c2013-05-16 13:35:39 -070099 /** How long we can hold the sleep wake lock before giving up. */
100 static final int SLEEP_TIMEOUT = 5*1000;
101
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700102 // How long we can hold the launch wake lock before giving up.
103 static final int LAUNCH_TIMEOUT = 10*1000;
104
Craig Mautner05d29032013-05-03 13:40:13 -0700105 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
106 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
107 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700108 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700109 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
110
111 // For debugging to make sure the caller when acquiring/releasing our
112 // wake lock is the system process.
113 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700114
Craig Mautner27084302013-03-25 08:05:25 -0700115 final ActivityManagerService mService;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700116 final Context mContext;
117 final Looper mLooper;
Craig Mautner27084302013-03-25 08:05:25 -0700118
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700119 final ActivityStackSupervisorHandler mHandler;
120
121 /** Short cut */
122 WindowManagerService mWindowManager;
123
Craig Mautner27084302013-03-25 08:05:25 -0700124 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700125 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700126
Craig Mautner8d341ef2013-03-26 09:03:27 -0700127 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700128 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700129
130 /** Task identifier that activities are currently being started in. Incremented each time a
131 * new task is created. */
132 private int mCurTaskId = 0;
133
Craig Mautner2420ead2013-04-01 17:13:20 -0700134 /** The current user */
135 private int mCurrentUser;
136
Craig Mautner8d341ef2013-03-26 09:03:27 -0700137 /** The stack containing the launcher app */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700138 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700139
Craig Mautnerde4ef022013-04-07 19:01:33 -0700140 /** The non-home stack currently receiving input or launching the next activity. If home is
Craig Mautner41c0f352013-05-28 08:39:25 -0700141 * in front then mHomeStack overrides mFocusedStack.
142 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
Craig Mautner29219d92013-04-16 20:19:12 -0700143 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700144
145 /** All the non-launcher stacks */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700146 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
147
Craig Mautnerde4ef022013-04-07 19:01:33 -0700148 private static final int STACK_STATE_HOME_IN_FRONT = 0;
149 private static final int STACK_STATE_HOME_TO_BACK = 1;
150 private static final int STACK_STATE_HOME_IN_BACK = 2;
151 private static final int STACK_STATE_HOME_TO_FRONT = 3;
152 private int mStackState = STACK_STATE_HOME_IN_FRONT;
153
154 /** List of activities that are waiting for a new activity to become visible before completing
155 * whatever operation they are supposed to do. */
156 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
157
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700158 /** List of processes waiting to find out about the next visible activity. */
159 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
160 new ArrayList<IActivityManager.WaitResult>();
161
162 /** List of processes waiting to find out about the next launched activity. */
163 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
164 new ArrayList<IActivityManager.WaitResult>();
165
Craig Mautnerde4ef022013-04-07 19:01:33 -0700166 /** List of activities that are ready to be stopped, but waiting for the next activity to
167 * settle down before doing so. */
168 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
169
Craig Mautnerf3333272013-04-22 10:55:53 -0700170 /** List of activities that are ready to be finished, but waiting for the previous activity to
171 * settle down before doing so. It contains ActivityRecord objects. */
172 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
173
Craig Mautner0eea92c2013-05-16 13:35:39 -0700174 /** List of activities that are in the process of going to sleep. */
175 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
176
Craig Mautnerf3333272013-04-22 10:55:53 -0700177 /** List of ActivityRecord objects that have been finished and must still report back to a
178 * pending thumbnail receiver. */
179 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
180
181 /** Used on user changes */
182 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
183
Craig Mautnerde4ef022013-04-07 19:01:33 -0700184 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
185 * is being brought in front of us. */
186 boolean mUserLeaving = false;
187
Craig Mautner0eea92c2013-05-16 13:35:39 -0700188 /** Set when we have taken too long waiting to go to sleep. */
189 boolean mSleepTimeout = false;
190
191 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700192 * We don't want to allow the device to go to sleep while in the process
193 * of launching an activity. This is primarily to allow alarm intent
194 * receivers to launch an activity and get that to run before the device
195 * goes back to sleep.
196 */
197 final PowerManager.WakeLock mLaunchingActivity;
198
199 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700200 * Set when the system is going to sleep, until we have
201 * successfully paused the current activity and released our wake lock.
202 * At that point the system is allowed to actually sleep.
203 */
204 final PowerManager.WakeLock mGoingToSleep;
205
Craig Mautner2219a1b2013-03-25 09:44:30 -0700206 public ActivityStackSupervisor(ActivityManagerService service, Context context,
207 Looper looper) {
Craig Mautner27084302013-03-25 08:05:25 -0700208 mService = service;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700209 mContext = context;
210 mLooper = looper;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700211 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
212 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700213 mHandler = new ActivityStackSupervisorHandler(looper);
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700214 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
215 throw new IllegalStateException("Calling must be system uid");
216 }
217 mLaunchingActivity =
218 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
219 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700220 }
221
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700222 void setWindowManager(WindowManagerService wm) {
223 mWindowManager = wm;
224 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700225 mStacks.add(mHomeStack);
Craig Mautner27084302013-03-25 08:05:25 -0700226 }
227
228 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700229 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700230 if (mDismissKeyguardOnNextActivity) {
231 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700232 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700233 }
234 }
235
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700236 ActivityStack getFocusedStack() {
Craig Mautnerf88c50f2013-04-18 19:25:12 -0700237 if (mFocusedStack == null) {
238 return mHomeStack;
239 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700240 switch (mStackState) {
241 case STACK_STATE_HOME_IN_FRONT:
242 case STACK_STATE_HOME_TO_FRONT:
243 return mHomeStack;
244 case STACK_STATE_HOME_IN_BACK:
245 case STACK_STATE_HOME_TO_BACK:
246 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700247 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700248 }
Craig Mautner20e72272013-04-01 13:45:53 -0700249 }
250
Craig Mautnerde4ef022013-04-07 19:01:33 -0700251 ActivityStack getLastStack() {
252 switch (mStackState) {
253 case STACK_STATE_HOME_IN_FRONT:
254 case STACK_STATE_HOME_TO_BACK:
255 return mHomeStack;
256 case STACK_STATE_HOME_TO_FRONT:
257 case STACK_STATE_HOME_IN_BACK:
258 default:
Craig Mautner29219d92013-04-16 20:19:12 -0700259 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700260 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700261 }
262
Craig Mautnerde4ef022013-04-07 19:01:33 -0700263 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700264 return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
Craig Mautner20e72272013-04-01 13:45:53 -0700265 }
266
Craig Mautnerde4ef022013-04-07 19:01:33 -0700267 void moveHomeStack(boolean toFront) {
268 final boolean homeInFront = isFrontStack(mHomeStack);
269 if (homeInFront ^ toFront) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700270 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
271 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
272 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700273 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
274 }
275 }
276
Craig Mautner69ada552013-04-18 13:51:51 -0700277 boolean resumeHomeActivity(ActivityRecord prev) {
278 moveHomeStack(true);
279 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700280 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700281 }
Craig Mautnera82aa092013-09-13 15:34:08 -0700282 mHomeStack.moveHomeTaskToTop();
Craig Mautnera8a90e02013-06-28 15:24:50 -0700283 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
284 if (r != null) {
285 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700286 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700287 }
288 return mService.startHomeActivityLocked(mCurrentUser);
289 }
290
Craig Mautnerde4ef022013-04-07 19:01:33 -0700291 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r,
292 ActivityStack stack) {
293 if (stack == mHomeStack) {
294 return;
295 }
296 if ((sourceRecord == null && getLastStack() == mHomeStack) ||
Craig Mautner86d67a42013-05-14 10:34:38 -0700297 (sourceRecord != null && sourceRecord.isHomeActivity())) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700298 if (r == null) {
299 r = stack.topRunningActivityLocked(null);
300 }
Craig Mautner86d67a42013-05-14 10:34:38 -0700301 if (r != null && !r.isHomeActivity() && r.isRootActivity()) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700302 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700303 }
304 }
Craig Mautner2219a1b2013-03-25 09:44:30 -0700305 }
306
Craig Mautner27084302013-03-25 08:05:25 -0700307 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700308 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700309 mDismissKeyguardOnNextActivity = dismiss;
310 }
311
Craig Mautner8d341ef2013-03-26 09:03:27 -0700312 TaskRecord anyTaskForIdLocked(int id) {
313 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
314 ActivityStack stack = mStacks.get(stackNdx);
315 TaskRecord task = stack.taskForIdLocked(id);
316 if (task != null) {
317 return task;
318 }
319 }
320 return null;
321 }
322
Craig Mautner6170f732013-04-02 13:05:23 -0700323 ActivityRecord isInAnyStackLocked(IBinder token) {
324 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
325 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
326 if (r != null) {
327 return r;
328 }
329 }
330 return null;
331 }
332
Craig Mautner8d341ef2013-03-26 09:03:27 -0700333 int getNextTaskId() {
334 do {
335 mCurTaskId++;
336 if (mCurTaskId <= 0) {
337 mCurTaskId = 1;
338 }
339 } while (anyTaskForIdLocked(mCurTaskId) != null);
340 return mCurTaskId;
341 }
342
Craig Mautnerde4ef022013-04-07 19:01:33 -0700343 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700344 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700345 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700346 final ActivityRecord r = stack.mResumedActivity;
347 if (r != null && r.task == task) {
348 stack.mResumedActivity = null;
349 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700350 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700351 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700352 mStacks.remove(stack);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700353 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700354 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700355 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Craig Mautnerac6f8432013-07-17 13:24:59 -0700356 if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {
Craig Mautner1602ec22013-05-12 10:24:27 -0700357 // If this is the last app stack, set mFocusedStack to null.
Craig Mautner29219d92013-04-16 20:19:12 -0700358 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700359 }
360 }
361 }
362
363 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700364 ActivityStack stack = getFocusedStack();
365 if (stack == null) {
366 return null;
367 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700368 ActivityRecord resumedActivity = stack.mResumedActivity;
369 if (resumedActivity == null || resumedActivity.app == null) {
370 resumedActivity = stack.mPausingActivity;
371 if (resumedActivity == null || resumedActivity.app == null) {
372 resumedActivity = stack.topRunningActivityLocked(null);
373 }
374 }
375 return resumedActivity;
376 }
377
Craig Mautner20e72272013-04-01 13:45:53 -0700378 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
379 boolean didSomething = false;
380 final String processName = app.processName;
381 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
382 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner858d8a62013-04-23 17:08:34 -0700383 if (!isFrontStack(stack)) {
384 continue;
385 }
Craig Mautner20e72272013-04-01 13:45:53 -0700386 ActivityRecord hr = stack.topRunningActivityLocked(null);
387 if (hr != null) {
388 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
389 && processName.equals(hr.processName)) {
390 try {
391 if (headless) {
392 Slog.e(TAG, "Starting activities not supported on headless device: "
393 + hr);
Craig Mautner2420ead2013-04-01 17:13:20 -0700394 } else if (realStartActivityLocked(hr, app, true, true)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700395 didSomething = true;
396 }
397 } catch (Exception e) {
398 Slog.w(TAG, "Exception in new application when starting activity "
399 + hr.intent.getComponent().flattenToShortString(), e);
400 throw e;
401 }
Craig Mautner20e72272013-04-01 13:45:53 -0700402 }
403 }
404 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700405 if (!didSomething) {
406 ensureActivitiesVisibleLocked(null, 0);
407 }
Craig Mautner20e72272013-04-01 13:45:53 -0700408 return didSomething;
409 }
410
411 boolean allResumedActivitiesIdle() {
412 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700413 final ActivityStack stack = mStacks.get(stackNdx);
414 if (!isFrontStack(stack)) {
415 continue;
416 }
417 final ActivityRecord resumedActivity = stack.mResumedActivity;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -0700418 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner20e72272013-04-01 13:45:53 -0700419 return false;
420 }
421 }
422 return true;
423 }
424
Craig Mautnerde4ef022013-04-07 19:01:33 -0700425 boolean allResumedActivitiesComplete() {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700426 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
427 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner967212c2013-04-13 21:10:58 -0700428 if (isFrontStack(stack)) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700429 final ActivityRecord r = stack.mResumedActivity;
430 if (r != null && r.state != ActivityState.RESUMED) {
431 return false;
432 }
433 }
434 }
435 // TODO: Not sure if this should check if all Paused are complete too.
436 switch (mStackState) {
437 case STACK_STATE_HOME_TO_BACK:
Craig Mautner76ea2242013-05-15 11:40:05 -0700438 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
439 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
440 stackStateToString(STACK_STATE_HOME_IN_BACK));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700441 mStackState = STACK_STATE_HOME_IN_BACK;
442 break;
443 case STACK_STATE_HOME_TO_FRONT:
Craig Mautner76ea2242013-05-15 11:40:05 -0700444 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
445 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
446 stackStateToString(STACK_STATE_HOME_IN_FRONT));
Craig Mautnerde4ef022013-04-07 19:01:33 -0700447 mStackState = STACK_STATE_HOME_IN_FRONT;
448 break;
449 }
450 return true;
451 }
452
453 boolean allResumedActivitiesVisible() {
454 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
455 final ActivityStack stack = mStacks.get(stackNdx);
456 final ActivityRecord r = stack.mResumedActivity;
457 if (r != null && (!r.nowVisible || r.waitingVisible)) {
458 return false;
459 }
460 }
461 return true;
462 }
463
Craig Mautner2acc3892013-09-23 10:28:14 -0700464 /**
465 * Pause all activities in either all of the stacks or just the back stacks.
466 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700467 * @return true if any activity was paused as a result of this call.
468 */
Craig Mautner5314a402013-09-26 12:40:16 -0700469 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700470 boolean someActivityPaused = false;
471 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
472 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner5314a402013-09-26 12:40:16 -0700473 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
474 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
Craig Mautnerac6f8432013-07-17 13:24:59 -0700475 " mResumedActivity=" + stack.mResumedActivity);
Craig Mautnercf910b02013-04-23 11:23:27 -0700476 stack.startPausingLocked(userLeaving, false);
477 someActivityPaused = true;
478 }
479 }
480 return someActivityPaused;
481 }
482
Craig Mautnerde4ef022013-04-07 19:01:33 -0700483 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700484 boolean pausing = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700485 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
486 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautner69ada552013-04-18 13:51:51 -0700487 final ActivityRecord r = stack.mPausingActivity;
488 if (r != null && r.state != ActivityState.PAUSED
489 && r.state != ActivityState.STOPPED
490 && r.state != ActivityState.STOPPING) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700491 if (DEBUG_STATES) {
492 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
493 pausing = false;
494 } else {
495 return false;
496 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700497 }
498 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700499 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700500 }
501
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700502 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700503 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700504 WaitResult w = mWaitingActivityVisible.get(i);
505 w.timeout = false;
506 if (r != null) {
507 w.who = new ComponentName(r.info.packageName, r.info.name);
508 }
509 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
510 w.thisTime = w.totalTime;
511 }
512 mService.notifyAll();
513 dismissKeyguard();
514 }
515
516 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
517 long thisTime, long totalTime) {
518 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700519 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700520 w.timeout = timeout;
521 if (r != null) {
522 w.who = new ComponentName(r.info.packageName, r.info.name);
523 }
524 w.thisTime = thisTime;
525 w.totalTime = totalTime;
526 }
527 mService.notifyAll();
528 }
529
Craig Mautner29219d92013-04-16 20:19:12 -0700530 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700531 final ActivityStack focusedStack = getFocusedStack();
532 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
533 if (r != null) {
534 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700535 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700536
Craig Mautner29219d92013-04-16 20:19:12 -0700537 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
538 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700539 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700540 r = stack.topRunningActivityLocked(null);
541 if (r != null) {
542 return r;
543 }
544 }
545 }
546 return null;
547 }
548
Craig Mautner20e72272013-04-01 13:45:53 -0700549 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
550 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
551 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700552
553 // Gather all of the running tasks for each stack into runningTaskLists.
554 final int numStacks = mStacks.size();
555 ArrayList<RunningTaskInfo>[] runningTaskLists = new ArrayList[numStacks];
556 for (int stackNdx = numStacks - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner20e72272013-04-01 13:45:53 -0700557 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700558 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
559 runningTaskLists[stackNdx] = stackTaskList;
560 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700561 if (isFrontStack(stack)) {
Craig Mautner20e72272013-04-01 13:45:53 -0700562 r = ar;
563 }
564 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700565
566 // The lists are already sorted from most recent to oldest. Just pull the most recent off
567 // each list and add it to list. Stop when all lists are empty or maxNum reached.
568 while (maxNum > 0) {
569 long mostRecentActiveTime = Long.MIN_VALUE;
570 ArrayList<RunningTaskInfo> selectedStackList = null;
571 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
572 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists[stackNdx];
573 if (!stackTaskList.isEmpty()) {
574 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
575 if (lastActiveTime > mostRecentActiveTime) {
576 mostRecentActiveTime = lastActiveTime;
577 selectedStackList = stackTaskList;
578 }
579 }
580 }
581 if (selectedStackList != null) {
582 list.add(selectedStackList.remove(0));
583 --maxNum;
584 } else {
585 break;
586 }
587 }
588
Craig Mautner20e72272013-04-01 13:45:53 -0700589 return r;
590 }
591
Craig Mautner23ac33b2013-04-01 16:26:35 -0700592 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
593 String profileFile, ParcelFileDescriptor profileFd, int userId) {
594 // Collect information about the target of the Intent.
595 ActivityInfo aInfo;
596 try {
597 ResolveInfo rInfo =
598 AppGlobals.getPackageManager().resolveIntent(
599 intent, resolvedType,
600 PackageManager.MATCH_DEFAULT_ONLY
601 | ActivityManagerService.STOCK_PM_FLAGS, userId);
602 aInfo = rInfo != null ? rInfo.activityInfo : null;
603 } catch (RemoteException e) {
604 aInfo = null;
605 }
606
607 if (aInfo != null) {
608 // Store the found target back into the intent, because now that
609 // we have it we never want to do this again. For example, if the
610 // user navigates back to this point in the history, we should
611 // always restart the exact same activity.
612 intent.setComponent(new ComponentName(
613 aInfo.applicationInfo.packageName, aInfo.name));
614
615 // Don't debug things in the system process
616 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
617 if (!aInfo.processName.equals("system")) {
618 mService.setDebugApp(aInfo.processName, true, false);
619 }
620 }
621
622 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
623 if (!aInfo.processName.equals("system")) {
624 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
625 }
626 }
627
628 if (profileFile != null) {
629 if (!aInfo.processName.equals("system")) {
630 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
631 profileFile, profileFd,
632 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
633 }
634 }
635 }
636 return aInfo;
637 }
638
Craig Mautner2219a1b2013-03-25 09:44:30 -0700639 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700640 moveHomeStack(true);
Craig Mautner6170f732013-04-02 13:05:23 -0700641 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700642 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700643 }
644
Craig Mautner23ac33b2013-04-01 16:26:35 -0700645 final int startActivityMayWait(IApplicationThread caller, int callingUid,
646 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
647 String resultWho, int requestCode, int startFlags, String profileFile,
648 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
649 Bundle options, int userId) {
650 // Refuse possible leaked file descriptors
651 if (intent != null && intent.hasFileDescriptors()) {
652 throw new IllegalArgumentException("File descriptors passed in Intent");
653 }
654 boolean componentSpecified = intent.getComponent() != null;
655
656 // Don't modify the client's object!
657 intent = new Intent(intent);
658
659 // Collect information about the target of the Intent.
660 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
661 profileFile, profileFd, userId);
662
663 synchronized (mService) {
664 int callingPid;
665 if (callingUid >= 0) {
666 callingPid = -1;
667 } else if (caller == null) {
668 callingPid = Binder.getCallingPid();
669 callingUid = Binder.getCallingUid();
670 } else {
671 callingPid = callingUid = -1;
672 }
673
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700674 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700675 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700676 && mService.mConfiguration.diff(config) != 0;
677 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700678 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700679
680 final long origId = Binder.clearCallingIdentity();
681
682 if (aInfo != null &&
683 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
684 // This may be a heavy-weight process! Check to see if we already
685 // have another, different heavy-weight process running.
686 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
687 if (mService.mHeavyWeightProcess != null &&
688 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
689 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700690 int realCallingUid = callingUid;
691 if (caller != null) {
692 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
693 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700694 realCallingUid = callerApp.info.uid;
695 } else {
696 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700697 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700698 + intent.toString());
699 ActivityOptions.abort(options);
700 return ActivityManager.START_PERMISSION_DENIED;
701 }
702 }
703
704 IIntentSender target = mService.getIntentSenderLocked(
705 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
706 realCallingUid, userId, null, null, 0, new Intent[] { intent },
707 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
708 | PendingIntent.FLAG_ONE_SHOT, null);
709
710 Intent newIntent = new Intent();
711 if (requestCode >= 0) {
712 // Caller is requesting a result.
713 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
714 }
715 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
716 new IntentSender(target));
717 if (mService.mHeavyWeightProcess.activities.size() > 0) {
718 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
719 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
720 hist.packageName);
721 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
722 hist.task.taskId);
723 }
724 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
725 aInfo.packageName);
726 newIntent.setFlags(intent.getFlags());
727 newIntent.setClassName("android",
728 HeavyWeightSwitcherActivity.class.getName());
729 intent = newIntent;
730 resolvedType = null;
731 caller = null;
732 callingUid = Binder.getCallingUid();
733 callingPid = Binder.getCallingPid();
734 componentSpecified = true;
735 try {
736 ResolveInfo rInfo =
737 AppGlobals.getPackageManager().resolveIntent(
738 intent, null,
739 PackageManager.MATCH_DEFAULT_ONLY
740 | ActivityManagerService.STOCK_PM_FLAGS, userId);
741 aInfo = rInfo != null ? rInfo.activityInfo : null;
742 aInfo = mService.getActivityInfoForUser(aInfo, userId);
743 } catch (RemoteException e) {
744 aInfo = null;
745 }
746 }
747 }
748 }
749
Craig Mautner6170f732013-04-02 13:05:23 -0700750 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700751 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
752 callingPackage, startFlags, options, componentSpecified, null);
753
Craig Mautnerde4ef022013-04-07 19:01:33 -0700754 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700755 // If the caller also wants to switch to a new configuration,
756 // do so now. This allows a clean switch, as we are waiting
757 // for the current activity to pause (so we will not destroy
758 // it), and have not yet started the next activity.
759 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
760 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700761 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700762 if (DEBUG_CONFIGURATION) Slog.v(TAG,
763 "Updating to new configuration after starting activity.");
764 mService.updateConfigurationLocked(config, null, false, false);
765 }
766
767 Binder.restoreCallingIdentity(origId);
768
769 if (outResult != null) {
770 outResult.result = res;
771 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700772 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700773 do {
774 try {
775 mService.wait();
776 } catch (InterruptedException e) {
777 }
778 } while (!outResult.timeout && outResult.who == null);
779 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700780 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700781 if (r.nowVisible) {
782 outResult.timeout = false;
783 outResult.who = new ComponentName(r.info.packageName, r.info.name);
784 outResult.totalTime = 0;
785 outResult.thisTime = 0;
786 } else {
787 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700788 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700789 do {
790 try {
791 mService.wait();
792 } catch (InterruptedException e) {
793 }
794 } while (!outResult.timeout && outResult.who == null);
795 }
796 }
797 }
798
799 return res;
800 }
801 }
802
803 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
804 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
805 Bundle options, int userId) {
806 if (intents == null) {
807 throw new NullPointerException("intents is null");
808 }
809 if (resolvedTypes == null) {
810 throw new NullPointerException("resolvedTypes is null");
811 }
812 if (intents.length != resolvedTypes.length) {
813 throw new IllegalArgumentException("intents are length different than resolvedTypes");
814 }
815
Craig Mautner23ac33b2013-04-01 16:26:35 -0700816
817 int callingPid;
818 if (callingUid >= 0) {
819 callingPid = -1;
820 } else if (caller == null) {
821 callingPid = Binder.getCallingPid();
822 callingUid = Binder.getCallingUid();
823 } else {
824 callingPid = callingUid = -1;
825 }
826 final long origId = Binder.clearCallingIdentity();
827 try {
828 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700829 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700830 for (int i=0; i<intents.length; i++) {
831 Intent intent = intents[i];
832 if (intent == null) {
833 continue;
834 }
835
836 // Refuse possible leaked file descriptors
837 if (intent != null && intent.hasFileDescriptors()) {
838 throw new IllegalArgumentException("File descriptors passed in Intent");
839 }
840
841 boolean componentSpecified = intent.getComponent() != null;
842
843 // Don't modify the client's object!
844 intent = new Intent(intent);
845
846 // Collect information about the target of the Intent.
847 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
848 0, null, null, userId);
849 // TODO: New, check if this is correct
850 aInfo = mService.getActivityInfoForUser(aInfo, userId);
851
852 if (aInfo != null &&
853 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
854 != 0) {
855 throw new IllegalArgumentException(
856 "FLAG_CANT_SAVE_STATE not supported here");
857 }
858
859 Bundle theseOptions;
860 if (options != null && i == intents.length-1) {
861 theseOptions = options;
862 } else {
863 theseOptions = null;
864 }
Craig Mautner6170f732013-04-02 13:05:23 -0700865 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700866 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
867 0, theseOptions, componentSpecified, outActivity);
868 if (res < 0) {
869 return res;
870 }
871
872 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
873 }
874 }
875 } finally {
876 Binder.restoreCallingIdentity(origId);
877 }
878
879 return ActivityManager.START_SUCCESS;
880 }
881
Craig Mautner2420ead2013-04-01 17:13:20 -0700882 final boolean realStartActivityLocked(ActivityRecord r,
883 ProcessRecord app, boolean andResume, boolean checkConfig)
884 throws RemoteException {
885
886 r.startFreezingScreenLocked(app, 0);
Craig Mautner323f7802013-10-01 21:16:22 -0700887 if (true) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700888 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700889
890 // schedule launch ticks to collect information about slow apps.
891 r.startLaunchTickingLocked();
892
893 // Have the window manager re-evaluate the orientation of
894 // the screen based on the new activity order. Note that
895 // as a result of this, it can call back into the activity
896 // manager with a new orientation. We don't care about that,
897 // because the activity is not currently running so we are
898 // just restarting it anyway.
899 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700900 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700901 mService.mConfiguration,
902 r.mayFreezeScreenLocked(app) ? r.appToken : null);
903 mService.updateConfigurationLocked(config, r, false, false);
904 }
905
906 r.app = app;
907 app.waitingToKill = null;
908 r.launchCount++;
909 r.lastLaunchTime = SystemClock.uptimeMillis();
910
911 if (localLOGV) Slog.v(TAG, "Launching: " + r);
912
913 int idx = app.activities.indexOf(r);
914 if (idx < 0) {
915 app.activities.add(r);
916 }
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700917 mService.updateLruProcessLocked(app, true, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700918
919 final ActivityStack stack = r.task.stack;
920 try {
921 if (app.thread == null) {
922 throw new RemoteException();
923 }
924 List<ResultInfo> results = null;
925 List<Intent> newIntents = null;
926 if (andResume) {
927 results = r.results;
928 newIntents = r.newIntents;
929 }
930 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
931 + " icicle=" + r.icicle
932 + " with results=" + results + " newIntents=" + newIntents
933 + " andResume=" + andResume);
934 if (andResume) {
935 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
936 r.userId, System.identityHashCode(r),
937 r.task.taskId, r.shortComponentName);
938 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700939 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700940 // Home process is the root process of the task.
941 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700942 }
943 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
944 r.sleeping = false;
945 r.forceNewConfig = false;
946 mService.showAskCompatModeDialogLocked(r);
947 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
948 String profileFile = null;
949 ParcelFileDescriptor profileFd = null;
950 boolean profileAutoStop = false;
951 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
952 if (mService.mProfileProc == null || mService.mProfileProc == app) {
953 mService.mProfileProc = app;
954 profileFile = mService.mProfileFile;
955 profileFd = mService.mProfileFd;
956 profileAutoStop = mService.mAutoStopProfiler;
957 }
958 }
959 app.hasShownUi = true;
960 app.pendingUiClean = true;
961 if (profileFd != null) {
962 try {
963 profileFd = profileFd.dup();
964 } catch (IOException e) {
965 if (profileFd != null) {
966 try {
967 profileFd.close();
968 } catch (IOException o) {
969 }
970 profileFd = null;
971 }
972 }
973 }
Dianne Hackborna413dc02013-07-12 12:02:55 -0700974 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -0700975 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
976 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -0700977 new Configuration(mService.mConfiguration), r.compat,
978 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -0700979 mService.isNextTransitionForward(), profileFile, profileFd,
980 profileAutoStop);
981
982 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
983 // This may be a heavy-weight process! Note that the package
984 // manager will ensure that only activity can run in the main
985 // process of the .apk, which is the only thing that will be
986 // considered heavy-weight.
987 if (app.processName.equals(app.info.packageName)) {
988 if (mService.mHeavyWeightProcess != null
989 && mService.mHeavyWeightProcess != app) {
990 Slog.w(TAG, "Starting new heavy weight process " + app
991 + " when already running "
992 + mService.mHeavyWeightProcess);
993 }
994 mService.mHeavyWeightProcess = app;
995 Message msg = mService.mHandler.obtainMessage(
996 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
997 msg.obj = r;
998 mService.mHandler.sendMessage(msg);
999 }
1000 }
1001
1002 } catch (RemoteException e) {
1003 if (r.launchFailed) {
1004 // This is the second time we failed -- finish activity
1005 // and give up.
1006 Slog.e(TAG, "Second failure launching "
1007 + r.intent.getComponent().flattenToShortString()
1008 + ", giving up", e);
1009 mService.appDiedLocked(app, app.pid, app.thread);
1010 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1011 "2nd-crash", false);
1012 return false;
1013 }
1014
1015 // This is the first time we failed -- restart process and
1016 // retry.
1017 app.activities.remove(r);
1018 throw e;
1019 }
1020
1021 r.launchFailed = false;
1022 if (stack.updateLRUListLocked(r)) {
1023 Slog.w(TAG, "Activity " + r
1024 + " being launched, but already in LRU list");
1025 }
1026
1027 if (andResume) {
1028 // As part of the process of launching, ActivityThread also performs
1029 // a resume.
1030 stack.minimalResumeActivityLocked(r);
1031 } else {
1032 // This activity is not starting in the resumed state... which
1033 // should look like we asked it to pause+stop (but remain visible),
1034 // and it has done so and reported back the current icicle and
1035 // other state.
1036 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1037 + " (starting in stopped state)");
1038 r.state = ActivityState.STOPPED;
1039 r.stopped = true;
1040 }
1041
1042 // Launch the new version setup screen if needed. We do this -after-
1043 // launching the initial activity (that is, home), so that it can have
1044 // a chance to initialize itself while in the background, making the
1045 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001046 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001047 mService.startSetupActivityLocked();
1048 }
1049
1050 return true;
1051 }
1052
Craig Mautnere79d42682013-04-01 19:01:53 -07001053 void startSpecificActivityLocked(ActivityRecord r,
1054 boolean andResume, boolean checkConfig) {
1055 // Is this activity's application already running?
1056 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001057 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001058
1059 r.task.stack.setLaunchTime(r);
1060
1061 if (app != null && app.thread != null) {
1062 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001063 app.addPackage(r.info.packageName, mService.mProcessStats);
Craig Mautnere79d42682013-04-01 19:01:53 -07001064 realStartActivityLocked(r, app, andResume, checkConfig);
1065 return;
1066 } catch (RemoteException e) {
1067 Slog.w(TAG, "Exception when starting activity "
1068 + r.intent.getComponent().flattenToShortString(), e);
1069 }
1070
1071 // If a dead object exception was thrown -- fall through to
1072 // restart the application.
1073 }
1074
1075 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001076 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001077 }
1078
Craig Mautner6170f732013-04-02 13:05:23 -07001079 final int startActivityLocked(IApplicationThread caller,
1080 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1081 String resultWho, int requestCode,
1082 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1083 boolean componentSpecified, ActivityRecord[] outActivity) {
1084 int err = ActivityManager.START_SUCCESS;
1085
1086 ProcessRecord callerApp = null;
1087 if (caller != null) {
1088 callerApp = mService.getRecordForAppLocked(caller);
1089 if (callerApp != null) {
1090 callingPid = callerApp.pid;
1091 callingUid = callerApp.info.uid;
1092 } else {
1093 Slog.w(TAG, "Unable to find app for caller " + caller
1094 + " (pid=" + callingPid + ") when starting: "
1095 + intent.toString());
1096 err = ActivityManager.START_PERMISSION_DENIED;
1097 }
1098 }
1099
1100 if (err == ActivityManager.START_SUCCESS) {
1101 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1102 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1103 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1104 }
1105
1106 ActivityRecord sourceRecord = null;
1107 ActivityRecord resultRecord = null;
1108 if (resultTo != null) {
1109 sourceRecord = isInAnyStackLocked(resultTo);
1110 if (DEBUG_RESULTS) Slog.v(
1111 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1112 if (sourceRecord != null) {
1113 if (requestCode >= 0 && !sourceRecord.finishing) {
1114 resultRecord = sourceRecord;
1115 }
1116 }
1117 }
1118 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1119
1120 int launchFlags = intent.getFlags();
1121
1122 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1123 && sourceRecord != null) {
1124 // Transfer the result target from the source activity to the new
1125 // one being started, including any failures.
1126 if (requestCode >= 0) {
1127 ActivityOptions.abort(options);
1128 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1129 }
1130 resultRecord = sourceRecord.resultTo;
1131 resultWho = sourceRecord.resultWho;
1132 requestCode = sourceRecord.requestCode;
1133 sourceRecord.resultTo = null;
1134 if (resultRecord != null) {
1135 resultRecord.removeResultsLocked(
1136 sourceRecord, resultWho, requestCode);
1137 }
1138 }
1139
1140 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1141 // We couldn't find a class that can handle the given Intent.
1142 // That's the end of that!
1143 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1144 }
1145
1146 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1147 // We couldn't find the specific class specified in the Intent.
1148 // Also the end of the line.
1149 err = ActivityManager.START_CLASS_NOT_FOUND;
1150 }
1151
1152 if (err != ActivityManager.START_SUCCESS) {
1153 if (resultRecord != null) {
1154 resultStack.sendActivityResultLocked(-1,
1155 resultRecord, resultWho, requestCode,
1156 Activity.RESULT_CANCELED, null);
1157 }
1158 setDismissKeyguard(false);
1159 ActivityOptions.abort(options);
1160 return err;
1161 }
1162
1163 final int startAnyPerm = mService.checkPermission(
1164 START_ANY_ACTIVITY, callingPid, callingUid);
1165 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1166 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1167 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1168 if (resultRecord != null) {
1169 resultStack.sendActivityResultLocked(-1,
1170 resultRecord, resultWho, requestCode,
1171 Activity.RESULT_CANCELED, null);
1172 }
1173 setDismissKeyguard(false);
1174 String msg;
1175 if (!aInfo.exported) {
1176 msg = "Permission Denial: starting " + intent.toString()
1177 + " from " + callerApp + " (pid=" + callingPid
1178 + ", uid=" + callingUid + ")"
1179 + " not exported from uid " + aInfo.applicationInfo.uid;
1180 } else {
1181 msg = "Permission Denial: starting " + intent.toString()
1182 + " from " + callerApp + " (pid=" + callingPid
1183 + ", uid=" + callingUid + ")"
1184 + " requires " + aInfo.permission;
1185 }
1186 Slog.w(TAG, msg);
1187 throw new SecurityException(msg);
1188 }
1189
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001190 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001191 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001192
Craig Mautner6170f732013-04-02 13:05:23 -07001193 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001194 try {
1195 // The Intent we give to the watcher has the extra data
1196 // stripped off, since it can contain private information.
1197 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001198 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001199 aInfo.applicationInfo.packageName);
1200 } catch (RemoteException e) {
1201 mService.mController = null;
1202 }
Ben Gruver5e207332013-04-03 17:41:37 -07001203 }
Craig Mautner6170f732013-04-02 13:05:23 -07001204
Ben Gruver5e207332013-04-03 17:41:37 -07001205 if (abort) {
1206 if (resultRecord != null) {
1207 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001208 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001209 }
Ben Gruver5e207332013-04-03 17:41:37 -07001210 // We pretend to the caller that it was really started, but
1211 // they will just get a cancel result.
1212 setDismissKeyguard(false);
1213 ActivityOptions.abort(options);
1214 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001215 }
1216
1217 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1218 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001219 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001220 if (outActivity != null) {
1221 outActivity[0] = r;
1222 }
1223
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001224 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001225 if (stack.mResumedActivity == null
1226 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001227 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1228 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001229 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001230 mService.mPendingActivityLaunches.add(pal);
1231 setDismissKeyguard(false);
1232 ActivityOptions.abort(options);
1233 return ActivityManager.START_SWITCHES_CANCELED;
1234 }
1235 }
1236
1237 if (mService.mDidAppSwitch) {
1238 // This is the second allowed switch since we stopped switches,
1239 // so now just generally allow switches. Use case: user presses
1240 // home (switches disabled, switch to home, mDidAppSwitch now true);
1241 // user taps a home icon (coming from home so allowed, we hit here
1242 // and now allow anyone to switch again).
1243 mService.mAppSwitchesAllowedTime = 0;
1244 } else {
1245 mService.mDidAppSwitch = true;
1246 }
1247
1248 mService.doPendingActivityLaunchesLocked(false);
1249
Craig Mautner8849a5e2013-04-02 16:41:03 -07001250 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001251
1252 if (allPausedActivitiesComplete()) {
1253 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001254 // activity start, but we are not actually doing an activity
1255 // switch... just dismiss the keyguard now, because we
1256 // probably want to see whatever is behind it.
1257 dismissKeyguard();
1258 }
1259 return err;
1260 }
1261
Craig Mautnerac6f8432013-07-17 13:24:59 -07001262 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001263 final TaskRecord task = r.task;
1264 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001265 if (task != null) {
1266 if (mFocusedStack != task.stack) {
1267 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1268 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
1269 mFocusedStack = task.stack;
1270 } else {
1271 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1272 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1273 }
1274 return mFocusedStack;
1275 }
1276
1277 if (mFocusedStack != null) {
1278 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1279 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1280 return mFocusedStack;
1281 }
1282
1283 for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1284 ActivityStack stack = mStacks.get(stackNdx);
1285 if (!stack.isHomeStack()) {
1286 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1287 "adjustStackFocus: Setting focused stack=" + stack);
1288 mFocusedStack = stack;
1289 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001290 }
1291 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001292
1293 // Time to create the first app stack for this user.
1294 int stackId = mService.createStack(-1, HOME_STACK_ID,
1295 StackBox.TASK_STACK_GOES_OVER, 1.0f);
1296 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1297 " stackId=" + stackId);
1298 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001299 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001300 }
1301 return mHomeStack;
1302 }
1303
Craig Mautner29219d92013-04-16 20:19:12 -07001304 void setFocusedStack(ActivityRecord r) {
1305 if (r == null) {
1306 return;
1307 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001308 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
Craig Mautner29219d92013-04-16 20:19:12 -07001309 if (mStackState != STACK_STATE_HOME_IN_FRONT) {
Craig Mautnere7c58b62013-06-12 20:19:00 -07001310 if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
Craig Mautner76ea2242013-05-15 11:40:05 -07001311 stackStateToString(mStackState) + " new=" +
1312 stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1313 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001314 mStackState = STACK_STATE_HOME_TO_FRONT;
1315 }
1316 } else {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001317 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1318 "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
1319 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001320 mFocusedStack = r.task.stack;
1321 if (mStackState != STACK_STATE_HOME_IN_BACK) {
Craig Mautner76ea2242013-05-15 11:40:05 -07001322 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1323 stackStateToString(mStackState) + " new=" +
1324 stackStateToString(STACK_STATE_HOME_TO_BACK) +
1325 " Callers=" + Debug.getCallers(3));
Craig Mautner29219d92013-04-16 20:19:12 -07001326 mStackState = STACK_STATE_HOME_TO_BACK;
1327 }
1328 }
1329 }
1330
Craig Mautner8849a5e2013-04-02 16:41:03 -07001331 final int startActivityUncheckedLocked(ActivityRecord r,
1332 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1333 Bundle options) {
1334 final Intent intent = r.intent;
1335 final int callingUid = r.launchedFromUid;
1336
1337 int launchFlags = intent.getFlags();
1338
Craig Mautner8849a5e2013-04-02 16:41:03 -07001339 // We'll invoke onUserLeaving before onPause only if the launching
1340 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001341 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1342 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001343
1344 // If the caller has asked not to resume at this point, we make note
1345 // of this in the record so that we can skip it when trying to find
1346 // the top running activity.
1347 if (!doResume) {
1348 r.delayedResume = true;
1349 }
1350
1351 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1352
1353 // If the onlyIfNeeded flag is set, then we can do this if the activity
1354 // being launched is the same as the one making the call... or, as
1355 // a special case, if we do not know the caller then we count the
1356 // current top activity as the caller.
1357 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1358 ActivityRecord checkedCaller = sourceRecord;
1359 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001360 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001361 }
1362 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1363 // Caller is not the same as launcher, so always needed.
1364 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1365 }
1366 }
1367
1368 if (sourceRecord == null) {
1369 // This activity is not being started from another... in this
1370 // case we -always- start a new task.
1371 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001372 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1373 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001374 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1375 }
1376 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1377 // The original activity who is starting us is running as a single
1378 // instance... this new activity it is starting must go on its
1379 // own task.
1380 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1381 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1382 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1383 // The activity being started is a single instance... it always
1384 // gets launched into its own task.
1385 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1386 }
1387
Craig Mautnerde4ef022013-04-07 19:01:33 -07001388 final ActivityStack sourceStack;
Craig Mautner525f3d92013-05-07 14:01:50 -07001389 TaskRecord sourceTask;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001390 if (sourceRecord != null) {
1391 sourceTask = sourceRecord.task;
1392 sourceStack = sourceTask.stack;
1393 } else {
1394 sourceTask = null;
1395 sourceStack = null;
1396 }
1397
Craig Mautner8849a5e2013-04-02 16:41:03 -07001398 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1399 // For whatever reason this activity is being launched into a new
1400 // task... yet the caller has requested a result back. Well, that
1401 // is pretty messed up, so instead immediately send back a cancel
1402 // and let the new task continue launched as normal without a
1403 // dependency on its originator.
1404 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1405 r.resultTo.task.stack.sendActivityResultLocked(-1,
1406 r.resultTo, r.resultWho, r.requestCode,
1407 Activity.RESULT_CANCELED, null);
1408 r.resultTo = null;
1409 }
1410
1411 boolean addingToTask = false;
1412 boolean movedHome = false;
1413 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001414 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001415 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1416 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1417 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1418 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1419 // If bring to front is requested, and no result is requested, and
1420 // we can find a task that was started with this same
1421 // component, then instead of launching bring that one to the front.
1422 if (r.resultTo == null) {
1423 // See if there is a task to bring to the front. If this is
1424 // a SINGLE_INSTANCE activity, there can be one and only one
1425 // instance of it in the history, and it is always in its own
1426 // unique task, so we do a special search.
1427 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001428 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001429 : findActivityLocked(intent, r.info);
1430 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001431 if (r.task == null) {
1432 r.task = intentActivity.task;
1433 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001434 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001435 targetStack.mLastPausedActivity = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001436 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001437 if (intentActivity.task.intent == null) {
1438 // This task was started because of movement of
1439 // the activity based on affinity... now that we
1440 // are actually launching it, we can assign the
1441 // base intent.
1442 intentActivity.task.setIntent(intent, r.info);
1443 }
1444 // If the target task is not in the front, then we need
1445 // to bring it to the front... except... well, with
1446 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1447 // to have the same behavior as if a new instance was
1448 // being started, which means not bringing it to the front
1449 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001450 final ActivityStack lastStack = getLastStack();
1451 ActivityRecord curTop = lastStack == null?
1452 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001453 if (curTop != null && (curTop.task != intentActivity.task ||
1454 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001455 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001456 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1457 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001458 // We really do want to push this one into the
1459 // user's face, right now.
1460 movedHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001461 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001462 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1463 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001464 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001465 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001466 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001467 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1468 options = null;
1469 }
1470 }
1471 // If the caller has requested that the target task be
1472 // reset, then do so.
1473 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1474 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1475 }
1476 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1477 // We don't need to start a new activity, and
1478 // the client said not to do anything if that
1479 // is the case, so this is it! And for paranoia, make
1480 // sure we have correctly resumed the top activity.
1481 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001482 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001483 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001484 } else {
1485 ActivityOptions.abort(options);
1486 }
Craig Mautner29219d92013-04-16 20:19:12 -07001487 if (r.task == null) Slog.v(TAG,
1488 "startActivityUncheckedLocked: task left null",
1489 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001490 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1491 }
1492 if ((launchFlags &
1493 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1494 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1495 // The caller has requested to completely replace any
1496 // existing task with its new activity. Well that should
1497 // not be too hard...
1498 reuseTask = intentActivity.task;
1499 reuseTask.performClearTaskLocked();
1500 reuseTask.setIntent(r.intent, r.info);
1501 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1502 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1503 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1504 // In this situation we want to remove all activities
1505 // from the task up to the one being started. In most
1506 // cases this means we are resetting the task to its
1507 // initial state.
1508 ActivityRecord top =
1509 intentActivity.task.performClearTaskLocked(r, launchFlags);
1510 if (top != null) {
1511 if (top.frontOfTask) {
1512 // Activity aliases may mean we use different
1513 // intents for the top activity, so make sure
1514 // the task now has the identity of the new
1515 // intent.
1516 top.task.setIntent(r.intent, r.info);
1517 }
1518 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1519 r, top.task);
1520 top.deliverNewIntentLocked(callingUid, r.intent);
1521 } else {
1522 // A special case: we need to
1523 // start the activity because it is not currently
1524 // running, and the caller has asked to clear the
1525 // current task to have this activity at the top.
1526 addingToTask = true;
1527 // Now pretend like this activity is being started
1528 // by the top of its task, so it is put in the
1529 // right place.
1530 sourceRecord = intentActivity;
1531 }
1532 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1533 // In this case the top activity on the task is the
1534 // same as the one being launched, so we take that
1535 // as a request to bring the task to the foreground.
1536 // If the top activity in the task is the root
1537 // activity, deliver this new intent to it if it
1538 // desires.
1539 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1540 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1541 && intentActivity.realActivity.equals(r.realActivity)) {
1542 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1543 intentActivity.task);
1544 if (intentActivity.frontOfTask) {
1545 intentActivity.task.setIntent(r.intent, r.info);
1546 }
1547 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1548 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1549 // In this case we are launching the root activity
1550 // of the task, but with a different intent. We
1551 // should start a new instance on top.
1552 addingToTask = true;
1553 sourceRecord = intentActivity;
1554 }
1555 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1556 // In this case an activity is being launched in to an
1557 // existing task, without resetting that task. This
1558 // is typically the situation of launching an activity
1559 // from a notification or shortcut. We want to place
1560 // the new activity on top of the current task.
1561 addingToTask = true;
1562 sourceRecord = intentActivity;
1563 } else if (!intentActivity.task.rootWasReset) {
1564 // In this case we are launching in to an existing task
1565 // that has not yet been started from its front door.
1566 // The current task has been brought to the front.
1567 // Ideally, we'd probably like to place this new task
1568 // at the bottom of its stack, but that's a little hard
1569 // to do with the current organization of the code so
1570 // for now we'll just drop it.
1571 intentActivity.task.setIntent(r.intent, r.info);
1572 }
1573 if (!addingToTask && reuseTask == null) {
1574 // We didn't do anything... but it was needed (a.k.a., client
1575 // don't use that intent!) And for paranoia, make
1576 // sure we have correctly resumed the top activity.
1577 if (doResume) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001578 // Reset flag so it gets correctly reevaluated.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001579 intentActivity.task.mOnTopOfHome = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001580 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1581 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001582 } else {
1583 ActivityOptions.abort(options);
1584 }
Craig Mautner29219d92013-04-16 20:19:12 -07001585 if (r.task == null) Slog.v(TAG,
1586 "startActivityUncheckedLocked: task left null",
1587 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001588 return ActivityManager.START_TASK_TO_FRONT;
1589 }
1590 }
1591 }
1592 }
1593
1594 //String uri = r.intent.toURI();
1595 //Intent intent2 = new Intent(uri);
1596 //Slog.i(TAG, "Given intent: " + r.intent);
1597 //Slog.i(TAG, "URI is: " + uri);
1598 //Slog.i(TAG, "To intent: " + intent2);
1599
1600 if (r.packageName != null) {
1601 // If the activity being launched is the same as the one currently
1602 // at the top, then we need to check if it should only be launched
1603 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001604 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001605 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001606 if (top != null && r.resultTo == null) {
1607 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1608 if (top.app != null && top.app.thread != null) {
1609 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1610 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1611 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1612 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1613 top.task);
1614 // For paranoia, make sure we have correctly
1615 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001616 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001617 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001618 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
Craig Mautner05d29032013-05-03 13:40:13 -07001619 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001620 }
1621 ActivityOptions.abort(options);
1622 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1623 // We don't need to start a new activity, and
1624 // the client said not to do anything if that
1625 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001626 if (r.task == null) Slog.v(TAG,
1627 "startActivityUncheckedLocked: task left null",
1628 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001629 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1630 }
1631 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001632 if (r.task == null) Slog.v(TAG,
1633 "startActivityUncheckedLocked: task left null",
1634 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001635 return ActivityManager.START_DELIVERED_TO_TOP;
1636 }
1637 }
1638 }
1639 }
1640
1641 } else {
1642 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001643 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1644 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001645 }
1646 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001647 if (r.task == null) Slog.v(TAG,
1648 "startActivityUncheckedLocked: task left null",
1649 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001650 return ActivityManager.START_CLASS_NOT_FOUND;
1651 }
1652
1653 boolean newTask = false;
1654 boolean keepCurTransition = false;
1655
1656 // Should this be considered a new task?
1657 if (r.resultTo == null && !addingToTask
1658 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001659 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001660 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001661 if (reuseTask == null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001662 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1663 null, true);
1664 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1665 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001666 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001667 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001668 }
1669 newTask = true;
1670 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001671 if ((launchFlags &
1672 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1673 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1674 // Caller wants to appear on home activity, so before starting
1675 // their own activity we will bring home to the front.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001676 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001677 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001678 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001679 } else if (sourceRecord != null) {
Craig Mautner525f3d92013-05-07 14:01:50 -07001680 sourceTask = sourceRecord.task;
1681 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001682 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001683 if (!addingToTask &&
1684 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1685 // In this case, we are adding the activity to an existing
1686 // task, but the caller has asked to clear that task if the
1687 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001688 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001689 keepCurTransition = true;
1690 if (top != null) {
1691 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1692 top.deliverNewIntentLocked(callingUid, r.intent);
1693 // For paranoia, make sure we have correctly
1694 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001695 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001696 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001697 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001698 targetStack.resumeTopActivityLocked(null);
1699 }
1700 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001701 if (r.task == null) Slog.v(TAG,
1702 "startActivityUncheckedLocked: task left null",
1703 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001704 return ActivityManager.START_DELIVERED_TO_TOP;
1705 }
1706 } else if (!addingToTask &&
1707 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1708 // In this case, we are launching an activity in our own task
1709 // that may already be running somewhere in the history, and
1710 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001711 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001712 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001713 final TaskRecord task = top.task;
1714 task.moveActivityToFrontLocked(top);
1715 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001716 top.updateOptionsLocked(options);
1717 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001718 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001719 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001720 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001721 targetStack.resumeTopActivityLocked(null);
1722 }
1723 return ActivityManager.START_DELIVERED_TO_TOP;
1724 }
1725 }
1726 // An existing activity is starting this new activity, so we want
1727 // to keep the new one in the same task as the one that is starting
1728 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001729 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001730 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1731 + " in existing task " + r.task);
1732
1733 } else {
1734 // This not being started from an existing activity, and not part
1735 // of a new task... just put it in the top task, though these days
1736 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001737 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001738 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001739 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001740 r.setTask(prev != null ? prev.task
1741 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1742 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001743 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1744 + " in new guessed " + r.task);
1745 }
1746
1747 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1748 intent, r.getUriPermissionsLocked());
1749
1750 if (newTask) {
1751 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1752 }
1753 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001754 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
Craig Mautner0f922742013-08-06 08:44:42 -07001755 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001756 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001757 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001758 return ActivityManager.START_SUCCESS;
1759 }
1760
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001761 void acquireLaunchWakelock() {
1762 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1763 throw new IllegalStateException("Calling must be system uid");
1764 }
1765 mLaunchingActivity.acquire();
1766 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1767 // To be safe, don't allow the wake lock to be held for too long.
1768 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1769 }
1770 }
1771
Craig Mautnerf3333272013-04-22 10:55:53 -07001772 // Checked.
1773 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1774 Configuration config) {
1775 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1776
Craig Mautnerf3333272013-04-22 10:55:53 -07001777 ArrayList<ActivityRecord> stops = null;
1778 ArrayList<ActivityRecord> finishes = null;
1779 ArrayList<UserStartedState> startingUsers = null;
1780 int NS = 0;
1781 int NF = 0;
1782 IApplicationThread sendThumbnail = null;
1783 boolean booting = false;
1784 boolean enableScreen = false;
1785 boolean activityRemoved = false;
1786
1787 ActivityRecord r = ActivityRecord.forToken(token);
1788 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001789 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1790 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001791 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1792 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001793 if (fromTimeout) {
1794 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001795 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001796
1797 // This is a hack to semi-deal with a race condition
1798 // in the client where it can be constructed with a
1799 // newer configuration from when we asked it to launch.
1800 // We'll update with whatever configuration it now says
1801 // it used to launch.
1802 if (config != null) {
1803 r.configuration = config;
1804 }
1805
1806 // We are now idle. If someone is waiting for a thumbnail from
1807 // us, we can now deliver.
1808 r.idle = true;
1809
1810 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1811 sendThumbnail = r.app.thread;
1812 r.thumbnailNeeded = false;
1813 }
1814
1815 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1816 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1817 mService.mBooted = true;
1818 enableScreen = true;
1819 }
1820 }
1821
1822 if (allResumedActivitiesIdle()) {
1823 if (r != null) {
1824 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001825 }
1826
1827 if (mLaunchingActivity.isHeld()) {
1828 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1829 if (VALIDATE_WAKE_LOCK_CALLER &&
1830 Binder.getCallingUid() != Process.myUid()) {
1831 throw new IllegalStateException("Calling must be system uid");
1832 }
1833 mLaunchingActivity.release();
1834 }
1835 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001836 }
1837
1838 // Atomically retrieve all of the other things to do.
1839 stops = processStoppingActivitiesLocked(true);
1840 NS = stops != null ? stops.size() : 0;
1841 if ((NF=mFinishingActivities.size()) > 0) {
1842 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1843 mFinishingActivities.clear();
1844 }
1845
1846 final ArrayList<ActivityRecord> thumbnails;
1847 final int NT = mCancelledThumbnails.size();
1848 if (NT > 0) {
1849 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1850 mCancelledThumbnails.clear();
1851 } else {
1852 thumbnails = null;
1853 }
1854
1855 if (isFrontStack(mHomeStack)) {
1856 booting = mService.mBooting;
1857 mService.mBooting = false;
1858 }
1859
1860 if (mStartingUsers.size() > 0) {
1861 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1862 mStartingUsers.clear();
1863 }
1864
1865 // Perform the following actions from unsynchronized state.
1866 final IApplicationThread thumbnailThread = sendThumbnail;
1867 mHandler.post(new Runnable() {
1868 @Override
1869 public void run() {
1870 if (thumbnailThread != null) {
1871 try {
1872 thumbnailThread.requestThumbnail(token);
1873 } catch (Exception e) {
1874 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1875 mService.sendPendingThumbnail(null, token, null, null, true);
1876 }
1877 }
1878
1879 // Report back to any thumbnail receivers.
1880 for (int i = 0; i < NT; i++) {
1881 ActivityRecord r = thumbnails.get(i);
1882 mService.sendPendingThumbnail(r, null, null, null, true);
1883 }
1884 }
1885 });
1886
1887 // Stop any activities that are scheduled to do so but have been
1888 // waiting for the next one to start.
1889 for (int i = 0; i < NS; i++) {
1890 r = stops.get(i);
1891 final ActivityStack stack = r.task.stack;
1892 if (r.finishing) {
1893 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1894 } else {
1895 stack.stopActivityLocked(r);
1896 }
1897 }
1898
1899 // Finish any activities that are scheduled to do so but have been
1900 // waiting for the next one to start.
1901 for (int i = 0; i < NF; i++) {
1902 r = finishes.get(i);
1903 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1904 }
1905
1906 if (booting) {
1907 mService.finishBooting();
1908 } else if (startingUsers != null) {
1909 for (int i = 0; i < startingUsers.size(); i++) {
1910 mService.finishUserSwitch(startingUsers.get(i));
1911 }
1912 }
1913
1914 mService.trimApplications();
1915 //dump();
1916 //mWindowManager.dump();
1917
1918 if (enableScreen) {
1919 mService.enableScreenAfterBoot();
1920 }
1921
1922 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001923 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001924 }
1925
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001926 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001927 }
1928
Craig Mautner19091252013-10-05 00:03:53 -07001929 boolean handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1930 boolean hasVisibleActivities = false;
1931 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1932 hasVisibleActivities |= mStacks.get(stackNdx).handleAppDiedLocked(app);
Craig Mautner6b74cb52013-09-27 17:02:21 -07001933 }
Craig Mautner19091252013-10-05 00:03:53 -07001934 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001935 }
1936
1937 void closeSystemDialogsLocked() {
1938 final int numStacks = mStacks.size();
1939 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1940 final ActivityStack stack = mStacks.get(stackNdx);
1941 stack.closeSystemDialogsLocked();
1942 }
1943 }
1944
1945 /**
1946 * @return true if some activity was finished (or would have finished if doit were true).
1947 */
1948 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1949 boolean didSomething = false;
1950 final int numStacks = mStacks.size();
1951 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1952 final ActivityStack stack = mStacks.get(stackNdx);
1953 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1954 didSomething = true;
1955 }
1956 }
1957 return didSomething;
1958 }
1959
Dianne Hackborna413dc02013-07-12 12:02:55 -07001960 void updatePreviousProcessLocked(ActivityRecord r) {
1961 // Now that this process has stopped, we may want to consider
1962 // it to be the previous app to try to keep around in case
1963 // the user wants to return to it.
1964
1965 // First, found out what is currently the foreground app, so that
1966 // we don't blow away the previous app if this activity is being
1967 // hosted by the process that is actually still the foreground.
1968 ProcessRecord fgApp = null;
1969 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1970 final ActivityStack stack = mStacks.get(stackNdx);
1971 if (isFrontStack(stack)) {
1972 if (stack.mResumedActivity != null) {
1973 fgApp = stack.mResumedActivity.app;
1974 } else if (stack.mPausingActivity != null) {
1975 fgApp = stack.mPausingActivity.app;
1976 }
1977 break;
1978 }
1979 }
1980
1981 // Now set this one as the previous process, only if that really
1982 // makes sense to.
1983 if (r.app != null && fgApp != null && r.app != fgApp
1984 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07001985 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07001986 mService.mPreviousProcess = r.app;
1987 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
1988 }
1989 }
1990
Craig Mautner05d29032013-05-03 13:40:13 -07001991 boolean resumeTopActivitiesLocked() {
1992 return resumeTopActivitiesLocked(null, null, null);
1993 }
1994
1995 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1996 Bundle targetOptions) {
1997 if (targetStack == null) {
1998 targetStack = getFocusedStack();
1999 }
2000 boolean result = false;
Craig Mautnerdbcb31f2013-04-02 12:32:53 -07002001 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002002 final ActivityStack stack = mStacks.get(stackNdx);
2003 if (isFrontStack(stack)) {
Craig Mautner05d29032013-05-03 13:40:13 -07002004 if (stack == targetStack) {
2005 result = stack.resumeTopActivityLocked(target, targetOptions);
2006 } else {
2007 stack.resumeTopActivityLocked(null);
2008 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002009 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002010 }
Craig Mautner05d29032013-05-03 13:40:13 -07002011 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002012 }
2013
2014 void finishTopRunningActivityLocked(ProcessRecord app) {
2015 final int numStacks = mStacks.size();
2016 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2017 final ActivityStack stack = mStacks.get(stackNdx);
2018 stack.finishTopRunningActivityLocked(app);
2019 }
2020 }
2021
Craig Mautner8d341ef2013-03-26 09:03:27 -07002022 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
2023 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2024 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002025 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
Craig Mautner1d001b62013-06-18 16:52:43 -07002026 mStacks.get(stackNdx));
Craig Mautner8d341ef2013-03-26 09:03:27 -07002027 return;
2028 }
2029 }
2030 }
2031
Craig Mautner967212c2013-04-13 21:10:58 -07002032 ActivityStack getStack(int stackId) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002033 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2034 final ActivityStack stack = mStacks.get(stackNdx);
2035 if (stack.getStackId() == stackId) {
2036 return stack;
2037 }
2038 }
2039 return null;
2040 }
2041
Craig Mautner967212c2013-04-13 21:10:58 -07002042 ArrayList<ActivityStack> getStacks() {
2043 return new ArrayList<ActivityStack>(mStacks);
2044 }
2045
2046 int createStack() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002047 while (true) {
2048 if (++mLastStackId <= HOME_STACK_ID) {
2049 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002050 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002051 if (getStack(mLastStackId) == null) {
2052 break;
2053 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002054 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002055 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
2056 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002057 }
2058
2059 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002060 final TaskRecord task = anyTaskForIdLocked(taskId);
2061 if (task == null) {
2062 return;
2063 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002064 final ActivityStack stack = getStack(stackId);
2065 if (stack == null) {
2066 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2067 return;
2068 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002069 removeTask(task);
2070 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002071 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002072 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002073 }
2074
Craig Mautnerac6f8432013-07-17 13:24:59 -07002075 ActivityRecord findTaskLocked(ActivityRecord r) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07002076 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07002077 final ActivityStack stack = mStacks.get(stackNdx);
2078 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2079 continue;
2080 }
2081 final ActivityRecord ar = stack.findTaskLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07002082 if (ar != null) {
2083 return ar;
2084 }
2085 }
2086 return null;
2087 }
2088
2089 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2090 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2091 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
2092 if (ar != null) {
2093 return ar;
2094 }
2095 }
2096 return null;
2097 }
2098
Craig Mautner8d341ef2013-03-26 09:03:27 -07002099 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002100 scheduleSleepTimeout();
2101 if (!mGoingToSleep.isHeld()) {
2102 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002103 if (mLaunchingActivity.isHeld()) {
2104 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2105 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002106 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002107 mLaunchingActivity.release();
2108 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002109 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002110 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002111 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002112 }
2113
2114 boolean shutdownLocked(int timeout) {
2115 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002116 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002117
2118 final long endTime = System.currentTimeMillis() + timeout;
2119 while (true) {
2120 boolean cantShutdown = false;
2121 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2122 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2123 }
2124 if (cantShutdown) {
2125 long timeRemaining = endTime - System.currentTimeMillis();
2126 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002127 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002128 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002129 } catch (InterruptedException e) {
2130 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002131 } else {
2132 Slog.w(TAG, "Activity manager shutdown timed out");
2133 timedout = true;
2134 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002135 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002136 } else {
2137 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002138 }
2139 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002140
2141 // Force checkReadyForSleep to complete.
2142 mSleepTimeout = true;
2143 checkReadyForSleepLocked();
2144
Craig Mautner8d341ef2013-03-26 09:03:27 -07002145 return timedout;
2146 }
2147
2148 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002149 removeSleepTimeouts();
2150 if (mGoingToSleep.isHeld()) {
2151 mGoingToSleep.release();
2152 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002153 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002154 final ActivityStack stack = mStacks.get(stackNdx);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002155 stack.awakeFromSleepingLocked();
Craig Mautner5314a402013-09-26 12:40:16 -07002156 if (isFrontStack(stack)) {
2157 resumeTopActivitiesLocked();
2158 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002159 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002160 mGoingToSleepActivities.clear();
2161 }
2162
2163 void activitySleptLocked(ActivityRecord r) {
2164 mGoingToSleepActivities.remove(r);
2165 checkReadyForSleepLocked();
2166 }
2167
2168 void checkReadyForSleepLocked() {
2169 if (!mService.isSleepingOrShuttingDown()) {
2170 // Do not care.
2171 return;
2172 }
2173
2174 if (!mSleepTimeout) {
2175 boolean dontSleep = false;
2176 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2177 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2178 }
2179
2180 if (mStoppingActivities.size() > 0) {
2181 // Still need to tell some activities to stop; can't sleep yet.
2182 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2183 + mStoppingActivities.size() + " activities");
2184 scheduleIdleLocked();
2185 dontSleep = true;
2186 }
2187
2188 if (mGoingToSleepActivities.size() > 0) {
2189 // Still need to tell some activities to sleep; can't sleep yet.
2190 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2191 + mGoingToSleepActivities.size() + " activities");
2192 dontSleep = true;
2193 }
2194
2195 if (dontSleep) {
2196 return;
2197 }
2198 }
2199
2200 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2201 mStacks.get(stackNdx).goToSleep();
2202 }
2203
2204 removeSleepTimeouts();
2205
2206 if (mGoingToSleep.isHeld()) {
2207 mGoingToSleep.release();
2208 }
2209 if (mService.mShuttingDown) {
2210 mService.notifyAll();
2211 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002212 }
2213
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002214 boolean reportResumedActivityLocked(ActivityRecord r) {
2215 final ActivityStack stack = r.task.stack;
2216 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002217 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002218 }
2219 if (allResumedActivitiesComplete()) {
2220 ensureActivitiesVisibleLocked(null, 0);
2221 mWindowManager.executeAppTransition();
2222 return true;
2223 }
2224 return false;
2225 }
2226
Craig Mautner8d341ef2013-03-26 09:03:27 -07002227 void handleAppCrashLocked(ProcessRecord app) {
2228 final int numStacks = mStacks.size();
2229 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2230 final ActivityStack stack = mStacks.get(stackNdx);
2231 stack.handleAppCrashLocked(app);
2232 }
2233 }
2234
Craig Mautnerde4ef022013-04-07 19:01:33 -07002235 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002236 // First the front stacks. In case any are not fullscreen and are in front of home.
2237 boolean showHomeBehindStack = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07002238 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner580ea812013-04-25 12:58:38 -07002239 final ActivityStack stack = mStacks.get(stackNdx);
2240 if (isFrontStack(stack)) {
2241 showHomeBehindStack =
2242 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2243 }
2244 }
2245 // Now do back stacks.
2246 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2247 final ActivityStack stack = mStacks.get(stackNdx);
2248 if (!isFrontStack(stack)) {
2249 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2250 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002251 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002252 }
2253
2254 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2255 final int numStacks = mStacks.size();
2256 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2257 final ActivityStack stack = mStacks.get(stackNdx);
2258 stack.scheduleDestroyActivities(app, false, reason);
2259 }
2260 }
2261
2262 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner2420ead2013-04-01 17:13:20 -07002263 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002264
Craig Mautner858d8a62013-04-23 17:08:34 -07002265 mStartingUsers.add(uss);
Craig Mautnerac6f8432013-07-17 13:24:59 -07002266 boolean haveActivities = false;
2267 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2268 haveActivities |= mStacks.get(stackNdx).switchUserLocked(userId);
2269 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002270
2271 resumeTopActivitiesLocked();
2272
Craig Mautner8d341ef2013-03-26 09:03:27 -07002273 return haveActivities;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002274 }
2275
Craig Mautnerde4ef022013-04-07 19:01:33 -07002276 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2277 int N = mStoppingActivities.size();
2278 if (N <= 0) return null;
2279
2280 ArrayList<ActivityRecord> stops = null;
2281
2282 final boolean nowVisible = allResumedActivitiesVisible();
2283 for (int i=0; i<N; i++) {
2284 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautner323f7802013-10-01 21:16:22 -07002285 if (true || localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002286 + nowVisible + " waitingVisible=" + s.waitingVisible
2287 + " finishing=" + s.finishing);
2288 if (s.waitingVisible && nowVisible) {
2289 mWaitingVisibleActivities.remove(s);
2290 s.waitingVisible = false;
2291 if (s.finishing) {
2292 // If this activity is finishing, it is sitting on top of
2293 // everyone else but we now know it is no longer needed...
2294 // so get rid of it. Otherwise, we need to go through the
2295 // normal flow and hide it once we determine that it is
2296 // hidden by the activities in front of it.
2297 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002298 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002299 }
2300 }
2301 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2302 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2303 if (stops == null) {
2304 stops = new ArrayList<ActivityRecord>();
2305 }
2306 stops.add(s);
2307 mStoppingActivities.remove(i);
2308 N--;
2309 i--;
2310 }
2311 }
2312
2313 return stops;
2314 }
2315
Craig Mautnercf910b02013-04-23 11:23:27 -07002316 void validateTopActivitiesLocked() {
2317 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2318 final ActivityStack stack = mStacks.get(stackNdx);
2319 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002320 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002321 if (isFrontStack(stack)) {
2322 if (r == null) {
2323 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2324 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002325 final ActivityRecord pausing = stack.mPausingActivity;
2326 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002327 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002328 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002329 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002330 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002331 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002332 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002333 }
2334 }
2335 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002336 final ActivityRecord resumed = stack.mResumedActivity;
2337 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002338 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002339 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002340 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002341 if (r != null && (state == ActivityState.INITIALIZING
2342 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002343 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002344 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002345 }
2346 }
2347 }
2348 }
2349
Craig Mautner76ea2242013-05-15 11:40:05 -07002350 private static String stackStateToString(int stackState) {
2351 switch (stackState) {
2352 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2353 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2354 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2355 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2356 default: return "Unknown stackState=" + stackState;
2357 }
2358 }
2359
Craig Mautner27084302013-03-25 08:05:25 -07002360 public void dump(PrintWriter pw, String prefix) {
2361 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2362 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautner76ea2242013-05-15 11:40:05 -07002363 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002364 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2365 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
Craig Mautner27084302013-03-25 08:05:25 -07002366 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002367
Craig Mautner20e72272013-04-01 13:45:53 -07002368 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002369 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002370 }
2371
Dianne Hackborn390517b2013-05-30 15:03:32 -07002372 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2373 boolean needSep, String prefix) {
2374 if (activity != null) {
2375 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2376 if (needSep) {
2377 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002378 }
2379 pw.print(prefix);
2380 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002381 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002382 }
2383 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002384 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002385 }
2386
Craig Mautner8d341ef2013-03-26 09:03:27 -07002387 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2388 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002389 boolean printed = false;
2390 boolean needSep = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002391 final int numStacks = mStacks.size();
2392 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2393 final ActivityStack stack = mStacks.get(stackNdx);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002394 StringBuilder stackHeader = new StringBuilder(128);
2395 stackHeader.append(" Stack #");
2396 stackHeader.append(mStacks.indexOf(stack));
2397 stackHeader.append(":");
2398 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2399 stackHeader.toString());
2400 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
2401 false, dumpPackage, true, " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002402
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002403 needSep = printed;
2404 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002405 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002406 if (pr) {
2407 printed = true;
2408 needSep = false;
2409 }
2410 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002411 " mResumedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002412 if (pr) {
2413 printed = true;
2414 needSep = false;
2415 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002416 if (dumpAll) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002417 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
Dianne Hackborn390517b2013-05-30 15:03:32 -07002418 " mLastPausedActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002419 if (pr) {
2420 printed = true;
Craig Mautner0f922742013-08-06 08:44:42 -07002421 needSep = true;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002422 }
Craig Mautner0f922742013-08-06 08:44:42 -07002423 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2424 needSep, " mLastNoHistoryActivity: ");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002425 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002426 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002427 }
2428
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002429 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2430 false, dumpPackage, true, " Activities waiting to finish:", null);
2431 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2432 false, dumpPackage, true, " Activities waiting to stop:", null);
2433 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2434 false, dumpPackage, true, " Activities waiting for another to become visible:",
2435 null);
2436 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2437 false, dumpPackage, true, " Activities waiting to sleep:", null);
2438 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2439 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002440
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002441 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002442 }
2443
Dianne Hackborn390517b2013-05-30 15:03:32 -07002444 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002445 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002446 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002447 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002448 String innerPrefix = null;
2449 String[] args = null;
2450 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002451 for (int i=list.size()-1; i>=0; i--) {
2452 final ActivityRecord r = list.get(i);
2453 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2454 continue;
2455 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002456 if (innerPrefix == null) {
2457 innerPrefix = prefix + " ";
2458 args = new String[0];
2459 }
2460 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002461 final boolean full = !brief && (complete || !r.isInHistory());
2462 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002463 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002464 needNL = false;
2465 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002466 if (header1 != null) {
2467 pw.println(header1);
2468 header1 = null;
2469 }
2470 if (header2 != null) {
2471 pw.println(header2);
2472 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002473 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002474 if (lastTask != r.task) {
2475 lastTask = r.task;
2476 pw.print(prefix);
2477 pw.print(full ? "* " : " ");
2478 pw.println(lastTask);
2479 if (full) {
2480 lastTask.dump(pw, prefix + " ");
2481 } else if (complete) {
2482 // Complete + brief == give a summary. Isn't that obvious?!?
2483 if (lastTask.intent != null) {
2484 pw.print(prefix); pw.print(" ");
2485 pw.println(lastTask.intent.toInsecureStringWithClip());
2486 }
2487 }
2488 }
2489 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2490 pw.print(" #"); pw.print(i); pw.print(": ");
2491 pw.println(r);
2492 if (full) {
2493 r.dump(pw, innerPrefix);
2494 } else if (complete) {
2495 // Complete + brief == give a summary. Isn't that obvious?!?
2496 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2497 if (r.app != null) {
2498 pw.print(innerPrefix); pw.println(r.app);
2499 }
2500 }
2501 if (client && r.app != null && r.app.thread != null) {
2502 // flush anything that is already in the PrintWriter since the thread is going
2503 // to write to the file descriptor directly
2504 pw.flush();
2505 try {
2506 TransferPipe tp = new TransferPipe();
2507 try {
2508 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2509 r.appToken, innerPrefix, args);
2510 // Short timeout, since blocking here can
2511 // deadlock with the application.
2512 tp.go(fd, 2000);
2513 } finally {
2514 tp.kill();
2515 }
2516 } catch (IOException e) {
2517 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2518 } catch (RemoteException e) {
2519 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2520 }
2521 needNL = true;
2522 }
2523 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002524 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002525 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002526
Craig Mautnerf3333272013-04-22 10:55:53 -07002527 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002528 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002529 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2530 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002531 }
2532
2533 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002534 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002535 }
2536
2537 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002538 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002539 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2540 }
2541
Craig Mautner05d29032013-05-03 13:40:13 -07002542 final void scheduleResumeTopActivities() {
2543 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2544 }
2545
Craig Mautner0eea92c2013-05-16 13:35:39 -07002546 void removeSleepTimeouts() {
2547 mSleepTimeout = false;
2548 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2549 }
2550
2551 final void scheduleSleepTimeout() {
2552 removeSleepTimeouts();
2553 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2554 }
2555
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002556 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002557
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002558 public ActivityStackSupervisorHandler(Looper looper) {
2559 super(looper);
2560 }
2561
Craig Mautnerf3333272013-04-22 10:55:53 -07002562 void activityIdleInternal(ActivityRecord r) {
2563 synchronized (mService) {
2564 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2565 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002566 }
2567
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002568 @Override
2569 public void handleMessage(Message msg) {
2570 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002571 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002572 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002573 if (mService.mDidDexOpt) {
2574 mService.mDidDexOpt = false;
2575 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2576 nmsg.obj = msg.obj;
2577 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2578 return;
2579 }
2580 // We don't at this point know if the activity is fullscreen,
2581 // so we need to be conservative and assume it isn't.
2582 activityIdleInternal((ActivityRecord)msg.obj);
2583 } break;
2584 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002585 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002586 activityIdleInternal((ActivityRecord)msg.obj);
2587 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002588 case RESUME_TOP_ACTIVITY_MSG: {
2589 synchronized (mService) {
2590 resumeTopActivitiesLocked();
2591 }
2592 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002593 case SLEEP_TIMEOUT_MSG: {
2594 synchronized (mService) {
2595 if (mService.isSleepingOrShuttingDown()) {
2596 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2597 mSleepTimeout = true;
2598 checkReadyForSleepLocked();
2599 }
2600 }
2601 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002602 case LAUNCH_TIMEOUT_MSG: {
2603 if (mService.mDidDexOpt) {
2604 mService.mDidDexOpt = false;
2605 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2606 return;
2607 }
2608 synchronized (mService) {
2609 if (mLaunchingActivity.isHeld()) {
2610 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2611 if (VALIDATE_WAKE_LOCK_CALLER
2612 && Binder.getCallingUid() != Process.myUid()) {
2613 throw new IllegalStateException("Calling must be system uid");
2614 }
2615 mLaunchingActivity.release();
2616 }
2617 }
2618 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002619 }
2620 }
2621 }
Craig Mautner27084302013-03-25 08:05:25 -07002622}