blob: f1ac7fe14151fadaf9c83d0c255b0c29ec2c39ef [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;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner23ac33b2013-04-01 16:26:35 -070062import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070063import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070064import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070065import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070067import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070068import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070069import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070070import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070071import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070072import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070074import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070075import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080077import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070078
Craig Mautner4a1cb222013-12-04 16:14:06 -080079import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080080import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.view.DisplayInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070082import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070083import com.android.internal.os.TransferPipe;
Craig Mautner6170f732013-04-02 13:05:23 -070084import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070085import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070086import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070087
Craig Mautner8d341ef2013-03-26 09:03:27 -070088import java.io.FileDescriptor;
89import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070090import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070091import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070092import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070093
Craig Mautner4a1cb222013-12-04 16:14:06 -080094public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -070095 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
96 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
97 static final boolean DEBUG_APP = DEBUG || false;
98 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -070099 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700100 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700101
Craig Mautner2219a1b2013-03-25 09:44:30 -0700102 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700103
Craig Mautnerf3333272013-04-22 10:55:53 -0700104 /** How long we wait until giving up on the last activity telling us it is idle. */
105 static final int IDLE_TIMEOUT = 10*1000;
106
Craig Mautner0eea92c2013-05-16 13:35:39 -0700107 /** How long we can hold the sleep wake lock before giving up. */
108 static final int SLEEP_TIMEOUT = 5*1000;
109
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700110 // How long we can hold the launch wake lock before giving up.
111 static final int LAUNCH_TIMEOUT = 10*1000;
112
Craig Mautner05d29032013-05-03 13:40:13 -0700113 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
114 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
115 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700116 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700117 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800118 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
119 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
120 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
121
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700122
123 // For debugging to make sure the caller when acquiring/releasing our
124 // wake lock is the system process.
125 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700126
Craig Mautner27084302013-03-25 08:05:25 -0700127 final ActivityManagerService mService;
128
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700129 final ActivityStackSupervisorHandler mHandler;
130
131 /** Short cut */
132 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800133 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700134
Craig Mautner27084302013-03-25 08:05:25 -0700135 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700136 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700137
Craig Mautner8d341ef2013-03-26 09:03:27 -0700138 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700139 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700140
141 /** Task identifier that activities are currently being started in. Incremented each time a
142 * new task is created. */
143 private int mCurTaskId = 0;
144
Craig Mautner2420ead2013-04-01 17:13:20 -0700145 /** The current user */
146 private int mCurrentUser;
147
Craig Mautner8d341ef2013-03-26 09:03:27 -0700148 /** The stack containing the launcher app */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700149 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700150
Craig Mautnerde4ef022013-04-07 19:01:33 -0700151 /** The non-home stack currently receiving input or launching the next activity. If home is
Craig Mautner41c0f352013-05-28 08:39:25 -0700152 * in front then mHomeStack overrides mFocusedStack.
153 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
Craig Mautner29219d92013-04-16 20:19:12 -0700154 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700155
Craig Mautner4a1cb222013-12-04 16:14:06 -0800156 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
157 * been resumed. If stacks are changing position this will hold the old stack until the new
158 * stack becomes resumed after which it will be set to the new stack. */
159 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700160
161 /** List of activities that are waiting for a new activity to become visible before completing
162 * whatever operation they are supposed to do. */
163 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
164
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700165 /** List of processes waiting to find out about the next visible activity. */
166 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
167 new ArrayList<IActivityManager.WaitResult>();
168
169 /** List of processes waiting to find out about the next launched activity. */
170 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
171 new ArrayList<IActivityManager.WaitResult>();
172
Craig Mautnerde4ef022013-04-07 19:01:33 -0700173 /** List of activities that are ready to be stopped, but waiting for the next activity to
174 * settle down before doing so. */
175 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
176
Craig Mautnerf3333272013-04-22 10:55:53 -0700177 /** List of activities that are ready to be finished, but waiting for the previous activity to
178 * settle down before doing so. It contains ActivityRecord objects. */
179 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
180
Craig Mautner0eea92c2013-05-16 13:35:39 -0700181 /** List of activities that are in the process of going to sleep. */
182 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
183
Craig Mautnerf3333272013-04-22 10:55:53 -0700184 /** List of ActivityRecord objects that have been finished and must still report back to a
185 * pending thumbnail receiver. */
186 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
187
188 /** Used on user changes */
189 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
190
Craig Mautnerde4ef022013-04-07 19:01:33 -0700191 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
192 * is being brought in front of us. */
193 boolean mUserLeaving = false;
194
Craig Mautner0eea92c2013-05-16 13:35:39 -0700195 /** Set when we have taken too long waiting to go to sleep. */
196 boolean mSleepTimeout = false;
197
198 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700199 * We don't want to allow the device to go to sleep while in the process
200 * of launching an activity. This is primarily to allow alarm intent
201 * receivers to launch an activity and get that to run before the device
202 * goes back to sleep.
203 */
204 final PowerManager.WakeLock mLaunchingActivity;
205
206 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700207 * Set when the system is going to sleep, until we have
208 * successfully paused the current activity and released our wake lock.
209 * At that point the system is allowed to actually sleep.
210 */
211 final PowerManager.WakeLock mGoingToSleep;
212
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700213 /** Stack id of the front stack when user switched, indexed by userId. */
214 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700215
Craig Mautner4a1cb222013-12-04 16:14:06 -0800216 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
217 SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
218
219 /** Mapping from displayId to display current state */
220 SparseArray<ActivityDisplayInfo> mDisplayInfos = new SparseArray<ActivityDisplayInfo>();
221
222 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700223 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800224 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700225 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800226 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700227 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
228 throw new IllegalStateException("Calling must be system uid");
229 }
230 mLaunchingActivity =
231 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
232 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700233 }
234
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700235 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800236 synchronized (mService) {
237 mWindowManager = wm;
238
239 mDisplayManager =
240 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
241 mDisplayManager.registerDisplayListener(this, null);
242
243 Display[] displays = mDisplayManager.getDisplays();
244 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
245 final int displayId = displays[displayNdx].getDisplayId();
246 ActivityDisplayInfo info = new ActivityDisplayInfo(displayId);
247 mDisplayInfos.put(displayId, info);
248 }
249
250 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
251 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
252 }
Craig Mautner27084302013-03-25 08:05:25 -0700253 }
254
255 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700256 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700257 if (mDismissKeyguardOnNextActivity) {
258 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700259 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700260 }
261 }
262
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700263 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800264 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700265 }
266
Craig Mautnerde4ef022013-04-07 19:01:33 -0700267 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800268 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700269 }
270
Craig Mautner4a1cb222013-12-04 16:14:06 -0800271 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
272 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700273 boolean isFrontStack(ActivityStack stack) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800274 ArrayList<ActivityStack> stacks = stack.getStacksLocked();
275 if (stacks != null && !stacks.isEmpty()) {
276 return stack == stacks.get(stacks.size() - 1);
277 }
278 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700279 }
280
Craig Mautnerde4ef022013-04-07 19:01:33 -0700281 void moveHomeStack(boolean toFront) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800282 ArrayList<ActivityStack> stacks = mHomeStack.getStacksLocked();
283 int topNdx = stacks.size() - 1;
284 if (topNdx <= 0) {
285 return;
286 }
287 ActivityStack topStack = stacks.get(topNdx);
288 final boolean homeInFront = topStack == mHomeStack;
289 if (homeInFront != toFront) {
290 mLastFocusedStack = topStack;
291 stacks.remove(mHomeStack);
292 stacks.add(toFront ? topNdx : 0, mHomeStack);
293 mFocusedStack = stacks.get(topNdx);
294 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
295 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700296 }
297 }
298
Craig Mautner8e569572013-10-11 17:36:59 -0700299 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700300 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700301 mHomeStack.moveHomeTaskToTop();
302 }
303
304 boolean resumeHomeActivity(ActivityRecord prev) {
305 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700306 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700307 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700308 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700309 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700310 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700311 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700312 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700313 }
314 return mService.startHomeActivityLocked(mCurrentUser);
315 }
316
Craig Mautner27084302013-03-25 08:05:25 -0700317 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700318 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700319 mDismissKeyguardOnNextActivity = dismiss;
320 }
321
Craig Mautner8d341ef2013-03-26 09:03:27 -0700322 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800323 int numDisplays = mDisplayInfos.size();
324 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
325 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
326 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
327 ActivityStack stack = stacks.get(stackNdx);
328 TaskRecord task = stack.taskForIdLocked(id);
329 if (task != null) {
330 return task;
331 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700332 }
333 }
334 return null;
335 }
336
Craig Mautner6170f732013-04-02 13:05:23 -0700337 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800338 int numDisplays = mDisplayInfos.size();
339 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
340 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
341 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
342 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
343 if (r != null) {
344 return r;
345 }
Craig Mautner6170f732013-04-02 13:05:23 -0700346 }
347 }
348 return null;
349 }
350
Craig Mautner8d341ef2013-03-26 09:03:27 -0700351 int getNextTaskId() {
352 do {
353 mCurTaskId++;
354 if (mCurTaskId <= 0) {
355 mCurTaskId = 1;
356 }
357 } while (anyTaskForIdLocked(mCurTaskId) != null);
358 return mCurTaskId;
359 }
360
Craig Mautnerde4ef022013-04-07 19:01:33 -0700361 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700362 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700363 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700364 final ActivityRecord r = stack.mResumedActivity;
365 if (r != null && r.task == task) {
366 stack.mResumedActivity = null;
367 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700368 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700369 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800370 stack.mActivityContainer.detachLocked();
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700371 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700372 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700373 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Craig Mautner4a1cb222013-12-04 16:14:06 -0800374 mFocusedStack = getStack(nextStackId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700375 }
376 }
377
378 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700379 ActivityStack stack = getFocusedStack();
380 if (stack == null) {
381 return null;
382 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700383 ActivityRecord resumedActivity = stack.mResumedActivity;
384 if (resumedActivity == null || resumedActivity.app == null) {
385 resumedActivity = stack.mPausingActivity;
386 if (resumedActivity == null || resumedActivity.app == null) {
387 resumedActivity = stack.topRunningActivityLocked(null);
388 }
389 }
390 return resumedActivity;
391 }
392
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800393 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700394 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800395 boolean didSomething = false;
396 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
397 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
398 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
399 final ActivityStack stack = stacks.get(stackNdx);
400 if (!isFrontStack(stack)) {
401 continue;
402 }
403 ActivityRecord hr = stack.topRunningActivityLocked(null);
404 if (hr != null) {
405 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
406 && processName.equals(hr.processName)) {
407 try {
408 if (realStartActivityLocked(hr, app, true, true)) {
409 didSomething = true;
410 }
411 } catch (Exception e) {
412 Slog.w(TAG, "Exception in new application when starting activity "
413 + hr.intent.getComponent().flattenToShortString(), e);
414 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700415 }
Craig Mautner20e72272013-04-01 13:45:53 -0700416 }
Craig Mautner20e72272013-04-01 13:45:53 -0700417 }
418 }
419 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700420 if (!didSomething) {
421 ensureActivitiesVisibleLocked(null, 0);
422 }
Craig Mautner20e72272013-04-01 13:45:53 -0700423 return didSomething;
424 }
425
426 boolean allResumedActivitiesIdle() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800427 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
428 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
429 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
430 final ActivityStack stack = stacks.get(stackNdx);
431 if (!isFrontStack(stack)) {
432 continue;
433 }
434 final ActivityRecord resumedActivity = stack.mResumedActivity;
435 if (resumedActivity == null || !resumedActivity.idle) {
436 return false;
437 }
Craig Mautner20e72272013-04-01 13:45:53 -0700438 }
439 }
440 return true;
441 }
442
Craig Mautnerde4ef022013-04-07 19:01:33 -0700443 boolean allResumedActivitiesComplete() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800444 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
445 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
446 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
447 final ActivityStack stack = stacks.get(stackNdx);
448 if (isFrontStack(stack)) {
449 final ActivityRecord r = stack.mResumedActivity;
450 if (r != null && r.state != ActivityState.RESUMED) {
451 return false;
452 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700453 }
454 }
455 }
456 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800457 if (DEBUG_STACK) Slog.d(TAG,
458 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
459 mLastFocusedStack + " to=" + mFocusedStack);
460 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700461 return true;
462 }
463
464 boolean allResumedActivitiesVisible() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800465 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
466 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
467 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
468 final ActivityStack stack = stacks.get(stackNdx);
469 final ActivityRecord r = stack.mResumedActivity;
470 if (r != null && (!r.nowVisible || r.waitingVisible)) {
471 return false;
472 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700473 }
474 }
475 return true;
476 }
477
Craig Mautner2acc3892013-09-23 10:28:14 -0700478 /**
479 * Pause all activities in either all of the stacks or just the back stacks.
480 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700481 * @return true if any activity was paused as a result of this call.
482 */
Craig Mautner5314a402013-09-26 12:40:16 -0700483 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700484 boolean someActivityPaused = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800485 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
486 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
487 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
488 final ActivityStack stack = stacks.get(stackNdx);
489 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
490 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
491 " mResumedActivity=" + stack.mResumedActivity);
492 stack.startPausingLocked(userLeaving, false);
493 someActivityPaused = true;
494 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700495 }
496 }
497 return someActivityPaused;
498 }
499
Craig Mautnerde4ef022013-04-07 19:01:33 -0700500 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700501 boolean pausing = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800502 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
503 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
504 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
505 final ActivityStack stack = stacks.get(stackNdx);
506 final ActivityRecord r = stack.mPausingActivity;
507 if (r != null && r.state != ActivityState.PAUSED
508 && r.state != ActivityState.STOPPED
509 && r.state != ActivityState.STOPPING) {
510 if (DEBUG_STATES) {
511 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
512 pausing = false;
513 } else {
514 return false;
515 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700516 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700517 }
518 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700519 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700520 }
521
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700522 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700523 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700524 WaitResult w = mWaitingActivityVisible.get(i);
525 w.timeout = false;
526 if (r != null) {
527 w.who = new ComponentName(r.info.packageName, r.info.name);
528 }
529 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
530 w.thisTime = w.totalTime;
531 }
532 mService.notifyAll();
533 dismissKeyguard();
534 }
535
536 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
537 long thisTime, long totalTime) {
538 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700539 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700540 w.timeout = timeout;
541 if (r != null) {
542 w.who = new ComponentName(r.info.packageName, r.info.name);
543 }
544 w.thisTime = thisTime;
545 w.totalTime = totalTime;
546 }
547 mService.notifyAll();
548 }
549
Craig Mautner29219d92013-04-16 20:19:12 -0700550 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700551 final ActivityStack focusedStack = getFocusedStack();
552 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
553 if (r != null) {
554 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700555 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700556
Craig Mautner4a1cb222013-12-04 16:14:06 -0800557 // Return to the home stack.
558 final ArrayList<ActivityStack> stacks = mHomeStack.getStacksLocked();
559 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
560 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700561 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700562 r = stack.topRunningActivityLocked(null);
563 if (r != null) {
564 return r;
565 }
566 }
567 }
568 return null;
569 }
570
Craig Mautner20e72272013-04-01 13:45:53 -0700571 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
572 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
573 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700574
575 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800576 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
577 new ArrayList<ArrayList<RunningTaskInfo>>();
578 final int numDisplays = mDisplayInfos.size();
579 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
580 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
581 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
582 final ActivityStack stack = stacks.get(stackNdx);
583 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
584 runningTaskLists.add(stackTaskList);
585 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
586 if (r == null && isFrontStack(stack)) {
587 r = ar;
588 }
Craig Mautner20e72272013-04-01 13:45:53 -0700589 }
590 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700591
592 // The lists are already sorted from most recent to oldest. Just pull the most recent off
593 // each list and add it to list. Stop when all lists are empty or maxNum reached.
594 while (maxNum > 0) {
595 long mostRecentActiveTime = Long.MIN_VALUE;
596 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800597 final int numTaskLists = runningTaskLists.size();
598 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
599 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700600 if (!stackTaskList.isEmpty()) {
601 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
602 if (lastActiveTime > mostRecentActiveTime) {
603 mostRecentActiveTime = lastActiveTime;
604 selectedStackList = stackTaskList;
605 }
606 }
607 }
608 if (selectedStackList != null) {
609 list.add(selectedStackList.remove(0));
610 --maxNum;
611 } else {
612 break;
613 }
614 }
615
Craig Mautner20e72272013-04-01 13:45:53 -0700616 return r;
617 }
618
Craig Mautner23ac33b2013-04-01 16:26:35 -0700619 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
620 String profileFile, ParcelFileDescriptor profileFd, int userId) {
621 // Collect information about the target of the Intent.
622 ActivityInfo aInfo;
623 try {
624 ResolveInfo rInfo =
625 AppGlobals.getPackageManager().resolveIntent(
626 intent, resolvedType,
627 PackageManager.MATCH_DEFAULT_ONLY
628 | ActivityManagerService.STOCK_PM_FLAGS, userId);
629 aInfo = rInfo != null ? rInfo.activityInfo : null;
630 } catch (RemoteException e) {
631 aInfo = null;
632 }
633
634 if (aInfo != null) {
635 // Store the found target back into the intent, because now that
636 // we have it we never want to do this again. For example, if the
637 // user navigates back to this point in the history, we should
638 // always restart the exact same activity.
639 intent.setComponent(new ComponentName(
640 aInfo.applicationInfo.packageName, aInfo.name));
641
642 // Don't debug things in the system process
643 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
644 if (!aInfo.processName.equals("system")) {
645 mService.setDebugApp(aInfo.processName, true, false);
646 }
647 }
648
649 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
650 if (!aInfo.processName.equals("system")) {
651 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
652 }
653 }
654
655 if (profileFile != null) {
656 if (!aInfo.processName.equals("system")) {
657 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
658 profileFile, profileFd,
659 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
660 }
661 }
662 }
663 return aInfo;
664 }
665
Craig Mautner2219a1b2013-03-25 09:44:30 -0700666 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700667 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700668 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautner2219a1b2013-03-25 09:44:30 -0700669 null, false, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700670 }
671
Craig Mautner23ac33b2013-04-01 16:26:35 -0700672 final int startActivityMayWait(IApplicationThread caller, int callingUid,
673 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
674 String resultWho, int requestCode, int startFlags, String profileFile,
675 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
676 Bundle options, int userId) {
677 // Refuse possible leaked file descriptors
678 if (intent != null && intent.hasFileDescriptors()) {
679 throw new IllegalArgumentException("File descriptors passed in Intent");
680 }
681 boolean componentSpecified = intent.getComponent() != null;
682
683 // Don't modify the client's object!
684 intent = new Intent(intent);
685
686 // Collect information about the target of the Intent.
687 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
688 profileFile, profileFd, userId);
689
690 synchronized (mService) {
691 int callingPid;
692 if (callingUid >= 0) {
693 callingPid = -1;
694 } else if (caller == null) {
695 callingPid = Binder.getCallingPid();
696 callingUid = Binder.getCallingUid();
697 } else {
698 callingPid = callingUid = -1;
699 }
700
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700701 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700702 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700703 && mService.mConfiguration.diff(config) != 0;
704 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700705 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700706
707 final long origId = Binder.clearCallingIdentity();
708
709 if (aInfo != null &&
710 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
711 // This may be a heavy-weight process! Check to see if we already
712 // have another, different heavy-weight process running.
713 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
714 if (mService.mHeavyWeightProcess != null &&
715 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
716 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700717 int realCallingUid = callingUid;
718 if (caller != null) {
719 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
720 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700721 realCallingUid = callerApp.info.uid;
722 } else {
723 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700724 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700725 + intent.toString());
726 ActivityOptions.abort(options);
727 return ActivityManager.START_PERMISSION_DENIED;
728 }
729 }
730
731 IIntentSender target = mService.getIntentSenderLocked(
732 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
733 realCallingUid, userId, null, null, 0, new Intent[] { intent },
734 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
735 | PendingIntent.FLAG_ONE_SHOT, null);
736
737 Intent newIntent = new Intent();
738 if (requestCode >= 0) {
739 // Caller is requesting a result.
740 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
741 }
742 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
743 new IntentSender(target));
744 if (mService.mHeavyWeightProcess.activities.size() > 0) {
745 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
746 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
747 hist.packageName);
748 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
749 hist.task.taskId);
750 }
751 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
752 aInfo.packageName);
753 newIntent.setFlags(intent.getFlags());
754 newIntent.setClassName("android",
755 HeavyWeightSwitcherActivity.class.getName());
756 intent = newIntent;
757 resolvedType = null;
758 caller = null;
759 callingUid = Binder.getCallingUid();
760 callingPid = Binder.getCallingPid();
761 componentSpecified = true;
762 try {
763 ResolveInfo rInfo =
764 AppGlobals.getPackageManager().resolveIntent(
765 intent, null,
766 PackageManager.MATCH_DEFAULT_ONLY
767 | ActivityManagerService.STOCK_PM_FLAGS, userId);
768 aInfo = rInfo != null ? rInfo.activityInfo : null;
769 aInfo = mService.getActivityInfoForUser(aInfo, userId);
770 } catch (RemoteException e) {
771 aInfo = null;
772 }
773 }
774 }
775 }
776
Craig Mautner6170f732013-04-02 13:05:23 -0700777 int res = startActivityLocked(caller, intent, resolvedType,
Craig Mautner23ac33b2013-04-01 16:26:35 -0700778 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
779 callingPackage, startFlags, options, componentSpecified, null);
780
Craig Mautnerde4ef022013-04-07 19:01:33 -0700781 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700782 // If the caller also wants to switch to a new configuration,
783 // do so now. This allows a clean switch, as we are waiting
784 // for the current activity to pause (so we will not destroy
785 // it), and have not yet started the next activity.
786 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
787 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700788 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700789 if (DEBUG_CONFIGURATION) Slog.v(TAG,
790 "Updating to new configuration after starting activity.");
791 mService.updateConfigurationLocked(config, null, false, false);
792 }
793
794 Binder.restoreCallingIdentity(origId);
795
796 if (outResult != null) {
797 outResult.result = res;
798 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700799 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700800 do {
801 try {
802 mService.wait();
803 } catch (InterruptedException e) {
804 }
805 } while (!outResult.timeout && outResult.who == null);
806 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700807 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700808 if (r.nowVisible) {
809 outResult.timeout = false;
810 outResult.who = new ComponentName(r.info.packageName, r.info.name);
811 outResult.totalTime = 0;
812 outResult.thisTime = 0;
813 } else {
814 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700815 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700816 do {
817 try {
818 mService.wait();
819 } catch (InterruptedException e) {
820 }
821 } while (!outResult.timeout && outResult.who == null);
822 }
823 }
824 }
825
826 return res;
827 }
828 }
829
830 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
831 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
832 Bundle options, int userId) {
833 if (intents == null) {
834 throw new NullPointerException("intents is null");
835 }
836 if (resolvedTypes == null) {
837 throw new NullPointerException("resolvedTypes is null");
838 }
839 if (intents.length != resolvedTypes.length) {
840 throw new IllegalArgumentException("intents are length different than resolvedTypes");
841 }
842
Craig Mautner23ac33b2013-04-01 16:26:35 -0700843
844 int callingPid;
845 if (callingUid >= 0) {
846 callingPid = -1;
847 } else if (caller == null) {
848 callingPid = Binder.getCallingPid();
849 callingUid = Binder.getCallingUid();
850 } else {
851 callingPid = callingUid = -1;
852 }
853 final long origId = Binder.clearCallingIdentity();
854 try {
855 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700856 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700857 for (int i=0; i<intents.length; i++) {
858 Intent intent = intents[i];
859 if (intent == null) {
860 continue;
861 }
862
863 // Refuse possible leaked file descriptors
864 if (intent != null && intent.hasFileDescriptors()) {
865 throw new IllegalArgumentException("File descriptors passed in Intent");
866 }
867
868 boolean componentSpecified = intent.getComponent() != null;
869
870 // Don't modify the client's object!
871 intent = new Intent(intent);
872
873 // Collect information about the target of the Intent.
874 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
875 0, null, null, userId);
876 // TODO: New, check if this is correct
877 aInfo = mService.getActivityInfoForUser(aInfo, userId);
878
879 if (aInfo != null &&
880 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
881 != 0) {
882 throw new IllegalArgumentException(
883 "FLAG_CANT_SAVE_STATE not supported here");
884 }
885
886 Bundle theseOptions;
887 if (options != null && i == intents.length-1) {
888 theseOptions = options;
889 } else {
890 theseOptions = null;
891 }
Craig Mautner6170f732013-04-02 13:05:23 -0700892 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700893 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
894 0, theseOptions, componentSpecified, outActivity);
895 if (res < 0) {
896 return res;
897 }
898
899 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
900 }
901 }
902 } finally {
903 Binder.restoreCallingIdentity(origId);
904 }
905
906 return ActivityManager.START_SUCCESS;
907 }
908
Craig Mautner2420ead2013-04-01 17:13:20 -0700909 final boolean realStartActivityLocked(ActivityRecord r,
910 ProcessRecord app, boolean andResume, boolean checkConfig)
911 throws RemoteException {
912
913 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700914 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700915 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700916
917 // schedule launch ticks to collect information about slow apps.
918 r.startLaunchTickingLocked();
919
920 // Have the window manager re-evaluate the orientation of
921 // the screen based on the new activity order. Note that
922 // as a result of this, it can call back into the activity
923 // manager with a new orientation. We don't care about that,
924 // because the activity is not currently running so we are
925 // just restarting it anyway.
926 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700927 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700928 mService.mConfiguration,
929 r.mayFreezeScreenLocked(app) ? r.appToken : null);
930 mService.updateConfigurationLocked(config, r, false, false);
931 }
932
933 r.app = app;
934 app.waitingToKill = null;
935 r.launchCount++;
936 r.lastLaunchTime = SystemClock.uptimeMillis();
937
938 if (localLOGV) Slog.v(TAG, "Launching: " + r);
939
940 int idx = app.activities.indexOf(r);
941 if (idx < 0) {
942 app.activities.add(r);
943 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700944 mService.updateLruProcessLocked(app, true, null);
945 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700946
947 final ActivityStack stack = r.task.stack;
948 try {
949 if (app.thread == null) {
950 throw new RemoteException();
951 }
952 List<ResultInfo> results = null;
953 List<Intent> newIntents = null;
954 if (andResume) {
955 results = r.results;
956 newIntents = r.newIntents;
957 }
958 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
959 + " icicle=" + r.icicle
960 + " with results=" + results + " newIntents=" + newIntents
961 + " andResume=" + andResume);
962 if (andResume) {
963 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
964 r.userId, System.identityHashCode(r),
965 r.task.taskId, r.shortComponentName);
966 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700967 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700968 // Home process is the root process of the task.
969 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700970 }
971 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
972 r.sleeping = false;
973 r.forceNewConfig = false;
974 mService.showAskCompatModeDialogLocked(r);
975 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
976 String profileFile = null;
977 ParcelFileDescriptor profileFd = null;
978 boolean profileAutoStop = false;
979 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
980 if (mService.mProfileProc == null || mService.mProfileProc == app) {
981 mService.mProfileProc = app;
982 profileFile = mService.mProfileFile;
983 profileFd = mService.mProfileFd;
984 profileAutoStop = mService.mAutoStopProfiler;
985 }
986 }
987 app.hasShownUi = true;
988 app.pendingUiClean = true;
989 if (profileFd != null) {
990 try {
991 profileFd = profileFd.dup();
992 } catch (IOException e) {
993 if (profileFd != null) {
994 try {
995 profileFd.close();
996 } catch (IOException o) {
997 }
998 profileFd = null;
999 }
1000 }
1001 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001002 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001003 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1004 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001005 new Configuration(mService.mConfiguration), r.compat,
1006 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001007 mService.isNextTransitionForward(), profileFile, profileFd,
1008 profileAutoStop);
1009
1010 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1011 // This may be a heavy-weight process! Note that the package
1012 // manager will ensure that only activity can run in the main
1013 // process of the .apk, which is the only thing that will be
1014 // considered heavy-weight.
1015 if (app.processName.equals(app.info.packageName)) {
1016 if (mService.mHeavyWeightProcess != null
1017 && mService.mHeavyWeightProcess != app) {
1018 Slog.w(TAG, "Starting new heavy weight process " + app
1019 + " when already running "
1020 + mService.mHeavyWeightProcess);
1021 }
1022 mService.mHeavyWeightProcess = app;
1023 Message msg = mService.mHandler.obtainMessage(
1024 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1025 msg.obj = r;
1026 mService.mHandler.sendMessage(msg);
1027 }
1028 }
1029
1030 } catch (RemoteException e) {
1031 if (r.launchFailed) {
1032 // This is the second time we failed -- finish activity
1033 // and give up.
1034 Slog.e(TAG, "Second failure launching "
1035 + r.intent.getComponent().flattenToShortString()
1036 + ", giving up", e);
1037 mService.appDiedLocked(app, app.pid, app.thread);
1038 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1039 "2nd-crash", false);
1040 return false;
1041 }
1042
1043 // This is the first time we failed -- restart process and
1044 // retry.
1045 app.activities.remove(r);
1046 throw e;
1047 }
1048
1049 r.launchFailed = false;
1050 if (stack.updateLRUListLocked(r)) {
1051 Slog.w(TAG, "Activity " + r
1052 + " being launched, but already in LRU list");
1053 }
1054
1055 if (andResume) {
1056 // As part of the process of launching, ActivityThread also performs
1057 // a resume.
1058 stack.minimalResumeActivityLocked(r);
1059 } else {
1060 // This activity is not starting in the resumed state... which
1061 // should look like we asked it to pause+stop (but remain visible),
1062 // and it has done so and reported back the current icicle and
1063 // other state.
1064 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1065 + " (starting in stopped state)");
1066 r.state = ActivityState.STOPPED;
1067 r.stopped = true;
1068 }
1069
1070 // Launch the new version setup screen if needed. We do this -after-
1071 // launching the initial activity (that is, home), so that it can have
1072 // a chance to initialize itself while in the background, making the
1073 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001074 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001075 mService.startSetupActivityLocked();
1076 }
1077
1078 return true;
1079 }
1080
Craig Mautnere79d42682013-04-01 19:01:53 -07001081 void startSpecificActivityLocked(ActivityRecord r,
1082 boolean andResume, boolean checkConfig) {
1083 // Is this activity's application already running?
1084 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001085 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001086
1087 r.task.stack.setLaunchTime(r);
1088
1089 if (app != null && app.thread != null) {
1090 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001091 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1092 || !"android".equals(r.info.packageName)) {
1093 // Don't add this if it is a platform component that is marked
1094 // to run in multiple processes, because this is actually
1095 // part of the framework so doesn't make sense to track as a
1096 // separate apk in the process.
1097 app.addPackage(r.info.packageName, mService.mProcessStats);
1098 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001099 realStartActivityLocked(r, app, andResume, checkConfig);
1100 return;
1101 } catch (RemoteException e) {
1102 Slog.w(TAG, "Exception when starting activity "
1103 + r.intent.getComponent().flattenToShortString(), e);
1104 }
1105
1106 // If a dead object exception was thrown -- fall through to
1107 // restart the application.
1108 }
1109
1110 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001111 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001112 }
1113
Craig Mautner6170f732013-04-02 13:05:23 -07001114 final int startActivityLocked(IApplicationThread caller,
1115 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1116 String resultWho, int requestCode,
1117 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1118 boolean componentSpecified, ActivityRecord[] outActivity) {
1119 int err = ActivityManager.START_SUCCESS;
1120
1121 ProcessRecord callerApp = null;
1122 if (caller != null) {
1123 callerApp = mService.getRecordForAppLocked(caller);
1124 if (callerApp != null) {
1125 callingPid = callerApp.pid;
1126 callingUid = callerApp.info.uid;
1127 } else {
1128 Slog.w(TAG, "Unable to find app for caller " + caller
1129 + " (pid=" + callingPid + ") when starting: "
1130 + intent.toString());
1131 err = ActivityManager.START_PERMISSION_DENIED;
1132 }
1133 }
1134
1135 if (err == ActivityManager.START_SUCCESS) {
1136 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1137 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1138 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1139 }
1140
1141 ActivityRecord sourceRecord = null;
1142 ActivityRecord resultRecord = null;
1143 if (resultTo != null) {
1144 sourceRecord = isInAnyStackLocked(resultTo);
1145 if (DEBUG_RESULTS) Slog.v(
1146 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1147 if (sourceRecord != null) {
1148 if (requestCode >= 0 && !sourceRecord.finishing) {
1149 resultRecord = sourceRecord;
1150 }
1151 }
1152 }
1153 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1154
1155 int launchFlags = intent.getFlags();
1156
1157 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1158 && sourceRecord != null) {
1159 // Transfer the result target from the source activity to the new
1160 // one being started, including any failures.
1161 if (requestCode >= 0) {
1162 ActivityOptions.abort(options);
1163 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1164 }
1165 resultRecord = sourceRecord.resultTo;
1166 resultWho = sourceRecord.resultWho;
1167 requestCode = sourceRecord.requestCode;
1168 sourceRecord.resultTo = null;
1169 if (resultRecord != null) {
1170 resultRecord.removeResultsLocked(
1171 sourceRecord, resultWho, requestCode);
1172 }
1173 }
1174
1175 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1176 // We couldn't find a class that can handle the given Intent.
1177 // That's the end of that!
1178 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1179 }
1180
1181 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1182 // We couldn't find the specific class specified in the Intent.
1183 // Also the end of the line.
1184 err = ActivityManager.START_CLASS_NOT_FOUND;
1185 }
1186
1187 if (err != ActivityManager.START_SUCCESS) {
1188 if (resultRecord != null) {
1189 resultStack.sendActivityResultLocked(-1,
1190 resultRecord, resultWho, requestCode,
1191 Activity.RESULT_CANCELED, null);
1192 }
1193 setDismissKeyguard(false);
1194 ActivityOptions.abort(options);
1195 return err;
1196 }
1197
1198 final int startAnyPerm = mService.checkPermission(
1199 START_ANY_ACTIVITY, callingPid, callingUid);
1200 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1201 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1202 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1203 if (resultRecord != null) {
1204 resultStack.sendActivityResultLocked(-1,
1205 resultRecord, resultWho, requestCode,
1206 Activity.RESULT_CANCELED, null);
1207 }
1208 setDismissKeyguard(false);
1209 String msg;
1210 if (!aInfo.exported) {
1211 msg = "Permission Denial: starting " + intent.toString()
1212 + " from " + callerApp + " (pid=" + callingPid
1213 + ", uid=" + callingUid + ")"
1214 + " not exported from uid " + aInfo.applicationInfo.uid;
1215 } else {
1216 msg = "Permission Denial: starting " + intent.toString()
1217 + " from " + callerApp + " (pid=" + callingPid
1218 + ", uid=" + callingUid + ")"
1219 + " requires " + aInfo.permission;
1220 }
1221 Slog.w(TAG, msg);
1222 throw new SecurityException(msg);
1223 }
1224
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001225 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001226 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001227
Craig Mautner6170f732013-04-02 13:05:23 -07001228 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001229 try {
1230 // The Intent we give to the watcher has the extra data
1231 // stripped off, since it can contain private information.
1232 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001233 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001234 aInfo.applicationInfo.packageName);
1235 } catch (RemoteException e) {
1236 mService.mController = null;
1237 }
Ben Gruver5e207332013-04-03 17:41:37 -07001238 }
Craig Mautner6170f732013-04-02 13:05:23 -07001239
Ben Gruver5e207332013-04-03 17:41:37 -07001240 if (abort) {
1241 if (resultRecord != null) {
1242 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001243 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001244 }
Ben Gruver5e207332013-04-03 17:41:37 -07001245 // We pretend to the caller that it was really started, but
1246 // they will just get a cancel result.
1247 setDismissKeyguard(false);
1248 ActivityOptions.abort(options);
1249 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001250 }
1251
1252 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1253 intent, resolvedType, aInfo, mService.mConfiguration,
Craig Mautnerde4ef022013-04-07 19:01:33 -07001254 resultRecord, resultWho, requestCode, componentSpecified, this);
Craig Mautner6170f732013-04-02 13:05:23 -07001255 if (outActivity != null) {
1256 outActivity[0] = r;
1257 }
1258
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001259 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001260 if (stack.mResumedActivity == null
1261 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001262 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1263 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001264 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001265 mService.mPendingActivityLaunches.add(pal);
1266 setDismissKeyguard(false);
1267 ActivityOptions.abort(options);
1268 return ActivityManager.START_SWITCHES_CANCELED;
1269 }
1270 }
1271
1272 if (mService.mDidAppSwitch) {
1273 // This is the second allowed switch since we stopped switches,
1274 // so now just generally allow switches. Use case: user presses
1275 // home (switches disabled, switch to home, mDidAppSwitch now true);
1276 // user taps a home icon (coming from home so allowed, we hit here
1277 // and now allow anyone to switch again).
1278 mService.mAppSwitchesAllowedTime = 0;
1279 } else {
1280 mService.mDidAppSwitch = true;
1281 }
1282
1283 mService.doPendingActivityLaunchesLocked(false);
1284
Craig Mautner8849a5e2013-04-02 16:41:03 -07001285 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001286
1287 if (allPausedActivitiesComplete()) {
1288 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001289 // activity start, but we are not actually doing an activity
1290 // switch... just dismiss the keyguard now, because we
1291 // probably want to see whatever is behind it.
1292 dismissKeyguard();
1293 }
1294 return err;
1295 }
1296
Craig Mautnerac6f8432013-07-17 13:24:59 -07001297 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001298 final TaskRecord task = r.task;
1299 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001300 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001301 final ActivityStack taskStack = task.stack;
1302 if (mFocusedStack != taskStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001303 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1304 "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
Craig Mautner4a1cb222013-12-04 16:14:06 -08001305 mFocusedStack = taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001306 } else {
1307 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1308 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1309 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001310 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001311 }
1312
Craig Mautner4a1cb222013-12-04 16:14:06 -08001313 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001314 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1315 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1316 return mFocusedStack;
1317 }
1318
Craig Mautner4a1cb222013-12-04 16:14:06 -08001319 int numDisplays = mDisplayInfos.size();
1320 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
1321 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
1322 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1323 ActivityStack stack = stacks.get(stackNdx);
1324 if (!stack.isHomeStack()) {
1325 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1326 "adjustStackFocus: Setting focused stack=" + stack);
1327 mFocusedStack = stack;
1328 return mFocusedStack;
1329 }
Craig Mautner858d8a62013-04-23 17:08:34 -07001330 }
1331 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001332
Craig Mautner4a1cb222013-12-04 16:14:06 -08001333 // Need to create an app stack for this user.
1334 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001335 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1336 " stackId=" + stackId);
1337 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001338 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001339 }
1340 return mHomeStack;
1341 }
1342
Craig Mautner29219d92013-04-16 20:19:12 -07001343 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001344 if (r != null) {
1345 final boolean isHomeActivity =
1346 !r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask());
1347 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001348 }
1349 }
1350
Craig Mautner8849a5e2013-04-02 16:41:03 -07001351 final int startActivityUncheckedLocked(ActivityRecord r,
1352 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1353 Bundle options) {
1354 final Intent intent = r.intent;
1355 final int callingUid = r.launchedFromUid;
1356
1357 int launchFlags = intent.getFlags();
1358
Craig Mautner8849a5e2013-04-02 16:41:03 -07001359 // We'll invoke onUserLeaving before onPause only if the launching
1360 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001361 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1362 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001363
1364 // If the caller has asked not to resume at this point, we make note
1365 // of this in the record so that we can skip it when trying to find
1366 // the top running activity.
1367 if (!doResume) {
1368 r.delayedResume = true;
1369 }
1370
1371 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1372
1373 // If the onlyIfNeeded flag is set, then we can do this if the activity
1374 // being launched is the same as the one making the call... or, as
1375 // a special case, if we do not know the caller then we count the
1376 // current top activity as the caller.
1377 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1378 ActivityRecord checkedCaller = sourceRecord;
1379 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001380 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001381 }
1382 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1383 // Caller is not the same as launcher, so always needed.
1384 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1385 }
1386 }
1387
1388 if (sourceRecord == null) {
1389 // This activity is not being started from another... in this
1390 // case we -always- start a new task.
1391 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001392 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1393 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001394 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1395 }
1396 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1397 // The original activity who is starting us is running as a single
1398 // instance... this new activity it is starting must go on its
1399 // own task.
1400 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1401 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1402 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1403 // The activity being started is a single instance... it always
1404 // gets launched into its own task.
1405 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1406 }
1407
Craig Mautner88629292013-11-10 20:39:05 -08001408 ActivityInfo newTaskInfo = null;
1409 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001410 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001411 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001412 if (sourceRecord.finishing) {
1413 // If the source is finishing, we can't further count it as our source. This
1414 // is because the task it is associated with may now be empty and on its way out,
1415 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001416 // the NEW_TASK flow and try to find a task for it. But save the task information
1417 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001418 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1419 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1420 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1421 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001422 newTaskInfo = sourceRecord.info;
1423 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001424 }
1425 sourceRecord = null;
1426 sourceStack = null;
1427 } else {
1428 sourceStack = sourceRecord.task.stack;
1429 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001430 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001431 sourceStack = null;
1432 }
1433
Craig Mautner8849a5e2013-04-02 16:41:03 -07001434 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1435 // For whatever reason this activity is being launched into a new
1436 // task... yet the caller has requested a result back. Well, that
1437 // is pretty messed up, so instead immediately send back a cancel
1438 // and let the new task continue launched as normal without a
1439 // dependency on its originator.
1440 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1441 r.resultTo.task.stack.sendActivityResultLocked(-1,
1442 r.resultTo, r.resultWho, r.requestCode,
1443 Activity.RESULT_CANCELED, null);
1444 r.resultTo = null;
1445 }
1446
1447 boolean addingToTask = false;
1448 boolean movedHome = false;
1449 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001450 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001451 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1452 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1453 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1454 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1455 // If bring to front is requested, and no result is requested, and
1456 // we can find a task that was started with this same
1457 // component, then instead of launching bring that one to the front.
1458 if (r.resultTo == null) {
1459 // See if there is a task to bring to the front. If this is
1460 // a SINGLE_INSTANCE activity, there can be one and only one
1461 // instance of it in the history, and it is always in its own
1462 // unique task, so we do a special search.
1463 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001464 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001465 : findActivityLocked(intent, r.info);
1466 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001467 if (r.task == null) {
1468 r.task = intentActivity.task;
1469 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001470 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001471 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001472 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1473 + " from " + intentActivity);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001474 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001475 if (intentActivity.task.intent == null) {
1476 // This task was started because of movement of
1477 // the activity based on affinity... now that we
1478 // are actually launching it, we can assign the
1479 // base intent.
1480 intentActivity.task.setIntent(intent, r.info);
1481 }
1482 // If the target task is not in the front, then we need
1483 // to bring it to the front... except... well, with
1484 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1485 // to have the same behavior as if a new instance was
1486 // being started, which means not bringing it to the front
1487 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001488 final ActivityStack lastStack = getLastStack();
1489 ActivityRecord curTop = lastStack == null?
1490 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001491 if (curTop != null && (curTop.task != intentActivity.task ||
1492 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001493 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001494 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1495 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001496 // We really do want to push this one into the
1497 // user's face, right now.
1498 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001499 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001500 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001501 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1502 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001503 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001504 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001505 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001506 options = null;
1507 }
1508 }
1509 // If the caller has requested that the target task be
1510 // reset, then do so.
1511 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1512 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1513 }
1514 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1515 // We don't need to start a new activity, and
1516 // the client said not to do anything if that
1517 // is the case, so this is it! And for paranoia, make
1518 // sure we have correctly resumed the top activity.
1519 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001520 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001521 } else {
1522 ActivityOptions.abort(options);
1523 }
Craig Mautner29219d92013-04-16 20:19:12 -07001524 if (r.task == null) Slog.v(TAG,
1525 "startActivityUncheckedLocked: task left null",
1526 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001527 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1528 }
1529 if ((launchFlags &
1530 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1531 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1532 // The caller has requested to completely replace any
1533 // existing task with its new activity. Well that should
1534 // not be too hard...
1535 reuseTask = intentActivity.task;
1536 reuseTask.performClearTaskLocked();
1537 reuseTask.setIntent(r.intent, r.info);
1538 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1539 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1540 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1541 // In this situation we want to remove all activities
1542 // from the task up to the one being started. In most
1543 // cases this means we are resetting the task to its
1544 // initial state.
1545 ActivityRecord top =
1546 intentActivity.task.performClearTaskLocked(r, launchFlags);
1547 if (top != null) {
1548 if (top.frontOfTask) {
1549 // Activity aliases may mean we use different
1550 // intents for the top activity, so make sure
1551 // the task now has the identity of the new
1552 // intent.
1553 top.task.setIntent(r.intent, r.info);
1554 }
1555 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1556 r, top.task);
1557 top.deliverNewIntentLocked(callingUid, r.intent);
1558 } else {
1559 // A special case: we need to
1560 // start the activity because it is not currently
1561 // running, and the caller has asked to clear the
1562 // current task to have this activity at the top.
1563 addingToTask = true;
1564 // Now pretend like this activity is being started
1565 // by the top of its task, so it is put in the
1566 // right place.
1567 sourceRecord = intentActivity;
1568 }
1569 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1570 // In this case the top activity on the task is the
1571 // same as the one being launched, so we take that
1572 // as a request to bring the task to the foreground.
1573 // If the top activity in the task is the root
1574 // activity, deliver this new intent to it if it
1575 // desires.
1576 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1577 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1578 && intentActivity.realActivity.equals(r.realActivity)) {
1579 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1580 intentActivity.task);
1581 if (intentActivity.frontOfTask) {
1582 intentActivity.task.setIntent(r.intent, r.info);
1583 }
1584 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1585 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1586 // In this case we are launching the root activity
1587 // of the task, but with a different intent. We
1588 // should start a new instance on top.
1589 addingToTask = true;
1590 sourceRecord = intentActivity;
1591 }
1592 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1593 // In this case an activity is being launched in to an
1594 // existing task, without resetting that task. This
1595 // is typically the situation of launching an activity
1596 // from a notification or shortcut. We want to place
1597 // the new activity on top of the current task.
1598 addingToTask = true;
1599 sourceRecord = intentActivity;
1600 } else if (!intentActivity.task.rootWasReset) {
1601 // In this case we are launching in to an existing task
1602 // that has not yet been started from its front door.
1603 // The current task has been brought to the front.
1604 // Ideally, we'd probably like to place this new task
1605 // at the bottom of its stack, but that's a little hard
1606 // to do with the current organization of the code so
1607 // for now we'll just drop it.
1608 intentActivity.task.setIntent(r.intent, r.info);
1609 }
1610 if (!addingToTask && reuseTask == null) {
1611 // We didn't do anything... but it was needed (a.k.a., client
1612 // don't use that intent!) And for paranoia, make
1613 // sure we have correctly resumed the top activity.
1614 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001615 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001616 } else {
1617 ActivityOptions.abort(options);
1618 }
Craig Mautner29219d92013-04-16 20:19:12 -07001619 if (r.task == null) Slog.v(TAG,
1620 "startActivityUncheckedLocked: task left null",
1621 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001622 return ActivityManager.START_TASK_TO_FRONT;
1623 }
1624 }
1625 }
1626 }
1627
1628 //String uri = r.intent.toURI();
1629 //Intent intent2 = new Intent(uri);
1630 //Slog.i(TAG, "Given intent: " + r.intent);
1631 //Slog.i(TAG, "URI is: " + uri);
1632 //Slog.i(TAG, "To intent: " + intent2);
1633
1634 if (r.packageName != null) {
1635 // If the activity being launched is the same as the one currently
1636 // at the top, then we need to check if it should only be launched
1637 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001638 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001639 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001640 if (top != null && r.resultTo == null) {
1641 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1642 if (top.app != null && top.app.thread != null) {
1643 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1644 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1645 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1646 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1647 top.task);
1648 // For paranoia, make sure we have correctly
1649 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001650 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001651 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001652 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001653 }
1654 ActivityOptions.abort(options);
1655 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1656 // We don't need to start a new activity, and
1657 // the client said not to do anything if that
1658 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001659 if (r.task == null) Slog.v(TAG,
1660 "startActivityUncheckedLocked: task left null",
1661 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001662 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1663 }
1664 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001665 if (r.task == null) Slog.v(TAG,
1666 "startActivityUncheckedLocked: task left null",
1667 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001668 return ActivityManager.START_DELIVERED_TO_TOP;
1669 }
1670 }
1671 }
1672 }
1673
1674 } else {
1675 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001676 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1677 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001678 }
1679 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001680 if (r.task == null) Slog.v(TAG,
1681 "startActivityUncheckedLocked: task left null",
1682 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001683 return ActivityManager.START_CLASS_NOT_FOUND;
1684 }
1685
1686 boolean newTask = false;
1687 boolean keepCurTransition = false;
1688
1689 // Should this be considered a new task?
1690 if (r.resultTo == null && !addingToTask
1691 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001692 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001693 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001694 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001695 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1696 newTaskInfo != null ? newTaskInfo : r.info,
1697 newTaskIntent != null ? newTaskIntent : intent,
1698 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001699 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1700 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001701 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001702 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001703 }
1704 newTask = true;
1705 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001706 if ((launchFlags &
1707 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1708 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1709 // Caller wants to appear on home activity, so before starting
1710 // their own activity we will bring home to the front.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001711 r.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001712 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001713 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001714 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001715 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001716 targetStack = sourceTask.stack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001717 moveHomeStack(targetStack.isHomeStack());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001718 if (!addingToTask &&
1719 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1720 // In this case, we are adding the activity to an existing
1721 // task, but the caller has asked to clear that task if the
1722 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001723 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001724 keepCurTransition = true;
1725 if (top != null) {
1726 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1727 top.deliverNewIntentLocked(callingUid, r.intent);
1728 // For paranoia, make sure we have correctly
1729 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001730 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001731 if (doResume) {
1732 targetStack.resumeTopActivityLocked(null);
1733 }
1734 ActivityOptions.abort(options);
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001735 if (r.task == null) Slog.w(TAG,
Craig Mautner29219d92013-04-16 20:19:12 -07001736 "startActivityUncheckedLocked: task left null",
1737 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001738 return ActivityManager.START_DELIVERED_TO_TOP;
1739 }
1740 } else if (!addingToTask &&
1741 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1742 // In this case, we are launching an activity in our own task
1743 // that may already be running somewhere in the history, and
1744 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001745 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001746 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001747 final TaskRecord task = top.task;
1748 task.moveActivityToFrontLocked(top);
1749 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001750 top.updateOptionsLocked(options);
1751 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001752 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001753 if (doResume) {
1754 targetStack.resumeTopActivityLocked(null);
1755 }
1756 return ActivityManager.START_DELIVERED_TO_TOP;
1757 }
1758 }
1759 // An existing activity is starting this new activity, so we want
1760 // to keep the new one in the same task as the one that is starting
1761 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001762 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001763 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001764 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001765
1766 } else {
1767 // This not being started from an existing activity, and not part
1768 // of a new task... just put it in the top task, though these days
1769 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001770 targetStack = adjustStackFocus(r);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001771 moveHomeStack(targetStack.isHomeStack());
Craig Mautner1602ec22013-05-12 10:24:27 -07001772 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001773 r.setTask(prev != null ? prev.task
1774 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1775 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001776 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1777 + " in new guessed " + r.task);
1778 }
1779
1780 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1781 intent, r.getUriPermissionsLocked());
1782
1783 if (newTask) {
1784 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1785 }
1786 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001787 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001788 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001789 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001790 return ActivityManager.START_SUCCESS;
1791 }
1792
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001793 void acquireLaunchWakelock() {
1794 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1795 throw new IllegalStateException("Calling must be system uid");
1796 }
1797 mLaunchingActivity.acquire();
1798 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1799 // To be safe, don't allow the wake lock to be held for too long.
1800 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1801 }
1802 }
1803
Craig Mautnerf3333272013-04-22 10:55:53 -07001804 // Checked.
1805 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1806 Configuration config) {
1807 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1808
Craig Mautnerf3333272013-04-22 10:55:53 -07001809 ArrayList<ActivityRecord> stops = null;
1810 ArrayList<ActivityRecord> finishes = null;
1811 ArrayList<UserStartedState> startingUsers = null;
1812 int NS = 0;
1813 int NF = 0;
1814 IApplicationThread sendThumbnail = null;
1815 boolean booting = false;
1816 boolean enableScreen = false;
1817 boolean activityRemoved = false;
1818
1819 ActivityRecord r = ActivityRecord.forToken(token);
1820 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001821 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1822 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001823 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1824 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001825 if (fromTimeout) {
1826 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001827 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001828
1829 // This is a hack to semi-deal with a race condition
1830 // in the client where it can be constructed with a
1831 // newer configuration from when we asked it to launch.
1832 // We'll update with whatever configuration it now says
1833 // it used to launch.
1834 if (config != null) {
1835 r.configuration = config;
1836 }
1837
1838 // We are now idle. If someone is waiting for a thumbnail from
1839 // us, we can now deliver.
1840 r.idle = true;
1841
1842 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1843 sendThumbnail = r.app.thread;
1844 r.thumbnailNeeded = false;
1845 }
1846
1847 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1848 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1849 mService.mBooted = true;
1850 enableScreen = true;
1851 }
1852 }
1853
1854 if (allResumedActivitiesIdle()) {
1855 if (r != null) {
1856 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001857 }
1858
1859 if (mLaunchingActivity.isHeld()) {
1860 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1861 if (VALIDATE_WAKE_LOCK_CALLER &&
1862 Binder.getCallingUid() != Process.myUid()) {
1863 throw new IllegalStateException("Calling must be system uid");
1864 }
1865 mLaunchingActivity.release();
1866 }
1867 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001868 }
1869
1870 // Atomically retrieve all of the other things to do.
1871 stops = processStoppingActivitiesLocked(true);
1872 NS = stops != null ? stops.size() : 0;
1873 if ((NF=mFinishingActivities.size()) > 0) {
1874 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1875 mFinishingActivities.clear();
1876 }
1877
1878 final ArrayList<ActivityRecord> thumbnails;
1879 final int NT = mCancelledThumbnails.size();
1880 if (NT > 0) {
1881 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1882 mCancelledThumbnails.clear();
1883 } else {
1884 thumbnails = null;
1885 }
1886
1887 if (isFrontStack(mHomeStack)) {
1888 booting = mService.mBooting;
1889 mService.mBooting = false;
1890 }
1891
1892 if (mStartingUsers.size() > 0) {
1893 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1894 mStartingUsers.clear();
1895 }
1896
1897 // Perform the following actions from unsynchronized state.
1898 final IApplicationThread thumbnailThread = sendThumbnail;
1899 mHandler.post(new Runnable() {
1900 @Override
1901 public void run() {
1902 if (thumbnailThread != null) {
1903 try {
1904 thumbnailThread.requestThumbnail(token);
1905 } catch (Exception e) {
1906 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1907 mService.sendPendingThumbnail(null, token, null, null, true);
1908 }
1909 }
1910
1911 // Report back to any thumbnail receivers.
1912 for (int i = 0; i < NT; i++) {
1913 ActivityRecord r = thumbnails.get(i);
1914 mService.sendPendingThumbnail(r, null, null, null, true);
1915 }
1916 }
1917 });
1918
1919 // Stop any activities that are scheduled to do so but have been
1920 // waiting for the next one to start.
1921 for (int i = 0; i < NS; i++) {
1922 r = stops.get(i);
1923 final ActivityStack stack = r.task.stack;
1924 if (r.finishing) {
1925 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1926 } else {
1927 stack.stopActivityLocked(r);
1928 }
1929 }
1930
1931 // Finish any activities that are scheduled to do so but have been
1932 // waiting for the next one to start.
1933 for (int i = 0; i < NF; i++) {
1934 r = finishes.get(i);
1935 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1936 }
1937
1938 if (booting) {
1939 mService.finishBooting();
1940 } else if (startingUsers != null) {
1941 for (int i = 0; i < startingUsers.size(); i++) {
1942 mService.finishUserSwitch(startingUsers.get(i));
1943 }
1944 }
1945
1946 mService.trimApplications();
1947 //dump();
1948 //mWindowManager.dump();
1949
1950 if (enableScreen) {
1951 mService.enableScreenAfterBoot();
1952 }
1953
1954 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001955 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001956 }
1957
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001958 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001959 }
1960
Craig Mautner8e569572013-10-11 17:36:59 -07001961 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001962 boolean hasVisibleActivities = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001963 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
1964 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
1965 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1966 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1967 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001968 }
Craig Mautner19091252013-10-05 00:03:53 -07001969 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001970 }
1971
1972 void closeSystemDialogsLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001973 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
1974 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
1975 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1976 stacks.get(stackNdx).closeSystemDialogsLocked();
1977 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001978 }
1979 }
1980
Craig Mautner93529a42013-10-04 15:03:13 -07001981 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07001982 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07001983 }
1984
Craig Mautner8d341ef2013-03-26 09:03:27 -07001985 /**
1986 * @return true if some activity was finished (or would have finished if doit were true).
1987 */
1988 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1989 boolean didSomething = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001990 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
1991 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
1992 final int numStacks = stacks.size();
1993 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1994 final ActivityStack stack = stacks.get(stackNdx);
1995 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1996 didSomething = true;
1997 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001998 }
1999 }
2000 return didSomething;
2001 }
2002
Dianne Hackborna413dc02013-07-12 12:02:55 -07002003 void updatePreviousProcessLocked(ActivityRecord r) {
2004 // Now that this process has stopped, we may want to consider
2005 // it to be the previous app to try to keep around in case
2006 // the user wants to return to it.
2007
2008 // First, found out what is currently the foreground app, so that
2009 // we don't blow away the previous app if this activity is being
2010 // hosted by the process that is actually still the foreground.
2011 ProcessRecord fgApp = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002012 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2013 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2014 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2015 final ActivityStack stack = stacks.get(stackNdx);
2016 if (isFrontStack(stack)) {
2017 if (stack.mResumedActivity != null) {
2018 fgApp = stack.mResumedActivity.app;
2019 } else if (stack.mPausingActivity != null) {
2020 fgApp = stack.mPausingActivity.app;
2021 }
2022 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002023 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002024 }
2025 }
2026
2027 // Now set this one as the previous process, only if that really
2028 // makes sense to.
2029 if (r.app != null && fgApp != null && r.app != fgApp
2030 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002031 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002032 mService.mPreviousProcess = r.app;
2033 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2034 }
2035 }
2036
Craig Mautner05d29032013-05-03 13:40:13 -07002037 boolean resumeTopActivitiesLocked() {
2038 return resumeTopActivitiesLocked(null, null, null);
2039 }
2040
2041 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2042 Bundle targetOptions) {
2043 if (targetStack == null) {
2044 targetStack = getFocusedStack();
2045 }
2046 boolean result = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002047 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2048 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2049 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2050 final ActivityStack stack = stacks.get(stackNdx);
2051 if (isFrontStack(stack)) {
2052 if (stack == targetStack) {
2053 result = stack.resumeTopActivityLocked(target, targetOptions);
2054 } else {
2055 stack.resumeTopActivityLocked(null);
2056 }
Craig Mautner05d29032013-05-03 13:40:13 -07002057 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002058 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002059 }
Craig Mautner05d29032013-05-03 13:40:13 -07002060 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002061 }
2062
2063 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002064 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2065 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2066 final int numStacks = stacks.size();
2067 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2068 final ActivityStack stack = stacks.get(stackNdx);
2069 stack.finishTopRunningActivityLocked(app);
2070 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002071 }
2072 }
2073
Craig Mautner8d341ef2013-03-26 09:03:27 -07002074 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002075 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2076 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2077 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2078 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2079 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2080 + stacks.get(stackNdx));
2081 return;
2082 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002083 }
2084 }
2085 }
2086
Craig Mautner967212c2013-04-13 21:10:58 -07002087 ActivityStack getStack(int stackId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002088 ActivityContainer activityContainer = mActivityContainers.get(stackId);
2089 if (activityContainer != null) {
2090 return activityContainer.mStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002091 }
2092 return null;
2093 }
2094
Craig Mautner967212c2013-04-13 21:10:58 -07002095 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002096 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2097 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2098 allStacks.addAll(mDisplayInfos.valueAt(displayNdx).stacks);
2099 }
2100 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002101 }
2102
Craig Mautner4a1cb222013-12-04 16:14:06 -08002103 IBinder getHomeActivityToken() {
2104 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2105 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2106 final TaskRecord task = tasks.get(taskNdx);
2107 if (task.isHomeTask()) {
2108 final ArrayList<ActivityRecord> activities = task.mActivities;
2109 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2110 final ActivityRecord r = activities.get(activityNdx);
2111 if (r.isHomeActivity()) {
2112 return r.appToken;
2113 }
2114 }
2115 }
2116 }
2117 return null;
2118 }
2119
2120 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2121 IActivityContainerCallback callback) {
2122 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2123 callback);
2124 mActivityContainers.put(stackId, activityContainer);
2125 if (parentActivity != null) {
2126 parentActivity.mChildContainers.add(activityContainer.mStack);
2127 }
2128 return activityContainer;
2129 }
2130
2131 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2132 IActivityContainerCallback callback) {
2133 return createActivityContainer(parentActivity, getNextStackId(), callback);
2134 }
2135
2136 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
2137 ActivityDisplayInfo displayInfo = mDisplayInfos.get(displayId);
2138 if (displayInfo == null) {
2139 return -1;
2140 }
2141
2142 ActivityContainer activityContainer =
2143 createActivityContainer(parentActivity, stackId, null);
2144 activityContainer.attachToDisplayLocked(displayInfo);
2145 return stackId;
2146 }
2147
2148 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002149 while (true) {
2150 if (++mLastStackId <= HOME_STACK_ID) {
2151 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002152 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002153 if (getStack(mLastStackId) == null) {
2154 break;
2155 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002156 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002157 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002158 }
2159
2160 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002161 final TaskRecord task = anyTaskForIdLocked(taskId);
2162 if (task == null) {
2163 return;
2164 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002165 final ActivityStack stack = getStack(stackId);
2166 if (stack == null) {
2167 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2168 return;
2169 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002170 removeTask(task);
2171 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002172 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002173 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002174 }
2175
Craig Mautnerac6f8432013-07-17 13:24:59 -07002176 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002177 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002178 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2179 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2180 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2181 final ActivityStack stack = stacks.get(stackNdx);
2182 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2183 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2184 continue;
2185 }
2186 final ActivityRecord ar = stack.findTaskLocked(r);
2187 if (ar != null) {
2188 return ar;
2189 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002190 }
2191 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002192 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002193 return null;
2194 }
2195
2196 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002197 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2198 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2199 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2200 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2201 if (ar != null) {
2202 return ar;
2203 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002204 }
2205 }
2206 return null;
2207 }
2208
Craig Mautner8d341ef2013-03-26 09:03:27 -07002209 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002210 scheduleSleepTimeout();
2211 if (!mGoingToSleep.isHeld()) {
2212 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002213 if (mLaunchingActivity.isHeld()) {
2214 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2215 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002216 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002217 mLaunchingActivity.release();
2218 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002219 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002220 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002221 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002222 }
2223
2224 boolean shutdownLocked(int timeout) {
2225 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002226 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002227
2228 final long endTime = System.currentTimeMillis() + timeout;
2229 while (true) {
2230 boolean cantShutdown = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002231 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2232 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2233 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2234 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2235 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002236 }
2237 if (cantShutdown) {
2238 long timeRemaining = endTime - System.currentTimeMillis();
2239 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002240 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002241 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002242 } catch (InterruptedException e) {
2243 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002244 } else {
2245 Slog.w(TAG, "Activity manager shutdown timed out");
2246 timedout = true;
2247 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002248 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002249 } else {
2250 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002251 }
2252 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002253
2254 // Force checkReadyForSleep to complete.
2255 mSleepTimeout = true;
2256 checkReadyForSleepLocked();
2257
Craig Mautner8d341ef2013-03-26 09:03:27 -07002258 return timedout;
2259 }
2260
2261 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002262 removeSleepTimeouts();
2263 if (mGoingToSleep.isHeld()) {
2264 mGoingToSleep.release();
2265 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002266 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2267 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2268 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2269 final ActivityStack stack = stacks.get(stackNdx);
2270 stack.awakeFromSleepingLocked();
2271 if (isFrontStack(stack)) {
2272 resumeTopActivitiesLocked();
2273 }
Craig Mautner5314a402013-09-26 12:40:16 -07002274 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002275 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002276 mGoingToSleepActivities.clear();
2277 }
2278
2279 void activitySleptLocked(ActivityRecord r) {
2280 mGoingToSleepActivities.remove(r);
2281 checkReadyForSleepLocked();
2282 }
2283
2284 void checkReadyForSleepLocked() {
2285 if (!mService.isSleepingOrShuttingDown()) {
2286 // Do not care.
2287 return;
2288 }
2289
2290 if (!mSleepTimeout) {
2291 boolean dontSleep = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002292 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2293 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2294 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2295 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2296 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002297 }
2298
2299 if (mStoppingActivities.size() > 0) {
2300 // Still need to tell some activities to stop; can't sleep yet.
2301 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2302 + mStoppingActivities.size() + " activities");
2303 scheduleIdleLocked();
2304 dontSleep = true;
2305 }
2306
2307 if (mGoingToSleepActivities.size() > 0) {
2308 // Still need to tell some activities to sleep; can't sleep yet.
2309 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2310 + mGoingToSleepActivities.size() + " activities");
2311 dontSleep = true;
2312 }
2313
2314 if (dontSleep) {
2315 return;
2316 }
2317 }
2318
Craig Mautner4a1cb222013-12-04 16:14:06 -08002319 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2320 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2321 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2322 stacks.get(stackNdx).goToSleep();
2323 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002324 }
2325
2326 removeSleepTimeouts();
2327
2328 if (mGoingToSleep.isHeld()) {
2329 mGoingToSleep.release();
2330 }
2331 if (mService.mShuttingDown) {
2332 mService.notifyAll();
2333 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002334 }
2335
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002336 boolean reportResumedActivityLocked(ActivityRecord r) {
2337 final ActivityStack stack = r.task.stack;
2338 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002339 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002340 }
2341 if (allResumedActivitiesComplete()) {
2342 ensureActivitiesVisibleLocked(null, 0);
2343 mWindowManager.executeAppTransition();
2344 return true;
2345 }
2346 return false;
2347 }
2348
Craig Mautner8d341ef2013-03-26 09:03:27 -07002349 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002350 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2351 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2352 final int numStacks = stacks.size();
2353 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2354 final ActivityStack stack = stacks.get(stackNdx);
2355 stack.handleAppCrashLocked(app);
2356 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002357 }
2358 }
2359
Craig Mautnerde4ef022013-04-07 19:01:33 -07002360 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002361 // First the front stacks. In case any are not fullscreen and are in front of home.
2362 boolean showHomeBehindStack = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002363 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2364 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2365 final int topStackNdx = stacks.size() - 1;
2366 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2367 final ActivityStack stack = stacks.get(stackNdx);
2368 if (stackNdx == topStackNdx) {
2369 // Top stack.
2370 showHomeBehindStack =
2371 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2372 } else {
2373 // Back stack.
2374 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2375 showHomeBehindStack);
2376 }
Craig Mautner580ea812013-04-25 12:58:38 -07002377 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002378 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002379 }
2380
2381 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002382 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2383 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2384 final int numStacks = stacks.size();
2385 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2386 final ActivityStack stack = stacks.get(stackNdx);
2387 stack.scheduleDestroyActivities(app, false, reason);
2388 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002389 }
2390 }
2391
2392 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002393 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2394 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002395 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002396
Craig Mautner858d8a62013-04-23 17:08:34 -07002397 mStartingUsers.add(uss);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002398 for (int displayNdx = mDisplayInfos.size() - 1; displayNdx >= 0; --displayNdx) {
2399 final ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2400 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2401 stacks.get(stackNdx).switchUserLocked(userId);
2402 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002403 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002404
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002405 ActivityStack stack = getStack(restoreStackId);
2406 if (stack == null) {
2407 stack = mHomeStack;
2408 }
2409 final boolean homeInFront = stack.isHomeStack();
Craig Mautner93529a42013-10-04 15:03:13 -07002410 moveHomeStack(homeInFront);
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002411 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner93529a42013-10-04 15:03:13 -07002412 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002413 }
2414
Craig Mautnerde4ef022013-04-07 19:01:33 -07002415 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2416 int N = mStoppingActivities.size();
2417 if (N <= 0) return null;
2418
2419 ArrayList<ActivityRecord> stops = null;
2420
2421 final boolean nowVisible = allResumedActivitiesVisible();
2422 for (int i=0; i<N; i++) {
2423 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002424 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002425 + nowVisible + " waitingVisible=" + s.waitingVisible
2426 + " finishing=" + s.finishing);
2427 if (s.waitingVisible && nowVisible) {
2428 mWaitingVisibleActivities.remove(s);
2429 s.waitingVisible = false;
2430 if (s.finishing) {
2431 // If this activity is finishing, it is sitting on top of
2432 // everyone else but we now know it is no longer needed...
2433 // so get rid of it. Otherwise, we need to go through the
2434 // normal flow and hide it once we determine that it is
2435 // hidden by the activities in front of it.
2436 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002437 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002438 }
2439 }
2440 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2441 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2442 if (stops == null) {
2443 stops = new ArrayList<ActivityRecord>();
2444 }
2445 stops.add(s);
2446 mStoppingActivities.remove(i);
2447 N--;
2448 i--;
2449 }
2450 }
2451
2452 return stops;
2453 }
2454
Craig Mautnercf910b02013-04-23 11:23:27 -07002455 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002456 // FIXME
2457/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2458 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002459 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002460 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002461 if (isFrontStack(stack)) {
2462 if (r == null) {
2463 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2464 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002465 final ActivityRecord pausing = stack.mPausingActivity;
2466 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002467 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002468 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002469 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002470 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002471 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002472 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002473 }
2474 }
2475 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002476 final ActivityRecord resumed = stack.mResumedActivity;
2477 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002478 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002479 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002480 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002481 if (r != null && (state == ActivityState.INITIALIZING
2482 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002483 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002484 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002485 }
2486 }
2487 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002488*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002489 }
2490
Craig Mautner27084302013-03-25 08:05:25 -07002491 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002492 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002493 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002494 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002495 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002496 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2497 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2498 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002499 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002500
Craig Mautner20e72272013-04-01 13:45:53 -07002501 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002502 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002503 }
2504
Dianne Hackborn390517b2013-05-30 15:03:32 -07002505 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2506 boolean needSep, String prefix) {
2507 if (activity != null) {
2508 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2509 if (needSep) {
2510 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002511 }
2512 pw.print(prefix);
2513 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002514 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002515 }
2516 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002517 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002518 }
2519
Craig Mautner8d341ef2013-03-26 09:03:27 -07002520 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2521 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002522 boolean printed = false;
2523 boolean needSep = false;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002524 for (int displayNdx = 0; displayNdx < mDisplayInfos.size(); ++displayNdx) {
2525 ActivityDisplayInfo info = mDisplayInfos.valueAt(displayNdx);
2526 pw.print("Display #"); pw.println(info.mDisplayId);
2527 ArrayList<ActivityStack> stacks = info.stacks;
2528 final int numStacks = stacks.size();
2529 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2530 final ActivityStack stack = stacks.get(stackNdx);
2531 StringBuilder stackHeader = new StringBuilder(128);
2532 stackHeader.append(" Stack #");
2533 stackHeader.append(stack.mStackId);
2534 stackHeader.append(":");
2535 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2536 needSep, stackHeader.toString());
2537 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2538 !dumpAll, false, dumpPackage, true,
2539 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002540
Craig Mautner4a1cb222013-12-04 16:14:06 -08002541 needSep = printed;
2542 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2543 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002544 if (pr) {
2545 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002546 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002547 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002548 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2549 " mResumedActivity: ");
2550 if (pr) {
2551 printed = true;
2552 needSep = false;
2553 }
2554 if (dumpAll) {
2555 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2556 " mLastPausedActivity: ");
2557 if (pr) {
2558 printed = true;
2559 needSep = true;
2560 }
2561 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2562 needSep, " mLastNoHistoryActivity: ");
2563 }
2564 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002565 }
2566 }
2567
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002568 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2569 false, dumpPackage, true, " Activities waiting to finish:", null);
2570 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2571 false, dumpPackage, true, " Activities waiting to stop:", null);
2572 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2573 false, dumpPackage, true, " Activities waiting for another to become visible:",
2574 null);
2575 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2576 false, dumpPackage, true, " Activities waiting to sleep:", null);
2577 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2578 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002579
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002580 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002581 }
2582
Dianne Hackborn390517b2013-05-30 15:03:32 -07002583 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002584 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002585 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002586 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002587 String innerPrefix = null;
2588 String[] args = null;
2589 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002590 for (int i=list.size()-1; i>=0; i--) {
2591 final ActivityRecord r = list.get(i);
2592 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2593 continue;
2594 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002595 if (innerPrefix == null) {
2596 innerPrefix = prefix + " ";
2597 args = new String[0];
2598 }
2599 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002600 final boolean full = !brief && (complete || !r.isInHistory());
2601 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002602 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002603 needNL = false;
2604 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002605 if (header1 != null) {
2606 pw.println(header1);
2607 header1 = null;
2608 }
2609 if (header2 != null) {
2610 pw.println(header2);
2611 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002612 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002613 if (lastTask != r.task) {
2614 lastTask = r.task;
2615 pw.print(prefix);
2616 pw.print(full ? "* " : " ");
2617 pw.println(lastTask);
2618 if (full) {
2619 lastTask.dump(pw, prefix + " ");
2620 } else if (complete) {
2621 // Complete + brief == give a summary. Isn't that obvious?!?
2622 if (lastTask.intent != null) {
2623 pw.print(prefix); pw.print(" ");
2624 pw.println(lastTask.intent.toInsecureStringWithClip());
2625 }
2626 }
2627 }
2628 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2629 pw.print(" #"); pw.print(i); pw.print(": ");
2630 pw.println(r);
2631 if (full) {
2632 r.dump(pw, innerPrefix);
2633 } else if (complete) {
2634 // Complete + brief == give a summary. Isn't that obvious?!?
2635 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2636 if (r.app != null) {
2637 pw.print(innerPrefix); pw.println(r.app);
2638 }
2639 }
2640 if (client && r.app != null && r.app.thread != null) {
2641 // flush anything that is already in the PrintWriter since the thread is going
2642 // to write to the file descriptor directly
2643 pw.flush();
2644 try {
2645 TransferPipe tp = new TransferPipe();
2646 try {
2647 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2648 r.appToken, innerPrefix, args);
2649 // Short timeout, since blocking here can
2650 // deadlock with the application.
2651 tp.go(fd, 2000);
2652 } finally {
2653 tp.kill();
2654 }
2655 } catch (IOException e) {
2656 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2657 } catch (RemoteException e) {
2658 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2659 }
2660 needNL = true;
2661 }
2662 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002663 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002664 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002665
Craig Mautnerf3333272013-04-22 10:55:53 -07002666 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002667 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002668 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2669 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002670 }
2671
2672 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002673 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002674 }
2675
2676 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002677 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002678 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2679 }
2680
Craig Mautner05d29032013-05-03 13:40:13 -07002681 final void scheduleResumeTopActivities() {
2682 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2683 }
2684
Craig Mautner0eea92c2013-05-16 13:35:39 -07002685 void removeSleepTimeouts() {
2686 mSleepTimeout = false;
2687 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2688 }
2689
2690 final void scheduleSleepTimeout() {
2691 removeSleepTimeouts();
2692 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2693 }
2694
Craig Mautner4a1cb222013-12-04 16:14:06 -08002695 @Override
2696 public void onDisplayAdded(int displayId) {
2697 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2698 }
2699
2700 @Override
2701 public void onDisplayRemoved(int displayId) {
2702 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2703 }
2704
2705 @Override
2706 public void onDisplayChanged(int displayId) {
2707 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2708 }
2709
2710 public void handleDisplayAddedLocked(int displayId) {
2711 synchronized (mService) {
2712 ActivityDisplayInfo info = new ActivityDisplayInfo(displayId);
2713 mDisplayInfos.put(displayId, info);
2714 }
2715 mWindowManager.onDisplayAdded(displayId);
2716 }
2717
2718 public void handleDisplayRemovedLocked(int displayId) {
2719 synchronized (mService) {
2720 ActivityDisplayInfo info = mDisplayInfos.get(displayId);
2721 if (info != null) {
2722 ArrayList<ActivityStack> stacks = info.stacks;
2723 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2724 info.detachActivities(stacks.get(stackNdx));
2725 }
2726 mDisplayInfos.remove(displayId);
2727 }
2728 }
2729 mWindowManager.onDisplayRemoved(displayId);
2730 }
2731
2732 public void handleDisplayChangedLocked(int displayId) {
2733 synchronized (mService) {
2734 ActivityDisplayInfo info = mDisplayInfos.get(displayId);
2735 if (info != null) {
2736 // TODO: Update the bounds.
2737 }
2738 }
2739 mWindowManager.onDisplayChanged(displayId);
2740 }
2741
2742 StackInfo getStackInfo(ActivityStack stack) {
2743 StackInfo info = new StackInfo();
2744 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2745 info.displayId = Display.DEFAULT_DISPLAY;
2746 info.stackId = stack.mStackId;
2747
2748 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2749 final int numTasks = tasks.size();
2750 int[] taskIds = new int[numTasks];
2751 String[] taskNames = new String[numTasks];
2752 for (int i = 0; i < numTasks; ++i) {
2753 final TaskRecord task = tasks.get(i);
2754 taskIds[i] = task.taskId;
2755 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2756 : task.realActivity != null ? task.realActivity.flattenToString()
2757 : task.getTopActivity() != null ? task.getTopActivity().packageName
2758 : "unknown";
2759 }
2760 info.taskIds = taskIds;
2761 info.taskNames = taskNames;
2762 return info;
2763 }
2764
2765 StackInfo getStackInfoLocked(int stackId) {
2766 ActivityStack stack = getStack(stackId);
2767 if (stack != null) {
2768 return getStackInfo(stack);
2769 }
2770 return null;
2771 }
2772
2773 ArrayList<StackInfo> getAllStackInfosLocked() {
2774 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2775 for (int displayNdx = 0; displayNdx < mDisplayInfos.size(); ++displayNdx) {
2776 ArrayList<ActivityStack> stacks = mDisplayInfos.valueAt(displayNdx).stacks;
2777 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2778 list.add(getStackInfo(stacks.get(ndx)));
2779 }
2780 }
2781 return list;
2782 }
2783
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002784 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002785
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002786 public ActivityStackSupervisorHandler(Looper looper) {
2787 super(looper);
2788 }
2789
Craig Mautnerf3333272013-04-22 10:55:53 -07002790 void activityIdleInternal(ActivityRecord r) {
2791 synchronized (mService) {
2792 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2793 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002794 }
2795
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002796 @Override
2797 public void handleMessage(Message msg) {
2798 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002799 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002800 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002801 if (mService.mDidDexOpt) {
2802 mService.mDidDexOpt = false;
2803 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2804 nmsg.obj = msg.obj;
2805 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2806 return;
2807 }
2808 // We don't at this point know if the activity is fullscreen,
2809 // so we need to be conservative and assume it isn't.
2810 activityIdleInternal((ActivityRecord)msg.obj);
2811 } break;
2812 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002813 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002814 activityIdleInternal((ActivityRecord)msg.obj);
2815 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002816 case RESUME_TOP_ACTIVITY_MSG: {
2817 synchronized (mService) {
2818 resumeTopActivitiesLocked();
2819 }
2820 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002821 case SLEEP_TIMEOUT_MSG: {
2822 synchronized (mService) {
2823 if (mService.isSleepingOrShuttingDown()) {
2824 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2825 mSleepTimeout = true;
2826 checkReadyForSleepLocked();
2827 }
2828 }
2829 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002830 case LAUNCH_TIMEOUT_MSG: {
2831 if (mService.mDidDexOpt) {
2832 mService.mDidDexOpt = false;
2833 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2834 return;
2835 }
2836 synchronized (mService) {
2837 if (mLaunchingActivity.isHeld()) {
2838 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2839 if (VALIDATE_WAKE_LOCK_CALLER
2840 && Binder.getCallingUid() != Process.myUid()) {
2841 throw new IllegalStateException("Calling must be system uid");
2842 }
2843 mLaunchingActivity.release();
2844 }
2845 }
2846 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002847 case HANDLE_DISPLAY_ADDED: {
2848 handleDisplayAddedLocked(msg.arg1);
2849 } break;
2850 case HANDLE_DISPLAY_CHANGED: {
2851 handleDisplayChangedLocked(msg.arg1);
2852 } break;
2853 case HANDLE_DISPLAY_REMOVED: {
2854 handleDisplayRemovedLocked(msg.arg1);
2855 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002856 }
2857 }
2858 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002859
Craig Mautner4a1cb222013-12-04 16:14:06 -08002860 class ActivityContainer extends IActivityContainer.Stub {
2861 final int mStackId;
2862 final IActivityContainerCallback mCallback;
2863 final ActivityStack mStack;
2864 final ActivityRecord mParentActivity;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002865
Craig Mautner4a1cb222013-12-04 16:14:06 -08002866 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
2867 ActivityDisplayInfo mActivityDisplayInfo;
2868
2869 ActivityContainer(ActivityRecord parentActivity, int stackId,
2870 IActivityContainerCallback callback) {
2871 synchronized (mService) {
2872 mStackId = stackId;
2873 mStack = new ActivityStack(this);
2874 mParentActivity = parentActivity;
2875 mCallback = callback;
2876 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002877 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002878
2879 void attachToDisplayLocked(ActivityDisplayInfo displayInfo) {
2880 mActivityDisplayInfo = displayInfo;
2881 displayInfo.attachActivities(mStack);
2882 mWindowManager.createStack(mStackId, displayInfo.mDisplayId);
2883 }
2884
2885 @Override
2886 public void attachToDisplay(int displayId) throws RemoteException {
2887 synchronized (mService) {
2888 ActivityDisplayInfo displayInfo = mDisplayInfos.get(displayId);
2889 if (displayInfo == null) {
2890 return;
2891 }
2892 attachToDisplayLocked(displayInfo);
2893 }
2894 }
2895
2896 @Override
2897 public int getStackId() throws RemoteException {
2898 return mStack.mStackId;
2899 }
2900
2901 void detachLocked() {
2902 if (mActivityDisplayInfo != null) {
2903 mActivityDisplayInfo.detachActivities(mStack);
2904 mActivityDisplayInfo = null;
2905 }
2906 }
2907
2908 @Override
2909 public void detachFromDisplay() throws RemoteException {
2910 synchronized (mService) {
2911 detachLocked();
2912 }
2913 }
2914
2915 @Override
2916 public void startActivity(Intent intent) throws RemoteException {
2917
2918 }
2919
2920 @Override
2921 public IBinder asBinder() {
2922 return this;
2923 }
2924
2925 ActivityStackSupervisor getOuter() {
2926 return ActivityStackSupervisor.this;
2927 }
2928
2929 boolean isAttached() {
2930 return mActivityDisplayInfo != null;
2931 }
2932
2933 void getBounds(Point outBounds) {
2934 if (mActivityDisplayInfo != null) {
2935 mActivityDisplayInfo.getBounds(outBounds);
2936 } else {
2937 outBounds.set(0, 0);
2938 }
2939 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002940 }
2941
Craig Mautner4a1cb222013-12-04 16:14:06 -08002942 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
2943 * attached {@link ActivityStack}s */
2944 final class ActivityDisplayInfo {
2945 /** Actual Display this object tracks. */
2946 final int mDisplayId;
2947 final Display mDisplay;
2948 final DisplayInfo mDisplayInfo = new DisplayInfo();
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002949
Craig Mautner4a1cb222013-12-04 16:14:06 -08002950 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
2951 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
2952 final ArrayList<ActivityStack> stacks = new ArrayList<ActivityStack>();
2953
2954 ActivityDisplayInfo(int displayId) {
2955 mDisplayId = displayId;
2956 mDisplay = mDisplayManager.getDisplay(displayId);
2957 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002958 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002959
2960 void attachActivities(ActivityStack stack) {
2961 stacks.add(stack);
2962 }
2963
2964 void detachActivities(ActivityStack stack) {
2965 stacks.remove(stack);
2966 }
2967
2968 void getBounds(Point bounds) {
2969 mDisplay.getDisplayInfo(mDisplayInfo);
2970 bounds.x = mDisplayInfo.appWidth;
2971 bounds.y = mDisplayInfo.appHeight;
2972 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002973 }
Craig Mautner27084302013-03-25 08:05:25 -07002974}