blob: bf93c5a1fc466d3f387183b4601cb5fa96b7276e [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 Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
Jeff Brown38f96e52014-02-11 14:32:56 -080064import android.hardware.input.InputManager;
65import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070067import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070068import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070069import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070070import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070071import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070072import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070074import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070075import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070078import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070079import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070082
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brown38f96e52014-02-11 14:32:56 -080086import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080087import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070088import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070089import com.android.internal.os.TransferPipe;
Jeff Brown38f96e52014-02-11 14:32:56 -080090import com.android.server.LocalServices;
Craig Mautner6170f732013-04-02 13:05:23 -070091import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070092import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070093import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070094
Craig Mautner8d341ef2013-03-26 09:03:27 -070095import java.io.FileDescriptor;
96import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070097import java.io.PrintWriter;
Craig Mautner4504de52013-12-20 09:06:56 -080098import java.lang.ref.WeakReference;
Craig Mautner2219a1b2013-03-25 09:44:30 -070099import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700100import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -0700101
Craig Mautner4a1cb222013-12-04 16:14:06 -0800102public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700103 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
104 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
105 static final boolean DEBUG_APP = DEBUG || false;
106 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700107 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700108 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700109
Craig Mautner2219a1b2013-03-25 09:44:30 -0700110 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700111
Craig Mautnerf3333272013-04-22 10:55:53 -0700112 /** How long we wait until giving up on the last activity telling us it is idle. */
113 static final int IDLE_TIMEOUT = 10*1000;
114
Craig Mautner0eea92c2013-05-16 13:35:39 -0700115 /** How long we can hold the sleep wake lock before giving up. */
116 static final int SLEEP_TIMEOUT = 5*1000;
117
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700118 // How long we can hold the launch wake lock before giving up.
119 static final int LAUNCH_TIMEOUT = 10*1000;
120
Craig Mautner05d29032013-05-03 13:40:13 -0700121 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
122 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
123 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700124 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700125 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800126 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
127 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
128 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
129
Craig Mautner4504de52013-12-20 09:06:56 -0800130 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700131
132 // For debugging to make sure the caller when acquiring/releasing our
133 // wake lock is the system process.
134 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700135
Craig Mautner27084302013-03-25 08:05:25 -0700136 final ActivityManagerService mService;
137
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700138 final ActivityStackSupervisorHandler mHandler;
139
140 /** Short cut */
141 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800142 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700143
Craig Mautner27084302013-03-25 08:05:25 -0700144 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700145 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700146
Craig Mautner8d341ef2013-03-26 09:03:27 -0700147 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700148 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700149
150 /** Task identifier that activities are currently being started in. Incremented each time a
151 * new task is created. */
152 private int mCurTaskId = 0;
153
Craig Mautner2420ead2013-04-01 17:13:20 -0700154 /** The current user */
155 private int mCurrentUser;
156
Craig Mautnere0a38842013-12-16 16:14:02 -0800157 /** The stack containing the launcher app. Assumed to always be attached to
158 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700159 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700160
Craig Mautnere0a38842013-12-16 16:14:02 -0800161 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700162 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700163
Craig Mautner4a1cb222013-12-04 16:14:06 -0800164 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
165 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800166 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800167 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700168
169 /** List of activities that are waiting for a new activity to become visible before completing
170 * whatever operation they are supposed to do. */
171 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
172
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700173 /** List of processes waiting to find out about the next visible activity. */
174 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
175 new ArrayList<IActivityManager.WaitResult>();
176
177 /** List of processes waiting to find out about the next launched activity. */
178 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
179 new ArrayList<IActivityManager.WaitResult>();
180
Craig Mautnerde4ef022013-04-07 19:01:33 -0700181 /** List of activities that are ready to be stopped, but waiting for the next activity to
182 * settle down before doing so. */
183 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
184
Craig Mautnerf3333272013-04-22 10:55:53 -0700185 /** List of activities that are ready to be finished, but waiting for the previous activity to
186 * settle down before doing so. It contains ActivityRecord objects. */
187 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
188
Craig Mautner0eea92c2013-05-16 13:35:39 -0700189 /** List of activities that are in the process of going to sleep. */
190 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
191
Craig Mautnerf3333272013-04-22 10:55:53 -0700192 /** List of ActivityRecord objects that have been finished and must still report back to a
193 * pending thumbnail receiver. */
194 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
195
196 /** Used on user changes */
197 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
198
Craig Mautnerde4ef022013-04-07 19:01:33 -0700199 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
200 * is being brought in front of us. */
201 boolean mUserLeaving = false;
202
Craig Mautner0eea92c2013-05-16 13:35:39 -0700203 /** Set when we have taken too long waiting to go to sleep. */
204 boolean mSleepTimeout = false;
205
206 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700207 * We don't want to allow the device to go to sleep while in the process
208 * of launching an activity. This is primarily to allow alarm intent
209 * receivers to launch an activity and get that to run before the device
210 * goes back to sleep.
211 */
212 final PowerManager.WakeLock mLaunchingActivity;
213
214 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700215 * Set when the system is going to sleep, until we have
216 * successfully paused the current activity and released our wake lock.
217 * At that point the system is allowed to actually sleep.
218 */
219 final PowerManager.WakeLock mGoingToSleep;
220
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700221 /** Stack id of the front stack when user switched, indexed by userId. */
222 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700223
Craig Mautner4504de52013-12-20 09:06:56 -0800224 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800225 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800226 SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
227 new SparseArray<WeakReference<ActivityContainer>>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800228
229 /** Mapping from displayId to display current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800230 private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800231
Jeff Brown38f96e52014-02-11 14:32:56 -0800232 InputManagerInternal mInputManagerInternal;
233
Craig Mautner4a1cb222013-12-04 16:14:06 -0800234 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700235 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800236 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700237 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800238 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700239 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
240 throw new IllegalStateException("Calling must be system uid");
241 }
242 mLaunchingActivity =
243 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
244 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700245 }
246
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700247 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800248 synchronized (mService) {
249 mWindowManager = wm;
250
251 mDisplayManager =
252 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
253 mDisplayManager.registerDisplayListener(this, null);
254
255 Display[] displays = mDisplayManager.getDisplays();
256 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
257 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800258 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
259 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800260 }
261
262 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
263 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brown38f96e52014-02-11 14:32:56 -0800264
265 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800266 }
Craig Mautner27084302013-03-25 08:05:25 -0700267 }
268
269 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700270 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700271 if (mDismissKeyguardOnNextActivity) {
272 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700273 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700274 }
275 }
276
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700277 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800278 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700279 }
280
Craig Mautnerde4ef022013-04-07 19:01:33 -0700281 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800282 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700283 }
284
Craig Mautner4a1cb222013-12-04 16:14:06 -0800285 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
286 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700287 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800288 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
289 if (parent != null) {
290 stack = parent.task.stack;
291 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800292 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800293 if (stacks != null && !stacks.isEmpty()) {
294 return stack == stacks.get(stacks.size() - 1);
295 }
296 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700297 }
298
Craig Mautnerde4ef022013-04-07 19:01:33 -0700299 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800300 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800301 int topNdx = stacks.size() - 1;
302 if (topNdx <= 0) {
303 return;
304 }
305 ActivityStack topStack = stacks.get(topNdx);
306 final boolean homeInFront = topStack == mHomeStack;
307 if (homeInFront != toFront) {
308 mLastFocusedStack = topStack;
309 stacks.remove(mHomeStack);
310 stacks.add(toFront ? topNdx : 0, mHomeStack);
311 mFocusedStack = stacks.get(topNdx);
312 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
313 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700314 }
315 }
316
Craig Mautner8e569572013-10-11 17:36:59 -0700317 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700318 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700319 mHomeStack.moveHomeTaskToTop();
320 }
321
322 boolean resumeHomeActivity(ActivityRecord prev) {
323 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700324 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700325 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700326 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700327 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700328 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700329 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700330 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700331 }
332 return mService.startHomeActivityLocked(mCurrentUser);
333 }
334
Craig Mautner27084302013-03-25 08:05:25 -0700335 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700336 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700337 mDismissKeyguardOnNextActivity = dismiss;
338 }
339
Craig Mautner8d341ef2013-03-26 09:03:27 -0700340 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800341 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800342 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800343 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800344 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
345 ActivityStack stack = stacks.get(stackNdx);
346 TaskRecord task = stack.taskForIdLocked(id);
347 if (task != null) {
348 return task;
349 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700350 }
351 }
352 return null;
353 }
354
Craig Mautner6170f732013-04-02 13:05:23 -0700355 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800356 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800357 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800358 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800359 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
360 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
361 if (r != null) {
362 return r;
363 }
Craig Mautner6170f732013-04-02 13:05:23 -0700364 }
365 }
366 return null;
367 }
368
Craig Mautner8d341ef2013-03-26 09:03:27 -0700369 int getNextTaskId() {
370 do {
371 mCurTaskId++;
372 if (mCurTaskId <= 0) {
373 mCurTaskId = 1;
374 }
375 } while (anyTaskForIdLocked(mCurTaskId) != null);
376 return mCurTaskId;
377 }
378
Craig Mautnerde4ef022013-04-07 19:01:33 -0700379 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700380 ActivityStack stack = getFocusedStack();
381 if (stack == null) {
382 return null;
383 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700384 ActivityRecord resumedActivity = stack.mResumedActivity;
385 if (resumedActivity == null || resumedActivity.app == null) {
386 resumedActivity = stack.mPausingActivity;
387 if (resumedActivity == null || resumedActivity.app == null) {
388 resumedActivity = stack.topRunningActivityLocked(null);
389 }
390 }
391 return resumedActivity;
392 }
393
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800394 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700395 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800396 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800397 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
398 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800399 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
400 final ActivityStack stack = stacks.get(stackNdx);
401 if (!isFrontStack(stack)) {
402 continue;
403 }
404 ActivityRecord hr = stack.topRunningActivityLocked(null);
405 if (hr != null) {
406 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
407 && processName.equals(hr.processName)) {
408 try {
409 if (realStartActivityLocked(hr, app, true, true)) {
410 didSomething = true;
411 }
412 } catch (Exception e) {
413 Slog.w(TAG, "Exception in new application when starting activity "
414 + hr.intent.getComponent().flattenToShortString(), e);
415 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700416 }
Craig Mautner20e72272013-04-01 13:45:53 -0700417 }
Craig Mautner20e72272013-04-01 13:45:53 -0700418 }
419 }
420 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700421 if (!didSomething) {
422 ensureActivitiesVisibleLocked(null, 0);
423 }
Craig Mautner20e72272013-04-01 13:45:53 -0700424 return didSomething;
425 }
426
427 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800428 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
429 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800430 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
431 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800432 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800433 continue;
434 }
435 final ActivityRecord resumedActivity = stack.mResumedActivity;
436 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800437 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
438 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800439 return false;
440 }
Craig Mautner20e72272013-04-01 13:45:53 -0700441 }
442 }
443 return true;
444 }
445
Craig Mautnerde4ef022013-04-07 19:01:33 -0700446 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800447 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
448 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800449 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
450 final ActivityStack stack = stacks.get(stackNdx);
451 if (isFrontStack(stack)) {
452 final ActivityRecord r = stack.mResumedActivity;
453 if (r != null && r.state != ActivityState.RESUMED) {
454 return false;
455 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700456 }
457 }
458 }
459 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800460 if (DEBUG_STACK) Slog.d(TAG,
461 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
462 mLastFocusedStack + " to=" + mFocusedStack);
463 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700464 return true;
465 }
466
467 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800468 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
469 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800470 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
471 final ActivityStack stack = stacks.get(stackNdx);
472 final ActivityRecord r = stack.mResumedActivity;
473 if (r != null && (!r.nowVisible || r.waitingVisible)) {
474 return false;
475 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700476 }
477 }
478 return true;
479 }
480
Craig Mautner2acc3892013-09-23 10:28:14 -0700481 /**
482 * Pause all activities in either all of the stacks or just the back stacks.
483 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700484 * @return true if any activity was paused as a result of this call.
485 */
Craig Mautner5314a402013-09-26 12:40:16 -0700486 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700487 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800488 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
489 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800490 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
491 final ActivityStack stack = stacks.get(stackNdx);
492 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
493 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
494 " mResumedActivity=" + stack.mResumedActivity);
495 stack.startPausingLocked(userLeaving, false);
496 someActivityPaused = true;
497 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700498 }
499 }
500 return someActivityPaused;
501 }
502
Craig Mautnerde4ef022013-04-07 19:01:33 -0700503 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700504 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800505 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
506 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800507 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
508 final ActivityStack stack = stacks.get(stackNdx);
509 final ActivityRecord r = stack.mPausingActivity;
510 if (r != null && r.state != ActivityState.PAUSED
511 && r.state != ActivityState.STOPPED
512 && r.state != ActivityState.STOPPING) {
513 if (DEBUG_STATES) {
514 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
515 pausing = false;
516 } else {
517 return false;
518 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700519 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700520 }
521 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700522 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700523 }
524
Craig Mautnerdf88d732014-01-27 09:21:32 -0800525 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
526 // TODO: Put all stacks in supervisor and iterate through them instead.
527 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
528 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
529 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
530 final ActivityStack stack = stacks.get(stackNdx);
531 if (stack.mResumedActivity != null &&
532 stack.mActivityContainer.mParentActivity == parent) {
533 stack.startPausingLocked(userLeaving, uiSleeping);
534 }
535 }
536 }
537 }
538
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700539 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700540 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700541 WaitResult w = mWaitingActivityVisible.get(i);
542 w.timeout = false;
543 if (r != null) {
544 w.who = new ComponentName(r.info.packageName, r.info.name);
545 }
546 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
547 w.thisTime = w.totalTime;
548 }
549 mService.notifyAll();
550 dismissKeyguard();
551 }
552
553 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
554 long thisTime, long totalTime) {
555 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700556 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700557 w.timeout = timeout;
558 if (r != null) {
559 w.who = new ComponentName(r.info.packageName, r.info.name);
560 }
561 w.thisTime = thisTime;
562 w.totalTime = totalTime;
563 }
564 mService.notifyAll();
565 }
566
Craig Mautner29219d92013-04-16 20:19:12 -0700567 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700568 final ActivityStack focusedStack = getFocusedStack();
569 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
570 if (r != null) {
571 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700572 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700573
Craig Mautner4a1cb222013-12-04 16:14:06 -0800574 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800575 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800576 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
577 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700578 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700579 r = stack.topRunningActivityLocked(null);
580 if (r != null) {
581 return r;
582 }
583 }
584 }
585 return null;
586 }
587
Craig Mautner20e72272013-04-01 13:45:53 -0700588 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
589 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
590 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700591
592 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800593 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
594 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800595 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800596 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800597 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800598 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
599 final ActivityStack stack = stacks.get(stackNdx);
600 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
601 runningTaskLists.add(stackTaskList);
602 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
603 if (r == null && isFrontStack(stack)) {
604 r = ar;
605 }
Craig Mautner20e72272013-04-01 13:45:53 -0700606 }
607 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700608
609 // The lists are already sorted from most recent to oldest. Just pull the most recent off
610 // each list and add it to list. Stop when all lists are empty or maxNum reached.
611 while (maxNum > 0) {
612 long mostRecentActiveTime = Long.MIN_VALUE;
613 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800614 final int numTaskLists = runningTaskLists.size();
615 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
616 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700617 if (!stackTaskList.isEmpty()) {
618 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
619 if (lastActiveTime > mostRecentActiveTime) {
620 mostRecentActiveTime = lastActiveTime;
621 selectedStackList = stackTaskList;
622 }
623 }
624 }
625 if (selectedStackList != null) {
626 list.add(selectedStackList.remove(0));
627 --maxNum;
628 } else {
629 break;
630 }
631 }
632
Craig Mautner20e72272013-04-01 13:45:53 -0700633 return r;
634 }
635
Craig Mautner23ac33b2013-04-01 16:26:35 -0700636 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
637 String profileFile, ParcelFileDescriptor profileFd, int userId) {
638 // Collect information about the target of the Intent.
639 ActivityInfo aInfo;
640 try {
641 ResolveInfo rInfo =
642 AppGlobals.getPackageManager().resolveIntent(
643 intent, resolvedType,
644 PackageManager.MATCH_DEFAULT_ONLY
645 | ActivityManagerService.STOCK_PM_FLAGS, userId);
646 aInfo = rInfo != null ? rInfo.activityInfo : null;
647 } catch (RemoteException e) {
648 aInfo = null;
649 }
650
651 if (aInfo != null) {
652 // Store the found target back into the intent, because now that
653 // we have it we never want to do this again. For example, if the
654 // user navigates back to this point in the history, we should
655 // always restart the exact same activity.
656 intent.setComponent(new ComponentName(
657 aInfo.applicationInfo.packageName, aInfo.name));
658
659 // Don't debug things in the system process
660 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
661 if (!aInfo.processName.equals("system")) {
662 mService.setDebugApp(aInfo.processName, true, false);
663 }
664 }
665
666 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
667 if (!aInfo.processName.equals("system")) {
668 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
669 }
670 }
671
672 if (profileFile != null) {
673 if (!aInfo.processName.equals("system")) {
674 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
675 profileFile, profileFd,
676 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
677 }
678 }
679 }
680 return aInfo;
681 }
682
Craig Mautner2219a1b2013-03-25 09:44:30 -0700683 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700684 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700685 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800686 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700687 }
688
Craig Mautner23ac33b2013-04-01 16:26:35 -0700689 final int startActivityMayWait(IApplicationThread caller, int callingUid,
690 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
691 String resultWho, int requestCode, int startFlags, String profileFile,
692 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800693 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700694 // Refuse possible leaked file descriptors
695 if (intent != null && intent.hasFileDescriptors()) {
696 throw new IllegalArgumentException("File descriptors passed in Intent");
697 }
698 boolean componentSpecified = intent.getComponent() != null;
699
700 // Don't modify the client's object!
701 intent = new Intent(intent);
702
703 // Collect information about the target of the Intent.
704 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
705 profileFile, profileFd, userId);
706
Craig Mautnere0a38842013-12-16 16:14:02 -0800707 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700708 synchronized (mService) {
709 int callingPid;
710 if (callingUid >= 0) {
711 callingPid = -1;
712 } else if (caller == null) {
713 callingPid = Binder.getCallingPid();
714 callingUid = Binder.getCallingUid();
715 } else {
716 callingPid = callingUid = -1;
717 }
718
Craig Mautnere0a38842013-12-16 16:14:02 -0800719 final ActivityStack stack;
720 if (container == null || container.mStack.isOnHomeDisplay()) {
721 stack = getFocusedStack();
722 } else {
723 stack = container.mStack;
724 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700725 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700726 && mService.mConfiguration.diff(config) != 0;
727 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700728 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700729
730 final long origId = Binder.clearCallingIdentity();
731
732 if (aInfo != null &&
733 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
734 // This may be a heavy-weight process! Check to see if we already
735 // have another, different heavy-weight process running.
736 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
737 if (mService.mHeavyWeightProcess != null &&
738 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
739 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700740 int realCallingUid = callingUid;
741 if (caller != null) {
742 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
743 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700744 realCallingUid = callerApp.info.uid;
745 } else {
746 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700747 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700748 + intent.toString());
749 ActivityOptions.abort(options);
750 return ActivityManager.START_PERMISSION_DENIED;
751 }
752 }
753
754 IIntentSender target = mService.getIntentSenderLocked(
755 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
756 realCallingUid, userId, null, null, 0, new Intent[] { intent },
757 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
758 | PendingIntent.FLAG_ONE_SHOT, null);
759
760 Intent newIntent = new Intent();
761 if (requestCode >= 0) {
762 // Caller is requesting a result.
763 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
764 }
765 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
766 new IntentSender(target));
767 if (mService.mHeavyWeightProcess.activities.size() > 0) {
768 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
769 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
770 hist.packageName);
771 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
772 hist.task.taskId);
773 }
774 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
775 aInfo.packageName);
776 newIntent.setFlags(intent.getFlags());
777 newIntent.setClassName("android",
778 HeavyWeightSwitcherActivity.class.getName());
779 intent = newIntent;
780 resolvedType = null;
781 caller = null;
782 callingUid = Binder.getCallingUid();
783 callingPid = Binder.getCallingPid();
784 componentSpecified = true;
785 try {
786 ResolveInfo rInfo =
787 AppGlobals.getPackageManager().resolveIntent(
788 intent, null,
789 PackageManager.MATCH_DEFAULT_ONLY
790 | ActivityManagerService.STOCK_PM_FLAGS, userId);
791 aInfo = rInfo != null ? rInfo.activityInfo : null;
792 aInfo = mService.getActivityInfoForUser(aInfo, userId);
793 } catch (RemoteException e) {
794 aInfo = null;
795 }
796 }
797 }
798 }
799
Craig Mautnere0a38842013-12-16 16:14:02 -0800800 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
801 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
802 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700803
Craig Mautnerde4ef022013-04-07 19:01:33 -0700804 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700805 // If the caller also wants to switch to a new configuration,
806 // do so now. This allows a clean switch, as we are waiting
807 // for the current activity to pause (so we will not destroy
808 // it), and have not yet started the next activity.
809 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
810 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700811 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700812 if (DEBUG_CONFIGURATION) Slog.v(TAG,
813 "Updating to new configuration after starting activity.");
814 mService.updateConfigurationLocked(config, null, false, false);
815 }
816
817 Binder.restoreCallingIdentity(origId);
818
819 if (outResult != null) {
820 outResult.result = res;
821 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700822 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700823 do {
824 try {
825 mService.wait();
826 } catch (InterruptedException e) {
827 }
828 } while (!outResult.timeout && outResult.who == null);
829 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700830 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700831 if (r.nowVisible) {
832 outResult.timeout = false;
833 outResult.who = new ComponentName(r.info.packageName, r.info.name);
834 outResult.totalTime = 0;
835 outResult.thisTime = 0;
836 } else {
837 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700838 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700839 do {
840 try {
841 mService.wait();
842 } catch (InterruptedException e) {
843 }
844 } while (!outResult.timeout && outResult.who == null);
845 }
846 }
847 }
848
849 return res;
850 }
851 }
852
853 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
854 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
855 Bundle options, int userId) {
856 if (intents == null) {
857 throw new NullPointerException("intents is null");
858 }
859 if (resolvedTypes == null) {
860 throw new NullPointerException("resolvedTypes is null");
861 }
862 if (intents.length != resolvedTypes.length) {
863 throw new IllegalArgumentException("intents are length different than resolvedTypes");
864 }
865
Craig Mautner23ac33b2013-04-01 16:26:35 -0700866
867 int callingPid;
868 if (callingUid >= 0) {
869 callingPid = -1;
870 } else if (caller == null) {
871 callingPid = Binder.getCallingPid();
872 callingUid = Binder.getCallingUid();
873 } else {
874 callingPid = callingUid = -1;
875 }
876 final long origId = Binder.clearCallingIdentity();
877 try {
878 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700879 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700880 for (int i=0; i<intents.length; i++) {
881 Intent intent = intents[i];
882 if (intent == null) {
883 continue;
884 }
885
886 // Refuse possible leaked file descriptors
887 if (intent != null && intent.hasFileDescriptors()) {
888 throw new IllegalArgumentException("File descriptors passed in Intent");
889 }
890
891 boolean componentSpecified = intent.getComponent() != null;
892
893 // Don't modify the client's object!
894 intent = new Intent(intent);
895
896 // Collect information about the target of the Intent.
897 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
898 0, null, null, userId);
899 // TODO: New, check if this is correct
900 aInfo = mService.getActivityInfoForUser(aInfo, userId);
901
902 if (aInfo != null &&
903 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
904 != 0) {
905 throw new IllegalArgumentException(
906 "FLAG_CANT_SAVE_STATE not supported here");
907 }
908
909 Bundle theseOptions;
910 if (options != null && i == intents.length-1) {
911 theseOptions = options;
912 } else {
913 theseOptions = null;
914 }
Craig Mautner6170f732013-04-02 13:05:23 -0700915 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700916 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800917 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700918 if (res < 0) {
919 return res;
920 }
921
922 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
923 }
924 }
925 } finally {
926 Binder.restoreCallingIdentity(origId);
927 }
928
929 return ActivityManager.START_SUCCESS;
930 }
931
Craig Mautner2420ead2013-04-01 17:13:20 -0700932 final boolean realStartActivityLocked(ActivityRecord r,
933 ProcessRecord app, boolean andResume, boolean checkConfig)
934 throws RemoteException {
935
936 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700937 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700938 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700939
940 // schedule launch ticks to collect information about slow apps.
941 r.startLaunchTickingLocked();
942
943 // Have the window manager re-evaluate the orientation of
944 // the screen based on the new activity order. Note that
945 // as a result of this, it can call back into the activity
946 // manager with a new orientation. We don't care about that,
947 // because the activity is not currently running so we are
948 // just restarting it anyway.
949 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700950 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700951 mService.mConfiguration,
952 r.mayFreezeScreenLocked(app) ? r.appToken : null);
953 mService.updateConfigurationLocked(config, r, false, false);
954 }
955
956 r.app = app;
957 app.waitingToKill = null;
958 r.launchCount++;
959 r.lastLaunchTime = SystemClock.uptimeMillis();
960
961 if (localLOGV) Slog.v(TAG, "Launching: " + r);
962
963 int idx = app.activities.indexOf(r);
964 if (idx < 0) {
965 app.activities.add(r);
966 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700967 mService.updateLruProcessLocked(app, true, null);
968 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700969
970 final ActivityStack stack = r.task.stack;
971 try {
972 if (app.thread == null) {
973 throw new RemoteException();
974 }
975 List<ResultInfo> results = null;
976 List<Intent> newIntents = null;
977 if (andResume) {
978 results = r.results;
979 newIntents = r.newIntents;
980 }
981 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
982 + " icicle=" + r.icicle
983 + " with results=" + results + " newIntents=" + newIntents
984 + " andResume=" + andResume);
985 if (andResume) {
986 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
987 r.userId, System.identityHashCode(r),
988 r.task.taskId, r.shortComponentName);
989 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700990 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700991 // Home process is the root process of the task.
992 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700993 }
994 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
995 r.sleeping = false;
996 r.forceNewConfig = false;
997 mService.showAskCompatModeDialogLocked(r);
998 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
999 String profileFile = null;
1000 ParcelFileDescriptor profileFd = null;
1001 boolean profileAutoStop = false;
1002 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1003 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1004 mService.mProfileProc = app;
1005 profileFile = mService.mProfileFile;
1006 profileFd = mService.mProfileFd;
1007 profileAutoStop = mService.mAutoStopProfiler;
1008 }
1009 }
1010 app.hasShownUi = true;
1011 app.pendingUiClean = true;
1012 if (profileFd != null) {
1013 try {
1014 profileFd = profileFd.dup();
1015 } catch (IOException e) {
1016 if (profileFd != null) {
1017 try {
1018 profileFd.close();
1019 } catch (IOException o) {
1020 }
1021 profileFd = null;
1022 }
1023 }
1024 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001025 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001026 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1027 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001028 new Configuration(mService.mConfiguration), r.compat,
1029 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001030 mService.isNextTransitionForward(), profileFile, profileFd,
1031 profileAutoStop);
1032
1033 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1034 // This may be a heavy-weight process! Note that the package
1035 // manager will ensure that only activity can run in the main
1036 // process of the .apk, which is the only thing that will be
1037 // considered heavy-weight.
1038 if (app.processName.equals(app.info.packageName)) {
1039 if (mService.mHeavyWeightProcess != null
1040 && mService.mHeavyWeightProcess != app) {
1041 Slog.w(TAG, "Starting new heavy weight process " + app
1042 + " when already running "
1043 + mService.mHeavyWeightProcess);
1044 }
1045 mService.mHeavyWeightProcess = app;
1046 Message msg = mService.mHandler.obtainMessage(
1047 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1048 msg.obj = r;
1049 mService.mHandler.sendMessage(msg);
1050 }
1051 }
1052
1053 } catch (RemoteException e) {
1054 if (r.launchFailed) {
1055 // This is the second time we failed -- finish activity
1056 // and give up.
1057 Slog.e(TAG, "Second failure launching "
1058 + r.intent.getComponent().flattenToShortString()
1059 + ", giving up", e);
1060 mService.appDiedLocked(app, app.pid, app.thread);
1061 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1062 "2nd-crash", false);
1063 return false;
1064 }
1065
1066 // This is the first time we failed -- restart process and
1067 // retry.
1068 app.activities.remove(r);
1069 throw e;
1070 }
1071
1072 r.launchFailed = false;
1073 if (stack.updateLRUListLocked(r)) {
1074 Slog.w(TAG, "Activity " + r
1075 + " being launched, but already in LRU list");
1076 }
1077
1078 if (andResume) {
1079 // As part of the process of launching, ActivityThread also performs
1080 // a resume.
1081 stack.minimalResumeActivityLocked(r);
1082 } else {
1083 // This activity is not starting in the resumed state... which
1084 // should look like we asked it to pause+stop (but remain visible),
1085 // and it has done so and reported back the current icicle and
1086 // other state.
1087 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1088 + " (starting in stopped state)");
1089 r.state = ActivityState.STOPPED;
1090 r.stopped = true;
1091 }
1092
1093 // Launch the new version setup screen if needed. We do this -after-
1094 // launching the initial activity (that is, home), so that it can have
1095 // a chance to initialize itself while in the background, making the
1096 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001097 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001098 mService.startSetupActivityLocked();
1099 }
1100
1101 return true;
1102 }
1103
Craig Mautnere79d42682013-04-01 19:01:53 -07001104 void startSpecificActivityLocked(ActivityRecord r,
1105 boolean andResume, boolean checkConfig) {
1106 // Is this activity's application already running?
1107 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001108 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001109
1110 r.task.stack.setLaunchTime(r);
1111
1112 if (app != null && app.thread != null) {
1113 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001114 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1115 || !"android".equals(r.info.packageName)) {
1116 // Don't add this if it is a platform component that is marked
1117 // to run in multiple processes, because this is actually
1118 // part of the framework so doesn't make sense to track as a
1119 // separate apk in the process.
1120 app.addPackage(r.info.packageName, mService.mProcessStats);
1121 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001122 realStartActivityLocked(r, app, andResume, checkConfig);
1123 return;
1124 } catch (RemoteException e) {
1125 Slog.w(TAG, "Exception when starting activity "
1126 + r.intent.getComponent().flattenToShortString(), e);
1127 }
1128
1129 // If a dead object exception was thrown -- fall through to
1130 // restart the application.
1131 }
1132
1133 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001134 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001135 }
1136
Craig Mautner6170f732013-04-02 13:05:23 -07001137 final int startActivityLocked(IApplicationThread caller,
1138 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1139 String resultWho, int requestCode,
1140 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001141 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001142 int err = ActivityManager.START_SUCCESS;
1143
1144 ProcessRecord callerApp = null;
1145 if (caller != null) {
1146 callerApp = mService.getRecordForAppLocked(caller);
1147 if (callerApp != null) {
1148 callingPid = callerApp.pid;
1149 callingUid = callerApp.info.uid;
1150 } else {
1151 Slog.w(TAG, "Unable to find app for caller " + caller
1152 + " (pid=" + callingPid + ") when starting: "
1153 + intent.toString());
1154 err = ActivityManager.START_PERMISSION_DENIED;
1155 }
1156 }
1157
1158 if (err == ActivityManager.START_SUCCESS) {
1159 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1160 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001161 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1162 + " on display " + (container == null ? (mFocusedStack == null ?
1163 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1164 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1165 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001166 }
1167
1168 ActivityRecord sourceRecord = null;
1169 ActivityRecord resultRecord = null;
1170 if (resultTo != null) {
1171 sourceRecord = isInAnyStackLocked(resultTo);
1172 if (DEBUG_RESULTS) Slog.v(
1173 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1174 if (sourceRecord != null) {
1175 if (requestCode >= 0 && !sourceRecord.finishing) {
1176 resultRecord = sourceRecord;
1177 }
1178 }
1179 }
1180 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1181
1182 int launchFlags = intent.getFlags();
1183
1184 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1185 && sourceRecord != null) {
1186 // Transfer the result target from the source activity to the new
1187 // one being started, including any failures.
1188 if (requestCode >= 0) {
1189 ActivityOptions.abort(options);
1190 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1191 }
1192 resultRecord = sourceRecord.resultTo;
1193 resultWho = sourceRecord.resultWho;
1194 requestCode = sourceRecord.requestCode;
1195 sourceRecord.resultTo = null;
1196 if (resultRecord != null) {
1197 resultRecord.removeResultsLocked(
1198 sourceRecord, resultWho, requestCode);
1199 }
Dianne Hackbornd4981012014-03-14 16:27:40 +00001200 if (sourceRecord.launchedFromUid == callingUid) {
1201 // The new activity is being launched from the same uid as the previous
1202 // activity in the flow, and asking to forward its result back to the
1203 // previous. In this case the activity is serving as a trampoline between
1204 // the two, so we also want to update its launchedFromPackage to be the
1205 // same as the previous activity. Note that this is safe, since we know
1206 // these two packages come from the same uid; the caller could just as
1207 // well have supplied that same package name itself. This specifially
1208 // deals with the case of an intent picker/chooser being launched in the app
1209 // flow to redirect to an activity picked by the user, where we want the final
1210 // activity to consider it to have been launched by the previous app activity.
1211 callingPackage = sourceRecord.launchedFromPackage;
1212 }
Craig Mautner6170f732013-04-02 13:05:23 -07001213 }
1214
1215 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1216 // We couldn't find a class that can handle the given Intent.
1217 // That's the end of that!
1218 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1219 }
1220
1221 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1222 // We couldn't find the specific class specified in the Intent.
1223 // Also the end of the line.
1224 err = ActivityManager.START_CLASS_NOT_FOUND;
1225 }
1226
1227 if (err != ActivityManager.START_SUCCESS) {
1228 if (resultRecord != null) {
1229 resultStack.sendActivityResultLocked(-1,
1230 resultRecord, resultWho, requestCode,
1231 Activity.RESULT_CANCELED, null);
1232 }
1233 setDismissKeyguard(false);
1234 ActivityOptions.abort(options);
1235 return err;
1236 }
1237
1238 final int startAnyPerm = mService.checkPermission(
1239 START_ANY_ACTIVITY, callingPid, callingUid);
1240 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1241 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1242 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1243 if (resultRecord != null) {
1244 resultStack.sendActivityResultLocked(-1,
1245 resultRecord, resultWho, requestCode,
1246 Activity.RESULT_CANCELED, null);
1247 }
1248 setDismissKeyguard(false);
1249 String msg;
1250 if (!aInfo.exported) {
1251 msg = "Permission Denial: starting " + intent.toString()
1252 + " from " + callerApp + " (pid=" + callingPid
1253 + ", uid=" + callingUid + ")"
1254 + " not exported from uid " + aInfo.applicationInfo.uid;
1255 } else {
1256 msg = "Permission Denial: starting " + intent.toString()
1257 + " from " + callerApp + " (pid=" + callingPid
1258 + ", uid=" + callingUid + ")"
1259 + " requires " + aInfo.permission;
1260 }
1261 Slog.w(TAG, msg);
1262 throw new SecurityException(msg);
1263 }
1264
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001265 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001266 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001267
Craig Mautner6170f732013-04-02 13:05:23 -07001268 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001269 try {
1270 // The Intent we give to the watcher has the extra data
1271 // stripped off, since it can contain private information.
1272 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001273 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001274 aInfo.applicationInfo.packageName);
1275 } catch (RemoteException e) {
1276 mService.mController = null;
1277 }
Ben Gruver5e207332013-04-03 17:41:37 -07001278 }
Craig Mautner6170f732013-04-02 13:05:23 -07001279
Ben Gruver5e207332013-04-03 17:41:37 -07001280 if (abort) {
1281 if (resultRecord != null) {
1282 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001283 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001284 }
Ben Gruver5e207332013-04-03 17:41:37 -07001285 // We pretend to the caller that it was really started, but
1286 // they will just get a cancel result.
1287 setDismissKeyguard(false);
1288 ActivityOptions.abort(options);
1289 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001290 }
1291
1292 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001293 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1294 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001295 if (outActivity != null) {
1296 outActivity[0] = r;
1297 }
1298
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001299 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001300 if (stack.mResumedActivity == null
1301 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001302 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1303 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001304 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001305 mService.mPendingActivityLaunches.add(pal);
1306 setDismissKeyguard(false);
1307 ActivityOptions.abort(options);
1308 return ActivityManager.START_SWITCHES_CANCELED;
1309 }
1310 }
1311
1312 if (mService.mDidAppSwitch) {
1313 // This is the second allowed switch since we stopped switches,
1314 // so now just generally allow switches. Use case: user presses
1315 // home (switches disabled, switch to home, mDidAppSwitch now true);
1316 // user taps a home icon (coming from home so allowed, we hit here
1317 // and now allow anyone to switch again).
1318 mService.mAppSwitchesAllowedTime = 0;
1319 } else {
1320 mService.mDidAppSwitch = true;
1321 }
1322
1323 mService.doPendingActivityLaunchesLocked(false);
1324
Craig Mautner8849a5e2013-04-02 16:41:03 -07001325 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001326
1327 if (allPausedActivitiesComplete()) {
1328 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001329 // activity start, but we are not actually doing an activity
1330 // switch... just dismiss the keyguard now, because we
1331 // probably want to see whatever is behind it.
1332 dismissKeyguard();
1333 }
1334 return err;
1335 }
1336
Craig Mautnerac6f8432013-07-17 13:24:59 -07001337 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001338 final TaskRecord task = r.task;
1339 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001340 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001341 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001342 if (taskStack.isOnHomeDisplay()) {
1343 if (mFocusedStack != taskStack) {
1344 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1345 "focused stack to r=" + r + " task=" + task);
1346 mFocusedStack = taskStack;
1347 } else {
1348 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1349 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1350 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001351 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001352 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001353 }
1354
Craig Mautnere0a38842013-12-16 16:14:02 -08001355 final ActivityContainer container = r.mInitialActivityContainer;
1356 if (container != null) {
1357 // The first time put it on the desired stack, after this put on task stack.
1358 r.mInitialActivityContainer = null;
1359 return container.mStack;
1360 }
1361
Craig Mautner4a1cb222013-12-04 16:14:06 -08001362 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001363 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1364 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1365 return mFocusedStack;
1366 }
1367
Craig Mautnere0a38842013-12-16 16:14:02 -08001368 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1369 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1370 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1371 if (!stack.isHomeStack()) {
1372 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1373 "adjustStackFocus: Setting focused stack=" + stack);
1374 mFocusedStack = stack;
1375 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001376 }
1377 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001378
Craig Mautner4a1cb222013-12-04 16:14:06 -08001379 // Need to create an app stack for this user.
1380 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001381 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1382 " stackId=" + stackId);
1383 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001384 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001385 }
1386 return mHomeStack;
1387 }
1388
Craig Mautner29219d92013-04-16 20:19:12 -07001389 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001390 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001391 final TaskRecord task = r.task;
1392 boolean isHomeActivity = !r.isApplicationActivity();
1393 if (!isHomeActivity && task != null) {
1394 isHomeActivity = !task.isApplicationTask();
1395 }
1396 if (!isHomeActivity && task != null) {
1397 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1398 isHomeActivity = parent != null && parent.isHomeActivity();
1399 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001400 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001401 }
1402 }
1403
Craig Mautner8849a5e2013-04-02 16:41:03 -07001404 final int startActivityUncheckedLocked(ActivityRecord r,
1405 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1406 Bundle options) {
1407 final Intent intent = r.intent;
1408 final int callingUid = r.launchedFromUid;
1409
1410 int launchFlags = intent.getFlags();
1411
Craig Mautner8849a5e2013-04-02 16:41:03 -07001412 // We'll invoke onUserLeaving before onPause only if the launching
1413 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001414 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1415 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001416
1417 // If the caller has asked not to resume at this point, we make note
1418 // of this in the record so that we can skip it when trying to find
1419 // the top running activity.
1420 if (!doResume) {
1421 r.delayedResume = true;
1422 }
1423
1424 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1425
1426 // If the onlyIfNeeded flag is set, then we can do this if the activity
1427 // being launched is the same as the one making the call... or, as
1428 // a special case, if we do not know the caller then we count the
1429 // current top activity as the caller.
1430 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1431 ActivityRecord checkedCaller = sourceRecord;
1432 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001433 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001434 }
1435 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1436 // Caller is not the same as launcher, so always needed.
1437 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1438 }
1439 }
1440
1441 if (sourceRecord == null) {
1442 // This activity is not being started from another... in this
1443 // case we -always- start a new task.
1444 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001445 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1446 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001447 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1448 }
1449 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1450 // The original activity who is starting us is running as a single
1451 // instance... this new activity it is starting must go on its
1452 // own task.
1453 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1454 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1455 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1456 // The activity being started is a single instance... it always
1457 // gets launched into its own task.
1458 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1459 }
1460
Craig Mautner88629292013-11-10 20:39:05 -08001461 ActivityInfo newTaskInfo = null;
1462 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001463 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001464 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001465 if (sourceRecord.finishing) {
1466 // If the source is finishing, we can't further count it as our source. This
1467 // is because the task it is associated with may now be empty and on its way out,
1468 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001469 // the NEW_TASK flow and try to find a task for it. But save the task information
1470 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001471 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1472 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1473 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1474 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001475 newTaskInfo = sourceRecord.info;
1476 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001477 }
1478 sourceRecord = null;
1479 sourceStack = null;
1480 } else {
1481 sourceStack = sourceRecord.task.stack;
1482 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001483 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001484 sourceStack = null;
1485 }
1486
Craig Mautner8849a5e2013-04-02 16:41:03 -07001487 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1488 // For whatever reason this activity is being launched into a new
1489 // task... yet the caller has requested a result back. Well, that
1490 // is pretty messed up, so instead immediately send back a cancel
1491 // and let the new task continue launched as normal without a
1492 // dependency on its originator.
1493 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1494 r.resultTo.task.stack.sendActivityResultLocked(-1,
1495 r.resultTo, r.resultWho, r.requestCode,
1496 Activity.RESULT_CANCELED, null);
1497 r.resultTo = null;
1498 }
1499
1500 boolean addingToTask = false;
1501 boolean movedHome = false;
1502 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001503 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001504 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1505 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1506 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1507 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1508 // If bring to front is requested, and no result is requested, and
1509 // we can find a task that was started with this same
1510 // component, then instead of launching bring that one to the front.
1511 if (r.resultTo == null) {
1512 // See if there is a task to bring to the front. If this is
1513 // a SINGLE_INSTANCE activity, there can be one and only one
1514 // instance of it in the history, and it is always in its own
1515 // unique task, so we do a special search.
1516 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001517 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001518 : findActivityLocked(intent, r.info);
1519 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001520 if (r.task == null) {
1521 r.task = intentActivity.task;
1522 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001523 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001524 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001525 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1526 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001527 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001528 if (intentActivity.task.intent == null) {
1529 // This task was started because of movement of
1530 // the activity based on affinity... now that we
1531 // are actually launching it, we can assign the
1532 // base intent.
1533 intentActivity.task.setIntent(intent, r.info);
1534 }
1535 // If the target task is not in the front, then we need
1536 // to bring it to the front... except... well, with
1537 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1538 // to have the same behavior as if a new instance was
1539 // being started, which means not bringing it to the front
1540 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001541 final ActivityStack lastStack = getLastStack();
1542 ActivityRecord curTop = lastStack == null?
1543 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001544 if (curTop != null && (curTop.task != intentActivity.task ||
1545 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001546 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001547 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1548 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001549 // We really do want to push this one into the
1550 // user's face, right now.
1551 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001552 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001553 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001554 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1555 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001556 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001557 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001558 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001559 options = null;
1560 }
1561 }
1562 // If the caller has requested that the target task be
1563 // reset, then do so.
1564 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1565 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1566 }
1567 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1568 // We don't need to start a new activity, and
1569 // the client said not to do anything if that
1570 // is the case, so this is it! And for paranoia, make
1571 // sure we have correctly resumed the top activity.
1572 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001573 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001574 } else {
1575 ActivityOptions.abort(options);
1576 }
1577 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1578 }
1579 if ((launchFlags &
1580 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1581 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1582 // The caller has requested to completely replace any
1583 // existing task with its new activity. Well that should
1584 // not be too hard...
1585 reuseTask = intentActivity.task;
1586 reuseTask.performClearTaskLocked();
1587 reuseTask.setIntent(r.intent, r.info);
1588 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1589 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1590 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1591 // In this situation we want to remove all activities
1592 // from the task up to the one being started. In most
1593 // cases this means we are resetting the task to its
1594 // initial state.
1595 ActivityRecord top =
1596 intentActivity.task.performClearTaskLocked(r, launchFlags);
1597 if (top != null) {
1598 if (top.frontOfTask) {
1599 // Activity aliases may mean we use different
1600 // intents for the top activity, so make sure
1601 // the task now has the identity of the new
1602 // intent.
1603 top.task.setIntent(r.intent, r.info);
1604 }
1605 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1606 r, top.task);
1607 top.deliverNewIntentLocked(callingUid, r.intent);
1608 } else {
1609 // A special case: we need to
1610 // start the activity because it is not currently
1611 // running, and the caller has asked to clear the
1612 // current task to have this activity at the top.
1613 addingToTask = true;
1614 // Now pretend like this activity is being started
1615 // by the top of its task, so it is put in the
1616 // right place.
1617 sourceRecord = intentActivity;
1618 }
1619 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1620 // In this case the top activity on the task is the
1621 // same as the one being launched, so we take that
1622 // as a request to bring the task to the foreground.
1623 // If the top activity in the task is the root
1624 // activity, deliver this new intent to it if it
1625 // desires.
1626 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1627 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1628 && intentActivity.realActivity.equals(r.realActivity)) {
1629 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1630 intentActivity.task);
1631 if (intentActivity.frontOfTask) {
1632 intentActivity.task.setIntent(r.intent, r.info);
1633 }
1634 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1635 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1636 // In this case we are launching the root activity
1637 // of the task, but with a different intent. We
1638 // should start a new instance on top.
1639 addingToTask = true;
1640 sourceRecord = intentActivity;
1641 }
1642 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1643 // In this case an activity is being launched in to an
1644 // existing task, without resetting that task. This
1645 // is typically the situation of launching an activity
1646 // from a notification or shortcut. We want to place
1647 // the new activity on top of the current task.
1648 addingToTask = true;
1649 sourceRecord = intentActivity;
1650 } else if (!intentActivity.task.rootWasReset) {
1651 // In this case we are launching in to an existing task
1652 // that has not yet been started from its front door.
1653 // The current task has been brought to the front.
1654 // Ideally, we'd probably like to place this new task
1655 // at the bottom of its stack, but that's a little hard
1656 // to do with the current organization of the code so
1657 // for now we'll just drop it.
1658 intentActivity.task.setIntent(r.intent, r.info);
1659 }
1660 if (!addingToTask && reuseTask == null) {
1661 // We didn't do anything... but it was needed (a.k.a., client
1662 // don't use that intent!) And for paranoia, make
1663 // sure we have correctly resumed the top activity.
1664 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001665 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001666 } else {
1667 ActivityOptions.abort(options);
1668 }
1669 return ActivityManager.START_TASK_TO_FRONT;
1670 }
1671 }
1672 }
1673 }
1674
1675 //String uri = r.intent.toURI();
1676 //Intent intent2 = new Intent(uri);
1677 //Slog.i(TAG, "Given intent: " + r.intent);
1678 //Slog.i(TAG, "URI is: " + uri);
1679 //Slog.i(TAG, "To intent: " + intent2);
1680
1681 if (r.packageName != null) {
1682 // If the activity being launched is the same as the one currently
1683 // at the top, then we need to check if it should only be launched
1684 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001685 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001686 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001687 if (top != null && r.resultTo == null) {
1688 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1689 if (top.app != null && top.app.thread != null) {
1690 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1691 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1692 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1693 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1694 top.task);
1695 // For paranoia, make sure we have correctly
1696 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001697 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001698 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001699 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001700 }
1701 ActivityOptions.abort(options);
1702 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1703 // We don't need to start a new activity, and
1704 // the client said not to do anything if that
1705 // is the case, so this is it!
1706 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1707 }
1708 top.deliverNewIntentLocked(callingUid, r.intent);
1709 return ActivityManager.START_DELIVERED_TO_TOP;
1710 }
1711 }
1712 }
1713 }
1714
1715 } else {
1716 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001717 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1718 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001719 }
1720 ActivityOptions.abort(options);
1721 return ActivityManager.START_CLASS_NOT_FOUND;
1722 }
1723
1724 boolean newTask = false;
1725 boolean keepCurTransition = false;
1726
1727 // Should this be considered a new task?
1728 if (r.resultTo == null && !addingToTask
1729 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001730 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001731 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001732 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001733 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1734 newTaskInfo != null ? newTaskInfo : r.info,
1735 newTaskIntent != null ? newTaskIntent : intent,
1736 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001737 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1738 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001739 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001740 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001741 }
1742 newTask = true;
1743 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001744 if ((launchFlags &
1745 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1746 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1747 // Caller wants to appear on home activity, so before starting
1748 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001749 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001750 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001751 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001752 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001753 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001754 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001755 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001756 if (!addingToTask &&
1757 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1758 // In this case, we are adding the activity to an existing
1759 // task, but the caller has asked to clear that task if the
1760 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001761 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001762 keepCurTransition = true;
1763 if (top != null) {
1764 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1765 top.deliverNewIntentLocked(callingUid, r.intent);
1766 // For paranoia, make sure we have correctly
1767 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001768 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001769 if (doResume) {
1770 targetStack.resumeTopActivityLocked(null);
1771 }
1772 ActivityOptions.abort(options);
1773 return ActivityManager.START_DELIVERED_TO_TOP;
1774 }
1775 } else if (!addingToTask &&
1776 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1777 // In this case, we are launching an activity in our own task
1778 // that may already be running somewhere in the history, and
1779 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001780 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001781 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001782 final TaskRecord task = top.task;
1783 task.moveActivityToFrontLocked(top);
1784 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001785 top.updateOptionsLocked(options);
1786 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001787 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001788 if (doResume) {
1789 targetStack.resumeTopActivityLocked(null);
1790 }
1791 return ActivityManager.START_DELIVERED_TO_TOP;
1792 }
1793 }
1794 // An existing activity is starting this new activity, so we want
1795 // to keep the new one in the same task as the one that is starting
1796 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001797 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001798 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001799 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001800
1801 } else {
1802 // This not being started from an existing activity, and not part
1803 // of a new task... just put it in the top task, though these days
1804 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001805 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001806 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001807 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001808 r.setTask(prev != null ? prev.task
1809 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1810 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001811 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1812 + " in new guessed " + r.task);
1813 }
1814
1815 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1816 intent, r.getUriPermissionsLocked());
1817
1818 if (newTask) {
1819 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1820 }
1821 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001822 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001823 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001824 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001825 return ActivityManager.START_SUCCESS;
1826 }
1827
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001828 void acquireLaunchWakelock() {
1829 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1830 throw new IllegalStateException("Calling must be system uid");
1831 }
1832 mLaunchingActivity.acquire();
1833 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1834 // To be safe, don't allow the wake lock to be held for too long.
1835 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1836 }
1837 }
1838
Craig Mautnerf3333272013-04-22 10:55:53 -07001839 // Checked.
1840 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1841 Configuration config) {
1842 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1843
Craig Mautnerf3333272013-04-22 10:55:53 -07001844 ArrayList<ActivityRecord> stops = null;
1845 ArrayList<ActivityRecord> finishes = null;
1846 ArrayList<UserStartedState> startingUsers = null;
1847 int NS = 0;
1848 int NF = 0;
1849 IApplicationThread sendThumbnail = null;
1850 boolean booting = false;
1851 boolean enableScreen = false;
1852 boolean activityRemoved = false;
1853
1854 ActivityRecord r = ActivityRecord.forToken(token);
1855 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001856 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1857 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001858 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1859 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001860 if (fromTimeout) {
1861 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001862 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001863
1864 // This is a hack to semi-deal with a race condition
1865 // in the client where it can be constructed with a
1866 // newer configuration from when we asked it to launch.
1867 // We'll update with whatever configuration it now says
1868 // it used to launch.
1869 if (config != null) {
1870 r.configuration = config;
1871 }
1872
1873 // We are now idle. If someone is waiting for a thumbnail from
1874 // us, we can now deliver.
1875 r.idle = true;
1876
1877 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1878 sendThumbnail = r.app.thread;
1879 r.thumbnailNeeded = false;
1880 }
1881
1882 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1883 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1884 mService.mBooted = true;
1885 enableScreen = true;
1886 }
1887 }
1888
1889 if (allResumedActivitiesIdle()) {
1890 if (r != null) {
1891 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001892 }
1893
1894 if (mLaunchingActivity.isHeld()) {
1895 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1896 if (VALIDATE_WAKE_LOCK_CALLER &&
1897 Binder.getCallingUid() != Process.myUid()) {
1898 throw new IllegalStateException("Calling must be system uid");
1899 }
1900 mLaunchingActivity.release();
1901 }
1902 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001903 }
1904
1905 // Atomically retrieve all of the other things to do.
1906 stops = processStoppingActivitiesLocked(true);
1907 NS = stops != null ? stops.size() : 0;
1908 if ((NF=mFinishingActivities.size()) > 0) {
1909 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1910 mFinishingActivities.clear();
1911 }
1912
1913 final ArrayList<ActivityRecord> thumbnails;
1914 final int NT = mCancelledThumbnails.size();
1915 if (NT > 0) {
1916 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1917 mCancelledThumbnails.clear();
1918 } else {
1919 thumbnails = null;
1920 }
1921
1922 if (isFrontStack(mHomeStack)) {
1923 booting = mService.mBooting;
1924 mService.mBooting = false;
1925 }
1926
1927 if (mStartingUsers.size() > 0) {
1928 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1929 mStartingUsers.clear();
1930 }
1931
1932 // Perform the following actions from unsynchronized state.
1933 final IApplicationThread thumbnailThread = sendThumbnail;
1934 mHandler.post(new Runnable() {
1935 @Override
1936 public void run() {
1937 if (thumbnailThread != null) {
1938 try {
1939 thumbnailThread.requestThumbnail(token);
1940 } catch (Exception e) {
1941 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1942 mService.sendPendingThumbnail(null, token, null, null, true);
1943 }
1944 }
1945
1946 // Report back to any thumbnail receivers.
1947 for (int i = 0; i < NT; i++) {
1948 ActivityRecord r = thumbnails.get(i);
1949 mService.sendPendingThumbnail(r, null, null, null, true);
1950 }
1951 }
1952 });
1953
1954 // Stop any activities that are scheduled to do so but have been
1955 // waiting for the next one to start.
1956 for (int i = 0; i < NS; i++) {
1957 r = stops.get(i);
1958 final ActivityStack stack = r.task.stack;
1959 if (r.finishing) {
1960 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1961 } else {
1962 stack.stopActivityLocked(r);
1963 }
1964 }
1965
1966 // Finish any activities that are scheduled to do so but have been
1967 // waiting for the next one to start.
1968 for (int i = 0; i < NF; i++) {
1969 r = finishes.get(i);
1970 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1971 }
1972
1973 if (booting) {
1974 mService.finishBooting();
1975 } else if (startingUsers != null) {
1976 for (int i = 0; i < startingUsers.size(); i++) {
1977 mService.finishUserSwitch(startingUsers.get(i));
1978 }
1979 }
1980
1981 mService.trimApplications();
1982 //dump();
1983 //mWindowManager.dump();
1984
1985 if (enableScreen) {
1986 mService.enableScreenAfterBoot();
1987 }
1988
1989 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001990 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001991 }
1992
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001993 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001994 }
1995
Craig Mautner8e569572013-10-11 17:36:59 -07001996 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001997 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001998 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1999 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002000 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2001 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2002 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002003 }
Craig Mautner19091252013-10-05 00:03:53 -07002004 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002005 }
2006
2007 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002008 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2009 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002010 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2011 stacks.get(stackNdx).closeSystemDialogsLocked();
2012 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002013 }
2014 }
2015
Craig Mautner93529a42013-10-04 15:03:13 -07002016 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002017 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002018 }
2019
Craig Mautner8d341ef2013-03-26 09:03:27 -07002020 /**
2021 * @return true if some activity was finished (or would have finished if doit were true).
2022 */
2023 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2024 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002025 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2026 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002027 final int numStacks = stacks.size();
2028 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2029 final ActivityStack stack = stacks.get(stackNdx);
2030 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2031 didSomething = true;
2032 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002033 }
2034 }
2035 return didSomething;
2036 }
2037
Dianne Hackborna413dc02013-07-12 12:02:55 -07002038 void updatePreviousProcessLocked(ActivityRecord r) {
2039 // Now that this process has stopped, we may want to consider
2040 // it to be the previous app to try to keep around in case
2041 // the user wants to return to it.
2042
2043 // First, found out what is currently the foreground app, so that
2044 // we don't blow away the previous app if this activity is being
2045 // hosted by the process that is actually still the foreground.
2046 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002047 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2048 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002049 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2050 final ActivityStack stack = stacks.get(stackNdx);
2051 if (isFrontStack(stack)) {
2052 if (stack.mResumedActivity != null) {
2053 fgApp = stack.mResumedActivity.app;
2054 } else if (stack.mPausingActivity != null) {
2055 fgApp = stack.mPausingActivity.app;
2056 }
2057 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002058 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002059 }
2060 }
2061
2062 // Now set this one as the previous process, only if that really
2063 // makes sense to.
2064 if (r.app != null && fgApp != null && r.app != fgApp
2065 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002066 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002067 mService.mPreviousProcess = r.app;
2068 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2069 }
2070 }
2071
Craig Mautner05d29032013-05-03 13:40:13 -07002072 boolean resumeTopActivitiesLocked() {
2073 return resumeTopActivitiesLocked(null, null, null);
2074 }
2075
2076 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2077 Bundle targetOptions) {
2078 if (targetStack == null) {
2079 targetStack = getFocusedStack();
2080 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002081 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002082 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002083 if (isFrontStack(targetStack)) {
2084 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2085 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002086 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2087 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002088 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2089 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002090 if (stack == targetStack) {
2091 // Already started above.
2092 continue;
2093 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002094 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002095 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002096 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002097 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002098 }
Craig Mautner05d29032013-05-03 13:40:13 -07002099 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002100 }
2101
2102 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002103 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2104 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002105 final int numStacks = stacks.size();
2106 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2107 final ActivityStack stack = stacks.get(stackNdx);
2108 stack.finishTopRunningActivityLocked(app);
2109 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002110 }
2111 }
2112
Craig Mautner8d341ef2013-03-26 09:03:27 -07002113 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002114 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2115 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002116 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2117 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2118 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2119 + stacks.get(stackNdx));
2120 return;
2121 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002122 }
2123 }
2124 }
2125
Craig Mautner967212c2013-04-13 21:10:58 -07002126 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002127 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2128 if (weakReference != null) {
2129 ActivityContainer activityContainer = weakReference.get();
2130 if (activityContainer != null) {
2131 return activityContainer.mStack;
2132 } else {
2133 mActivityContainers.remove(stackId);
2134 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002135 }
2136 return null;
2137 }
2138
Craig Mautner967212c2013-04-13 21:10:58 -07002139 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002140 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002141 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2142 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002143 }
2144 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002145 }
2146
Craig Mautner4a1cb222013-12-04 16:14:06 -08002147 IBinder getHomeActivityToken() {
2148 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2149 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2150 final TaskRecord task = tasks.get(taskNdx);
2151 if (task.isHomeTask()) {
2152 final ArrayList<ActivityRecord> activities = task.mActivities;
2153 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2154 final ActivityRecord r = activities.get(activityNdx);
2155 if (r.isHomeActivity()) {
2156 return r.appToken;
2157 }
2158 }
2159 }
2160 }
2161 return null;
2162 }
2163
2164 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2165 IActivityContainerCallback callback) {
2166 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2167 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002168 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002169 if (parentActivity != null) {
2170 parentActivity.mChildContainers.add(activityContainer.mStack);
2171 }
2172 return activityContainer;
2173 }
2174
2175 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2176 IActivityContainerCallback callback) {
2177 return createActivityContainer(parentActivity, getNextStackId(), callback);
2178 }
2179
Craig Mautner34b73df2014-01-12 21:11:08 -08002180 void removeChildActivityContainers(ActivityRecord parentActivity) {
2181 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2182 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2183 if (container == null) {
2184 mActivityContainers.removeAt(ndx);
2185 continue;
2186 }
2187 if (container.mParentActivity != parentActivity) {
2188 continue;
2189 }
2190
2191 ActivityStack stack = container.mStack;
2192 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2193 if (top != null) {
2194 // TODO: Make sure the next activity doesn't start up when top is destroyed.
Craig Mautner95da1082014-02-24 17:54:35 -08002195 stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
Craig Mautner34b73df2014-01-12 21:11:08 -08002196 }
2197 mActivityContainers.removeAt(ndx);
2198 container.detachLocked();
2199 }
2200 }
2201
Craig Mautner95da1082014-02-24 17:54:35 -08002202 void deleteActivityContainer(IActivityContainer container) {
2203 ActivityContainer activityContainer = (ActivityContainer)container;
2204 if (activityContainer != null) {
2205 activityContainer.mStack.destroyActivitiesLocked(null, true,
2206 "deleteActivityContainer");
2207 final ActivityRecord parent = activityContainer.mParentActivity;
2208 if (parent != null) {
2209 parent.mChildContainers.remove(activityContainer);
2210 }
2211 final int stackId = activityContainer.mStackId;
2212 mActivityContainers.remove(stackId);
2213 mWindowManager.removeStack(stackId);
2214 }
2215 }
2216
Craig Mautner4a1cb222013-12-04 16:14:06 -08002217 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002218 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2219 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002220 return -1;
2221 }
2222
2223 ActivityContainer activityContainer =
2224 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002225 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002226 return stackId;
2227 }
2228
2229 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002230 while (true) {
2231 if (++mLastStackId <= HOME_STACK_ID) {
2232 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002233 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002234 if (getStack(mLastStackId) == null) {
2235 break;
2236 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002237 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002238 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002239 }
2240
2241 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002242 final TaskRecord task = anyTaskForIdLocked(taskId);
2243 if (task == null) {
2244 return;
2245 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002246 final ActivityStack stack = getStack(stackId);
2247 if (stack == null) {
2248 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2249 return;
2250 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002251 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002252 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002253 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002254 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002255 }
2256
Craig Mautnerac6f8432013-07-17 13:24:59 -07002257 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002258 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002259 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2260 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002261 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2262 final ActivityStack stack = stacks.get(stackNdx);
2263 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2264 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2265 continue;
2266 }
2267 final ActivityRecord ar = stack.findTaskLocked(r);
2268 if (ar != null) {
2269 return ar;
2270 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002271 }
2272 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002273 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002274 return null;
2275 }
2276
2277 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002278 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2279 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002280 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2281 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2282 if (ar != null) {
2283 return ar;
2284 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002285 }
2286 }
2287 return null;
2288 }
2289
Craig Mautner8d341ef2013-03-26 09:03:27 -07002290 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002291 scheduleSleepTimeout();
2292 if (!mGoingToSleep.isHeld()) {
2293 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002294 if (mLaunchingActivity.isHeld()) {
2295 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2296 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002297 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002298 mLaunchingActivity.release();
2299 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002300 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002301 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002302 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002303 }
2304
2305 boolean shutdownLocked(int timeout) {
2306 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002307 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002308
2309 final long endTime = System.currentTimeMillis() + timeout;
2310 while (true) {
2311 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002312 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2313 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002314 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2315 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2316 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002317 }
2318 if (cantShutdown) {
2319 long timeRemaining = endTime - System.currentTimeMillis();
2320 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002321 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002322 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002323 } catch (InterruptedException e) {
2324 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002325 } else {
2326 Slog.w(TAG, "Activity manager shutdown timed out");
2327 timedout = true;
2328 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002329 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002330 } else {
2331 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002332 }
2333 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002334
2335 // Force checkReadyForSleep to complete.
2336 mSleepTimeout = true;
2337 checkReadyForSleepLocked();
2338
Craig Mautner8d341ef2013-03-26 09:03:27 -07002339 return timedout;
2340 }
2341
2342 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002343 removeSleepTimeouts();
2344 if (mGoingToSleep.isHeld()) {
2345 mGoingToSleep.release();
2346 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002347 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2348 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002349 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2350 final ActivityStack stack = stacks.get(stackNdx);
2351 stack.awakeFromSleepingLocked();
2352 if (isFrontStack(stack)) {
2353 resumeTopActivitiesLocked();
2354 }
Craig Mautner5314a402013-09-26 12:40:16 -07002355 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002356 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002357 mGoingToSleepActivities.clear();
2358 }
2359
2360 void activitySleptLocked(ActivityRecord r) {
2361 mGoingToSleepActivities.remove(r);
2362 checkReadyForSleepLocked();
2363 }
2364
2365 void checkReadyForSleepLocked() {
2366 if (!mService.isSleepingOrShuttingDown()) {
2367 // Do not care.
2368 return;
2369 }
2370
2371 if (!mSleepTimeout) {
2372 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002373 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2374 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002375 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2376 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2377 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002378 }
2379
2380 if (mStoppingActivities.size() > 0) {
2381 // Still need to tell some activities to stop; can't sleep yet.
2382 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2383 + mStoppingActivities.size() + " activities");
2384 scheduleIdleLocked();
2385 dontSleep = true;
2386 }
2387
2388 if (mGoingToSleepActivities.size() > 0) {
2389 // Still need to tell some activities to sleep; can't sleep yet.
2390 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2391 + mGoingToSleepActivities.size() + " activities");
2392 dontSleep = true;
2393 }
2394
2395 if (dontSleep) {
2396 return;
2397 }
2398 }
2399
Craig Mautnere0a38842013-12-16 16:14:02 -08002400 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2401 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002402 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2403 stacks.get(stackNdx).goToSleep();
2404 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002405 }
2406
2407 removeSleepTimeouts();
2408
2409 if (mGoingToSleep.isHeld()) {
2410 mGoingToSleep.release();
2411 }
2412 if (mService.mShuttingDown) {
2413 mService.notifyAll();
2414 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002415 }
2416
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002417 boolean reportResumedActivityLocked(ActivityRecord r) {
2418 final ActivityStack stack = r.task.stack;
2419 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002420 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002421 }
2422 if (allResumedActivitiesComplete()) {
2423 ensureActivitiesVisibleLocked(null, 0);
2424 mWindowManager.executeAppTransition();
2425 return true;
2426 }
2427 return false;
2428 }
2429
Craig Mautner8d341ef2013-03-26 09:03:27 -07002430 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002431 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2432 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002433 final int numStacks = stacks.size();
2434 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2435 final ActivityStack stack = stacks.get(stackNdx);
2436 stack.handleAppCrashLocked(app);
2437 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002438 }
2439 }
2440
Craig Mautnerde4ef022013-04-07 19:01:33 -07002441 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002442 // First the front stacks. In case any are not fullscreen and are in front of home.
2443 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002444 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2445 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002446 final int topStackNdx = stacks.size() - 1;
2447 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2448 final ActivityStack stack = stacks.get(stackNdx);
2449 if (stackNdx == topStackNdx) {
2450 // Top stack.
2451 showHomeBehindStack =
2452 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2453 } else {
2454 // Back stack.
2455 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2456 showHomeBehindStack);
2457 }
Craig Mautner580ea812013-04-25 12:58:38 -07002458 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002459 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002460 }
2461
2462 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002463 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2464 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002465 final int numStacks = stacks.size();
2466 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2467 final ActivityStack stack = stacks.get(stackNdx);
2468 stack.scheduleDestroyActivities(app, false, reason);
2469 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002470 }
2471 }
2472
2473 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002474 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2475 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002476 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002477
Craig Mautner858d8a62013-04-23 17:08:34 -07002478 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002479 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2480 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002481 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002482 final ActivityStack stack = stacks.get(stackNdx);
2483 stack.switchUserLocked(userId);
2484 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002485 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002486 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002487
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002488 ActivityStack stack = getStack(restoreStackId);
2489 if (stack == null) {
2490 stack = mHomeStack;
2491 }
2492 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002493 if (stack.isOnHomeDisplay()) {
2494 moveHomeStack(homeInFront);
2495 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2496 } else {
2497 // Stack was moved to another display while user was swapped out.
2498 resumeHomeActivity(null);
2499 }
Craig Mautner93529a42013-10-04 15:03:13 -07002500 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002501 }
2502
Craig Mautnerde4ef022013-04-07 19:01:33 -07002503 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2504 int N = mStoppingActivities.size();
2505 if (N <= 0) return null;
2506
2507 ArrayList<ActivityRecord> stops = null;
2508
2509 final boolean nowVisible = allResumedActivitiesVisible();
2510 for (int i=0; i<N; i++) {
2511 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002512 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002513 + nowVisible + " waitingVisible=" + s.waitingVisible
2514 + " finishing=" + s.finishing);
2515 if (s.waitingVisible && nowVisible) {
2516 mWaitingVisibleActivities.remove(s);
2517 s.waitingVisible = false;
2518 if (s.finishing) {
2519 // If this activity is finishing, it is sitting on top of
2520 // everyone else but we now know it is no longer needed...
2521 // so get rid of it. Otherwise, we need to go through the
2522 // normal flow and hide it once we determine that it is
2523 // hidden by the activities in front of it.
2524 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002525 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002526 }
2527 }
2528 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2529 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2530 if (stops == null) {
2531 stops = new ArrayList<ActivityRecord>();
2532 }
2533 stops.add(s);
2534 mStoppingActivities.remove(i);
2535 N--;
2536 i--;
2537 }
2538 }
2539
2540 return stops;
2541 }
2542
Craig Mautnercf910b02013-04-23 11:23:27 -07002543 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002544 // FIXME
2545/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2546 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002547 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002548 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002549 if (isFrontStack(stack)) {
2550 if (r == null) {
2551 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2552 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002553 final ActivityRecord pausing = stack.mPausingActivity;
2554 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002555 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002556 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002557 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002558 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002559 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002560 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002561 }
2562 }
2563 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002564 final ActivityRecord resumed = stack.mResumedActivity;
2565 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002566 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002567 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002568 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002569 if (r != null && (state == ActivityState.INITIALIZING
2570 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002571 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002572 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002573 }
2574 }
2575 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002576*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002577 }
2578
Craig Mautner27084302013-03-25 08:05:25 -07002579 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002580 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002581 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002582 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002583 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002584 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2585 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2586 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002587 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002588 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002589
Craig Mautner20e72272013-04-01 13:45:53 -07002590 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002591 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002592 }
2593
Dianne Hackborn390517b2013-05-30 15:03:32 -07002594 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2595 boolean needSep, String prefix) {
2596 if (activity != null) {
2597 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2598 if (needSep) {
2599 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002600 }
2601 pw.print(prefix);
2602 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002603 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002604 }
2605 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002606 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002607 }
2608
Craig Mautner8d341ef2013-03-26 09:03:27 -07002609 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2610 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002611 boolean printed = false;
2612 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002613 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2614 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2615 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2616 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002617 final int numStacks = stacks.size();
2618 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2619 final ActivityStack stack = stacks.get(stackNdx);
2620 StringBuilder stackHeader = new StringBuilder(128);
2621 stackHeader.append(" Stack #");
2622 stackHeader.append(stack.mStackId);
2623 stackHeader.append(":");
2624 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2625 needSep, stackHeader.toString());
2626 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2627 !dumpAll, false, dumpPackage, true,
2628 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002629
Craig Mautner4a1cb222013-12-04 16:14:06 -08002630 needSep = printed;
2631 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2632 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002633 if (pr) {
2634 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002635 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002636 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002637 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2638 " mResumedActivity: ");
2639 if (pr) {
2640 printed = true;
2641 needSep = false;
2642 }
2643 if (dumpAll) {
2644 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2645 " mLastPausedActivity: ");
2646 if (pr) {
2647 printed = true;
2648 needSep = true;
2649 }
2650 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2651 needSep, " mLastNoHistoryActivity: ");
2652 }
2653 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002654 }
2655 }
2656
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002657 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2658 false, dumpPackage, true, " Activities waiting to finish:", null);
2659 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2660 false, dumpPackage, true, " Activities waiting to stop:", null);
2661 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2662 false, dumpPackage, true, " Activities waiting for another to become visible:",
2663 null);
2664 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2665 false, dumpPackage, true, " Activities waiting to sleep:", null);
2666 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2667 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002668
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002669 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002670 }
2671
Dianne Hackborn390517b2013-05-30 15:03:32 -07002672 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002673 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002674 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002675 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002676 String innerPrefix = null;
2677 String[] args = null;
2678 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002679 for (int i=list.size()-1; i>=0; i--) {
2680 final ActivityRecord r = list.get(i);
2681 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2682 continue;
2683 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002684 if (innerPrefix == null) {
2685 innerPrefix = prefix + " ";
2686 args = new String[0];
2687 }
2688 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002689 final boolean full = !brief && (complete || !r.isInHistory());
2690 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002691 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002692 needNL = false;
2693 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002694 if (header1 != null) {
2695 pw.println(header1);
2696 header1 = null;
2697 }
2698 if (header2 != null) {
2699 pw.println(header2);
2700 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002701 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002702 if (lastTask != r.task) {
2703 lastTask = r.task;
2704 pw.print(prefix);
2705 pw.print(full ? "* " : " ");
2706 pw.println(lastTask);
2707 if (full) {
2708 lastTask.dump(pw, prefix + " ");
2709 } else if (complete) {
2710 // Complete + brief == give a summary. Isn't that obvious?!?
2711 if (lastTask.intent != null) {
2712 pw.print(prefix); pw.print(" ");
2713 pw.println(lastTask.intent.toInsecureStringWithClip());
2714 }
2715 }
2716 }
2717 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2718 pw.print(" #"); pw.print(i); pw.print(": ");
2719 pw.println(r);
2720 if (full) {
2721 r.dump(pw, innerPrefix);
2722 } else if (complete) {
2723 // Complete + brief == give a summary. Isn't that obvious?!?
2724 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2725 if (r.app != null) {
2726 pw.print(innerPrefix); pw.println(r.app);
2727 }
2728 }
2729 if (client && r.app != null && r.app.thread != null) {
2730 // flush anything that is already in the PrintWriter since the thread is going
2731 // to write to the file descriptor directly
2732 pw.flush();
2733 try {
2734 TransferPipe tp = new TransferPipe();
2735 try {
2736 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2737 r.appToken, innerPrefix, args);
2738 // Short timeout, since blocking here can
2739 // deadlock with the application.
2740 tp.go(fd, 2000);
2741 } finally {
2742 tp.kill();
2743 }
2744 } catch (IOException e) {
2745 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2746 } catch (RemoteException e) {
2747 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2748 }
2749 needNL = true;
2750 }
2751 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002752 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002753 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002754
Craig Mautnerf3333272013-04-22 10:55:53 -07002755 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002756 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002757 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2758 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002759 }
2760
2761 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002762 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002763 }
2764
2765 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002766 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002767 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2768 }
2769
Craig Mautner05d29032013-05-03 13:40:13 -07002770 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002771 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2772 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2773 }
Craig Mautner05d29032013-05-03 13:40:13 -07002774 }
2775
Craig Mautner0eea92c2013-05-16 13:35:39 -07002776 void removeSleepTimeouts() {
2777 mSleepTimeout = false;
2778 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2779 }
2780
2781 final void scheduleSleepTimeout() {
2782 removeSleepTimeouts();
2783 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2784 }
2785
Craig Mautner4a1cb222013-12-04 16:14:06 -08002786 @Override
2787 public void onDisplayAdded(int displayId) {
2788 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2789 }
2790
2791 @Override
2792 public void onDisplayRemoved(int displayId) {
2793 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2794 }
2795
2796 @Override
2797 public void onDisplayChanged(int displayId) {
2798 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2799 }
2800
2801 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002802 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002803 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002804 newDisplay = mActivityDisplays.get(displayId) == null;
2805 if (newDisplay) {
2806 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2807 mActivityDisplays.put(displayId, activityDisplay);
2808 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002809 }
Craig Mautner4504de52013-12-20 09:06:56 -08002810 if (newDisplay) {
2811 mWindowManager.onDisplayAdded(displayId);
2812 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002813 }
2814
2815 public void handleDisplayRemovedLocked(int displayId) {
2816 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002817 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2818 if (activityDisplay != null) {
2819 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002820 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002821 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002822 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002823 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002824 }
2825 }
2826 mWindowManager.onDisplayRemoved(displayId);
2827 }
2828
2829 public void handleDisplayChangedLocked(int displayId) {
2830 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002831 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2832 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002833 // TODO: Update the bounds.
2834 }
2835 }
2836 mWindowManager.onDisplayChanged(displayId);
2837 }
2838
2839 StackInfo getStackInfo(ActivityStack stack) {
2840 StackInfo info = new StackInfo();
2841 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2842 info.displayId = Display.DEFAULT_DISPLAY;
2843 info.stackId = stack.mStackId;
2844
2845 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2846 final int numTasks = tasks.size();
2847 int[] taskIds = new int[numTasks];
2848 String[] taskNames = new String[numTasks];
2849 for (int i = 0; i < numTasks; ++i) {
2850 final TaskRecord task = tasks.get(i);
2851 taskIds[i] = task.taskId;
2852 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2853 : task.realActivity != null ? task.realActivity.flattenToString()
2854 : task.getTopActivity() != null ? task.getTopActivity().packageName
2855 : "unknown";
2856 }
2857 info.taskIds = taskIds;
2858 info.taskNames = taskNames;
2859 return info;
2860 }
2861
2862 StackInfo getStackInfoLocked(int stackId) {
2863 ActivityStack stack = getStack(stackId);
2864 if (stack != null) {
2865 return getStackInfo(stack);
2866 }
2867 return null;
2868 }
2869
2870 ArrayList<StackInfo> getAllStackInfosLocked() {
2871 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002872 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2873 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002874 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2875 list.add(getStackInfo(stacks.get(ndx)));
2876 }
2877 }
2878 return list;
2879 }
2880
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002881 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002882
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002883 public ActivityStackSupervisorHandler(Looper looper) {
2884 super(looper);
2885 }
2886
Craig Mautnerf3333272013-04-22 10:55:53 -07002887 void activityIdleInternal(ActivityRecord r) {
2888 synchronized (mService) {
2889 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2890 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002891 }
2892
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002893 @Override
2894 public void handleMessage(Message msg) {
2895 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002896 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002897 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002898 if (mService.mDidDexOpt) {
2899 mService.mDidDexOpt = false;
2900 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2901 nmsg.obj = msg.obj;
2902 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2903 return;
2904 }
2905 // We don't at this point know if the activity is fullscreen,
2906 // so we need to be conservative and assume it isn't.
2907 activityIdleInternal((ActivityRecord)msg.obj);
2908 } break;
2909 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002910 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002911 activityIdleInternal((ActivityRecord)msg.obj);
2912 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002913 case RESUME_TOP_ACTIVITY_MSG: {
2914 synchronized (mService) {
2915 resumeTopActivitiesLocked();
2916 }
2917 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002918 case SLEEP_TIMEOUT_MSG: {
2919 synchronized (mService) {
2920 if (mService.isSleepingOrShuttingDown()) {
2921 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2922 mSleepTimeout = true;
2923 checkReadyForSleepLocked();
2924 }
2925 }
2926 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002927 case LAUNCH_TIMEOUT_MSG: {
2928 if (mService.mDidDexOpt) {
2929 mService.mDidDexOpt = false;
2930 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2931 return;
2932 }
2933 synchronized (mService) {
2934 if (mLaunchingActivity.isHeld()) {
2935 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2936 if (VALIDATE_WAKE_LOCK_CALLER
2937 && Binder.getCallingUid() != Process.myUid()) {
2938 throw new IllegalStateException("Calling must be system uid");
2939 }
2940 mLaunchingActivity.release();
2941 }
2942 }
2943 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002944 case HANDLE_DISPLAY_ADDED: {
2945 handleDisplayAddedLocked(msg.arg1);
2946 } break;
2947 case HANDLE_DISPLAY_CHANGED: {
2948 handleDisplayChangedLocked(msg.arg1);
2949 } break;
2950 case HANDLE_DISPLAY_REMOVED: {
2951 handleDisplayRemovedLocked(msg.arg1);
2952 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002953 }
2954 }
2955 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002956
Craig Mautner4a1cb222013-12-04 16:14:06 -08002957 class ActivityContainer extends IActivityContainer.Stub {
2958 final int mStackId;
2959 final IActivityContainerCallback mCallback;
2960 final ActivityStack mStack;
2961 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08002962 final String mIdString;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002963
Craig Mautner4a1cb222013-12-04 16:14:06 -08002964 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002965 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002966
2967 ActivityContainer(ActivityRecord parentActivity, int stackId,
2968 IActivityContainerCallback callback) {
2969 synchronized (mService) {
2970 mStackId = stackId;
2971 mStack = new ActivityStack(this);
2972 mParentActivity = parentActivity;
2973 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08002974 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2975 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002976 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002977 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002978
Craig Mautnere0a38842013-12-16 16:14:02 -08002979 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002980 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2981 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002982 mActivityDisplay = activityDisplay;
2983 mStack.mDisplayId = activityDisplay.mDisplayId;
2984 mStack.mStacks = activityDisplay.mStacks;
2985
2986 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002987 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002988 }
2989
2990 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08002991 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002992 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002993 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2994 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002995 return;
2996 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002997 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002998 }
2999 }
3000
3001 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003002 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003003 if (mActivityDisplay != null) {
3004 return mActivityDisplay.mDisplayId;
3005 }
3006 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003007 }
3008
Jeff Brown38f96e52014-02-11 14:32:56 -08003009 @Override
3010 public boolean injectEvent(InputEvent event) {
3011 final long origId = Binder.clearCallingIdentity();
3012 try {
3013 if (mActivityDisplay != null) {
3014 return mInputManagerInternal.injectInputEvent(event,
3015 mActivityDisplay.mDisplayId,
3016 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3017 }
3018 return false;
3019 } finally {
3020 Binder.restoreCallingIdentity(origId);
3021 }
3022 }
3023
Craig Mautner34b73df2014-01-12 21:11:08 -08003024 private void detachLocked() {
3025 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3026 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003027 if (mActivityDisplay != null) {
3028 mActivityDisplay.detachActivitiesLocked(mStack);
3029 mActivityDisplay = null;
3030 mStack.mDisplayId = -1;
3031 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003032 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003033 }
3034 }
3035
3036 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003037 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003038 synchronized (mService) {
3039 detachLocked();
3040 }
3041 }
3042
3043 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003044 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003045 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003046 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3047 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3048 // TODO: Switch to user app stacks here.
3049 String mimeType = intent.getType();
3050 if (mimeType == null && intent.getData() != null
3051 && "content".equals(intent.getData().getScheme())) {
3052 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3053 }
3054 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3055 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003056 }
3057
3058 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003059 public final int startActivityIntentSender(IIntentSender intentSender) {
3060 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3061
3062 if (!(intentSender instanceof PendingIntentRecord)) {
3063 throw new IllegalArgumentException("Bad PendingIntent object");
3064 }
3065
3066 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3067 null, 0, 0, 0, null, this);
3068 }
3069
3070 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003071 public IBinder asBinder() {
3072 return this;
3073 }
3074
Craig Mautner4504de52013-12-20 09:06:56 -08003075 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003076 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003077 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3078
3079 final long origId = Binder.clearCallingIdentity();
3080 try {
3081 synchronized (mService) {
3082 ActivityDisplay activityDisplay =
3083 new ActivityDisplay(surface, width, height, density);
3084 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3085 attachToDisplayLocked(activityDisplay);
3086 mStack.resumeTopActivityLocked(null);
3087 }
3088 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3089 + mActivityDisplay);
3090 } finally {
3091 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003092 }
Craig Mautner4504de52013-12-20 09:06:56 -08003093 }
3094
Craig Mautner4a1cb222013-12-04 16:14:06 -08003095 ActivityStackSupervisor getOuter() {
3096 return ActivityStackSupervisor.this;
3097 }
3098
3099 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003100 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003101 }
3102
3103 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003104 if (mActivityDisplay != null) {
3105 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003106 } else {
3107 outBounds.set(0, 0);
3108 }
3109 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003110
3111 @Override
3112 public String toString() {
3113 return mIdString + (mActivityDisplay == null ? "N" : "A");
3114 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003115 }
3116
Craig Mautner4a1cb222013-12-04 16:14:06 -08003117 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3118 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003119 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003120 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003121 int mDisplayId;
3122 Display mDisplay;
3123 DisplayInfo mDisplayInfo = new DisplayInfo();
3124 Surface mSurface;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003125
Craig Mautner4a1cb222013-12-04 16:14:06 -08003126 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3127 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003128 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003129
Craig Mautner4504de52013-12-20 09:06:56 -08003130 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3131 * here. */
3132 VirtualDisplay mVirtualDisplay;
3133
Craig Mautnere0a38842013-12-16 16:14:02 -08003134 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003135 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003136 }
3137
Craig Mautner34b73df2014-01-12 21:11:08 -08003138 ActivityDisplay(Surface surface, int width, int height, int density) {
3139 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3140 long ident = Binder.clearCallingIdentity();
3141 try {
3142 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3143 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3144 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3145 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3146 } finally {
3147 Binder.restoreCallingIdentity(ident);
3148 }
3149
3150 init(mVirtualDisplay.getDisplay());
3151 mSurface = surface;
3152
3153 mWindowManager.handleDisplayAdded(mDisplayId);
3154 }
3155
3156 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003157 mDisplay = display;
3158 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003159 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003160 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003161
3162 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003163 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3164 + mDisplayId);
3165 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003166 }
3167
Craig Mautnere0a38842013-12-16 16:14:02 -08003168 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003169 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003170 + " from displayId=" + mDisplayId);
3171 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003172 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3173 mVirtualDisplay.release();
3174 mVirtualDisplay = null;
3175 }
3176 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003177 }
3178
3179 void getBounds(Point bounds) {
3180 mDisplay.getDisplayInfo(mDisplayInfo);
3181 bounds.x = mDisplayInfo.appWidth;
3182 bounds.y = mDisplayInfo.appHeight;
3183 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003184
3185 @Override
3186 public String toString() {
3187 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3188 + " numStacks=" + mStacks.size() + "}";
3189 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003190 }
Craig Mautner27084302013-03-25 08:05:25 -07003191}