blob: dc20a12048632788146ef91e620a0ab9a94eb52e [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 Mautnered6649f2013-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 Brownca9bc702014-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 Mautnered6649f2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brownca9bc702014-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 Brownca9bc702014-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 Brownca9bc702014-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 Brownca9bc702014-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 Lockwooded8902d2013-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 {
Craig Mautner74266842013-12-19 13:02:30 -0800409 if (realStartActivityLocked(hr, app, true, true, null)) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800410 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) {
John Spurlock8a985d22014-02-25 09:40:05 -0500526 // TODO: Put all stacks in supervisor and iterate through them instead.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800527 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,
Adam Powellcfbe9be2013-11-06 14:58:58 -0800933 ProcessRecord app, boolean andResume, boolean checkConfig, Bundle resumeArgs)
Craig Mautner2420ead2013-04-01 17:13:20 -0700934 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 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001025
Dianne Hackborna413dc02013-07-12 12:02:55 -07001026 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001027 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1028 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001029 new Configuration(mService.mConfiguration), r.compat,
1030 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001031 mService.isNextTransitionForward(), profileFile, profileFd,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001032 profileAutoStop, resumeArgs);
Craig Mautner2420ead2013-04-01 17:13:20 -07001033
1034 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1035 // This may be a heavy-weight process! Note that the package
1036 // manager will ensure that only activity can run in the main
1037 // process of the .apk, which is the only thing that will be
1038 // considered heavy-weight.
1039 if (app.processName.equals(app.info.packageName)) {
1040 if (mService.mHeavyWeightProcess != null
1041 && mService.mHeavyWeightProcess != app) {
1042 Slog.w(TAG, "Starting new heavy weight process " + app
1043 + " when already running "
1044 + mService.mHeavyWeightProcess);
1045 }
1046 mService.mHeavyWeightProcess = app;
1047 Message msg = mService.mHandler.obtainMessage(
1048 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1049 msg.obj = r;
1050 mService.mHandler.sendMessage(msg);
1051 }
1052 }
1053
1054 } catch (RemoteException e) {
1055 if (r.launchFailed) {
1056 // This is the second time we failed -- finish activity
1057 // and give up.
1058 Slog.e(TAG, "Second failure launching "
1059 + r.intent.getComponent().flattenToShortString()
1060 + ", giving up", e);
1061 mService.appDiedLocked(app, app.pid, app.thread);
1062 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1063 "2nd-crash", false);
1064 return false;
1065 }
1066
1067 // This is the first time we failed -- restart process and
1068 // retry.
1069 app.activities.remove(r);
1070 throw e;
1071 }
1072
1073 r.launchFailed = false;
1074 if (stack.updateLRUListLocked(r)) {
1075 Slog.w(TAG, "Activity " + r
1076 + " being launched, but already in LRU list");
1077 }
1078
1079 if (andResume) {
1080 // As part of the process of launching, ActivityThread also performs
1081 // a resume.
1082 stack.minimalResumeActivityLocked(r);
1083 } else {
1084 // This activity is not starting in the resumed state... which
1085 // should look like we asked it to pause+stop (but remain visible),
1086 // and it has done so and reported back the current icicle and
1087 // other state.
1088 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1089 + " (starting in stopped state)");
1090 r.state = ActivityState.STOPPED;
1091 r.stopped = true;
1092 }
1093
1094 // Launch the new version setup screen if needed. We do this -after-
1095 // launching the initial activity (that is, home), so that it can have
1096 // a chance to initialize itself while in the background, making the
1097 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001098 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001099 mService.startSetupActivityLocked();
1100 }
1101
1102 return true;
1103 }
1104
Craig Mautnere79d42682013-04-01 19:01:53 -07001105 void startSpecificActivityLocked(ActivityRecord r,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001106 boolean andResume, boolean checkConfig, Bundle resumeArgs) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001107 // Is this activity's application already running?
1108 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001109 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001110
1111 r.task.stack.setLaunchTime(r);
1112
1113 if (app != null && app.thread != null) {
1114 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001115 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1116 || !"android".equals(r.info.packageName)) {
1117 // Don't add this if it is a platform component that is marked
1118 // to run in multiple processes, because this is actually
1119 // part of the framework so doesn't make sense to track as a
1120 // separate apk in the process.
1121 app.addPackage(r.info.packageName, mService.mProcessStats);
1122 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001123 realStartActivityLocked(r, app, andResume, checkConfig, resumeArgs);
Craig Mautnere79d42682013-04-01 19:01:53 -07001124 return;
1125 } catch (RemoteException e) {
1126 Slog.w(TAG, "Exception when starting activity "
1127 + r.intent.getComponent().flattenToShortString(), e);
1128 }
1129
1130 // If a dead object exception was thrown -- fall through to
1131 // restart the application.
1132 }
1133
1134 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001135 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001136 }
1137
Craig Mautner6170f732013-04-02 13:05:23 -07001138 final int startActivityLocked(IApplicationThread caller,
1139 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1140 String resultWho, int requestCode,
1141 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001142 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001143 int err = ActivityManager.START_SUCCESS;
1144
1145 ProcessRecord callerApp = null;
1146 if (caller != null) {
1147 callerApp = mService.getRecordForAppLocked(caller);
1148 if (callerApp != null) {
1149 callingPid = callerApp.pid;
1150 callingUid = callerApp.info.uid;
1151 } else {
1152 Slog.w(TAG, "Unable to find app for caller " + caller
1153 + " (pid=" + callingPid + ") when starting: "
1154 + intent.toString());
1155 err = ActivityManager.START_PERMISSION_DENIED;
1156 }
1157 }
1158
1159 if (err == ActivityManager.START_SUCCESS) {
1160 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1161 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001162 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1163 + " on display " + (container == null ? (mFocusedStack == null ?
1164 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1165 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1166 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001167 }
1168
1169 ActivityRecord sourceRecord = null;
1170 ActivityRecord resultRecord = null;
1171 if (resultTo != null) {
1172 sourceRecord = isInAnyStackLocked(resultTo);
1173 if (DEBUG_RESULTS) Slog.v(
1174 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1175 if (sourceRecord != null) {
1176 if (requestCode >= 0 && !sourceRecord.finishing) {
1177 resultRecord = sourceRecord;
1178 }
1179 }
1180 }
1181 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1182
1183 int launchFlags = intent.getFlags();
1184
1185 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1186 && sourceRecord != null) {
1187 // Transfer the result target from the source activity to the new
1188 // one being started, including any failures.
1189 if (requestCode >= 0) {
1190 ActivityOptions.abort(options);
1191 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1192 }
1193 resultRecord = sourceRecord.resultTo;
1194 resultWho = sourceRecord.resultWho;
1195 requestCode = sourceRecord.requestCode;
1196 sourceRecord.resultTo = null;
1197 if (resultRecord != null) {
1198 resultRecord.removeResultsLocked(
1199 sourceRecord, resultWho, requestCode);
1200 }
1201 }
1202
1203 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1204 // We couldn't find a class that can handle the given Intent.
1205 // That's the end of that!
1206 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1207 }
1208
1209 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1210 // We couldn't find the specific class specified in the Intent.
1211 // Also the end of the line.
1212 err = ActivityManager.START_CLASS_NOT_FOUND;
1213 }
1214
1215 if (err != ActivityManager.START_SUCCESS) {
1216 if (resultRecord != null) {
1217 resultStack.sendActivityResultLocked(-1,
1218 resultRecord, resultWho, requestCode,
1219 Activity.RESULT_CANCELED, null);
1220 }
1221 setDismissKeyguard(false);
1222 ActivityOptions.abort(options);
1223 return err;
1224 }
1225
1226 final int startAnyPerm = mService.checkPermission(
1227 START_ANY_ACTIVITY, callingPid, callingUid);
1228 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1229 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1230 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1231 if (resultRecord != null) {
1232 resultStack.sendActivityResultLocked(-1,
1233 resultRecord, resultWho, requestCode,
1234 Activity.RESULT_CANCELED, null);
1235 }
1236 setDismissKeyguard(false);
1237 String msg;
1238 if (!aInfo.exported) {
1239 msg = "Permission Denial: starting " + intent.toString()
1240 + " from " + callerApp + " (pid=" + callingPid
1241 + ", uid=" + callingUid + ")"
1242 + " not exported from uid " + aInfo.applicationInfo.uid;
1243 } else {
1244 msg = "Permission Denial: starting " + intent.toString()
1245 + " from " + callerApp + " (pid=" + callingPid
1246 + ", uid=" + callingUid + ")"
1247 + " requires " + aInfo.permission;
1248 }
1249 Slog.w(TAG, msg);
1250 throw new SecurityException(msg);
1251 }
1252
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001253 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001254 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001255
Craig Mautner6170f732013-04-02 13:05:23 -07001256 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001257 try {
1258 // The Intent we give to the watcher has the extra data
1259 // stripped off, since it can contain private information.
1260 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001261 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001262 aInfo.applicationInfo.packageName);
1263 } catch (RemoteException e) {
1264 mService.mController = null;
1265 }
Ben Gruver5e207332013-04-03 17:41:37 -07001266 }
Craig Mautner6170f732013-04-02 13:05:23 -07001267
Ben Gruver5e207332013-04-03 17:41:37 -07001268 if (abort) {
1269 if (resultRecord != null) {
1270 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001271 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001272 }
Ben Gruver5e207332013-04-03 17:41:37 -07001273 // We pretend to the caller that it was really started, but
1274 // they will just get a cancel result.
1275 setDismissKeyguard(false);
1276 ActivityOptions.abort(options);
1277 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001278 }
1279
1280 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001281 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1282 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001283 if (outActivity != null) {
1284 outActivity[0] = r;
1285 }
1286
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001287 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001288 if (stack.mResumedActivity == null
1289 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001290 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1291 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001292 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001293 mService.mPendingActivityLaunches.add(pal);
1294 setDismissKeyguard(false);
1295 ActivityOptions.abort(options);
1296 return ActivityManager.START_SWITCHES_CANCELED;
1297 }
1298 }
1299
1300 if (mService.mDidAppSwitch) {
1301 // This is the second allowed switch since we stopped switches,
1302 // so now just generally allow switches. Use case: user presses
1303 // home (switches disabled, switch to home, mDidAppSwitch now true);
1304 // user taps a home icon (coming from home so allowed, we hit here
1305 // and now allow anyone to switch again).
1306 mService.mAppSwitchesAllowedTime = 0;
1307 } else {
1308 mService.mDidAppSwitch = true;
1309 }
1310
1311 mService.doPendingActivityLaunchesLocked(false);
1312
Craig Mautner8849a5e2013-04-02 16:41:03 -07001313 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001314
1315 if (allPausedActivitiesComplete()) {
1316 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001317 // activity start, but we are not actually doing an activity
1318 // switch... just dismiss the keyguard now, because we
1319 // probably want to see whatever is behind it.
1320 dismissKeyguard();
1321 }
1322 return err;
1323 }
1324
Craig Mautnerac6f8432013-07-17 13:24:59 -07001325 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001326 final TaskRecord task = r.task;
1327 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001328 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001329 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001330 if (taskStack.isOnHomeDisplay()) {
1331 if (mFocusedStack != taskStack) {
1332 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1333 "focused stack to r=" + r + " task=" + task);
1334 mFocusedStack = taskStack;
1335 } else {
1336 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1337 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1338 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001339 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001340 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001341 }
1342
Craig Mautnere0a38842013-12-16 16:14:02 -08001343 final ActivityContainer container = r.mInitialActivityContainer;
1344 if (container != null) {
1345 // The first time put it on the desired stack, after this put on task stack.
1346 r.mInitialActivityContainer = null;
1347 return container.mStack;
1348 }
1349
Craig Mautner4a1cb222013-12-04 16:14:06 -08001350 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001351 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1352 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1353 return mFocusedStack;
1354 }
1355
Craig Mautnere0a38842013-12-16 16:14:02 -08001356 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1357 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1358 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1359 if (!stack.isHomeStack()) {
1360 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1361 "adjustStackFocus: Setting focused stack=" + stack);
1362 mFocusedStack = stack;
1363 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001364 }
1365 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001366
Craig Mautner4a1cb222013-12-04 16:14:06 -08001367 // Need to create an app stack for this user.
1368 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001369 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1370 " stackId=" + stackId);
1371 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001372 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001373 }
1374 return mHomeStack;
1375 }
1376
Craig Mautner29219d92013-04-16 20:19:12 -07001377 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001378 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001379 final TaskRecord task = r.task;
1380 boolean isHomeActivity = !r.isApplicationActivity();
1381 if (!isHomeActivity && task != null) {
1382 isHomeActivity = !task.isApplicationTask();
1383 }
1384 if (!isHomeActivity && task != null) {
1385 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1386 isHomeActivity = parent != null && parent.isHomeActivity();
1387 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001388 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001389 }
1390 }
1391
Craig Mautner8849a5e2013-04-02 16:41:03 -07001392 final int startActivityUncheckedLocked(ActivityRecord r,
1393 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1394 Bundle options) {
1395 final Intent intent = r.intent;
1396 final int callingUid = r.launchedFromUid;
1397
1398 int launchFlags = intent.getFlags();
1399
Craig Mautner8849a5e2013-04-02 16:41:03 -07001400 // We'll invoke onUserLeaving before onPause only if the launching
1401 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001402 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1403 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001404
1405 // If the caller has asked not to resume at this point, we make note
1406 // of this in the record so that we can skip it when trying to find
1407 // the top running activity.
1408 if (!doResume) {
1409 r.delayedResume = true;
1410 }
1411
1412 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1413
1414 // If the onlyIfNeeded flag is set, then we can do this if the activity
1415 // being launched is the same as the one making the call... or, as
1416 // a special case, if we do not know the caller then we count the
1417 // current top activity as the caller.
1418 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1419 ActivityRecord checkedCaller = sourceRecord;
1420 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001421 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001422 }
1423 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1424 // Caller is not the same as launcher, so always needed.
1425 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1426 }
1427 }
1428
1429 if (sourceRecord == null) {
1430 // This activity is not being started from another... in this
1431 // case we -always- start a new task.
1432 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001433 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1434 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001435 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1436 }
1437 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1438 // The original activity who is starting us is running as a single
1439 // instance... this new activity it is starting must go on its
1440 // own task.
1441 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1442 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1443 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1444 // The activity being started is a single instance... it always
1445 // gets launched into its own task.
1446 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1447 }
1448
Craig Mautner88629292013-11-10 20:39:05 -08001449 ActivityInfo newTaskInfo = null;
1450 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001451 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001452 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001453 if (sourceRecord.finishing) {
1454 // If the source is finishing, we can't further count it as our source. This
1455 // is because the task it is associated with may now be empty and on its way out,
1456 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001457 // the NEW_TASK flow and try to find a task for it. But save the task information
1458 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001459 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1460 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1461 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1462 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001463 newTaskInfo = sourceRecord.info;
1464 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001465 }
1466 sourceRecord = null;
1467 sourceStack = null;
1468 } else {
1469 sourceStack = sourceRecord.task.stack;
1470 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001471 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001472 sourceStack = null;
1473 }
1474
Craig Mautner8849a5e2013-04-02 16:41:03 -07001475 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1476 // For whatever reason this activity is being launched into a new
1477 // task... yet the caller has requested a result back. Well, that
1478 // is pretty messed up, so instead immediately send back a cancel
1479 // and let the new task continue launched as normal without a
1480 // dependency on its originator.
1481 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1482 r.resultTo.task.stack.sendActivityResultLocked(-1,
1483 r.resultTo, r.resultWho, r.requestCode,
1484 Activity.RESULT_CANCELED, null);
1485 r.resultTo = null;
1486 }
1487
1488 boolean addingToTask = false;
1489 boolean movedHome = false;
1490 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001491 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001492 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1493 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1494 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1495 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1496 // If bring to front is requested, and no result is requested, and
1497 // we can find a task that was started with this same
1498 // component, then instead of launching bring that one to the front.
1499 if (r.resultTo == null) {
1500 // See if there is a task to bring to the front. If this is
1501 // a SINGLE_INSTANCE activity, there can be one and only one
1502 // instance of it in the history, and it is always in its own
1503 // unique task, so we do a special search.
1504 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001505 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001506 : findActivityLocked(intent, r.info);
1507 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001508 if (r.task == null) {
1509 r.task = intentActivity.task;
1510 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001511 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001512 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001513 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1514 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001515 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001516 if (intentActivity.task.intent == null) {
1517 // This task was started because of movement of
1518 // the activity based on affinity... now that we
1519 // are actually launching it, we can assign the
1520 // base intent.
1521 intentActivity.task.setIntent(intent, r.info);
1522 }
1523 // If the target task is not in the front, then we need
1524 // to bring it to the front... except... well, with
1525 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1526 // to have the same behavior as if a new instance was
1527 // being started, which means not bringing it to the front
1528 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001529 final ActivityStack lastStack = getLastStack();
1530 ActivityRecord curTop = lastStack == null?
1531 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001532 if (curTop != null && (curTop.task != intentActivity.task ||
1533 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001534 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001535 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1536 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001537 // We really do want to push this one into the
1538 // user's face, right now.
1539 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001540 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001541 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001542 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1543 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001544 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001545 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001546 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001547 options = null;
1548 }
1549 }
1550 // If the caller has requested that the target task be
1551 // reset, then do so.
1552 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1553 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1554 }
1555 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1556 // We don't need to start a new activity, and
1557 // the client said not to do anything if that
1558 // is the case, so this is it! And for paranoia, make
1559 // sure we have correctly resumed the top activity.
1560 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001561 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001562 } else {
1563 ActivityOptions.abort(options);
1564 }
1565 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1566 }
1567 if ((launchFlags &
1568 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1569 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1570 // The caller has requested to completely replace any
1571 // existing task with its new activity. Well that should
1572 // not be too hard...
1573 reuseTask = intentActivity.task;
1574 reuseTask.performClearTaskLocked();
1575 reuseTask.setIntent(r.intent, r.info);
1576 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1577 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1578 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1579 // In this situation we want to remove all activities
1580 // from the task up to the one being started. In most
1581 // cases this means we are resetting the task to its
1582 // initial state.
1583 ActivityRecord top =
1584 intentActivity.task.performClearTaskLocked(r, launchFlags);
1585 if (top != null) {
1586 if (top.frontOfTask) {
1587 // Activity aliases may mean we use different
1588 // intents for the top activity, so make sure
1589 // the task now has the identity of the new
1590 // intent.
1591 top.task.setIntent(r.intent, r.info);
1592 }
1593 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1594 r, top.task);
1595 top.deliverNewIntentLocked(callingUid, r.intent);
1596 } else {
1597 // A special case: we need to
1598 // start the activity because it is not currently
1599 // running, and the caller has asked to clear the
1600 // current task to have this activity at the top.
1601 addingToTask = true;
1602 // Now pretend like this activity is being started
1603 // by the top of its task, so it is put in the
1604 // right place.
1605 sourceRecord = intentActivity;
1606 }
1607 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1608 // In this case the top activity on the task is the
1609 // same as the one being launched, so we take that
1610 // as a request to bring the task to the foreground.
1611 // If the top activity in the task is the root
1612 // activity, deliver this new intent to it if it
1613 // desires.
1614 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1615 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1616 && intentActivity.realActivity.equals(r.realActivity)) {
1617 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1618 intentActivity.task);
1619 if (intentActivity.frontOfTask) {
1620 intentActivity.task.setIntent(r.intent, r.info);
1621 }
1622 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1623 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1624 // In this case we are launching the root activity
1625 // of the task, but with a different intent. We
1626 // should start a new instance on top.
1627 addingToTask = true;
1628 sourceRecord = intentActivity;
1629 }
1630 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1631 // In this case an activity is being launched in to an
1632 // existing task, without resetting that task. This
1633 // is typically the situation of launching an activity
1634 // from a notification or shortcut. We want to place
1635 // the new activity on top of the current task.
1636 addingToTask = true;
1637 sourceRecord = intentActivity;
1638 } else if (!intentActivity.task.rootWasReset) {
1639 // In this case we are launching in to an existing task
1640 // that has not yet been started from its front door.
1641 // The current task has been brought to the front.
1642 // Ideally, we'd probably like to place this new task
1643 // at the bottom of its stack, but that's a little hard
1644 // to do with the current organization of the code so
1645 // for now we'll just drop it.
1646 intentActivity.task.setIntent(r.intent, r.info);
1647 }
1648 if (!addingToTask && reuseTask == null) {
1649 // We didn't do anything... but it was needed (a.k.a., client
1650 // don't use that intent!) And for paranoia, make
1651 // sure we have correctly resumed the top activity.
1652 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001653 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001654 } else {
1655 ActivityOptions.abort(options);
1656 }
1657 return ActivityManager.START_TASK_TO_FRONT;
1658 }
1659 }
1660 }
1661 }
1662
1663 //String uri = r.intent.toURI();
1664 //Intent intent2 = new Intent(uri);
1665 //Slog.i(TAG, "Given intent: " + r.intent);
1666 //Slog.i(TAG, "URI is: " + uri);
1667 //Slog.i(TAG, "To intent: " + intent2);
1668
1669 if (r.packageName != null) {
1670 // If the activity being launched is the same as the one currently
1671 // at the top, then we need to check if it should only be launched
1672 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001673 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001674 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001675 if (top != null && r.resultTo == null) {
1676 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1677 if (top.app != null && top.app.thread != null) {
1678 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1679 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1680 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1681 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1682 top.task);
1683 // For paranoia, make sure we have correctly
1684 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001685 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001686 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001687 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001688 }
1689 ActivityOptions.abort(options);
1690 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1691 // We don't need to start a new activity, and
1692 // the client said not to do anything if that
1693 // is the case, so this is it!
1694 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1695 }
1696 top.deliverNewIntentLocked(callingUid, r.intent);
1697 return ActivityManager.START_DELIVERED_TO_TOP;
1698 }
1699 }
1700 }
1701 }
1702
1703 } else {
1704 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001705 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1706 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001707 }
1708 ActivityOptions.abort(options);
1709 return ActivityManager.START_CLASS_NOT_FOUND;
1710 }
1711
1712 boolean newTask = false;
1713 boolean keepCurTransition = false;
1714
1715 // Should this be considered a new task?
1716 if (r.resultTo == null && !addingToTask
1717 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001718 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001719 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001720 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001721 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1722 newTaskInfo != null ? newTaskInfo : r.info,
1723 newTaskIntent != null ? newTaskIntent : intent,
1724 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001725 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1726 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001727 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001728 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001729 }
1730 newTask = true;
1731 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001732 if ((launchFlags &
1733 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1734 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1735 // Caller wants to appear on home activity, so before starting
1736 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001737 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001738 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001739 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001740 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001741 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001742 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001743 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001744 if (!addingToTask &&
1745 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1746 // In this case, we are adding the activity to an existing
1747 // task, but the caller has asked to clear that task if the
1748 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001749 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001750 keepCurTransition = true;
1751 if (top != null) {
1752 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1753 top.deliverNewIntentLocked(callingUid, r.intent);
1754 // For paranoia, make sure we have correctly
1755 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001756 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001757 if (doResume) {
1758 targetStack.resumeTopActivityLocked(null);
1759 }
1760 ActivityOptions.abort(options);
1761 return ActivityManager.START_DELIVERED_TO_TOP;
1762 }
1763 } else if (!addingToTask &&
1764 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1765 // In this case, we are launching an activity in our own task
1766 // that may already be running somewhere in the history, and
1767 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001768 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001769 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001770 final TaskRecord task = top.task;
1771 task.moveActivityToFrontLocked(top);
1772 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001773 top.updateOptionsLocked(options);
1774 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001775 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001776 if (doResume) {
1777 targetStack.resumeTopActivityLocked(null);
1778 }
1779 return ActivityManager.START_DELIVERED_TO_TOP;
1780 }
1781 }
1782 // An existing activity is starting this new activity, so we want
1783 // to keep the new one in the same task as the one that is starting
1784 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001785 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001786 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001787 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001788
1789 } else {
1790 // This not being started from an existing activity, and not part
1791 // of a new task... just put it in the top task, though these days
1792 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001793 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001794 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001795 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001796 r.setTask(prev != null ? prev.task
1797 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1798 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001799 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1800 + " in new guessed " + r.task);
1801 }
1802
1803 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1804 intent, r.getUriPermissionsLocked());
1805
1806 if (newTask) {
1807 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1808 }
1809 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001810 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001811 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001812 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001813 return ActivityManager.START_SUCCESS;
1814 }
1815
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001816 void acquireLaunchWakelock() {
1817 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1818 throw new IllegalStateException("Calling must be system uid");
1819 }
1820 mLaunchingActivity.acquire();
1821 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1822 // To be safe, don't allow the wake lock to be held for too long.
1823 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1824 }
1825 }
1826
Craig Mautnerf3333272013-04-22 10:55:53 -07001827 // Checked.
1828 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1829 Configuration config) {
1830 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1831
Craig Mautnerf3333272013-04-22 10:55:53 -07001832 ArrayList<ActivityRecord> stops = null;
1833 ArrayList<ActivityRecord> finishes = null;
1834 ArrayList<UserStartedState> startingUsers = null;
1835 int NS = 0;
1836 int NF = 0;
1837 IApplicationThread sendThumbnail = null;
1838 boolean booting = false;
1839 boolean enableScreen = false;
1840 boolean activityRemoved = false;
1841
1842 ActivityRecord r = ActivityRecord.forToken(token);
1843 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001844 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1845 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001846 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1847 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001848 if (fromTimeout) {
1849 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001850 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001851
1852 // This is a hack to semi-deal with a race condition
1853 // in the client where it can be constructed with a
1854 // newer configuration from when we asked it to launch.
1855 // We'll update with whatever configuration it now says
1856 // it used to launch.
1857 if (config != null) {
1858 r.configuration = config;
1859 }
1860
1861 // We are now idle. If someone is waiting for a thumbnail from
1862 // us, we can now deliver.
1863 r.idle = true;
1864
1865 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1866 sendThumbnail = r.app.thread;
1867 r.thumbnailNeeded = false;
1868 }
1869
1870 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1871 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1872 mService.mBooted = true;
1873 enableScreen = true;
1874 }
1875 }
1876
1877 if (allResumedActivitiesIdle()) {
1878 if (r != null) {
1879 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001880 }
1881
1882 if (mLaunchingActivity.isHeld()) {
1883 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1884 if (VALIDATE_WAKE_LOCK_CALLER &&
1885 Binder.getCallingUid() != Process.myUid()) {
1886 throw new IllegalStateException("Calling must be system uid");
1887 }
1888 mLaunchingActivity.release();
1889 }
1890 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001891 }
1892
1893 // Atomically retrieve all of the other things to do.
1894 stops = processStoppingActivitiesLocked(true);
1895 NS = stops != null ? stops.size() : 0;
1896 if ((NF=mFinishingActivities.size()) > 0) {
1897 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1898 mFinishingActivities.clear();
1899 }
1900
1901 final ArrayList<ActivityRecord> thumbnails;
1902 final int NT = mCancelledThumbnails.size();
1903 if (NT > 0) {
1904 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1905 mCancelledThumbnails.clear();
1906 } else {
1907 thumbnails = null;
1908 }
1909
1910 if (isFrontStack(mHomeStack)) {
1911 booting = mService.mBooting;
1912 mService.mBooting = false;
1913 }
1914
1915 if (mStartingUsers.size() > 0) {
1916 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1917 mStartingUsers.clear();
1918 }
1919
1920 // Perform the following actions from unsynchronized state.
1921 final IApplicationThread thumbnailThread = sendThumbnail;
1922 mHandler.post(new Runnable() {
1923 @Override
1924 public void run() {
1925 if (thumbnailThread != null) {
1926 try {
1927 thumbnailThread.requestThumbnail(token);
1928 } catch (Exception e) {
1929 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1930 mService.sendPendingThumbnail(null, token, null, null, true);
1931 }
1932 }
1933
1934 // Report back to any thumbnail receivers.
1935 for (int i = 0; i < NT; i++) {
1936 ActivityRecord r = thumbnails.get(i);
1937 mService.sendPendingThumbnail(r, null, null, null, true);
1938 }
1939 }
1940 });
1941
1942 // Stop any activities that are scheduled to do so but have been
1943 // waiting for the next one to start.
1944 for (int i = 0; i < NS; i++) {
1945 r = stops.get(i);
1946 final ActivityStack stack = r.task.stack;
1947 if (r.finishing) {
1948 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1949 } else {
1950 stack.stopActivityLocked(r);
1951 }
1952 }
1953
1954 // Finish 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 < NF; i++) {
1957 r = finishes.get(i);
1958 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1959 }
1960
1961 if (booting) {
1962 mService.finishBooting();
1963 } else if (startingUsers != null) {
1964 for (int i = 0; i < startingUsers.size(); i++) {
1965 mService.finishUserSwitch(startingUsers.get(i));
1966 }
1967 }
1968
1969 mService.trimApplications();
1970 //dump();
1971 //mWindowManager.dump();
1972
1973 if (enableScreen) {
1974 mService.enableScreenAfterBoot();
1975 }
1976
1977 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001978 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001979 }
1980
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001981 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001982 }
1983
Craig Mautner8e569572013-10-11 17:36:59 -07001984 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001985 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001986 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1987 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001988 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1989 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1990 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001991 }
Craig Mautner19091252013-10-05 00:03:53 -07001992 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001993 }
1994
1995 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08001996 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1997 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001998 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1999 stacks.get(stackNdx).closeSystemDialogsLocked();
2000 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002001 }
2002 }
2003
Craig Mautner93529a42013-10-04 15:03:13 -07002004 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002005 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002006 }
2007
Craig Mautner8d341ef2013-03-26 09:03:27 -07002008 /**
2009 * @return true if some activity was finished (or would have finished if doit were true).
2010 */
2011 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2012 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002013 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2014 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002015 final int numStacks = stacks.size();
2016 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2017 final ActivityStack stack = stacks.get(stackNdx);
2018 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2019 didSomething = true;
2020 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002021 }
2022 }
2023 return didSomething;
2024 }
2025
Dianne Hackborna413dc02013-07-12 12:02:55 -07002026 void updatePreviousProcessLocked(ActivityRecord r) {
2027 // Now that this process has stopped, we may want to consider
2028 // it to be the previous app to try to keep around in case
2029 // the user wants to return to it.
2030
2031 // First, found out what is currently the foreground app, so that
2032 // we don't blow away the previous app if this activity is being
2033 // hosted by the process that is actually still the foreground.
2034 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002035 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2036 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002037 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2038 final ActivityStack stack = stacks.get(stackNdx);
2039 if (isFrontStack(stack)) {
2040 if (stack.mResumedActivity != null) {
2041 fgApp = stack.mResumedActivity.app;
2042 } else if (stack.mPausingActivity != null) {
2043 fgApp = stack.mPausingActivity.app;
2044 }
2045 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002046 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002047 }
2048 }
2049
2050 // Now set this one as the previous process, only if that really
2051 // makes sense to.
2052 if (r.app != null && fgApp != null && r.app != fgApp
2053 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002054 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002055 mService.mPreviousProcess = r.app;
2056 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2057 }
2058 }
2059
Craig Mautner05d29032013-05-03 13:40:13 -07002060 boolean resumeTopActivitiesLocked() {
2061 return resumeTopActivitiesLocked(null, null, null);
2062 }
2063
2064 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2065 Bundle targetOptions) {
2066 if (targetStack == null) {
2067 targetStack = getFocusedStack();
2068 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002069 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002070 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002071 if (isFrontStack(targetStack)) {
2072 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2073 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002074 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2075 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002076 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2077 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002078 if (stack == targetStack) {
2079 // Already started above.
2080 continue;
2081 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002082 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002083 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002084 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002085 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002086 }
Craig Mautner05d29032013-05-03 13:40:13 -07002087 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002088 }
2089
2090 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002091 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2092 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002093 final int numStacks = stacks.size();
2094 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2095 final ActivityStack stack = stacks.get(stackNdx);
2096 stack.finishTopRunningActivityLocked(app);
2097 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002098 }
2099 }
2100
Craig Mautner8d341ef2013-03-26 09:03:27 -07002101 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002102 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2103 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002104 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2105 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2106 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2107 + stacks.get(stackNdx));
2108 return;
2109 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002110 }
2111 }
2112 }
2113
Craig Mautner967212c2013-04-13 21:10:58 -07002114 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002115 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2116 if (weakReference != null) {
2117 ActivityContainer activityContainer = weakReference.get();
2118 if (activityContainer != null) {
2119 return activityContainer.mStack;
2120 } else {
2121 mActivityContainers.remove(stackId);
2122 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002123 }
2124 return null;
2125 }
2126
Craig Mautner967212c2013-04-13 21:10:58 -07002127 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002128 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002129 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2130 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002131 }
2132 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002133 }
2134
Craig Mautner4a1cb222013-12-04 16:14:06 -08002135 IBinder getHomeActivityToken() {
2136 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2137 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2138 final TaskRecord task = tasks.get(taskNdx);
2139 if (task.isHomeTask()) {
2140 final ArrayList<ActivityRecord> activities = task.mActivities;
2141 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2142 final ActivityRecord r = activities.get(activityNdx);
2143 if (r.isHomeActivity()) {
2144 return r.appToken;
2145 }
2146 }
2147 }
2148 }
2149 return null;
2150 }
2151
2152 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2153 IActivityContainerCallback callback) {
2154 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2155 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002156 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002157 if (parentActivity != null) {
2158 parentActivity.mChildContainers.add(activityContainer.mStack);
2159 }
2160 return activityContainer;
2161 }
2162
2163 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2164 IActivityContainerCallback callback) {
2165 return createActivityContainer(parentActivity, getNextStackId(), callback);
2166 }
2167
Craig Mautner34b73df2014-01-12 21:11:08 -08002168 void removeChildActivityContainers(ActivityRecord parentActivity) {
2169 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2170 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2171 if (container == null) {
2172 mActivityContainers.removeAt(ndx);
2173 continue;
2174 }
2175 if (container.mParentActivity != parentActivity) {
2176 continue;
2177 }
2178
2179 ActivityStack stack = container.mStack;
2180 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2181 if (top != null) {
2182 // TODO: Make sure the next activity doesn't start up when top is destroyed.
2183 stack.destroyActivityLocked(top, true, true, "stack removal");
2184 }
2185 mActivityContainers.removeAt(ndx);
2186 container.detachLocked();
2187 }
2188 }
2189
Craig Mautner4a1cb222013-12-04 16:14:06 -08002190 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002191 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2192 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002193 return -1;
2194 }
2195
2196 ActivityContainer activityContainer =
2197 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002198 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002199 return stackId;
2200 }
2201
2202 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002203 while (true) {
2204 if (++mLastStackId <= HOME_STACK_ID) {
2205 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002206 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002207 if (getStack(mLastStackId) == null) {
2208 break;
2209 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002210 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002211 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002212 }
2213
2214 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002215 final TaskRecord task = anyTaskForIdLocked(taskId);
2216 if (task == null) {
2217 return;
2218 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002219 final ActivityStack stack = getStack(stackId);
2220 if (stack == null) {
2221 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2222 return;
2223 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002224 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002225 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002226 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002227 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002228 }
2229
Craig Mautnerac6f8432013-07-17 13:24:59 -07002230 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002231 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002232 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2233 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002234 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2235 final ActivityStack stack = stacks.get(stackNdx);
2236 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2237 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2238 continue;
2239 }
2240 final ActivityRecord ar = stack.findTaskLocked(r);
2241 if (ar != null) {
2242 return ar;
2243 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002244 }
2245 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002246 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002247 return null;
2248 }
2249
2250 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002251 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2252 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002253 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2254 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2255 if (ar != null) {
2256 return ar;
2257 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002258 }
2259 }
2260 return null;
2261 }
2262
Craig Mautner8d341ef2013-03-26 09:03:27 -07002263 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002264 scheduleSleepTimeout();
2265 if (!mGoingToSleep.isHeld()) {
2266 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002267 if (mLaunchingActivity.isHeld()) {
2268 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2269 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002270 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002271 mLaunchingActivity.release();
2272 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002273 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002274 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002275 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002276 }
2277
2278 boolean shutdownLocked(int timeout) {
2279 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002280 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002281
2282 final long endTime = System.currentTimeMillis() + timeout;
2283 while (true) {
2284 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002285 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2286 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002287 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2288 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2289 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002290 }
2291 if (cantShutdown) {
2292 long timeRemaining = endTime - System.currentTimeMillis();
2293 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002294 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002295 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002296 } catch (InterruptedException e) {
2297 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002298 } else {
2299 Slog.w(TAG, "Activity manager shutdown timed out");
2300 timedout = true;
2301 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002302 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002303 } else {
2304 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002305 }
2306 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002307
2308 // Force checkReadyForSleep to complete.
2309 mSleepTimeout = true;
2310 checkReadyForSleepLocked();
2311
Craig Mautner8d341ef2013-03-26 09:03:27 -07002312 return timedout;
2313 }
2314
2315 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002316 removeSleepTimeouts();
2317 if (mGoingToSleep.isHeld()) {
2318 mGoingToSleep.release();
2319 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002320 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2321 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002322 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2323 final ActivityStack stack = stacks.get(stackNdx);
2324 stack.awakeFromSleepingLocked();
2325 if (isFrontStack(stack)) {
2326 resumeTopActivitiesLocked();
2327 }
Craig Mautner5314a402013-09-26 12:40:16 -07002328 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002329 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002330 mGoingToSleepActivities.clear();
2331 }
2332
2333 void activitySleptLocked(ActivityRecord r) {
2334 mGoingToSleepActivities.remove(r);
2335 checkReadyForSleepLocked();
2336 }
2337
2338 void checkReadyForSleepLocked() {
2339 if (!mService.isSleepingOrShuttingDown()) {
2340 // Do not care.
2341 return;
2342 }
2343
2344 if (!mSleepTimeout) {
2345 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002346 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2347 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002348 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2349 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2350 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002351 }
2352
2353 if (mStoppingActivities.size() > 0) {
2354 // Still need to tell some activities to stop; can't sleep yet.
2355 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2356 + mStoppingActivities.size() + " activities");
2357 scheduleIdleLocked();
2358 dontSleep = true;
2359 }
2360
2361 if (mGoingToSleepActivities.size() > 0) {
2362 // Still need to tell some activities to sleep; can't sleep yet.
2363 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2364 + mGoingToSleepActivities.size() + " activities");
2365 dontSleep = true;
2366 }
2367
2368 if (dontSleep) {
2369 return;
2370 }
2371 }
2372
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 stacks.get(stackNdx).goToSleep();
2377 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002378 }
2379
2380 removeSleepTimeouts();
2381
2382 if (mGoingToSleep.isHeld()) {
2383 mGoingToSleep.release();
2384 }
2385 if (mService.mShuttingDown) {
2386 mService.notifyAll();
2387 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002388 }
2389
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002390 boolean reportResumedActivityLocked(ActivityRecord r) {
2391 final ActivityStack stack = r.task.stack;
2392 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002393 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002394 }
2395 if (allResumedActivitiesComplete()) {
2396 ensureActivitiesVisibleLocked(null, 0);
2397 mWindowManager.executeAppTransition();
2398 return true;
2399 }
2400 return false;
2401 }
2402
Craig Mautner8d341ef2013-03-26 09:03:27 -07002403 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002404 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2405 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002406 final int numStacks = stacks.size();
2407 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2408 final ActivityStack stack = stacks.get(stackNdx);
2409 stack.handleAppCrashLocked(app);
2410 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002411 }
2412 }
2413
Craig Mautnerde4ef022013-04-07 19:01:33 -07002414 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002415 // First the front stacks. In case any are not fullscreen and are in front of home.
2416 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002417 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2418 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002419 final int topStackNdx = stacks.size() - 1;
2420 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2421 final ActivityStack stack = stacks.get(stackNdx);
2422 if (stackNdx == topStackNdx) {
2423 // Top stack.
2424 showHomeBehindStack =
2425 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2426 } else {
2427 // Back stack.
2428 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2429 showHomeBehindStack);
2430 }
Craig Mautner580ea812013-04-25 12:58:38 -07002431 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002432 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002433 }
2434
2435 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002436 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2437 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002438 final int numStacks = stacks.size();
2439 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2440 final ActivityStack stack = stacks.get(stackNdx);
2441 stack.scheduleDestroyActivities(app, false, reason);
2442 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002443 }
2444 }
2445
2446 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002447 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2448 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002449 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002450
Craig Mautner858d8a62013-04-23 17:08:34 -07002451 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002452 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2453 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002454 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002455 final ActivityStack stack = stacks.get(stackNdx);
2456 stack.switchUserLocked(userId);
2457 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002458 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002459 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002460
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002461 ActivityStack stack = getStack(restoreStackId);
2462 if (stack == null) {
2463 stack = mHomeStack;
2464 }
2465 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002466 if (stack.isOnHomeDisplay()) {
2467 moveHomeStack(homeInFront);
2468 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2469 } else {
2470 // Stack was moved to another display while user was swapped out.
2471 resumeHomeActivity(null);
2472 }
Craig Mautner93529a42013-10-04 15:03:13 -07002473 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002474 }
2475
Craig Mautnerde4ef022013-04-07 19:01:33 -07002476 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2477 int N = mStoppingActivities.size();
2478 if (N <= 0) return null;
2479
2480 ArrayList<ActivityRecord> stops = null;
2481
2482 final boolean nowVisible = allResumedActivitiesVisible();
2483 for (int i=0; i<N; i++) {
2484 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002485 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002486 + nowVisible + " waitingVisible=" + s.waitingVisible
2487 + " finishing=" + s.finishing);
2488 if (s.waitingVisible && nowVisible) {
2489 mWaitingVisibleActivities.remove(s);
2490 s.waitingVisible = false;
2491 if (s.finishing) {
2492 // If this activity is finishing, it is sitting on top of
2493 // everyone else but we now know it is no longer needed...
2494 // so get rid of it. Otherwise, we need to go through the
2495 // normal flow and hide it once we determine that it is
2496 // hidden by the activities in front of it.
2497 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002498 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002499 }
2500 }
2501 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2502 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2503 if (stops == null) {
2504 stops = new ArrayList<ActivityRecord>();
2505 }
2506 stops.add(s);
2507 mStoppingActivities.remove(i);
2508 N--;
2509 i--;
2510 }
2511 }
2512
2513 return stops;
2514 }
2515
Craig Mautnercf910b02013-04-23 11:23:27 -07002516 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002517 // FIXME
2518/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2519 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002520 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002521 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002522 if (isFrontStack(stack)) {
2523 if (r == null) {
2524 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2525 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002526 final ActivityRecord pausing = stack.mPausingActivity;
2527 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002528 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002529 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002530 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002531 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002532 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002533 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002534 }
2535 }
2536 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002537 final ActivityRecord resumed = stack.mResumedActivity;
2538 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002539 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002540 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002541 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002542 if (r != null && (state == ActivityState.INITIALIZING
2543 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002544 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002545 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002546 }
2547 }
2548 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002549*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002550 }
2551
Craig Mautner27084302013-03-25 08:05:25 -07002552 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002553 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002554 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002555 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002556 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002557 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2558 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2559 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002560 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002561
Craig Mautner20e72272013-04-01 13:45:53 -07002562 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002563 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002564 }
2565
Dianne Hackborn390517b2013-05-30 15:03:32 -07002566 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2567 boolean needSep, String prefix) {
2568 if (activity != null) {
2569 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2570 if (needSep) {
2571 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002572 }
2573 pw.print(prefix);
2574 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002575 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002576 }
2577 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002578 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002579 }
2580
Craig Mautner8d341ef2013-03-26 09:03:27 -07002581 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2582 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002583 boolean printed = false;
2584 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002585 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2586 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2587 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2588 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002589 final int numStacks = stacks.size();
2590 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2591 final ActivityStack stack = stacks.get(stackNdx);
2592 StringBuilder stackHeader = new StringBuilder(128);
2593 stackHeader.append(" Stack #");
2594 stackHeader.append(stack.mStackId);
2595 stackHeader.append(":");
2596 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2597 needSep, stackHeader.toString());
2598 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2599 !dumpAll, false, dumpPackage, true,
2600 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002601
Craig Mautner4a1cb222013-12-04 16:14:06 -08002602 needSep = printed;
2603 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2604 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002605 if (pr) {
2606 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002607 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002608 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002609 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2610 " mResumedActivity: ");
2611 if (pr) {
2612 printed = true;
2613 needSep = false;
2614 }
2615 if (dumpAll) {
2616 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2617 " mLastPausedActivity: ");
2618 if (pr) {
2619 printed = true;
2620 needSep = true;
2621 }
2622 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2623 needSep, " mLastNoHistoryActivity: ");
2624 }
2625 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002626 }
2627 }
2628
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002629 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2630 false, dumpPackage, true, " Activities waiting to finish:", null);
2631 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2632 false, dumpPackage, true, " Activities waiting to stop:", null);
2633 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2634 false, dumpPackage, true, " Activities waiting for another to become visible:",
2635 null);
2636 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2637 false, dumpPackage, true, " Activities waiting to sleep:", null);
2638 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2639 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002640
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002641 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002642 }
2643
Dianne Hackborn390517b2013-05-30 15:03:32 -07002644 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002645 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002646 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002647 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002648 String innerPrefix = null;
2649 String[] args = null;
2650 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002651 for (int i=list.size()-1; i>=0; i--) {
2652 final ActivityRecord r = list.get(i);
2653 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2654 continue;
2655 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002656 if (innerPrefix == null) {
2657 innerPrefix = prefix + " ";
2658 args = new String[0];
2659 }
2660 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002661 final boolean full = !brief && (complete || !r.isInHistory());
2662 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002663 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002664 needNL = false;
2665 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002666 if (header1 != null) {
2667 pw.println(header1);
2668 header1 = null;
2669 }
2670 if (header2 != null) {
2671 pw.println(header2);
2672 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002673 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002674 if (lastTask != r.task) {
2675 lastTask = r.task;
2676 pw.print(prefix);
2677 pw.print(full ? "* " : " ");
2678 pw.println(lastTask);
2679 if (full) {
2680 lastTask.dump(pw, prefix + " ");
2681 } else if (complete) {
2682 // Complete + brief == give a summary. Isn't that obvious?!?
2683 if (lastTask.intent != null) {
2684 pw.print(prefix); pw.print(" ");
2685 pw.println(lastTask.intent.toInsecureStringWithClip());
2686 }
2687 }
2688 }
2689 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2690 pw.print(" #"); pw.print(i); pw.print(": ");
2691 pw.println(r);
2692 if (full) {
2693 r.dump(pw, innerPrefix);
2694 } else if (complete) {
2695 // Complete + brief == give a summary. Isn't that obvious?!?
2696 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2697 if (r.app != null) {
2698 pw.print(innerPrefix); pw.println(r.app);
2699 }
2700 }
2701 if (client && r.app != null && r.app.thread != null) {
2702 // flush anything that is already in the PrintWriter since the thread is going
2703 // to write to the file descriptor directly
2704 pw.flush();
2705 try {
2706 TransferPipe tp = new TransferPipe();
2707 try {
2708 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2709 r.appToken, innerPrefix, args);
2710 // Short timeout, since blocking here can
2711 // deadlock with the application.
2712 tp.go(fd, 2000);
2713 } finally {
2714 tp.kill();
2715 }
2716 } catch (IOException e) {
2717 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2718 } catch (RemoteException e) {
2719 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2720 }
2721 needNL = true;
2722 }
2723 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002724 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002725 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002726
Craig Mautnerf3333272013-04-22 10:55:53 -07002727 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002728 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002729 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2730 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002731 }
2732
2733 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002734 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002735 }
2736
2737 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002738 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002739 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2740 }
2741
Craig Mautner05d29032013-05-03 13:40:13 -07002742 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002743 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2744 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2745 }
Craig Mautner05d29032013-05-03 13:40:13 -07002746 }
2747
Craig Mautner0eea92c2013-05-16 13:35:39 -07002748 void removeSleepTimeouts() {
2749 mSleepTimeout = false;
2750 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2751 }
2752
2753 final void scheduleSleepTimeout() {
2754 removeSleepTimeouts();
2755 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2756 }
2757
Craig Mautner4a1cb222013-12-04 16:14:06 -08002758 @Override
2759 public void onDisplayAdded(int displayId) {
2760 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2761 }
2762
2763 @Override
2764 public void onDisplayRemoved(int displayId) {
2765 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2766 }
2767
2768 @Override
2769 public void onDisplayChanged(int displayId) {
2770 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2771 }
2772
2773 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002774 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002775 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002776 newDisplay = mActivityDisplays.get(displayId) == null;
2777 if (newDisplay) {
2778 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2779 mActivityDisplays.put(displayId, activityDisplay);
2780 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002781 }
Craig Mautner4504de52013-12-20 09:06:56 -08002782 if (newDisplay) {
2783 mWindowManager.onDisplayAdded(displayId);
2784 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002785 }
2786
2787 public void handleDisplayRemovedLocked(int displayId) {
2788 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002789 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2790 if (activityDisplay != null) {
2791 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002792 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002793 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002794 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002795 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002796 }
2797 }
2798 mWindowManager.onDisplayRemoved(displayId);
2799 }
2800
2801 public void handleDisplayChangedLocked(int displayId) {
2802 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002803 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2804 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002805 // TODO: Update the bounds.
2806 }
2807 }
2808 mWindowManager.onDisplayChanged(displayId);
2809 }
2810
2811 StackInfo getStackInfo(ActivityStack stack) {
2812 StackInfo info = new StackInfo();
2813 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2814 info.displayId = Display.DEFAULT_DISPLAY;
2815 info.stackId = stack.mStackId;
2816
2817 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2818 final int numTasks = tasks.size();
2819 int[] taskIds = new int[numTasks];
2820 String[] taskNames = new String[numTasks];
2821 for (int i = 0; i < numTasks; ++i) {
2822 final TaskRecord task = tasks.get(i);
2823 taskIds[i] = task.taskId;
2824 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2825 : task.realActivity != null ? task.realActivity.flattenToString()
2826 : task.getTopActivity() != null ? task.getTopActivity().packageName
2827 : "unknown";
2828 }
2829 info.taskIds = taskIds;
2830 info.taskNames = taskNames;
2831 return info;
2832 }
2833
2834 StackInfo getStackInfoLocked(int stackId) {
2835 ActivityStack stack = getStack(stackId);
2836 if (stack != null) {
2837 return getStackInfo(stack);
2838 }
2839 return null;
2840 }
2841
2842 ArrayList<StackInfo> getAllStackInfosLocked() {
2843 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002844 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2845 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002846 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2847 list.add(getStackInfo(stacks.get(ndx)));
2848 }
2849 }
2850 return list;
2851 }
2852
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002853 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002854
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002855 public ActivityStackSupervisorHandler(Looper looper) {
2856 super(looper);
2857 }
2858
Craig Mautnerf3333272013-04-22 10:55:53 -07002859 void activityIdleInternal(ActivityRecord r) {
2860 synchronized (mService) {
2861 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2862 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002863 }
2864
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002865 @Override
2866 public void handleMessage(Message msg) {
2867 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002868 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002869 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002870 if (mService.mDidDexOpt) {
2871 mService.mDidDexOpt = false;
2872 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2873 nmsg.obj = msg.obj;
2874 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2875 return;
2876 }
2877 // We don't at this point know if the activity is fullscreen,
2878 // so we need to be conservative and assume it isn't.
2879 activityIdleInternal((ActivityRecord)msg.obj);
2880 } break;
2881 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002882 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002883 activityIdleInternal((ActivityRecord)msg.obj);
2884 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002885 case RESUME_TOP_ACTIVITY_MSG: {
2886 synchronized (mService) {
2887 resumeTopActivitiesLocked();
2888 }
2889 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002890 case SLEEP_TIMEOUT_MSG: {
2891 synchronized (mService) {
2892 if (mService.isSleepingOrShuttingDown()) {
2893 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2894 mSleepTimeout = true;
2895 checkReadyForSleepLocked();
2896 }
2897 }
2898 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002899 case LAUNCH_TIMEOUT_MSG: {
2900 if (mService.mDidDexOpt) {
2901 mService.mDidDexOpt = false;
2902 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2903 return;
2904 }
2905 synchronized (mService) {
2906 if (mLaunchingActivity.isHeld()) {
2907 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2908 if (VALIDATE_WAKE_LOCK_CALLER
2909 && Binder.getCallingUid() != Process.myUid()) {
2910 throw new IllegalStateException("Calling must be system uid");
2911 }
2912 mLaunchingActivity.release();
2913 }
2914 }
2915 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002916 case HANDLE_DISPLAY_ADDED: {
2917 handleDisplayAddedLocked(msg.arg1);
2918 } break;
2919 case HANDLE_DISPLAY_CHANGED: {
2920 handleDisplayChangedLocked(msg.arg1);
2921 } break;
2922 case HANDLE_DISPLAY_REMOVED: {
2923 handleDisplayRemovedLocked(msg.arg1);
2924 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002925 }
2926 }
2927 }
Craig Mautnered6649f2013-12-02 14:08:25 -08002928
Craig Mautner4a1cb222013-12-04 16:14:06 -08002929 class ActivityContainer extends IActivityContainer.Stub {
2930 final int mStackId;
2931 final IActivityContainerCallback mCallback;
2932 final ActivityStack mStack;
2933 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08002934 final String mIdString;
Craig Mautnered6649f2013-12-02 14:08:25 -08002935
Craig Mautner4a1cb222013-12-04 16:14:06 -08002936 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002937 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002938
2939 ActivityContainer(ActivityRecord parentActivity, int stackId,
2940 IActivityContainerCallback callback) {
2941 synchronized (mService) {
2942 mStackId = stackId;
2943 mStack = new ActivityStack(this);
2944 mParentActivity = parentActivity;
2945 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08002946 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2947 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002948 }
Craig Mautnered6649f2013-12-02 14:08:25 -08002949 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002950
Craig Mautnere0a38842013-12-16 16:14:02 -08002951 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002952 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2953 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002954 mActivityDisplay = activityDisplay;
2955 mStack.mDisplayId = activityDisplay.mDisplayId;
2956 mStack.mStacks = activityDisplay.mStacks;
2957
2958 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002959 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002960 }
2961
2962 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08002963 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002964 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002965 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2966 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002967 return;
2968 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002969 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002970 }
2971 }
2972
2973 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08002974 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002975 if (mActivityDisplay != null) {
2976 return mActivityDisplay.mDisplayId;
2977 }
2978 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002979 }
2980
Jeff Brownca9bc702014-02-11 14:32:56 -08002981 @Override
2982 public boolean injectEvent(InputEvent event) {
2983 final long origId = Binder.clearCallingIdentity();
2984 try {
2985 if (mActivityDisplay != null) {
2986 return mInputManagerInternal.injectInputEvent(event,
2987 mActivityDisplay.mDisplayId,
2988 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
2989 }
2990 return false;
2991 } finally {
2992 Binder.restoreCallingIdentity(origId);
2993 }
2994 }
2995
Craig Mautner34b73df2014-01-12 21:11:08 -08002996 private void detachLocked() {
2997 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
2998 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08002999 if (mActivityDisplay != null) {
3000 mActivityDisplay.detachActivitiesLocked(mStack);
3001 mActivityDisplay = null;
3002 mStack.mDisplayId = -1;
3003 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003004 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003005 }
3006 }
3007
3008 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003009 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003010 synchronized (mService) {
3011 detachLocked();
3012 }
3013 }
3014
3015 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003016 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003017 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003018 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3019 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3020 // TODO: Switch to user app stacks here.
3021 String mimeType = intent.getType();
3022 if (mimeType == null && intent.getData() != null
3023 && "content".equals(intent.getData().getScheme())) {
3024 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3025 }
3026 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3027 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003028 }
3029
3030 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003031 public final int startActivityIntentSender(IIntentSender intentSender) {
3032 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3033
3034 if (!(intentSender instanceof PendingIntentRecord)) {
3035 throw new IllegalArgumentException("Bad PendingIntent object");
3036 }
3037
3038 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3039 null, 0, 0, 0, null, this);
3040 }
3041
3042 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003043 public IBinder asBinder() {
3044 return this;
3045 }
3046
Craig Mautner4504de52013-12-20 09:06:56 -08003047 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003048 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003049 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3050
3051 final long origId = Binder.clearCallingIdentity();
3052 try {
3053 synchronized (mService) {
3054 ActivityDisplay activityDisplay =
3055 new ActivityDisplay(surface, width, height, density);
3056 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3057 attachToDisplayLocked(activityDisplay);
3058 mStack.resumeTopActivityLocked(null);
3059 }
3060 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3061 + mActivityDisplay);
3062 } finally {
3063 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003064 }
Craig Mautner4504de52013-12-20 09:06:56 -08003065 }
3066
Craig Mautner4a1cb222013-12-04 16:14:06 -08003067 ActivityStackSupervisor getOuter() {
3068 return ActivityStackSupervisor.this;
3069 }
3070
3071 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003072 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003073 }
3074
3075 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003076 if (mActivityDisplay != null) {
3077 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003078 } else {
3079 outBounds.set(0, 0);
3080 }
3081 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003082
3083 @Override
3084 public String toString() {
3085 return mIdString + (mActivityDisplay == null ? "N" : "A");
3086 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003087 }
3088
Craig Mautner4a1cb222013-12-04 16:14:06 -08003089 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3090 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003091 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003092 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003093 int mDisplayId;
3094 Display mDisplay;
3095 DisplayInfo mDisplayInfo = new DisplayInfo();
3096 Surface mSurface;
Craig Mautnered6649f2013-12-02 14:08:25 -08003097
Craig Mautner4a1cb222013-12-04 16:14:06 -08003098 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3099 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003100 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003101
Craig Mautner4504de52013-12-20 09:06:56 -08003102 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3103 * here. */
3104 VirtualDisplay mVirtualDisplay;
3105
Craig Mautnere0a38842013-12-16 16:14:02 -08003106 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003107 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003108 }
3109
Craig Mautner34b73df2014-01-12 21:11:08 -08003110 ActivityDisplay(Surface surface, int width, int height, int density) {
3111 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3112 long ident = Binder.clearCallingIdentity();
3113 try {
3114 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3115 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3116 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3117 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3118 } finally {
3119 Binder.restoreCallingIdentity(ident);
3120 }
3121
3122 init(mVirtualDisplay.getDisplay());
3123 mSurface = surface;
3124
3125 mWindowManager.handleDisplayAdded(mDisplayId);
3126 }
3127
3128 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003129 mDisplay = display;
3130 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003131 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnered6649f2013-12-02 14:08:25 -08003132 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003133
3134 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003135 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3136 + mDisplayId);
3137 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003138 }
3139
Craig Mautnere0a38842013-12-16 16:14:02 -08003140 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003141 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003142 + " from displayId=" + mDisplayId);
3143 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003144 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3145 mVirtualDisplay.release();
3146 mVirtualDisplay = null;
3147 }
3148 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003149 }
3150
3151 void getBounds(Point bounds) {
3152 mDisplay.getDisplayInfo(mDisplayInfo);
3153 bounds.x = mDisplayInfo.appWidth;
3154 bounds.y = mDisplayInfo.appHeight;
3155 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003156
3157 @Override
3158 public String toString() {
3159 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3160 + " numStacks=" + mStacks.size() + "}";
3161 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003162 }
Craig Mautner27084302013-03-25 08:05:25 -07003163}