blob: 3587241aad1c1012de55156d3aa01b949bdeeae8 [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
Jeff Brown38f96e52014-02-11 14:32:56 -080064import android.hardware.input.InputManager;
65import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070067import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070068import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070069import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070070import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070071import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070072import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070074import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070075import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070078import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070079import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070082
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brown38f96e52014-02-11 14:32:56 -080086import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080087import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070088import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070089import com.android.internal.os.TransferPipe;
Jeff Brown38f96e52014-02-11 14:32:56 -080090import com.android.server.LocalServices;
Craig Mautner6170f732013-04-02 13:05:23 -070091import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070092import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070093import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070094
Craig Mautner8d341ef2013-03-26 09:03:27 -070095import java.io.FileDescriptor;
96import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070097import java.io.PrintWriter;
Craig Mautner4504de52013-12-20 09:06:56 -080098import java.lang.ref.WeakReference;
Craig Mautner2219a1b2013-03-25 09:44:30 -070099import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700100import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -0700101
Craig Mautner4a1cb222013-12-04 16:14:06 -0800102public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700103 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
104 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
105 static final boolean DEBUG_APP = DEBUG || false;
106 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700107 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700108 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700109
Craig Mautner2219a1b2013-03-25 09:44:30 -0700110 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700111
Craig Mautnerf3333272013-04-22 10:55:53 -0700112 /** How long we wait until giving up on the last activity telling us it is idle. */
113 static final int IDLE_TIMEOUT = 10*1000;
114
Craig Mautner0eea92c2013-05-16 13:35:39 -0700115 /** How long we can hold the sleep wake lock before giving up. */
116 static final int SLEEP_TIMEOUT = 5*1000;
117
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700118 // How long we can hold the launch wake lock before giving up.
119 static final int LAUNCH_TIMEOUT = 10*1000;
120
Craig Mautner05d29032013-05-03 13:40:13 -0700121 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
122 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
123 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700124 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700125 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800126 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
127 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
128 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
129
Craig Mautner4504de52013-12-20 09:06:56 -0800130 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700131
132 // For debugging to make sure the caller when acquiring/releasing our
133 // wake lock is the system process.
134 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700135
Craig Mautner27084302013-03-25 08:05:25 -0700136 final ActivityManagerService mService;
137
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700138 final ActivityStackSupervisorHandler mHandler;
139
140 /** Short cut */
141 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800142 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700143
Craig Mautner27084302013-03-25 08:05:25 -0700144 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700145 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700146
Craig Mautner8d341ef2013-03-26 09:03:27 -0700147 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700148 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700149
150 /** Task identifier that activities are currently being started in. Incremented each time a
151 * new task is created. */
152 private int mCurTaskId = 0;
153
Craig Mautner2420ead2013-04-01 17:13:20 -0700154 /** The current user */
155 private int mCurrentUser;
156
Craig Mautnere0a38842013-12-16 16:14:02 -0800157 /** The stack containing the launcher app. Assumed to always be attached to
158 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700159 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700160
Craig Mautnere0a38842013-12-16 16:14:02 -0800161 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700162 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700163
Craig Mautner4a1cb222013-12-04 16:14:06 -0800164 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
165 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800166 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800167 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700168
169 /** List of activities that are waiting for a new activity to become visible before completing
170 * whatever operation they are supposed to do. */
171 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
172
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700173 /** List of processes waiting to find out about the next visible activity. */
174 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
175 new ArrayList<IActivityManager.WaitResult>();
176
177 /** List of processes waiting to find out about the next launched activity. */
178 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
179 new ArrayList<IActivityManager.WaitResult>();
180
Craig Mautnerde4ef022013-04-07 19:01:33 -0700181 /** List of activities that are ready to be stopped, but waiting for the next activity to
182 * settle down before doing so. */
183 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
184
Craig Mautnerf3333272013-04-22 10:55:53 -0700185 /** List of activities that are ready to be finished, but waiting for the previous activity to
186 * settle down before doing so. It contains ActivityRecord objects. */
187 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
188
Craig Mautner0eea92c2013-05-16 13:35:39 -0700189 /** List of activities that are in the process of going to sleep. */
190 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
191
Craig Mautnerf3333272013-04-22 10:55:53 -0700192 /** List of ActivityRecord objects that have been finished and must still report back to a
193 * pending thumbnail receiver. */
194 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
195
196 /** Used on user changes */
197 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
198
Craig Mautnerde4ef022013-04-07 19:01:33 -0700199 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
200 * is being brought in front of us. */
201 boolean mUserLeaving = false;
202
Craig Mautner0eea92c2013-05-16 13:35:39 -0700203 /** Set when we have taken too long waiting to go to sleep. */
204 boolean mSleepTimeout = false;
205
206 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700207 * We don't want to allow the device to go to sleep while in the process
208 * of launching an activity. This is primarily to allow alarm intent
209 * receivers to launch an activity and get that to run before the device
210 * goes back to sleep.
211 */
212 final PowerManager.WakeLock mLaunchingActivity;
213
214 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700215 * Set when the system is going to sleep, until we have
216 * successfully paused the current activity and released our wake lock.
217 * At that point the system is allowed to actually sleep.
218 */
219 final PowerManager.WakeLock mGoingToSleep;
220
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700221 /** Stack id of the front stack when user switched, indexed by userId. */
222 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700223
Craig Mautner4504de52013-12-20 09:06:56 -0800224 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800225 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800226 SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
227 new SparseArray<WeakReference<ActivityContainer>>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800228
229 /** Mapping from displayId to display current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800230 private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800231
Jeff Brown38f96e52014-02-11 14:32:56 -0800232 InputManagerInternal mInputManagerInternal;
233
Craig Mautner4a1cb222013-12-04 16:14:06 -0800234 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700235 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800236 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700237 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800238 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700239 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
240 throw new IllegalStateException("Calling must be system uid");
241 }
242 mLaunchingActivity =
243 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
244 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700245 }
246
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700247 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800248 synchronized (mService) {
249 mWindowManager = wm;
250
251 mDisplayManager =
252 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
253 mDisplayManager.registerDisplayListener(this, null);
254
255 Display[] displays = mDisplayManager.getDisplays();
256 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
257 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800258 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
259 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800260 }
261
262 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
263 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brown38f96e52014-02-11 14:32:56 -0800264
265 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800266 }
Craig Mautner27084302013-03-25 08:05:25 -0700267 }
268
269 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700270 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700271 if (mDismissKeyguardOnNextActivity) {
272 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700273 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700274 }
275 }
276
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700277 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800278 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700279 }
280
Craig Mautnerde4ef022013-04-07 19:01:33 -0700281 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800282 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700283 }
284
Craig Mautner4a1cb222013-12-04 16:14:06 -0800285 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
286 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700287 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800288 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
289 if (parent != null) {
290 stack = parent.task.stack;
291 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800292 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800293 if (stacks != null && !stacks.isEmpty()) {
294 return stack == stacks.get(stacks.size() - 1);
295 }
296 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700297 }
298
Craig Mautnerde4ef022013-04-07 19:01:33 -0700299 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800300 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800301 int topNdx = stacks.size() - 1;
302 if (topNdx <= 0) {
303 return;
304 }
305 ActivityStack topStack = stacks.get(topNdx);
306 final boolean homeInFront = topStack == mHomeStack;
307 if (homeInFront != toFront) {
308 mLastFocusedStack = topStack;
309 stacks.remove(mHomeStack);
310 stacks.add(toFront ? topNdx : 0, mHomeStack);
311 mFocusedStack = stacks.get(topNdx);
312 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
313 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700314 }
315 }
316
Craig Mautner8e569572013-10-11 17:36:59 -0700317 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700318 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700319 mHomeStack.moveHomeTaskToTop();
320 }
321
322 boolean resumeHomeActivity(ActivityRecord prev) {
323 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700324 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700325 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700326 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700327 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700328 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700329 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700330 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700331 }
332 return mService.startHomeActivityLocked(mCurrentUser);
333 }
334
Craig Mautner27084302013-03-25 08:05:25 -0700335 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700336 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700337 mDismissKeyguardOnNextActivity = dismiss;
338 }
339
Craig Mautner8d341ef2013-03-26 09:03:27 -0700340 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800341 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800342 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800343 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800344 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
345 ActivityStack stack = stacks.get(stackNdx);
346 TaskRecord task = stack.taskForIdLocked(id);
347 if (task != null) {
348 return task;
349 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700350 }
351 }
352 return null;
353 }
354
Craig Mautner6170f732013-04-02 13:05:23 -0700355 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800356 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800357 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800358 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800359 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
360 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
361 if (r != null) {
362 return r;
363 }
Craig Mautner6170f732013-04-02 13:05:23 -0700364 }
365 }
366 return null;
367 }
368
Craig Mautner8d341ef2013-03-26 09:03:27 -0700369 int getNextTaskId() {
370 do {
371 mCurTaskId++;
372 if (mCurTaskId <= 0) {
373 mCurTaskId = 1;
374 }
375 } while (anyTaskForIdLocked(mCurTaskId) != null);
376 return mCurTaskId;
377 }
378
Craig Mautnerde4ef022013-04-07 19:01:33 -0700379 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700380 ActivityStack stack = getFocusedStack();
381 if (stack == null) {
382 return null;
383 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700384 ActivityRecord resumedActivity = stack.mResumedActivity;
385 if (resumedActivity == null || resumedActivity.app == null) {
386 resumedActivity = stack.mPausingActivity;
387 if (resumedActivity == null || resumedActivity.app == null) {
388 resumedActivity = stack.topRunningActivityLocked(null);
389 }
390 }
391 return resumedActivity;
392 }
393
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800394 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700395 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800396 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800397 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
398 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800399 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
400 final ActivityStack stack = stacks.get(stackNdx);
401 if (!isFrontStack(stack)) {
402 continue;
403 }
404 ActivityRecord hr = stack.topRunningActivityLocked(null);
405 if (hr != null) {
406 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
407 && processName.equals(hr.processName)) {
408 try {
409 if (realStartActivityLocked(hr, app, true, true)) {
410 didSomething = true;
411 }
412 } catch (Exception e) {
413 Slog.w(TAG, "Exception in new application when starting activity "
414 + hr.intent.getComponent().flattenToShortString(), e);
415 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700416 }
Craig Mautner20e72272013-04-01 13:45:53 -0700417 }
Craig Mautner20e72272013-04-01 13:45:53 -0700418 }
419 }
420 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700421 if (!didSomething) {
422 ensureActivitiesVisibleLocked(null, 0);
423 }
Craig Mautner20e72272013-04-01 13:45:53 -0700424 return didSomething;
425 }
426
427 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800428 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
429 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800430 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
431 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800432 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800433 continue;
434 }
435 final ActivityRecord resumedActivity = stack.mResumedActivity;
436 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800437 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
438 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800439 return false;
440 }
Craig Mautner20e72272013-04-01 13:45:53 -0700441 }
442 }
443 return true;
444 }
445
Craig Mautnerde4ef022013-04-07 19:01:33 -0700446 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800447 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
448 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800449 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
450 final ActivityStack stack = stacks.get(stackNdx);
451 if (isFrontStack(stack)) {
452 final ActivityRecord r = stack.mResumedActivity;
453 if (r != null && r.state != ActivityState.RESUMED) {
454 return false;
455 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700456 }
457 }
458 }
459 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800460 if (DEBUG_STACK) Slog.d(TAG,
461 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
462 mLastFocusedStack + " to=" + mFocusedStack);
463 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700464 return true;
465 }
466
467 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800468 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
469 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800470 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
471 final ActivityStack stack = stacks.get(stackNdx);
472 final ActivityRecord r = stack.mResumedActivity;
473 if (r != null && (!r.nowVisible || r.waitingVisible)) {
474 return false;
475 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700476 }
477 }
478 return true;
479 }
480
Craig Mautner2acc3892013-09-23 10:28:14 -0700481 /**
482 * Pause all activities in either all of the stacks or just the back stacks.
483 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700484 * @return true if any activity was paused as a result of this call.
485 */
Craig Mautner5314a402013-09-26 12:40:16 -0700486 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700487 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800488 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
489 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800490 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
491 final ActivityStack stack = stacks.get(stackNdx);
492 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
493 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
494 " mResumedActivity=" + stack.mResumedActivity);
495 stack.startPausingLocked(userLeaving, false);
496 someActivityPaused = true;
497 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700498 }
499 }
500 return someActivityPaused;
501 }
502
Craig Mautnerde4ef022013-04-07 19:01:33 -0700503 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700504 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800505 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
506 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800507 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
508 final ActivityStack stack = stacks.get(stackNdx);
509 final ActivityRecord r = stack.mPausingActivity;
510 if (r != null && r.state != ActivityState.PAUSED
511 && r.state != ActivityState.STOPPED
512 && r.state != ActivityState.STOPPING) {
513 if (DEBUG_STATES) {
514 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
515 pausing = false;
516 } else {
517 return false;
518 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700519 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700520 }
521 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700522 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700523 }
524
Craig Mautnerdf88d732014-01-27 09:21:32 -0800525 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
526 // TODO: Put all stacks in supervisor and iterate through them instead.
527 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
528 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
529 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
530 final ActivityStack stack = stacks.get(stackNdx);
531 if (stack.mResumedActivity != null &&
532 stack.mActivityContainer.mParentActivity == parent) {
533 stack.startPausingLocked(userLeaving, uiSleeping);
534 }
535 }
536 }
537 }
538
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700539 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700540 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700541 WaitResult w = mWaitingActivityVisible.get(i);
542 w.timeout = false;
543 if (r != null) {
544 w.who = new ComponentName(r.info.packageName, r.info.name);
545 }
546 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
547 w.thisTime = w.totalTime;
548 }
549 mService.notifyAll();
550 dismissKeyguard();
551 }
552
553 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
554 long thisTime, long totalTime) {
555 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700556 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700557 w.timeout = timeout;
558 if (r != null) {
559 w.who = new ComponentName(r.info.packageName, r.info.name);
560 }
561 w.thisTime = thisTime;
562 w.totalTime = totalTime;
563 }
564 mService.notifyAll();
565 }
566
Craig Mautner29219d92013-04-16 20:19:12 -0700567 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700568 final ActivityStack focusedStack = getFocusedStack();
569 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
570 if (r != null) {
571 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700572 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700573
Craig Mautner4a1cb222013-12-04 16:14:06 -0800574 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800575 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800576 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
577 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700578 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700579 r = stack.topRunningActivityLocked(null);
580 if (r != null) {
581 return r;
582 }
583 }
584 }
585 return null;
586 }
587
Craig Mautner20e72272013-04-01 13:45:53 -0700588 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
589 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
590 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700591
592 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800593 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
594 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800595 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800596 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800597 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800598 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
599 final ActivityStack stack = stacks.get(stackNdx);
600 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
601 runningTaskLists.add(stackTaskList);
602 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
603 if (r == null && isFrontStack(stack)) {
604 r = ar;
605 }
Craig Mautner20e72272013-04-01 13:45:53 -0700606 }
607 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700608
609 // The lists are already sorted from most recent to oldest. Just pull the most recent off
610 // each list and add it to list. Stop when all lists are empty or maxNum reached.
611 while (maxNum > 0) {
612 long mostRecentActiveTime = Long.MIN_VALUE;
613 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800614 final int numTaskLists = runningTaskLists.size();
615 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
616 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700617 if (!stackTaskList.isEmpty()) {
618 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
619 if (lastActiveTime > mostRecentActiveTime) {
620 mostRecentActiveTime = lastActiveTime;
621 selectedStackList = stackTaskList;
622 }
623 }
624 }
625 if (selectedStackList != null) {
626 list.add(selectedStackList.remove(0));
627 --maxNum;
628 } else {
629 break;
630 }
631 }
632
Craig Mautner20e72272013-04-01 13:45:53 -0700633 return r;
634 }
635
Craig Mautner23ac33b2013-04-01 16:26:35 -0700636 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
637 String profileFile, ParcelFileDescriptor profileFd, int userId) {
638 // Collect information about the target of the Intent.
639 ActivityInfo aInfo;
640 try {
641 ResolveInfo rInfo =
642 AppGlobals.getPackageManager().resolveIntent(
643 intent, resolvedType,
644 PackageManager.MATCH_DEFAULT_ONLY
645 | ActivityManagerService.STOCK_PM_FLAGS, userId);
646 aInfo = rInfo != null ? rInfo.activityInfo : null;
647 } catch (RemoteException e) {
648 aInfo = null;
649 }
650
651 if (aInfo != null) {
652 // Store the found target back into the intent, because now that
653 // we have it we never want to do this again. For example, if the
654 // user navigates back to this point in the history, we should
655 // always restart the exact same activity.
656 intent.setComponent(new ComponentName(
657 aInfo.applicationInfo.packageName, aInfo.name));
658
659 // Don't debug things in the system process
660 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
661 if (!aInfo.processName.equals("system")) {
662 mService.setDebugApp(aInfo.processName, true, false);
663 }
664 }
665
666 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
667 if (!aInfo.processName.equals("system")) {
668 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
669 }
670 }
671
672 if (profileFile != null) {
673 if (!aInfo.processName.equals("system")) {
674 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
675 profileFile, profileFd,
676 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
677 }
678 }
679 }
680 return aInfo;
681 }
682
Craig Mautner2219a1b2013-03-25 09:44:30 -0700683 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700684 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700685 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800686 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700687 }
688
Craig Mautner23ac33b2013-04-01 16:26:35 -0700689 final int startActivityMayWait(IApplicationThread caller, int callingUid,
690 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
691 String resultWho, int requestCode, int startFlags, String profileFile,
692 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800693 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700694 // Refuse possible leaked file descriptors
695 if (intent != null && intent.hasFileDescriptors()) {
696 throw new IllegalArgumentException("File descriptors passed in Intent");
697 }
698 boolean componentSpecified = intent.getComponent() != null;
699
700 // Don't modify the client's object!
701 intent = new Intent(intent);
702
703 // Collect information about the target of the Intent.
704 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
705 profileFile, profileFd, userId);
706
Craig Mautnere0a38842013-12-16 16:14:02 -0800707 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700708 synchronized (mService) {
709 int callingPid;
710 if (callingUid >= 0) {
711 callingPid = -1;
712 } else if (caller == null) {
713 callingPid = Binder.getCallingPid();
714 callingUid = Binder.getCallingUid();
715 } else {
716 callingPid = callingUid = -1;
717 }
718
Craig Mautnere0a38842013-12-16 16:14:02 -0800719 final ActivityStack stack;
720 if (container == null || container.mStack.isOnHomeDisplay()) {
721 stack = getFocusedStack();
722 } else {
723 stack = container.mStack;
724 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700725 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700726 && mService.mConfiguration.diff(config) != 0;
727 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700728 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700729
730 final long origId = Binder.clearCallingIdentity();
731
732 if (aInfo != null &&
733 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
734 // This may be a heavy-weight process! Check to see if we already
735 // have another, different heavy-weight process running.
736 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
737 if (mService.mHeavyWeightProcess != null &&
738 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
739 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700740 int realCallingUid = callingUid;
741 if (caller != null) {
742 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
743 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700744 realCallingUid = callerApp.info.uid;
745 } else {
746 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700747 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700748 + intent.toString());
749 ActivityOptions.abort(options);
750 return ActivityManager.START_PERMISSION_DENIED;
751 }
752 }
753
754 IIntentSender target = mService.getIntentSenderLocked(
755 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
756 realCallingUid, userId, null, null, 0, new Intent[] { intent },
757 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
758 | PendingIntent.FLAG_ONE_SHOT, null);
759
760 Intent newIntent = new Intent();
761 if (requestCode >= 0) {
762 // Caller is requesting a result.
763 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
764 }
765 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
766 new IntentSender(target));
767 if (mService.mHeavyWeightProcess.activities.size() > 0) {
768 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
769 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
770 hist.packageName);
771 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
772 hist.task.taskId);
773 }
774 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
775 aInfo.packageName);
776 newIntent.setFlags(intent.getFlags());
777 newIntent.setClassName("android",
778 HeavyWeightSwitcherActivity.class.getName());
779 intent = newIntent;
780 resolvedType = null;
781 caller = null;
782 callingUid = Binder.getCallingUid();
783 callingPid = Binder.getCallingPid();
784 componentSpecified = true;
785 try {
786 ResolveInfo rInfo =
787 AppGlobals.getPackageManager().resolveIntent(
788 intent, null,
789 PackageManager.MATCH_DEFAULT_ONLY
790 | ActivityManagerService.STOCK_PM_FLAGS, userId);
791 aInfo = rInfo != null ? rInfo.activityInfo : null;
792 aInfo = mService.getActivityInfoForUser(aInfo, userId);
793 } catch (RemoteException e) {
794 aInfo = null;
795 }
796 }
797 }
798 }
799
Craig Mautnere0a38842013-12-16 16:14:02 -0800800 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
801 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
802 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700803
Craig Mautnerde4ef022013-04-07 19:01:33 -0700804 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700805 // If the caller also wants to switch to a new configuration,
806 // do so now. This allows a clean switch, as we are waiting
807 // for the current activity to pause (so we will not destroy
808 // it), and have not yet started the next activity.
809 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
810 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700811 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700812 if (DEBUG_CONFIGURATION) Slog.v(TAG,
813 "Updating to new configuration after starting activity.");
814 mService.updateConfigurationLocked(config, null, false, false);
815 }
816
817 Binder.restoreCallingIdentity(origId);
818
819 if (outResult != null) {
820 outResult.result = res;
821 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700822 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700823 do {
824 try {
825 mService.wait();
826 } catch (InterruptedException e) {
827 }
828 } while (!outResult.timeout && outResult.who == null);
829 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700830 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700831 if (r.nowVisible) {
832 outResult.timeout = false;
833 outResult.who = new ComponentName(r.info.packageName, r.info.name);
834 outResult.totalTime = 0;
835 outResult.thisTime = 0;
836 } else {
837 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700838 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700839 do {
840 try {
841 mService.wait();
842 } catch (InterruptedException e) {
843 }
844 } while (!outResult.timeout && outResult.who == null);
845 }
846 }
847 }
848
849 return res;
850 }
851 }
852
853 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
854 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
855 Bundle options, int userId) {
856 if (intents == null) {
857 throw new NullPointerException("intents is null");
858 }
859 if (resolvedTypes == null) {
860 throw new NullPointerException("resolvedTypes is null");
861 }
862 if (intents.length != resolvedTypes.length) {
863 throw new IllegalArgumentException("intents are length different than resolvedTypes");
864 }
865
Craig Mautner23ac33b2013-04-01 16:26:35 -0700866
867 int callingPid;
868 if (callingUid >= 0) {
869 callingPid = -1;
870 } else if (caller == null) {
871 callingPid = Binder.getCallingPid();
872 callingUid = Binder.getCallingUid();
873 } else {
874 callingPid = callingUid = -1;
875 }
876 final long origId = Binder.clearCallingIdentity();
877 try {
878 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700879 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700880 for (int i=0; i<intents.length; i++) {
881 Intent intent = intents[i];
882 if (intent == null) {
883 continue;
884 }
885
886 // Refuse possible leaked file descriptors
887 if (intent != null && intent.hasFileDescriptors()) {
888 throw new IllegalArgumentException("File descriptors passed in Intent");
889 }
890
891 boolean componentSpecified = intent.getComponent() != null;
892
893 // Don't modify the client's object!
894 intent = new Intent(intent);
895
896 // Collect information about the target of the Intent.
897 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
898 0, null, null, userId);
899 // TODO: New, check if this is correct
900 aInfo = mService.getActivityInfoForUser(aInfo, userId);
901
902 if (aInfo != null &&
903 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
904 != 0) {
905 throw new IllegalArgumentException(
906 "FLAG_CANT_SAVE_STATE not supported here");
907 }
908
909 Bundle theseOptions;
910 if (options != null && i == intents.length-1) {
911 theseOptions = options;
912 } else {
913 theseOptions = null;
914 }
Craig Mautner6170f732013-04-02 13:05:23 -0700915 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700916 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800917 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700918 if (res < 0) {
919 return res;
920 }
921
922 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
923 }
924 }
925 } finally {
926 Binder.restoreCallingIdentity(origId);
927 }
928
929 return ActivityManager.START_SUCCESS;
930 }
931
Craig Mautner2420ead2013-04-01 17:13:20 -0700932 final boolean realStartActivityLocked(ActivityRecord r,
933 ProcessRecord app, boolean andResume, boolean checkConfig)
934 throws RemoteException {
935
936 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700937 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700938 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700939
940 // schedule launch ticks to collect information about slow apps.
941 r.startLaunchTickingLocked();
942
943 // Have the window manager re-evaluate the orientation of
944 // the screen based on the new activity order. Note that
945 // as a result of this, it can call back into the activity
946 // manager with a new orientation. We don't care about that,
947 // because the activity is not currently running so we are
948 // just restarting it anyway.
949 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700950 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700951 mService.mConfiguration,
952 r.mayFreezeScreenLocked(app) ? r.appToken : null);
953 mService.updateConfigurationLocked(config, r, false, false);
954 }
955
956 r.app = app;
957 app.waitingToKill = null;
958 r.launchCount++;
959 r.lastLaunchTime = SystemClock.uptimeMillis();
960
961 if (localLOGV) Slog.v(TAG, "Launching: " + r);
962
963 int idx = app.activities.indexOf(r);
964 if (idx < 0) {
965 app.activities.add(r);
966 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700967 mService.updateLruProcessLocked(app, true, null);
968 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700969
970 final ActivityStack stack = r.task.stack;
971 try {
972 if (app.thread == null) {
973 throw new RemoteException();
974 }
975 List<ResultInfo> results = null;
976 List<Intent> newIntents = null;
977 if (andResume) {
978 results = r.results;
979 newIntents = r.newIntents;
980 }
981 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
982 + " icicle=" + r.icicle
983 + " with results=" + results + " newIntents=" + newIntents
984 + " andResume=" + andResume);
985 if (andResume) {
986 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
987 r.userId, System.identityHashCode(r),
988 r.task.taskId, r.shortComponentName);
989 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700990 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700991 // Home process is the root process of the task.
992 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700993 }
994 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
995 r.sleeping = false;
996 r.forceNewConfig = false;
997 mService.showAskCompatModeDialogLocked(r);
998 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
999 String profileFile = null;
1000 ParcelFileDescriptor profileFd = null;
1001 boolean profileAutoStop = false;
1002 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1003 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1004 mService.mProfileProc = app;
1005 profileFile = mService.mProfileFile;
1006 profileFd = mService.mProfileFd;
1007 profileAutoStop = mService.mAutoStopProfiler;
1008 }
1009 }
1010 app.hasShownUi = true;
1011 app.pendingUiClean = true;
1012 if (profileFd != null) {
1013 try {
1014 profileFd = profileFd.dup();
1015 } catch (IOException e) {
1016 if (profileFd != null) {
1017 try {
1018 profileFd.close();
1019 } catch (IOException o) {
1020 }
1021 profileFd = null;
1022 }
1023 }
1024 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001025 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001026 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1027 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001028 new Configuration(mService.mConfiguration), r.compat,
1029 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001030 mService.isNextTransitionForward(), profileFile, profileFd,
1031 profileAutoStop);
1032
1033 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1034 // This may be a heavy-weight process! Note that the package
1035 // manager will ensure that only activity can run in the main
1036 // process of the .apk, which is the only thing that will be
1037 // considered heavy-weight.
1038 if (app.processName.equals(app.info.packageName)) {
1039 if (mService.mHeavyWeightProcess != null
1040 && mService.mHeavyWeightProcess != app) {
1041 Slog.w(TAG, "Starting new heavy weight process " + app
1042 + " when already running "
1043 + mService.mHeavyWeightProcess);
1044 }
1045 mService.mHeavyWeightProcess = app;
1046 Message msg = mService.mHandler.obtainMessage(
1047 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1048 msg.obj = r;
1049 mService.mHandler.sendMessage(msg);
1050 }
1051 }
1052
1053 } catch (RemoteException e) {
1054 if (r.launchFailed) {
1055 // This is the second time we failed -- finish activity
1056 // and give up.
1057 Slog.e(TAG, "Second failure launching "
1058 + r.intent.getComponent().flattenToShortString()
1059 + ", giving up", e);
1060 mService.appDiedLocked(app, app.pid, app.thread);
1061 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1062 "2nd-crash", false);
1063 return false;
1064 }
1065
1066 // This is the first time we failed -- restart process and
1067 // retry.
1068 app.activities.remove(r);
1069 throw e;
1070 }
1071
1072 r.launchFailed = false;
1073 if (stack.updateLRUListLocked(r)) {
1074 Slog.w(TAG, "Activity " + r
1075 + " being launched, but already in LRU list");
1076 }
1077
1078 if (andResume) {
1079 // As part of the process of launching, ActivityThread also performs
1080 // a resume.
1081 stack.minimalResumeActivityLocked(r);
1082 } else {
1083 // This activity is not starting in the resumed state... which
1084 // should look like we asked it to pause+stop (but remain visible),
1085 // and it has done so and reported back the current icicle and
1086 // other state.
1087 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1088 + " (starting in stopped state)");
1089 r.state = ActivityState.STOPPED;
1090 r.stopped = true;
1091 }
1092
1093 // Launch the new version setup screen if needed. We do this -after-
1094 // launching the initial activity (that is, home), so that it can have
1095 // a chance to initialize itself while in the background, making the
1096 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001097 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001098 mService.startSetupActivityLocked();
1099 }
1100
1101 return true;
1102 }
1103
Craig Mautnere79d42682013-04-01 19:01:53 -07001104 void startSpecificActivityLocked(ActivityRecord r,
1105 boolean andResume, boolean checkConfig) {
1106 // Is this activity's application already running?
1107 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001108 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001109
1110 r.task.stack.setLaunchTime(r);
1111
1112 if (app != null && app.thread != null) {
1113 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001114 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1115 || !"android".equals(r.info.packageName)) {
1116 // Don't add this if it is a platform component that is marked
1117 // to run in multiple processes, because this is actually
1118 // part of the framework so doesn't make sense to track as a
1119 // separate apk in the process.
1120 app.addPackage(r.info.packageName, mService.mProcessStats);
1121 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001122 realStartActivityLocked(r, app, andResume, checkConfig);
1123 return;
1124 } catch (RemoteException e) {
1125 Slog.w(TAG, "Exception when starting activity "
1126 + r.intent.getComponent().flattenToShortString(), e);
1127 }
1128
1129 // If a dead object exception was thrown -- fall through to
1130 // restart the application.
1131 }
1132
1133 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001134 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001135 }
1136
Craig Mautner6170f732013-04-02 13:05:23 -07001137 final int startActivityLocked(IApplicationThread caller,
1138 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1139 String resultWho, int requestCode,
1140 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001141 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001142 int err = ActivityManager.START_SUCCESS;
1143
1144 ProcessRecord callerApp = null;
1145 if (caller != null) {
1146 callerApp = mService.getRecordForAppLocked(caller);
1147 if (callerApp != null) {
1148 callingPid = callerApp.pid;
1149 callingUid = callerApp.info.uid;
1150 } else {
1151 Slog.w(TAG, "Unable to find app for caller " + caller
1152 + " (pid=" + callingPid + ") when starting: "
1153 + intent.toString());
1154 err = ActivityManager.START_PERMISSION_DENIED;
1155 }
1156 }
1157
1158 if (err == ActivityManager.START_SUCCESS) {
1159 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1160 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001161 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1162 + " on display " + (container == null ? (mFocusedStack == null ?
1163 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1164 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1165 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001166 }
1167
1168 ActivityRecord sourceRecord = null;
1169 ActivityRecord resultRecord = null;
1170 if (resultTo != null) {
1171 sourceRecord = isInAnyStackLocked(resultTo);
1172 if (DEBUG_RESULTS) Slog.v(
1173 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1174 if (sourceRecord != null) {
1175 if (requestCode >= 0 && !sourceRecord.finishing) {
1176 resultRecord = sourceRecord;
1177 }
1178 }
1179 }
1180 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1181
1182 int launchFlags = intent.getFlags();
1183
1184 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1185 && sourceRecord != null) {
1186 // Transfer the result target from the source activity to the new
1187 // one being started, including any failures.
1188 if (requestCode >= 0) {
1189 ActivityOptions.abort(options);
1190 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1191 }
1192 resultRecord = sourceRecord.resultTo;
1193 resultWho = sourceRecord.resultWho;
1194 requestCode = sourceRecord.requestCode;
1195 sourceRecord.resultTo = null;
1196 if (resultRecord != null) {
1197 resultRecord.removeResultsLocked(
1198 sourceRecord, resultWho, requestCode);
1199 }
1200 }
1201
1202 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1203 // We couldn't find a class that can handle the given Intent.
1204 // That's the end of that!
1205 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1206 }
1207
1208 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1209 // We couldn't find the specific class specified in the Intent.
1210 // Also the end of the line.
1211 err = ActivityManager.START_CLASS_NOT_FOUND;
1212 }
1213
1214 if (err != ActivityManager.START_SUCCESS) {
1215 if (resultRecord != null) {
1216 resultStack.sendActivityResultLocked(-1,
1217 resultRecord, resultWho, requestCode,
1218 Activity.RESULT_CANCELED, null);
1219 }
1220 setDismissKeyguard(false);
1221 ActivityOptions.abort(options);
1222 return err;
1223 }
1224
1225 final int startAnyPerm = mService.checkPermission(
1226 START_ANY_ACTIVITY, callingPid, callingUid);
1227 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1228 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1229 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1230 if (resultRecord != null) {
1231 resultStack.sendActivityResultLocked(-1,
1232 resultRecord, resultWho, requestCode,
1233 Activity.RESULT_CANCELED, null);
1234 }
1235 setDismissKeyguard(false);
1236 String msg;
1237 if (!aInfo.exported) {
1238 msg = "Permission Denial: starting " + intent.toString()
1239 + " from " + callerApp + " (pid=" + callingPid
1240 + ", uid=" + callingUid + ")"
1241 + " not exported from uid " + aInfo.applicationInfo.uid;
1242 } else {
1243 msg = "Permission Denial: starting " + intent.toString()
1244 + " from " + callerApp + " (pid=" + callingPid
1245 + ", uid=" + callingUid + ")"
1246 + " requires " + aInfo.permission;
1247 }
1248 Slog.w(TAG, msg);
1249 throw new SecurityException(msg);
1250 }
1251
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001252 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001253 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001254
Craig Mautner6170f732013-04-02 13:05:23 -07001255 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001256 try {
1257 // The Intent we give to the watcher has the extra data
1258 // stripped off, since it can contain private information.
1259 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001260 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001261 aInfo.applicationInfo.packageName);
1262 } catch (RemoteException e) {
1263 mService.mController = null;
1264 }
Ben Gruver5e207332013-04-03 17:41:37 -07001265 }
Craig Mautner6170f732013-04-02 13:05:23 -07001266
Ben Gruver5e207332013-04-03 17:41:37 -07001267 if (abort) {
1268 if (resultRecord != null) {
1269 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001270 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001271 }
Ben Gruver5e207332013-04-03 17:41:37 -07001272 // We pretend to the caller that it was really started, but
1273 // they will just get a cancel result.
1274 setDismissKeyguard(false);
1275 ActivityOptions.abort(options);
1276 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001277 }
1278
1279 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001280 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1281 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001282 if (outActivity != null) {
1283 outActivity[0] = r;
1284 }
1285
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001286 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001287 if (stack.mResumedActivity == null
1288 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001289 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1290 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001291 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001292 mService.mPendingActivityLaunches.add(pal);
1293 setDismissKeyguard(false);
1294 ActivityOptions.abort(options);
1295 return ActivityManager.START_SWITCHES_CANCELED;
1296 }
1297 }
1298
1299 if (mService.mDidAppSwitch) {
1300 // This is the second allowed switch since we stopped switches,
1301 // so now just generally allow switches. Use case: user presses
1302 // home (switches disabled, switch to home, mDidAppSwitch now true);
1303 // user taps a home icon (coming from home so allowed, we hit here
1304 // and now allow anyone to switch again).
1305 mService.mAppSwitchesAllowedTime = 0;
1306 } else {
1307 mService.mDidAppSwitch = true;
1308 }
1309
1310 mService.doPendingActivityLaunchesLocked(false);
1311
Craig Mautner8849a5e2013-04-02 16:41:03 -07001312 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001313
1314 if (allPausedActivitiesComplete()) {
1315 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001316 // activity start, but we are not actually doing an activity
1317 // switch... just dismiss the keyguard now, because we
1318 // probably want to see whatever is behind it.
1319 dismissKeyguard();
1320 }
1321 return err;
1322 }
1323
Craig Mautnerac6f8432013-07-17 13:24:59 -07001324 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001325 final TaskRecord task = r.task;
1326 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001327 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001328 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001329 if (taskStack.isOnHomeDisplay()) {
1330 if (mFocusedStack != taskStack) {
1331 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1332 "focused stack to r=" + r + " task=" + task);
1333 mFocusedStack = taskStack;
1334 } else {
1335 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1336 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1337 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001338 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001339 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001340 }
1341
Craig Mautnere0a38842013-12-16 16:14:02 -08001342 final ActivityContainer container = r.mInitialActivityContainer;
1343 if (container != null) {
1344 // The first time put it on the desired stack, after this put on task stack.
1345 r.mInitialActivityContainer = null;
1346 return container.mStack;
1347 }
1348
Craig Mautner4a1cb222013-12-04 16:14:06 -08001349 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001350 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1351 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1352 return mFocusedStack;
1353 }
1354
Craig Mautnere0a38842013-12-16 16:14:02 -08001355 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1356 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1357 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1358 if (!stack.isHomeStack()) {
1359 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1360 "adjustStackFocus: Setting focused stack=" + stack);
1361 mFocusedStack = stack;
1362 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001363 }
1364 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001365
Craig Mautner4a1cb222013-12-04 16:14:06 -08001366 // Need to create an app stack for this user.
1367 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001368 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1369 " stackId=" + stackId);
1370 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001371 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001372 }
1373 return mHomeStack;
1374 }
1375
Craig Mautner29219d92013-04-16 20:19:12 -07001376 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001377 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001378 final TaskRecord task = r.task;
1379 boolean isHomeActivity = !r.isApplicationActivity();
1380 if (!isHomeActivity && task != null) {
1381 isHomeActivity = !task.isApplicationTask();
1382 }
1383 if (!isHomeActivity && task != null) {
1384 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1385 isHomeActivity = parent != null && parent.isHomeActivity();
1386 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001387 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001388 }
1389 }
1390
Craig Mautner8849a5e2013-04-02 16:41:03 -07001391 final int startActivityUncheckedLocked(ActivityRecord r,
1392 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1393 Bundle options) {
1394 final Intent intent = r.intent;
1395 final int callingUid = r.launchedFromUid;
1396
1397 int launchFlags = intent.getFlags();
1398
Craig Mautner8849a5e2013-04-02 16:41:03 -07001399 // We'll invoke onUserLeaving before onPause only if the launching
1400 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001401 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1402 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001403
1404 // If the caller has asked not to resume at this point, we make note
1405 // of this in the record so that we can skip it when trying to find
1406 // the top running activity.
1407 if (!doResume) {
1408 r.delayedResume = true;
1409 }
1410
1411 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1412
1413 // If the onlyIfNeeded flag is set, then we can do this if the activity
1414 // being launched is the same as the one making the call... or, as
1415 // a special case, if we do not know the caller then we count the
1416 // current top activity as the caller.
1417 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1418 ActivityRecord checkedCaller = sourceRecord;
1419 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001420 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001421 }
1422 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1423 // Caller is not the same as launcher, so always needed.
1424 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1425 }
1426 }
1427
1428 if (sourceRecord == null) {
1429 // This activity is not being started from another... in this
1430 // case we -always- start a new task.
1431 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001432 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1433 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001434 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1435 }
1436 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1437 // The original activity who is starting us is running as a single
1438 // instance... this new activity it is starting must go on its
1439 // own task.
1440 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1441 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1442 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1443 // The activity being started is a single instance... it always
1444 // gets launched into its own task.
1445 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1446 }
1447
Craig Mautner88629292013-11-10 20:39:05 -08001448 ActivityInfo newTaskInfo = null;
1449 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001450 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001451 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001452 if (sourceRecord.finishing) {
1453 // If the source is finishing, we can't further count it as our source. This
1454 // is because the task it is associated with may now be empty and on its way out,
1455 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001456 // the NEW_TASK flow and try to find a task for it. But save the task information
1457 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001458 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1459 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1460 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1461 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001462 newTaskInfo = sourceRecord.info;
1463 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001464 }
1465 sourceRecord = null;
1466 sourceStack = null;
1467 } else {
1468 sourceStack = sourceRecord.task.stack;
1469 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001470 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001471 sourceStack = null;
1472 }
1473
Craig Mautner8849a5e2013-04-02 16:41:03 -07001474 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1475 // For whatever reason this activity is being launched into a new
1476 // task... yet the caller has requested a result back. Well, that
1477 // is pretty messed up, so instead immediately send back a cancel
1478 // and let the new task continue launched as normal without a
1479 // dependency on its originator.
1480 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1481 r.resultTo.task.stack.sendActivityResultLocked(-1,
1482 r.resultTo, r.resultWho, r.requestCode,
1483 Activity.RESULT_CANCELED, null);
1484 r.resultTo = null;
1485 }
1486
1487 boolean addingToTask = false;
1488 boolean movedHome = false;
1489 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001490 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001491 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1492 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1493 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1494 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1495 // If bring to front is requested, and no result is requested, and
1496 // we can find a task that was started with this same
1497 // component, then instead of launching bring that one to the front.
1498 if (r.resultTo == null) {
1499 // See if there is a task to bring to the front. If this is
1500 // a SINGLE_INSTANCE activity, there can be one and only one
1501 // instance of it in the history, and it is always in its own
1502 // unique task, so we do a special search.
1503 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001504 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001505 : findActivityLocked(intent, r.info);
1506 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001507 if (r.task == null) {
1508 r.task = intentActivity.task;
1509 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001510 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001511 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001512 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1513 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001514 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001515 if (intentActivity.task.intent == null) {
1516 // This task was started because of movement of
1517 // the activity based on affinity... now that we
1518 // are actually launching it, we can assign the
1519 // base intent.
1520 intentActivity.task.setIntent(intent, r.info);
1521 }
1522 // If the target task is not in the front, then we need
1523 // to bring it to the front... except... well, with
1524 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1525 // to have the same behavior as if a new instance was
1526 // being started, which means not bringing it to the front
1527 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001528 final ActivityStack lastStack = getLastStack();
1529 ActivityRecord curTop = lastStack == null?
1530 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001531 if (curTop != null && (curTop.task != intentActivity.task ||
1532 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001533 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001534 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1535 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001536 // We really do want to push this one into the
1537 // user's face, right now.
1538 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001539 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001540 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001541 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1542 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001543 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001544 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001545 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001546 options = null;
1547 }
1548 }
1549 // If the caller has requested that the target task be
1550 // reset, then do so.
1551 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1552 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1553 }
1554 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1555 // We don't need to start a new activity, and
1556 // the client said not to do anything if that
1557 // is the case, so this is it! And for paranoia, make
1558 // sure we have correctly resumed the top activity.
1559 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001560 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001561 } else {
1562 ActivityOptions.abort(options);
1563 }
1564 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1565 }
1566 if ((launchFlags &
1567 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1568 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1569 // The caller has requested to completely replace any
1570 // existing task with its new activity. Well that should
1571 // not be too hard...
1572 reuseTask = intentActivity.task;
1573 reuseTask.performClearTaskLocked();
1574 reuseTask.setIntent(r.intent, r.info);
1575 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1576 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1577 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1578 // In this situation we want to remove all activities
1579 // from the task up to the one being started. In most
1580 // cases this means we are resetting the task to its
1581 // initial state.
1582 ActivityRecord top =
1583 intentActivity.task.performClearTaskLocked(r, launchFlags);
1584 if (top != null) {
1585 if (top.frontOfTask) {
1586 // Activity aliases may mean we use different
1587 // intents for the top activity, so make sure
1588 // the task now has the identity of the new
1589 // intent.
1590 top.task.setIntent(r.intent, r.info);
1591 }
1592 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1593 r, top.task);
1594 top.deliverNewIntentLocked(callingUid, r.intent);
1595 } else {
1596 // A special case: we need to
1597 // start the activity because it is not currently
1598 // running, and the caller has asked to clear the
1599 // current task to have this activity at the top.
1600 addingToTask = true;
1601 // Now pretend like this activity is being started
1602 // by the top of its task, so it is put in the
1603 // right place.
1604 sourceRecord = intentActivity;
1605 }
1606 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1607 // In this case the top activity on the task is the
1608 // same as the one being launched, so we take that
1609 // as a request to bring the task to the foreground.
1610 // If the top activity in the task is the root
1611 // activity, deliver this new intent to it if it
1612 // desires.
1613 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1614 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1615 && intentActivity.realActivity.equals(r.realActivity)) {
1616 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1617 intentActivity.task);
1618 if (intentActivity.frontOfTask) {
1619 intentActivity.task.setIntent(r.intent, r.info);
1620 }
1621 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1622 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1623 // In this case we are launching the root activity
1624 // of the task, but with a different intent. We
1625 // should start a new instance on top.
1626 addingToTask = true;
1627 sourceRecord = intentActivity;
1628 }
1629 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1630 // In this case an activity is being launched in to an
1631 // existing task, without resetting that task. This
1632 // is typically the situation of launching an activity
1633 // from a notification or shortcut. We want to place
1634 // the new activity on top of the current task.
1635 addingToTask = true;
1636 sourceRecord = intentActivity;
1637 } else if (!intentActivity.task.rootWasReset) {
1638 // In this case we are launching in to an existing task
1639 // that has not yet been started from its front door.
1640 // The current task has been brought to the front.
1641 // Ideally, we'd probably like to place this new task
1642 // at the bottom of its stack, but that's a little hard
1643 // to do with the current organization of the code so
1644 // for now we'll just drop it.
1645 intentActivity.task.setIntent(r.intent, r.info);
1646 }
1647 if (!addingToTask && reuseTask == null) {
1648 // We didn't do anything... but it was needed (a.k.a., client
1649 // don't use that intent!) And for paranoia, make
1650 // sure we have correctly resumed the top activity.
1651 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001652 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001653 } else {
1654 ActivityOptions.abort(options);
1655 }
1656 return ActivityManager.START_TASK_TO_FRONT;
1657 }
1658 }
1659 }
1660 }
1661
1662 //String uri = r.intent.toURI();
1663 //Intent intent2 = new Intent(uri);
1664 //Slog.i(TAG, "Given intent: " + r.intent);
1665 //Slog.i(TAG, "URI is: " + uri);
1666 //Slog.i(TAG, "To intent: " + intent2);
1667
1668 if (r.packageName != null) {
1669 // If the activity being launched is the same as the one currently
1670 // at the top, then we need to check if it should only be launched
1671 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001672 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001673 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001674 if (top != null && r.resultTo == null) {
1675 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1676 if (top.app != null && top.app.thread != null) {
1677 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1678 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1679 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1680 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1681 top.task);
1682 // For paranoia, make sure we have correctly
1683 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001684 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001685 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001686 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001687 }
1688 ActivityOptions.abort(options);
1689 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1690 // We don't need to start a new activity, and
1691 // the client said not to do anything if that
1692 // is the case, so this is it!
1693 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1694 }
1695 top.deliverNewIntentLocked(callingUid, r.intent);
1696 return ActivityManager.START_DELIVERED_TO_TOP;
1697 }
1698 }
1699 }
1700 }
1701
1702 } else {
1703 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001704 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1705 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001706 }
1707 ActivityOptions.abort(options);
1708 return ActivityManager.START_CLASS_NOT_FOUND;
1709 }
1710
1711 boolean newTask = false;
1712 boolean keepCurTransition = false;
1713
1714 // Should this be considered a new task?
1715 if (r.resultTo == null && !addingToTask
1716 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001717 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001718 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001719 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001720 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1721 newTaskInfo != null ? newTaskInfo : r.info,
1722 newTaskIntent != null ? newTaskIntent : intent,
1723 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001724 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1725 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001726 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001727 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001728 }
1729 newTask = true;
1730 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001731 if ((launchFlags &
1732 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1733 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1734 // Caller wants to appear on home activity, so before starting
1735 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001736 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001737 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001738 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001739 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001740 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001741 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001742 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001743 if (!addingToTask &&
1744 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1745 // In this case, we are adding the activity to an existing
1746 // task, but the caller has asked to clear that task if the
1747 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001748 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001749 keepCurTransition = true;
1750 if (top != null) {
1751 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1752 top.deliverNewIntentLocked(callingUid, r.intent);
1753 // For paranoia, make sure we have correctly
1754 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001755 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001756 if (doResume) {
1757 targetStack.resumeTopActivityLocked(null);
1758 }
1759 ActivityOptions.abort(options);
1760 return ActivityManager.START_DELIVERED_TO_TOP;
1761 }
1762 } else if (!addingToTask &&
1763 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1764 // In this case, we are launching an activity in our own task
1765 // that may already be running somewhere in the history, and
1766 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001767 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001768 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001769 final TaskRecord task = top.task;
1770 task.moveActivityToFrontLocked(top);
1771 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001772 top.updateOptionsLocked(options);
1773 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001774 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001775 if (doResume) {
1776 targetStack.resumeTopActivityLocked(null);
1777 }
1778 return ActivityManager.START_DELIVERED_TO_TOP;
1779 }
1780 }
1781 // An existing activity is starting this new activity, so we want
1782 // to keep the new one in the same task as the one that is starting
1783 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001784 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001785 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001786 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001787
1788 } else {
1789 // This not being started from an existing activity, and not part
1790 // of a new task... just put it in the top task, though these days
1791 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001792 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001793 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001794 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001795 r.setTask(prev != null ? prev.task
1796 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1797 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001798 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1799 + " in new guessed " + r.task);
1800 }
1801
1802 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1803 intent, r.getUriPermissionsLocked());
1804
1805 if (newTask) {
1806 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1807 }
1808 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001809 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001810 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001811 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001812 return ActivityManager.START_SUCCESS;
1813 }
1814
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001815 void acquireLaunchWakelock() {
1816 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1817 throw new IllegalStateException("Calling must be system uid");
1818 }
1819 mLaunchingActivity.acquire();
1820 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1821 // To be safe, don't allow the wake lock to be held for too long.
1822 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1823 }
1824 }
1825
Craig Mautnerf3333272013-04-22 10:55:53 -07001826 // Checked.
1827 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1828 Configuration config) {
1829 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1830
Craig Mautnerf3333272013-04-22 10:55:53 -07001831 ArrayList<ActivityRecord> stops = null;
1832 ArrayList<ActivityRecord> finishes = null;
1833 ArrayList<UserStartedState> startingUsers = null;
1834 int NS = 0;
1835 int NF = 0;
1836 IApplicationThread sendThumbnail = null;
1837 boolean booting = false;
1838 boolean enableScreen = false;
1839 boolean activityRemoved = false;
1840
1841 ActivityRecord r = ActivityRecord.forToken(token);
1842 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001843 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1844 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001845 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1846 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001847 if (fromTimeout) {
1848 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001849 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001850
1851 // This is a hack to semi-deal with a race condition
1852 // in the client where it can be constructed with a
1853 // newer configuration from when we asked it to launch.
1854 // We'll update with whatever configuration it now says
1855 // it used to launch.
1856 if (config != null) {
1857 r.configuration = config;
1858 }
1859
1860 // We are now idle. If someone is waiting for a thumbnail from
1861 // us, we can now deliver.
1862 r.idle = true;
1863
1864 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1865 sendThumbnail = r.app.thread;
1866 r.thumbnailNeeded = false;
1867 }
1868
1869 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1870 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1871 mService.mBooted = true;
1872 enableScreen = true;
1873 }
1874 }
1875
1876 if (allResumedActivitiesIdle()) {
1877 if (r != null) {
1878 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001879 }
1880
1881 if (mLaunchingActivity.isHeld()) {
1882 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1883 if (VALIDATE_WAKE_LOCK_CALLER &&
1884 Binder.getCallingUid() != Process.myUid()) {
1885 throw new IllegalStateException("Calling must be system uid");
1886 }
1887 mLaunchingActivity.release();
1888 }
1889 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001890 }
1891
1892 // Atomically retrieve all of the other things to do.
1893 stops = processStoppingActivitiesLocked(true);
1894 NS = stops != null ? stops.size() : 0;
1895 if ((NF=mFinishingActivities.size()) > 0) {
1896 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1897 mFinishingActivities.clear();
1898 }
1899
1900 final ArrayList<ActivityRecord> thumbnails;
1901 final int NT = mCancelledThumbnails.size();
1902 if (NT > 0) {
1903 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1904 mCancelledThumbnails.clear();
1905 } else {
1906 thumbnails = null;
1907 }
1908
1909 if (isFrontStack(mHomeStack)) {
1910 booting = mService.mBooting;
1911 mService.mBooting = false;
1912 }
1913
1914 if (mStartingUsers.size() > 0) {
1915 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1916 mStartingUsers.clear();
1917 }
1918
1919 // Perform the following actions from unsynchronized state.
1920 final IApplicationThread thumbnailThread = sendThumbnail;
1921 mHandler.post(new Runnable() {
1922 @Override
1923 public void run() {
1924 if (thumbnailThread != null) {
1925 try {
1926 thumbnailThread.requestThumbnail(token);
1927 } catch (Exception e) {
1928 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1929 mService.sendPendingThumbnail(null, token, null, null, true);
1930 }
1931 }
1932
1933 // Report back to any thumbnail receivers.
1934 for (int i = 0; i < NT; i++) {
1935 ActivityRecord r = thumbnails.get(i);
1936 mService.sendPendingThumbnail(r, null, null, null, true);
1937 }
1938 }
1939 });
1940
1941 // Stop any activities that are scheduled to do so but have been
1942 // waiting for the next one to start.
1943 for (int i = 0; i < NS; i++) {
1944 r = stops.get(i);
1945 final ActivityStack stack = r.task.stack;
1946 if (r.finishing) {
1947 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1948 } else {
1949 stack.stopActivityLocked(r);
1950 }
1951 }
1952
1953 // Finish any activities that are scheduled to do so but have been
1954 // waiting for the next one to start.
1955 for (int i = 0; i < NF; i++) {
1956 r = finishes.get(i);
1957 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1958 }
1959
1960 if (booting) {
1961 mService.finishBooting();
1962 } else if (startingUsers != null) {
1963 for (int i = 0; i < startingUsers.size(); i++) {
1964 mService.finishUserSwitch(startingUsers.get(i));
1965 }
1966 }
1967
1968 mService.trimApplications();
1969 //dump();
1970 //mWindowManager.dump();
1971
1972 if (enableScreen) {
1973 mService.enableScreenAfterBoot();
1974 }
1975
1976 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001977 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001978 }
1979
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001980 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001981 }
1982
Craig Mautner8e569572013-10-11 17:36:59 -07001983 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001984 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001985 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1986 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001987 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1988 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1989 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001990 }
Craig Mautner19091252013-10-05 00:03:53 -07001991 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001992 }
1993
1994 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08001995 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1996 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001997 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1998 stacks.get(stackNdx).closeSystemDialogsLocked();
1999 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002000 }
2001 }
2002
Craig Mautner93529a42013-10-04 15:03:13 -07002003 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002004 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002005 }
2006
Craig Mautner8d341ef2013-03-26 09:03:27 -07002007 /**
2008 * @return true if some activity was finished (or would have finished if doit were true).
2009 */
2010 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2011 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002012 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2013 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002014 final int numStacks = stacks.size();
2015 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2016 final ActivityStack stack = stacks.get(stackNdx);
2017 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2018 didSomething = true;
2019 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002020 }
2021 }
2022 return didSomething;
2023 }
2024
Dianne Hackborna413dc02013-07-12 12:02:55 -07002025 void updatePreviousProcessLocked(ActivityRecord r) {
2026 // Now that this process has stopped, we may want to consider
2027 // it to be the previous app to try to keep around in case
2028 // the user wants to return to it.
2029
2030 // First, found out what is currently the foreground app, so that
2031 // we don't blow away the previous app if this activity is being
2032 // hosted by the process that is actually still the foreground.
2033 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002034 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2035 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002036 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2037 final ActivityStack stack = stacks.get(stackNdx);
2038 if (isFrontStack(stack)) {
2039 if (stack.mResumedActivity != null) {
2040 fgApp = stack.mResumedActivity.app;
2041 } else if (stack.mPausingActivity != null) {
2042 fgApp = stack.mPausingActivity.app;
2043 }
2044 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002045 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002046 }
2047 }
2048
2049 // Now set this one as the previous process, only if that really
2050 // makes sense to.
2051 if (r.app != null && fgApp != null && r.app != fgApp
2052 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002053 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002054 mService.mPreviousProcess = r.app;
2055 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2056 }
2057 }
2058
Craig Mautner05d29032013-05-03 13:40:13 -07002059 boolean resumeTopActivitiesLocked() {
2060 return resumeTopActivitiesLocked(null, null, null);
2061 }
2062
2063 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2064 Bundle targetOptions) {
2065 if (targetStack == null) {
2066 targetStack = getFocusedStack();
2067 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002068 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002069 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002070 if (isFrontStack(targetStack)) {
2071 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2072 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002073 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2074 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002075 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2076 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002077 if (stack == targetStack) {
2078 // Already started above.
2079 continue;
2080 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002081 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002082 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002083 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002084 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002085 }
Craig Mautner05d29032013-05-03 13:40:13 -07002086 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002087 }
2088
2089 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002090 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2091 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002092 final int numStacks = stacks.size();
2093 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2094 final ActivityStack stack = stacks.get(stackNdx);
2095 stack.finishTopRunningActivityLocked(app);
2096 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002097 }
2098 }
2099
Craig Mautner8d341ef2013-03-26 09:03:27 -07002100 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002101 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2102 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002103 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2104 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2105 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2106 + stacks.get(stackNdx));
2107 return;
2108 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002109 }
2110 }
2111 }
2112
Craig Mautner967212c2013-04-13 21:10:58 -07002113 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002114 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2115 if (weakReference != null) {
2116 ActivityContainer activityContainer = weakReference.get();
2117 if (activityContainer != null) {
2118 return activityContainer.mStack;
2119 } else {
2120 mActivityContainers.remove(stackId);
2121 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002122 }
2123 return null;
2124 }
2125
Craig Mautner967212c2013-04-13 21:10:58 -07002126 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002127 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002128 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2129 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002130 }
2131 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002132 }
2133
Craig Mautner4a1cb222013-12-04 16:14:06 -08002134 IBinder getHomeActivityToken() {
2135 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2136 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2137 final TaskRecord task = tasks.get(taskNdx);
2138 if (task.isHomeTask()) {
2139 final ArrayList<ActivityRecord> activities = task.mActivities;
2140 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2141 final ActivityRecord r = activities.get(activityNdx);
2142 if (r.isHomeActivity()) {
2143 return r.appToken;
2144 }
2145 }
2146 }
2147 }
2148 return null;
2149 }
2150
2151 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2152 IActivityContainerCallback callback) {
2153 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2154 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002155 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002156 if (parentActivity != null) {
2157 parentActivity.mChildContainers.add(activityContainer.mStack);
2158 }
2159 return activityContainer;
2160 }
2161
2162 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2163 IActivityContainerCallback callback) {
2164 return createActivityContainer(parentActivity, getNextStackId(), callback);
2165 }
2166
Craig Mautner34b73df2014-01-12 21:11:08 -08002167 void removeChildActivityContainers(ActivityRecord parentActivity) {
2168 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2169 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2170 if (container == null) {
2171 mActivityContainers.removeAt(ndx);
2172 continue;
2173 }
2174 if (container.mParentActivity != parentActivity) {
2175 continue;
2176 }
2177
2178 ActivityStack stack = container.mStack;
2179 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2180 if (top != null) {
2181 // TODO: Make sure the next activity doesn't start up when top is destroyed.
2182 stack.destroyActivityLocked(top, true, true, "stack removal");
2183 }
2184 mActivityContainers.removeAt(ndx);
2185 container.detachLocked();
2186 }
2187 }
2188
Craig Mautner4a1cb222013-12-04 16:14:06 -08002189 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002190 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2191 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002192 return -1;
2193 }
2194
2195 ActivityContainer activityContainer =
2196 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002197 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002198 return stackId;
2199 }
2200
2201 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002202 while (true) {
2203 if (++mLastStackId <= HOME_STACK_ID) {
2204 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002205 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002206 if (getStack(mLastStackId) == null) {
2207 break;
2208 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002209 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002210 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002211 }
2212
2213 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002214 final TaskRecord task = anyTaskForIdLocked(taskId);
2215 if (task == null) {
2216 return;
2217 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002218 final ActivityStack stack = getStack(stackId);
2219 if (stack == null) {
2220 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2221 return;
2222 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002223 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002224 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002225 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002226 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002227 }
2228
Craig Mautnerac6f8432013-07-17 13:24:59 -07002229 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002230 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002231 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2232 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002233 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2234 final ActivityStack stack = stacks.get(stackNdx);
2235 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2236 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2237 continue;
2238 }
2239 final ActivityRecord ar = stack.findTaskLocked(r);
2240 if (ar != null) {
2241 return ar;
2242 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002243 }
2244 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002245 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002246 return null;
2247 }
2248
2249 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002250 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2251 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002252 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2253 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2254 if (ar != null) {
2255 return ar;
2256 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002257 }
2258 }
2259 return null;
2260 }
2261
Craig Mautner8d341ef2013-03-26 09:03:27 -07002262 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002263 scheduleSleepTimeout();
2264 if (!mGoingToSleep.isHeld()) {
2265 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002266 if (mLaunchingActivity.isHeld()) {
2267 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2268 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002269 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002270 mLaunchingActivity.release();
2271 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002272 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002273 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002274 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002275 }
2276
2277 boolean shutdownLocked(int timeout) {
2278 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002279 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002280
2281 final long endTime = System.currentTimeMillis() + timeout;
2282 while (true) {
2283 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002284 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2285 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002286 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2287 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2288 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002289 }
2290 if (cantShutdown) {
2291 long timeRemaining = endTime - System.currentTimeMillis();
2292 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002293 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002294 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002295 } catch (InterruptedException e) {
2296 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002297 } else {
2298 Slog.w(TAG, "Activity manager shutdown timed out");
2299 timedout = true;
2300 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002301 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002302 } else {
2303 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002304 }
2305 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002306
2307 // Force checkReadyForSleep to complete.
2308 mSleepTimeout = true;
2309 checkReadyForSleepLocked();
2310
Craig Mautner8d341ef2013-03-26 09:03:27 -07002311 return timedout;
2312 }
2313
2314 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002315 removeSleepTimeouts();
2316 if (mGoingToSleep.isHeld()) {
2317 mGoingToSleep.release();
2318 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002319 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2320 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002321 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2322 final ActivityStack stack = stacks.get(stackNdx);
2323 stack.awakeFromSleepingLocked();
2324 if (isFrontStack(stack)) {
2325 resumeTopActivitiesLocked();
2326 }
Craig Mautner5314a402013-09-26 12:40:16 -07002327 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002328 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002329 mGoingToSleepActivities.clear();
2330 }
2331
2332 void activitySleptLocked(ActivityRecord r) {
2333 mGoingToSleepActivities.remove(r);
2334 checkReadyForSleepLocked();
2335 }
2336
2337 void checkReadyForSleepLocked() {
2338 if (!mService.isSleepingOrShuttingDown()) {
2339 // Do not care.
2340 return;
2341 }
2342
2343 if (!mSleepTimeout) {
2344 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002345 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2346 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002347 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2348 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2349 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002350 }
2351
2352 if (mStoppingActivities.size() > 0) {
2353 // Still need to tell some activities to stop; can't sleep yet.
2354 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2355 + mStoppingActivities.size() + " activities");
2356 scheduleIdleLocked();
2357 dontSleep = true;
2358 }
2359
2360 if (mGoingToSleepActivities.size() > 0) {
2361 // Still need to tell some activities to sleep; can't sleep yet.
2362 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2363 + mGoingToSleepActivities.size() + " activities");
2364 dontSleep = true;
2365 }
2366
2367 if (dontSleep) {
2368 return;
2369 }
2370 }
2371
Craig Mautnere0a38842013-12-16 16:14:02 -08002372 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2373 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002374 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2375 stacks.get(stackNdx).goToSleep();
2376 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002377 }
2378
2379 removeSleepTimeouts();
2380
2381 if (mGoingToSleep.isHeld()) {
2382 mGoingToSleep.release();
2383 }
2384 if (mService.mShuttingDown) {
2385 mService.notifyAll();
2386 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002387 }
2388
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002389 boolean reportResumedActivityLocked(ActivityRecord r) {
2390 final ActivityStack stack = r.task.stack;
2391 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002392 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002393 }
2394 if (allResumedActivitiesComplete()) {
2395 ensureActivitiesVisibleLocked(null, 0);
2396 mWindowManager.executeAppTransition();
2397 return true;
2398 }
2399 return false;
2400 }
2401
Craig Mautner8d341ef2013-03-26 09:03:27 -07002402 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002403 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2404 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002405 final int numStacks = stacks.size();
2406 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2407 final ActivityStack stack = stacks.get(stackNdx);
2408 stack.handleAppCrashLocked(app);
2409 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002410 }
2411 }
2412
Craig Mautnerde4ef022013-04-07 19:01:33 -07002413 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002414 // First the front stacks. In case any are not fullscreen and are in front of home.
2415 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002416 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2417 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002418 final int topStackNdx = stacks.size() - 1;
2419 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2420 final ActivityStack stack = stacks.get(stackNdx);
2421 if (stackNdx == topStackNdx) {
2422 // Top stack.
2423 showHomeBehindStack =
2424 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2425 } else {
2426 // Back stack.
2427 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2428 showHomeBehindStack);
2429 }
Craig Mautner580ea812013-04-25 12:58:38 -07002430 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002431 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002432 }
2433
2434 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002435 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2436 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002437 final int numStacks = stacks.size();
2438 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2439 final ActivityStack stack = stacks.get(stackNdx);
2440 stack.scheduleDestroyActivities(app, false, reason);
2441 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002442 }
2443 }
2444
2445 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002446 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2447 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002448 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002449
Craig Mautner858d8a62013-04-23 17:08:34 -07002450 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002451 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2452 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002453 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002454 final ActivityStack stack = stacks.get(stackNdx);
2455 stack.switchUserLocked(userId);
2456 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002457 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002458 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002459
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002460 ActivityStack stack = getStack(restoreStackId);
2461 if (stack == null) {
2462 stack = mHomeStack;
2463 }
2464 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002465 if (stack.isOnHomeDisplay()) {
2466 moveHomeStack(homeInFront);
2467 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2468 } else {
2469 // Stack was moved to another display while user was swapped out.
2470 resumeHomeActivity(null);
2471 }
Craig Mautner93529a42013-10-04 15:03:13 -07002472 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002473 }
2474
Craig Mautnerde4ef022013-04-07 19:01:33 -07002475 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2476 int N = mStoppingActivities.size();
2477 if (N <= 0) return null;
2478
2479 ArrayList<ActivityRecord> stops = null;
2480
2481 final boolean nowVisible = allResumedActivitiesVisible();
2482 for (int i=0; i<N; i++) {
2483 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002484 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002485 + nowVisible + " waitingVisible=" + s.waitingVisible
2486 + " finishing=" + s.finishing);
2487 if (s.waitingVisible && nowVisible) {
2488 mWaitingVisibleActivities.remove(s);
2489 s.waitingVisible = false;
2490 if (s.finishing) {
2491 // If this activity is finishing, it is sitting on top of
2492 // everyone else but we now know it is no longer needed...
2493 // so get rid of it. Otherwise, we need to go through the
2494 // normal flow and hide it once we determine that it is
2495 // hidden by the activities in front of it.
2496 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002497 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002498 }
2499 }
2500 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2501 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2502 if (stops == null) {
2503 stops = new ArrayList<ActivityRecord>();
2504 }
2505 stops.add(s);
2506 mStoppingActivities.remove(i);
2507 N--;
2508 i--;
2509 }
2510 }
2511
2512 return stops;
2513 }
2514
Craig Mautnercf910b02013-04-23 11:23:27 -07002515 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002516 // FIXME
2517/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2518 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002519 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002520 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002521 if (isFrontStack(stack)) {
2522 if (r == null) {
2523 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2524 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002525 final ActivityRecord pausing = stack.mPausingActivity;
2526 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002527 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002528 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002529 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002530 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002531 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002532 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002533 }
2534 }
2535 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002536 final ActivityRecord resumed = stack.mResumedActivity;
2537 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002538 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002539 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002540 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002541 if (r != null && (state == ActivityState.INITIALIZING
2542 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002543 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002544 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002545 }
2546 }
2547 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002548*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002549 }
2550
Craig Mautner27084302013-03-25 08:05:25 -07002551 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002552 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002553 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002554 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002555 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002556 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2557 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2558 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002559 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002560
Craig Mautner20e72272013-04-01 13:45:53 -07002561 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002562 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002563 }
2564
Dianne Hackborn390517b2013-05-30 15:03:32 -07002565 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2566 boolean needSep, String prefix) {
2567 if (activity != null) {
2568 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2569 if (needSep) {
2570 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002571 }
2572 pw.print(prefix);
2573 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002574 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002575 }
2576 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002577 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002578 }
2579
Craig Mautner8d341ef2013-03-26 09:03:27 -07002580 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2581 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002582 boolean printed = false;
2583 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002584 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2585 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2586 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2587 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002588 final int numStacks = stacks.size();
2589 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2590 final ActivityStack stack = stacks.get(stackNdx);
2591 StringBuilder stackHeader = new StringBuilder(128);
2592 stackHeader.append(" Stack #");
2593 stackHeader.append(stack.mStackId);
2594 stackHeader.append(":");
2595 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2596 needSep, stackHeader.toString());
2597 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2598 !dumpAll, false, dumpPackage, true,
2599 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002600
Craig Mautner4a1cb222013-12-04 16:14:06 -08002601 needSep = printed;
2602 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2603 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002604 if (pr) {
2605 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002606 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002607 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002608 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2609 " mResumedActivity: ");
2610 if (pr) {
2611 printed = true;
2612 needSep = false;
2613 }
2614 if (dumpAll) {
2615 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2616 " mLastPausedActivity: ");
2617 if (pr) {
2618 printed = true;
2619 needSep = true;
2620 }
2621 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2622 needSep, " mLastNoHistoryActivity: ");
2623 }
2624 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002625 }
2626 }
2627
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002628 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2629 false, dumpPackage, true, " Activities waiting to finish:", null);
2630 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2631 false, dumpPackage, true, " Activities waiting to stop:", null);
2632 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2633 false, dumpPackage, true, " Activities waiting for another to become visible:",
2634 null);
2635 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2636 false, dumpPackage, true, " Activities waiting to sleep:", null);
2637 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2638 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002639
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002640 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002641 }
2642
Dianne Hackborn390517b2013-05-30 15:03:32 -07002643 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002644 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002645 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002646 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002647 String innerPrefix = null;
2648 String[] args = null;
2649 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002650 for (int i=list.size()-1; i>=0; i--) {
2651 final ActivityRecord r = list.get(i);
2652 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2653 continue;
2654 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002655 if (innerPrefix == null) {
2656 innerPrefix = prefix + " ";
2657 args = new String[0];
2658 }
2659 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002660 final boolean full = !brief && (complete || !r.isInHistory());
2661 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002662 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002663 needNL = false;
2664 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002665 if (header1 != null) {
2666 pw.println(header1);
2667 header1 = null;
2668 }
2669 if (header2 != null) {
2670 pw.println(header2);
2671 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002672 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002673 if (lastTask != r.task) {
2674 lastTask = r.task;
2675 pw.print(prefix);
2676 pw.print(full ? "* " : " ");
2677 pw.println(lastTask);
2678 if (full) {
2679 lastTask.dump(pw, prefix + " ");
2680 } else if (complete) {
2681 // Complete + brief == give a summary. Isn't that obvious?!?
2682 if (lastTask.intent != null) {
2683 pw.print(prefix); pw.print(" ");
2684 pw.println(lastTask.intent.toInsecureStringWithClip());
2685 }
2686 }
2687 }
2688 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2689 pw.print(" #"); pw.print(i); pw.print(": ");
2690 pw.println(r);
2691 if (full) {
2692 r.dump(pw, innerPrefix);
2693 } else if (complete) {
2694 // Complete + brief == give a summary. Isn't that obvious?!?
2695 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2696 if (r.app != null) {
2697 pw.print(innerPrefix); pw.println(r.app);
2698 }
2699 }
2700 if (client && r.app != null && r.app.thread != null) {
2701 // flush anything that is already in the PrintWriter since the thread is going
2702 // to write to the file descriptor directly
2703 pw.flush();
2704 try {
2705 TransferPipe tp = new TransferPipe();
2706 try {
2707 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2708 r.appToken, innerPrefix, args);
2709 // Short timeout, since blocking here can
2710 // deadlock with the application.
2711 tp.go(fd, 2000);
2712 } finally {
2713 tp.kill();
2714 }
2715 } catch (IOException e) {
2716 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2717 } catch (RemoteException e) {
2718 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2719 }
2720 needNL = true;
2721 }
2722 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002723 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002724 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002725
Craig Mautnerf3333272013-04-22 10:55:53 -07002726 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002727 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002728 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2729 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002730 }
2731
2732 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002733 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002734 }
2735
2736 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002737 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002738 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2739 }
2740
Craig Mautner05d29032013-05-03 13:40:13 -07002741 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002742 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2743 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2744 }
Craig Mautner05d29032013-05-03 13:40:13 -07002745 }
2746
Craig Mautner0eea92c2013-05-16 13:35:39 -07002747 void removeSleepTimeouts() {
2748 mSleepTimeout = false;
2749 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2750 }
2751
2752 final void scheduleSleepTimeout() {
2753 removeSleepTimeouts();
2754 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2755 }
2756
Craig Mautner4a1cb222013-12-04 16:14:06 -08002757 @Override
2758 public void onDisplayAdded(int displayId) {
2759 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2760 }
2761
2762 @Override
2763 public void onDisplayRemoved(int displayId) {
2764 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2765 }
2766
2767 @Override
2768 public void onDisplayChanged(int displayId) {
2769 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2770 }
2771
2772 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002773 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002774 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002775 newDisplay = mActivityDisplays.get(displayId) == null;
2776 if (newDisplay) {
2777 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2778 mActivityDisplays.put(displayId, activityDisplay);
2779 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002780 }
Craig Mautner4504de52013-12-20 09:06:56 -08002781 if (newDisplay) {
2782 mWindowManager.onDisplayAdded(displayId);
2783 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002784 }
2785
2786 public void handleDisplayRemovedLocked(int displayId) {
2787 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002788 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2789 if (activityDisplay != null) {
2790 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002791 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002792 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002793 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002794 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002795 }
2796 }
2797 mWindowManager.onDisplayRemoved(displayId);
2798 }
2799
2800 public void handleDisplayChangedLocked(int displayId) {
2801 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002802 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2803 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002804 // TODO: Update the bounds.
2805 }
2806 }
2807 mWindowManager.onDisplayChanged(displayId);
2808 }
2809
2810 StackInfo getStackInfo(ActivityStack stack) {
2811 StackInfo info = new StackInfo();
2812 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2813 info.displayId = Display.DEFAULT_DISPLAY;
2814 info.stackId = stack.mStackId;
2815
2816 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2817 final int numTasks = tasks.size();
2818 int[] taskIds = new int[numTasks];
2819 String[] taskNames = new String[numTasks];
2820 for (int i = 0; i < numTasks; ++i) {
2821 final TaskRecord task = tasks.get(i);
2822 taskIds[i] = task.taskId;
2823 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2824 : task.realActivity != null ? task.realActivity.flattenToString()
2825 : task.getTopActivity() != null ? task.getTopActivity().packageName
2826 : "unknown";
2827 }
2828 info.taskIds = taskIds;
2829 info.taskNames = taskNames;
2830 return info;
2831 }
2832
2833 StackInfo getStackInfoLocked(int stackId) {
2834 ActivityStack stack = getStack(stackId);
2835 if (stack != null) {
2836 return getStackInfo(stack);
2837 }
2838 return null;
2839 }
2840
2841 ArrayList<StackInfo> getAllStackInfosLocked() {
2842 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002843 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2844 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002845 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2846 list.add(getStackInfo(stacks.get(ndx)));
2847 }
2848 }
2849 return list;
2850 }
2851
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002852 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002853
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002854 public ActivityStackSupervisorHandler(Looper looper) {
2855 super(looper);
2856 }
2857
Craig Mautnerf3333272013-04-22 10:55:53 -07002858 void activityIdleInternal(ActivityRecord r) {
2859 synchronized (mService) {
2860 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2861 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002862 }
2863
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002864 @Override
2865 public void handleMessage(Message msg) {
2866 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002867 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002868 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002869 if (mService.mDidDexOpt) {
2870 mService.mDidDexOpt = false;
2871 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2872 nmsg.obj = msg.obj;
2873 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2874 return;
2875 }
2876 // We don't at this point know if the activity is fullscreen,
2877 // so we need to be conservative and assume it isn't.
2878 activityIdleInternal((ActivityRecord)msg.obj);
2879 } break;
2880 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002881 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002882 activityIdleInternal((ActivityRecord)msg.obj);
2883 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002884 case RESUME_TOP_ACTIVITY_MSG: {
2885 synchronized (mService) {
2886 resumeTopActivitiesLocked();
2887 }
2888 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002889 case SLEEP_TIMEOUT_MSG: {
2890 synchronized (mService) {
2891 if (mService.isSleepingOrShuttingDown()) {
2892 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2893 mSleepTimeout = true;
2894 checkReadyForSleepLocked();
2895 }
2896 }
2897 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002898 case LAUNCH_TIMEOUT_MSG: {
2899 if (mService.mDidDexOpt) {
2900 mService.mDidDexOpt = false;
2901 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2902 return;
2903 }
2904 synchronized (mService) {
2905 if (mLaunchingActivity.isHeld()) {
2906 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2907 if (VALIDATE_WAKE_LOCK_CALLER
2908 && Binder.getCallingUid() != Process.myUid()) {
2909 throw new IllegalStateException("Calling must be system uid");
2910 }
2911 mLaunchingActivity.release();
2912 }
2913 }
2914 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002915 case HANDLE_DISPLAY_ADDED: {
2916 handleDisplayAddedLocked(msg.arg1);
2917 } break;
2918 case HANDLE_DISPLAY_CHANGED: {
2919 handleDisplayChangedLocked(msg.arg1);
2920 } break;
2921 case HANDLE_DISPLAY_REMOVED: {
2922 handleDisplayRemovedLocked(msg.arg1);
2923 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002924 }
2925 }
2926 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002927
Craig Mautner4a1cb222013-12-04 16:14:06 -08002928 class ActivityContainer extends IActivityContainer.Stub {
2929 final int mStackId;
2930 final IActivityContainerCallback mCallback;
2931 final ActivityStack mStack;
2932 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08002933 final String mIdString;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002934
Craig Mautner4a1cb222013-12-04 16:14:06 -08002935 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002936 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002937
2938 ActivityContainer(ActivityRecord parentActivity, int stackId,
2939 IActivityContainerCallback callback) {
2940 synchronized (mService) {
2941 mStackId = stackId;
2942 mStack = new ActivityStack(this);
2943 mParentActivity = parentActivity;
2944 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08002945 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2946 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002947 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002948 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002949
Craig Mautnere0a38842013-12-16 16:14:02 -08002950 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002951 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2952 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002953 mActivityDisplay = activityDisplay;
2954 mStack.mDisplayId = activityDisplay.mDisplayId;
2955 mStack.mStacks = activityDisplay.mStacks;
2956
2957 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002958 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002959 }
2960
2961 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08002962 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002963 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002964 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2965 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002966 return;
2967 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002968 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002969 }
2970 }
2971
2972 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08002973 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002974 if (mActivityDisplay != null) {
2975 return mActivityDisplay.mDisplayId;
2976 }
2977 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002978 }
2979
Jeff Brown38f96e52014-02-11 14:32:56 -08002980 @Override
2981 public boolean injectEvent(InputEvent event) {
2982 final long origId = Binder.clearCallingIdentity();
2983 try {
2984 if (mActivityDisplay != null) {
2985 return mInputManagerInternal.injectInputEvent(event,
2986 mActivityDisplay.mDisplayId,
2987 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
2988 }
2989 return false;
2990 } finally {
2991 Binder.restoreCallingIdentity(origId);
2992 }
2993 }
2994
Craig Mautner34b73df2014-01-12 21:11:08 -08002995 private void detachLocked() {
2996 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
2997 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08002998 if (mActivityDisplay != null) {
2999 mActivityDisplay.detachActivitiesLocked(mStack);
3000 mActivityDisplay = null;
3001 mStack.mDisplayId = -1;
3002 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003003 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003004 }
3005 }
3006
3007 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003008 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003009 synchronized (mService) {
3010 detachLocked();
3011 }
3012 }
3013
3014 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003015 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003016 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003017 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3018 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3019 // TODO: Switch to user app stacks here.
3020 String mimeType = intent.getType();
3021 if (mimeType == null && intent.getData() != null
3022 && "content".equals(intent.getData().getScheme())) {
3023 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3024 }
3025 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3026 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003027 }
3028
3029 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003030 public final int startActivityIntentSender(IIntentSender intentSender) {
3031 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3032
3033 if (!(intentSender instanceof PendingIntentRecord)) {
3034 throw new IllegalArgumentException("Bad PendingIntent object");
3035 }
3036
3037 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3038 null, 0, 0, 0, null, this);
3039 }
3040
3041 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003042 public IBinder asBinder() {
3043 return this;
3044 }
3045
Craig Mautner4504de52013-12-20 09:06:56 -08003046 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003047 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003048 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3049
3050 final long origId = Binder.clearCallingIdentity();
3051 try {
3052 synchronized (mService) {
3053 ActivityDisplay activityDisplay =
3054 new ActivityDisplay(surface, width, height, density);
3055 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3056 attachToDisplayLocked(activityDisplay);
3057 mStack.resumeTopActivityLocked(null);
3058 }
3059 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3060 + mActivityDisplay);
3061 } finally {
3062 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003063 }
Craig Mautner4504de52013-12-20 09:06:56 -08003064 }
3065
Craig Mautner4a1cb222013-12-04 16:14:06 -08003066 ActivityStackSupervisor getOuter() {
3067 return ActivityStackSupervisor.this;
3068 }
3069
3070 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003071 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003072 }
3073
3074 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003075 if (mActivityDisplay != null) {
3076 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003077 } else {
3078 outBounds.set(0, 0);
3079 }
3080 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003081
3082 @Override
3083 public String toString() {
3084 return mIdString + (mActivityDisplay == null ? "N" : "A");
3085 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003086 }
3087
Craig Mautner4a1cb222013-12-04 16:14:06 -08003088 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3089 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003090 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003091 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003092 int mDisplayId;
3093 Display mDisplay;
3094 DisplayInfo mDisplayInfo = new DisplayInfo();
3095 Surface mSurface;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003096
Craig Mautner4a1cb222013-12-04 16:14:06 -08003097 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3098 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003099 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003100
Craig Mautner4504de52013-12-20 09:06:56 -08003101 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3102 * here. */
3103 VirtualDisplay mVirtualDisplay;
3104
Craig Mautnere0a38842013-12-16 16:14:02 -08003105 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003106 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003107 }
3108
Craig Mautner34b73df2014-01-12 21:11:08 -08003109 ActivityDisplay(Surface surface, int width, int height, int density) {
3110 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3111 long ident = Binder.clearCallingIdentity();
3112 try {
3113 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3114 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3115 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3116 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3117 } finally {
3118 Binder.restoreCallingIdentity(ident);
3119 }
3120
3121 init(mVirtualDisplay.getDisplay());
3122 mSurface = surface;
3123
3124 mWindowManager.handleDisplayAdded(mDisplayId);
3125 }
3126
3127 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003128 mDisplay = display;
3129 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003130 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003131 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003132
3133 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003134 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3135 + mDisplayId);
3136 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003137 }
3138
Craig Mautnere0a38842013-12-16 16:14:02 -08003139 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003140 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003141 + " from displayId=" + mDisplayId);
3142 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003143 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3144 mVirtualDisplay.release();
3145 mVirtualDisplay = null;
3146 }
3147 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003148 }
3149
3150 void getBounds(Point bounds) {
3151 mDisplay.getDisplayInfo(mDisplayInfo);
3152 bounds.x = mDisplayInfo.appWidth;
3153 bounds.y = mDisplayInfo.appHeight;
3154 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003155
3156 @Override
3157 public String toString() {
3158 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3159 + " numStacks=" + mStacks.size() + "}";
3160 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003161 }
Craig Mautner27084302013-03-25 08:05:25 -07003162}