blob: 93156480ca54b906de8e94bced81da7ade73b448 [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
Craig Mautnered6649f2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
Jeff Brownca9bc702014-02-11 14:32:56 -080064import android.hardware.input.InputManager;
65import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070067import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070068import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070069import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070070import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070071import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070072import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070074import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070075import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070078import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070079import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070082
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.util.SparseIntArray;
Craig Mautnered6649f2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brownca9bc702014-02-11 14:32:56 -080086import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080087import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070088import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070089import com.android.internal.os.TransferPipe;
Jeff Brownca9bc702014-02-11 14:32:56 -080090import com.android.server.LocalServices;
Craig Mautner6170f732013-04-02 13:05:23 -070091import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070092import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070093import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070094
Craig Mautner8d341ef2013-03-26 09:03:27 -070095import java.io.FileDescriptor;
96import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070097import java.io.PrintWriter;
Craig Mautner4504de52013-12-20 09:06:56 -080098import java.lang.ref.WeakReference;
Craig Mautner2219a1b2013-03-25 09:44:30 -070099import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700100import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -0700101
Craig Mautner4a1cb222013-12-04 16:14:06 -0800102public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700103 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
104 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
105 static final boolean DEBUG_APP = DEBUG || false;
106 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700107 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700108 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700109
Craig Mautner2219a1b2013-03-25 09:44:30 -0700110 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700111
Craig Mautnerf3333272013-04-22 10:55:53 -0700112 /** How long we wait until giving up on the last activity telling us it is idle. */
113 static final int IDLE_TIMEOUT = 10*1000;
114
Craig Mautner0eea92c2013-05-16 13:35:39 -0700115 /** How long we can hold the sleep wake lock before giving up. */
116 static final int SLEEP_TIMEOUT = 5*1000;
117
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700118 // How long we can hold the launch wake lock before giving up.
119 static final int LAUNCH_TIMEOUT = 10*1000;
120
Craig Mautner05d29032013-05-03 13:40:13 -0700121 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
122 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
123 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700124 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700125 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800126 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
127 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
128 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
129
Craig Mautner4504de52013-12-20 09:06:56 -0800130 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700131
132 // For debugging to make sure the caller when acquiring/releasing our
133 // wake lock is the system process.
134 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700135
Craig Mautner27084302013-03-25 08:05:25 -0700136 final ActivityManagerService mService;
137
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700138 final ActivityStackSupervisorHandler mHandler;
139
140 /** Short cut */
141 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800142 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700143
Craig Mautner27084302013-03-25 08:05:25 -0700144 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700145 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700146
Craig Mautner8d341ef2013-03-26 09:03:27 -0700147 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700148 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700149
150 /** Task identifier that activities are currently being started in. Incremented each time a
151 * new task is created. */
152 private int mCurTaskId = 0;
153
Craig Mautner2420ead2013-04-01 17:13:20 -0700154 /** The current user */
155 private int mCurrentUser;
156
Craig Mautnere0a38842013-12-16 16:14:02 -0800157 /** The stack containing the launcher app. Assumed to always be attached to
158 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700159 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700160
Craig Mautnere0a38842013-12-16 16:14:02 -0800161 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700162 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700163
Craig Mautner4a1cb222013-12-04 16:14:06 -0800164 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
165 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800166 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800167 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700168
169 /** List of activities that are waiting for a new activity to become visible before completing
170 * whatever operation they are supposed to do. */
171 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
172
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700173 /** List of processes waiting to find out about the next visible activity. */
174 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
175 new ArrayList<IActivityManager.WaitResult>();
176
177 /** List of processes waiting to find out about the next launched activity. */
178 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
179 new ArrayList<IActivityManager.WaitResult>();
180
Craig Mautnerde4ef022013-04-07 19:01:33 -0700181 /** List of activities that are ready to be stopped, but waiting for the next activity to
182 * settle down before doing so. */
183 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
184
Craig Mautnerf3333272013-04-22 10:55:53 -0700185 /** List of activities that are ready to be finished, but waiting for the previous activity to
186 * settle down before doing so. It contains ActivityRecord objects. */
187 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
188
Craig Mautner0eea92c2013-05-16 13:35:39 -0700189 /** List of activities that are in the process of going to sleep. */
190 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
191
Craig Mautnerf3333272013-04-22 10:55:53 -0700192 /** List of ActivityRecord objects that have been finished and must still report back to a
193 * pending thumbnail receiver. */
194 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
195
196 /** Used on user changes */
197 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
198
Craig Mautnerde4ef022013-04-07 19:01:33 -0700199 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
200 * is being brought in front of us. */
201 boolean mUserLeaving = false;
202
Craig Mautner0eea92c2013-05-16 13:35:39 -0700203 /** Set when we have taken too long waiting to go to sleep. */
204 boolean mSleepTimeout = false;
205
206 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700207 * We don't want to allow the device to go to sleep while in the process
208 * of launching an activity. This is primarily to allow alarm intent
209 * receivers to launch an activity and get that to run before the device
210 * goes back to sleep.
211 */
212 final PowerManager.WakeLock mLaunchingActivity;
213
214 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700215 * Set when the system is going to sleep, until we have
216 * successfully paused the current activity and released our wake lock.
217 * At that point the system is allowed to actually sleep.
218 */
219 final PowerManager.WakeLock mGoingToSleep;
220
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700221 /** Stack id of the front stack when user switched, indexed by userId. */
222 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700223
Craig Mautner4504de52013-12-20 09:06:56 -0800224 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800225 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800226 SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
227 new SparseArray<WeakReference<ActivityContainer>>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800228
229 /** Mapping from displayId to display current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800230 private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800231
Jeff Brownca9bc702014-02-11 14:32:56 -0800232 InputManagerInternal mInputManagerInternal;
233
Craig Mautneraea74a52014-03-08 14:23:10 -0800234 /** If non-null then the task specified remains in front and no other tasks may be started
235 * until the task exits or #stopLockTaskMode() is called. */
236 private TaskRecord mLockTaskModeTask;
237
Craig Mautner4a1cb222013-12-04 16:14:06 -0800238 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700239 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800240 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700241 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800242 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700243 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
244 throw new IllegalStateException("Calling must be system uid");
245 }
246 mLaunchingActivity =
247 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
248 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700249 }
250
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700251 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800252 synchronized (mService) {
253 mWindowManager = wm;
254
255 mDisplayManager =
256 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
257 mDisplayManager.registerDisplayListener(this, null);
258
259 Display[] displays = mDisplayManager.getDisplays();
260 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
261 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800262 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
263 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800264 }
265
266 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
267 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brownca9bc702014-02-11 14:32:56 -0800268
269 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800270 }
Craig Mautner27084302013-03-25 08:05:25 -0700271 }
272
273 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700274 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700275 if (mDismissKeyguardOnNextActivity) {
276 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700277 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700278 }
279 }
280
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700281 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800282 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700283 }
284
Craig Mautnerde4ef022013-04-07 19:01:33 -0700285 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800286 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700287 }
288
Craig Mautner4a1cb222013-12-04 16:14:06 -0800289 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
290 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700291 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800292 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
293 if (parent != null) {
294 stack = parent.task.stack;
295 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800296 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800297 if (stacks != null && !stacks.isEmpty()) {
298 return stack == stacks.get(stacks.size() - 1);
299 }
300 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700301 }
302
Craig Mautnerde4ef022013-04-07 19:01:33 -0700303 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800304 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800305 int topNdx = stacks.size() - 1;
306 if (topNdx <= 0) {
307 return;
308 }
309 ActivityStack topStack = stacks.get(topNdx);
310 final boolean homeInFront = topStack == mHomeStack;
311 if (homeInFront != toFront) {
312 mLastFocusedStack = topStack;
313 stacks.remove(mHomeStack);
314 stacks.add(toFront ? topNdx : 0, mHomeStack);
315 mFocusedStack = stacks.get(topNdx);
316 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
317 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700318 }
319 }
320
Craig Mautner8e569572013-10-11 17:36:59 -0700321 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700322 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700323 mHomeStack.moveHomeTaskToTop();
324 }
325
326 boolean resumeHomeActivity(ActivityRecord prev) {
327 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700328 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700329 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700330 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700331 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700332 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700333 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700334 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700335 }
336 return mService.startHomeActivityLocked(mCurrentUser);
337 }
338
Craig Mautner27084302013-03-25 08:05:25 -0700339 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700340 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700341 mDismissKeyguardOnNextActivity = dismiss;
342 }
343
Craig Mautner8d341ef2013-03-26 09:03:27 -0700344 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800345 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800346 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800347 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800348 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
349 ActivityStack stack = stacks.get(stackNdx);
350 TaskRecord task = stack.taskForIdLocked(id);
351 if (task != null) {
352 return task;
353 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700354 }
355 }
356 return null;
357 }
358
Craig Mautner6170f732013-04-02 13:05:23 -0700359 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800360 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800361 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800362 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800363 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
364 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
365 if (r != null) {
366 return r;
367 }
Craig Mautner6170f732013-04-02 13:05:23 -0700368 }
369 }
370 return null;
371 }
372
Craig Mautner8d341ef2013-03-26 09:03:27 -0700373 int getNextTaskId() {
374 do {
375 mCurTaskId++;
376 if (mCurTaskId <= 0) {
377 mCurTaskId = 1;
378 }
379 } while (anyTaskForIdLocked(mCurTaskId) != null);
380 return mCurTaskId;
381 }
382
Craig Mautnerde4ef022013-04-07 19:01:33 -0700383 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700384 ActivityStack stack = getFocusedStack();
385 if (stack == null) {
386 return null;
387 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700388 ActivityRecord resumedActivity = stack.mResumedActivity;
389 if (resumedActivity == null || resumedActivity.app == null) {
390 resumedActivity = stack.mPausingActivity;
391 if (resumedActivity == null || resumedActivity.app == null) {
392 resumedActivity = stack.topRunningActivityLocked(null);
393 }
394 }
395 return resumedActivity;
396 }
397
Mike Lockwooded8902d2013-11-15 11:01:47 -0800398 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700399 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800400 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800401 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
402 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800403 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
404 final ActivityStack stack = stacks.get(stackNdx);
405 if (!isFrontStack(stack)) {
406 continue;
407 }
408 ActivityRecord hr = stack.topRunningActivityLocked(null);
409 if (hr != null) {
410 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
411 && processName.equals(hr.processName)) {
412 try {
Craig Mautner74266842013-12-19 13:02:30 -0800413 if (realStartActivityLocked(hr, app, true, true, null)) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800414 didSomething = true;
415 }
416 } catch (Exception e) {
417 Slog.w(TAG, "Exception in new application when starting activity "
418 + hr.intent.getComponent().flattenToShortString(), e);
419 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700420 }
Craig Mautner20e72272013-04-01 13:45:53 -0700421 }
Craig Mautner20e72272013-04-01 13:45:53 -0700422 }
423 }
424 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700425 if (!didSomething) {
426 ensureActivitiesVisibleLocked(null, 0);
427 }
Craig Mautner20e72272013-04-01 13:45:53 -0700428 return didSomething;
429 }
430
431 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800432 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
433 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800434 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
435 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800436 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800437 continue;
438 }
439 final ActivityRecord resumedActivity = stack.mResumedActivity;
440 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800441 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
442 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800443 return false;
444 }
Craig Mautner20e72272013-04-01 13:45:53 -0700445 }
446 }
447 return true;
448 }
449
Craig Mautnerde4ef022013-04-07 19:01:33 -0700450 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800451 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
452 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800453 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
454 final ActivityStack stack = stacks.get(stackNdx);
455 if (isFrontStack(stack)) {
456 final ActivityRecord r = stack.mResumedActivity;
457 if (r != null && r.state != ActivityState.RESUMED) {
458 return false;
459 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700460 }
461 }
462 }
463 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800464 if (DEBUG_STACK) Slog.d(TAG,
465 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
466 mLastFocusedStack + " to=" + mFocusedStack);
467 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700468 return true;
469 }
470
471 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800472 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
473 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800474 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
475 final ActivityStack stack = stacks.get(stackNdx);
476 final ActivityRecord r = stack.mResumedActivity;
477 if (r != null && (!r.nowVisible || r.waitingVisible)) {
478 return false;
479 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700480 }
481 }
482 return true;
483 }
484
Craig Mautner2acc3892013-09-23 10:28:14 -0700485 /**
486 * Pause all activities in either all of the stacks or just the back stacks.
487 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700488 * @return true if any activity was paused as a result of this call.
489 */
Craig Mautner5314a402013-09-26 12:40:16 -0700490 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700491 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800492 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
493 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800494 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
495 final ActivityStack stack = stacks.get(stackNdx);
496 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
497 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
498 " mResumedActivity=" + stack.mResumedActivity);
499 stack.startPausingLocked(userLeaving, false);
500 someActivityPaused = true;
501 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700502 }
503 }
504 return someActivityPaused;
505 }
506
Craig Mautnerde4ef022013-04-07 19:01:33 -0700507 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700508 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800509 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
510 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800511 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
512 final ActivityStack stack = stacks.get(stackNdx);
513 final ActivityRecord r = stack.mPausingActivity;
514 if (r != null && r.state != ActivityState.PAUSED
515 && r.state != ActivityState.STOPPED
516 && r.state != ActivityState.STOPPING) {
517 if (DEBUG_STATES) {
518 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
519 pausing = false;
520 } else {
521 return false;
522 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700523 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700524 }
525 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700526 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700527 }
528
Craig Mautnerdf88d732014-01-27 09:21:32 -0800529 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
John Spurlock8a985d22014-02-25 09:40:05 -0500530 // TODO: Put all stacks in supervisor and iterate through them instead.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800531 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
532 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
533 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
534 final ActivityStack stack = stacks.get(stackNdx);
535 if (stack.mResumedActivity != null &&
536 stack.mActivityContainer.mParentActivity == parent) {
537 stack.startPausingLocked(userLeaving, uiSleeping);
538 }
539 }
540 }
541 }
542
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700543 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700544 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700545 WaitResult w = mWaitingActivityVisible.get(i);
546 w.timeout = false;
547 if (r != null) {
548 w.who = new ComponentName(r.info.packageName, r.info.name);
549 }
550 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
551 w.thisTime = w.totalTime;
552 }
553 mService.notifyAll();
554 dismissKeyguard();
555 }
556
557 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
558 long thisTime, long totalTime) {
559 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700560 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700561 w.timeout = timeout;
562 if (r != null) {
563 w.who = new ComponentName(r.info.packageName, r.info.name);
564 }
565 w.thisTime = thisTime;
566 w.totalTime = totalTime;
567 }
568 mService.notifyAll();
569 }
570
Craig Mautner29219d92013-04-16 20:19:12 -0700571 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700572 final ActivityStack focusedStack = getFocusedStack();
573 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
574 if (r != null) {
575 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700576 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700577
Craig Mautner4a1cb222013-12-04 16:14:06 -0800578 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800579 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800580 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
581 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700582 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700583 r = stack.topRunningActivityLocked(null);
584 if (r != null) {
585 return r;
586 }
587 }
588 }
589 return null;
590 }
591
Craig Mautner20e72272013-04-01 13:45:53 -0700592 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
593 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
594 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700595
596 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800597 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
598 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800599 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800600 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800601 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800602 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
603 final ActivityStack stack = stacks.get(stackNdx);
604 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
605 runningTaskLists.add(stackTaskList);
606 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
607 if (r == null && isFrontStack(stack)) {
608 r = ar;
609 }
Craig Mautner20e72272013-04-01 13:45:53 -0700610 }
611 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700612
613 // The lists are already sorted from most recent to oldest. Just pull the most recent off
614 // each list and add it to list. Stop when all lists are empty or maxNum reached.
615 while (maxNum > 0) {
616 long mostRecentActiveTime = Long.MIN_VALUE;
617 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800618 final int numTaskLists = runningTaskLists.size();
619 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
620 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700621 if (!stackTaskList.isEmpty()) {
622 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
623 if (lastActiveTime > mostRecentActiveTime) {
624 mostRecentActiveTime = lastActiveTime;
625 selectedStackList = stackTaskList;
626 }
627 }
628 }
629 if (selectedStackList != null) {
630 list.add(selectedStackList.remove(0));
631 --maxNum;
632 } else {
633 break;
634 }
635 }
636
Craig Mautner20e72272013-04-01 13:45:53 -0700637 return r;
638 }
639
Craig Mautner23ac33b2013-04-01 16:26:35 -0700640 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
641 String profileFile, ParcelFileDescriptor profileFd, int userId) {
642 // Collect information about the target of the Intent.
643 ActivityInfo aInfo;
644 try {
645 ResolveInfo rInfo =
646 AppGlobals.getPackageManager().resolveIntent(
647 intent, resolvedType,
648 PackageManager.MATCH_DEFAULT_ONLY
649 | ActivityManagerService.STOCK_PM_FLAGS, userId);
650 aInfo = rInfo != null ? rInfo.activityInfo : null;
651 } catch (RemoteException e) {
652 aInfo = null;
653 }
654
655 if (aInfo != null) {
656 // Store the found target back into the intent, because now that
657 // we have it we never want to do this again. For example, if the
658 // user navigates back to this point in the history, we should
659 // always restart the exact same activity.
660 intent.setComponent(new ComponentName(
661 aInfo.applicationInfo.packageName, aInfo.name));
662
663 // Don't debug things in the system process
664 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
665 if (!aInfo.processName.equals("system")) {
666 mService.setDebugApp(aInfo.processName, true, false);
667 }
668 }
669
670 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
671 if (!aInfo.processName.equals("system")) {
672 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
673 }
674 }
675
676 if (profileFile != null) {
677 if (!aInfo.processName.equals("system")) {
678 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
679 profileFile, profileFd,
680 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
681 }
682 }
683 }
684 return aInfo;
685 }
686
Craig Mautner2219a1b2013-03-25 09:44:30 -0700687 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700688 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700689 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800690 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700691 }
692
Craig Mautner23ac33b2013-04-01 16:26:35 -0700693 final int startActivityMayWait(IApplicationThread caller, int callingUid,
694 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
695 String resultWho, int requestCode, int startFlags, String profileFile,
696 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800697 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700698 // Refuse possible leaked file descriptors
699 if (intent != null && intent.hasFileDescriptors()) {
700 throw new IllegalArgumentException("File descriptors passed in Intent");
701 }
702 boolean componentSpecified = intent.getComponent() != null;
703
704 // Don't modify the client's object!
705 intent = new Intent(intent);
706
707 // Collect information about the target of the Intent.
708 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
709 profileFile, profileFd, userId);
710
Craig Mautnere0a38842013-12-16 16:14:02 -0800711 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700712 synchronized (mService) {
713 int callingPid;
714 if (callingUid >= 0) {
715 callingPid = -1;
716 } else if (caller == null) {
717 callingPid = Binder.getCallingPid();
718 callingUid = Binder.getCallingUid();
719 } else {
720 callingPid = callingUid = -1;
721 }
722
Craig Mautnere0a38842013-12-16 16:14:02 -0800723 final ActivityStack stack;
724 if (container == null || container.mStack.isOnHomeDisplay()) {
725 stack = getFocusedStack();
726 } else {
727 stack = container.mStack;
728 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700729 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700730 && mService.mConfiguration.diff(config) != 0;
731 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700732 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700733
734 final long origId = Binder.clearCallingIdentity();
735
736 if (aInfo != null &&
737 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
738 // This may be a heavy-weight process! Check to see if we already
739 // have another, different heavy-weight process running.
740 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
741 if (mService.mHeavyWeightProcess != null &&
742 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
743 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700744 int realCallingUid = callingUid;
745 if (caller != null) {
746 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
747 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700748 realCallingUid = callerApp.info.uid;
749 } else {
750 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700751 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700752 + intent.toString());
753 ActivityOptions.abort(options);
754 return ActivityManager.START_PERMISSION_DENIED;
755 }
756 }
757
758 IIntentSender target = mService.getIntentSenderLocked(
759 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
760 realCallingUid, userId, null, null, 0, new Intent[] { intent },
761 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
762 | PendingIntent.FLAG_ONE_SHOT, null);
763
764 Intent newIntent = new Intent();
765 if (requestCode >= 0) {
766 // Caller is requesting a result.
767 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
768 }
769 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
770 new IntentSender(target));
771 if (mService.mHeavyWeightProcess.activities.size() > 0) {
772 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
773 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
774 hist.packageName);
775 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
776 hist.task.taskId);
777 }
778 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
779 aInfo.packageName);
780 newIntent.setFlags(intent.getFlags());
781 newIntent.setClassName("android",
782 HeavyWeightSwitcherActivity.class.getName());
783 intent = newIntent;
784 resolvedType = null;
785 caller = null;
786 callingUid = Binder.getCallingUid();
787 callingPid = Binder.getCallingPid();
788 componentSpecified = true;
789 try {
790 ResolveInfo rInfo =
791 AppGlobals.getPackageManager().resolveIntent(
792 intent, null,
793 PackageManager.MATCH_DEFAULT_ONLY
794 | ActivityManagerService.STOCK_PM_FLAGS, userId);
795 aInfo = rInfo != null ? rInfo.activityInfo : null;
796 aInfo = mService.getActivityInfoForUser(aInfo, userId);
797 } catch (RemoteException e) {
798 aInfo = null;
799 }
800 }
801 }
802 }
803
Craig Mautnere0a38842013-12-16 16:14:02 -0800804 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
805 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
806 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700807
Craig Mautnerde4ef022013-04-07 19:01:33 -0700808 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700809 // If the caller also wants to switch to a new configuration,
810 // do so now. This allows a clean switch, as we are waiting
811 // for the current activity to pause (so we will not destroy
812 // it), and have not yet started the next activity.
813 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
814 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700815 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700816 if (DEBUG_CONFIGURATION) Slog.v(TAG,
817 "Updating to new configuration after starting activity.");
818 mService.updateConfigurationLocked(config, null, false, false);
819 }
820
821 Binder.restoreCallingIdentity(origId);
822
823 if (outResult != null) {
824 outResult.result = res;
825 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700826 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700827 do {
828 try {
829 mService.wait();
830 } catch (InterruptedException e) {
831 }
832 } while (!outResult.timeout && outResult.who == null);
833 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700834 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700835 if (r.nowVisible) {
836 outResult.timeout = false;
837 outResult.who = new ComponentName(r.info.packageName, r.info.name);
838 outResult.totalTime = 0;
839 outResult.thisTime = 0;
840 } else {
841 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700842 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700843 do {
844 try {
845 mService.wait();
846 } catch (InterruptedException e) {
847 }
848 } while (!outResult.timeout && outResult.who == null);
849 }
850 }
851 }
852
853 return res;
854 }
855 }
856
857 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
858 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
859 Bundle options, int userId) {
860 if (intents == null) {
861 throw new NullPointerException("intents is null");
862 }
863 if (resolvedTypes == null) {
864 throw new NullPointerException("resolvedTypes is null");
865 }
866 if (intents.length != resolvedTypes.length) {
867 throw new IllegalArgumentException("intents are length different than resolvedTypes");
868 }
869
Craig Mautner23ac33b2013-04-01 16:26:35 -0700870
871 int callingPid;
872 if (callingUid >= 0) {
873 callingPid = -1;
874 } else if (caller == null) {
875 callingPid = Binder.getCallingPid();
876 callingUid = Binder.getCallingUid();
877 } else {
878 callingPid = callingUid = -1;
879 }
880 final long origId = Binder.clearCallingIdentity();
881 try {
882 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700883 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700884 for (int i=0; i<intents.length; i++) {
885 Intent intent = intents[i];
886 if (intent == null) {
887 continue;
888 }
889
890 // Refuse possible leaked file descriptors
891 if (intent != null && intent.hasFileDescriptors()) {
892 throw new IllegalArgumentException("File descriptors passed in Intent");
893 }
894
895 boolean componentSpecified = intent.getComponent() != null;
896
897 // Don't modify the client's object!
898 intent = new Intent(intent);
899
900 // Collect information about the target of the Intent.
901 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
902 0, null, null, userId);
903 // TODO: New, check if this is correct
904 aInfo = mService.getActivityInfoForUser(aInfo, userId);
905
906 if (aInfo != null &&
907 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
908 != 0) {
909 throw new IllegalArgumentException(
910 "FLAG_CANT_SAVE_STATE not supported here");
911 }
912
913 Bundle theseOptions;
914 if (options != null && i == intents.length-1) {
915 theseOptions = options;
916 } else {
917 theseOptions = null;
918 }
Craig Mautner6170f732013-04-02 13:05:23 -0700919 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700920 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800921 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700922 if (res < 0) {
923 return res;
924 }
925
926 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
927 }
928 }
929 } finally {
930 Binder.restoreCallingIdentity(origId);
931 }
932
933 return ActivityManager.START_SUCCESS;
934 }
935
Craig Mautner2420ead2013-04-01 17:13:20 -0700936 final boolean realStartActivityLocked(ActivityRecord r,
Adam Powellcfbe9be2013-11-06 14:58:58 -0800937 ProcessRecord app, boolean andResume, boolean checkConfig, Bundle resumeArgs)
Craig Mautner2420ead2013-04-01 17:13:20 -0700938 throws RemoteException {
939
940 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700941 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700942 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700943
944 // schedule launch ticks to collect information about slow apps.
945 r.startLaunchTickingLocked();
946
947 // Have the window manager re-evaluate the orientation of
948 // the screen based on the new activity order. Note that
949 // as a result of this, it can call back into the activity
950 // manager with a new orientation. We don't care about that,
951 // because the activity is not currently running so we are
952 // just restarting it anyway.
953 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700954 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700955 mService.mConfiguration,
956 r.mayFreezeScreenLocked(app) ? r.appToken : null);
957 mService.updateConfigurationLocked(config, r, false, false);
958 }
959
960 r.app = app;
961 app.waitingToKill = null;
962 r.launchCount++;
963 r.lastLaunchTime = SystemClock.uptimeMillis();
964
965 if (localLOGV) Slog.v(TAG, "Launching: " + r);
966
967 int idx = app.activities.indexOf(r);
968 if (idx < 0) {
969 app.activities.add(r);
970 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700971 mService.updateLruProcessLocked(app, true, null);
972 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700973
974 final ActivityStack stack = r.task.stack;
975 try {
976 if (app.thread == null) {
977 throw new RemoteException();
978 }
979 List<ResultInfo> results = null;
980 List<Intent> newIntents = null;
981 if (andResume) {
982 results = r.results;
983 newIntents = r.newIntents;
984 }
985 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
986 + " icicle=" + r.icicle
987 + " with results=" + results + " newIntents=" + newIntents
988 + " andResume=" + andResume);
989 if (andResume) {
990 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
991 r.userId, System.identityHashCode(r),
992 r.task.taskId, r.shortComponentName);
993 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700994 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700995 // Home process is the root process of the task.
996 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700997 }
998 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
999 r.sleeping = false;
1000 r.forceNewConfig = false;
1001 mService.showAskCompatModeDialogLocked(r);
1002 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1003 String profileFile = null;
1004 ParcelFileDescriptor profileFd = null;
1005 boolean profileAutoStop = false;
1006 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1007 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1008 mService.mProfileProc = app;
1009 profileFile = mService.mProfileFile;
1010 profileFd = mService.mProfileFd;
1011 profileAutoStop = mService.mAutoStopProfiler;
1012 }
1013 }
1014 app.hasShownUi = true;
1015 app.pendingUiClean = true;
1016 if (profileFd != null) {
1017 try {
1018 profileFd = profileFd.dup();
1019 } catch (IOException e) {
1020 if (profileFd != null) {
1021 try {
1022 profileFd.close();
1023 } catch (IOException o) {
1024 }
1025 profileFd = null;
1026 }
1027 }
1028 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001029
Dianne Hackborna413dc02013-07-12 12:02:55 -07001030 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001031 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1032 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001033 new Configuration(mService.mConfiguration), r.compat,
1034 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001035 mService.isNextTransitionForward(), profileFile, profileFd,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001036 profileAutoStop, resumeArgs);
Craig Mautner2420ead2013-04-01 17:13:20 -07001037
1038 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1039 // This may be a heavy-weight process! Note that the package
1040 // manager will ensure that only activity can run in the main
1041 // process of the .apk, which is the only thing that will be
1042 // considered heavy-weight.
1043 if (app.processName.equals(app.info.packageName)) {
1044 if (mService.mHeavyWeightProcess != null
1045 && mService.mHeavyWeightProcess != app) {
1046 Slog.w(TAG, "Starting new heavy weight process " + app
1047 + " when already running "
1048 + mService.mHeavyWeightProcess);
1049 }
1050 mService.mHeavyWeightProcess = app;
1051 Message msg = mService.mHandler.obtainMessage(
1052 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1053 msg.obj = r;
1054 mService.mHandler.sendMessage(msg);
1055 }
1056 }
1057
1058 } catch (RemoteException e) {
1059 if (r.launchFailed) {
1060 // This is the second time we failed -- finish activity
1061 // and give up.
1062 Slog.e(TAG, "Second failure launching "
1063 + r.intent.getComponent().flattenToShortString()
1064 + ", giving up", e);
1065 mService.appDiedLocked(app, app.pid, app.thread);
1066 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1067 "2nd-crash", false);
1068 return false;
1069 }
1070
1071 // This is the first time we failed -- restart process and
1072 // retry.
1073 app.activities.remove(r);
1074 throw e;
1075 }
1076
1077 r.launchFailed = false;
1078 if (stack.updateLRUListLocked(r)) {
1079 Slog.w(TAG, "Activity " + r
1080 + " being launched, but already in LRU list");
1081 }
1082
1083 if (andResume) {
1084 // As part of the process of launching, ActivityThread also performs
1085 // a resume.
1086 stack.minimalResumeActivityLocked(r);
1087 } else {
1088 // This activity is not starting in the resumed state... which
1089 // should look like we asked it to pause+stop (but remain visible),
1090 // and it has done so and reported back the current icicle and
1091 // other state.
1092 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1093 + " (starting in stopped state)");
1094 r.state = ActivityState.STOPPED;
1095 r.stopped = true;
1096 }
1097
1098 // Launch the new version setup screen if needed. We do this -after-
1099 // launching the initial activity (that is, home), so that it can have
1100 // a chance to initialize itself while in the background, making the
1101 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001102 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001103 mService.startSetupActivityLocked();
1104 }
1105
1106 return true;
1107 }
1108
Craig Mautnere79d42682013-04-01 19:01:53 -07001109 void startSpecificActivityLocked(ActivityRecord r,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001110 boolean andResume, boolean checkConfig, Bundle resumeArgs) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001111 // Is this activity's application already running?
1112 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001113 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001114
1115 r.task.stack.setLaunchTime(r);
1116
1117 if (app != null && app.thread != null) {
1118 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001119 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1120 || !"android".equals(r.info.packageName)) {
1121 // Don't add this if it is a platform component that is marked
1122 // to run in multiple processes, because this is actually
1123 // part of the framework so doesn't make sense to track as a
1124 // separate apk in the process.
1125 app.addPackage(r.info.packageName, mService.mProcessStats);
1126 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001127 realStartActivityLocked(r, app, andResume, checkConfig, resumeArgs);
Craig Mautnere79d42682013-04-01 19:01:53 -07001128 return;
1129 } catch (RemoteException e) {
1130 Slog.w(TAG, "Exception when starting activity "
1131 + r.intent.getComponent().flattenToShortString(), e);
1132 }
1133
1134 // If a dead object exception was thrown -- fall through to
1135 // restart the application.
1136 }
1137
1138 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001139 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001140 }
1141
Craig Mautner6170f732013-04-02 13:05:23 -07001142 final int startActivityLocked(IApplicationThread caller,
1143 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1144 String resultWho, int requestCode,
1145 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001146 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001147 int err = ActivityManager.START_SUCCESS;
1148
1149 ProcessRecord callerApp = null;
1150 if (caller != null) {
1151 callerApp = mService.getRecordForAppLocked(caller);
1152 if (callerApp != null) {
1153 callingPid = callerApp.pid;
1154 callingUid = callerApp.info.uid;
1155 } else {
1156 Slog.w(TAG, "Unable to find app for caller " + caller
1157 + " (pid=" + callingPid + ") when starting: "
1158 + intent.toString());
1159 err = ActivityManager.START_PERMISSION_DENIED;
1160 }
1161 }
1162
1163 if (err == ActivityManager.START_SUCCESS) {
1164 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1165 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001166 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1167 + " on display " + (container == null ? (mFocusedStack == null ?
1168 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1169 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1170 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001171 }
1172
1173 ActivityRecord sourceRecord = null;
1174 ActivityRecord resultRecord = null;
1175 if (resultTo != null) {
1176 sourceRecord = isInAnyStackLocked(resultTo);
1177 if (DEBUG_RESULTS) Slog.v(
1178 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1179 if (sourceRecord != null) {
1180 if (requestCode >= 0 && !sourceRecord.finishing) {
1181 resultRecord = sourceRecord;
1182 }
1183 }
1184 }
1185 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1186
1187 int launchFlags = intent.getFlags();
1188
1189 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1190 && sourceRecord != null) {
1191 // Transfer the result target from the source activity to the new
1192 // one being started, including any failures.
1193 if (requestCode >= 0) {
1194 ActivityOptions.abort(options);
1195 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1196 }
1197 resultRecord = sourceRecord.resultTo;
1198 resultWho = sourceRecord.resultWho;
1199 requestCode = sourceRecord.requestCode;
1200 sourceRecord.resultTo = null;
1201 if (resultRecord != null) {
1202 resultRecord.removeResultsLocked(
1203 sourceRecord, resultWho, requestCode);
1204 }
1205 }
1206
1207 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1208 // We couldn't find a class that can handle the given Intent.
1209 // That's the end of that!
1210 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1211 }
1212
1213 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1214 // We couldn't find the specific class specified in the Intent.
1215 // Also the end of the line.
1216 err = ActivityManager.START_CLASS_NOT_FOUND;
1217 }
1218
1219 if (err != ActivityManager.START_SUCCESS) {
1220 if (resultRecord != null) {
1221 resultStack.sendActivityResultLocked(-1,
1222 resultRecord, resultWho, requestCode,
1223 Activity.RESULT_CANCELED, null);
1224 }
1225 setDismissKeyguard(false);
1226 ActivityOptions.abort(options);
1227 return err;
1228 }
1229
1230 final int startAnyPerm = mService.checkPermission(
1231 START_ANY_ACTIVITY, callingPid, callingUid);
1232 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1233 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1234 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1235 if (resultRecord != null) {
1236 resultStack.sendActivityResultLocked(-1,
1237 resultRecord, resultWho, requestCode,
1238 Activity.RESULT_CANCELED, null);
1239 }
1240 setDismissKeyguard(false);
1241 String msg;
1242 if (!aInfo.exported) {
1243 msg = "Permission Denial: starting " + intent.toString()
1244 + " from " + callerApp + " (pid=" + callingPid
1245 + ", uid=" + callingUid + ")"
1246 + " not exported from uid " + aInfo.applicationInfo.uid;
1247 } else {
1248 msg = "Permission Denial: starting " + intent.toString()
1249 + " from " + callerApp + " (pid=" + callingPid
1250 + ", uid=" + callingUid + ")"
1251 + " requires " + aInfo.permission;
1252 }
1253 Slog.w(TAG, msg);
1254 throw new SecurityException(msg);
1255 }
1256
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001257 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001258 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001259
Craig Mautner6170f732013-04-02 13:05:23 -07001260 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001261 try {
1262 // The Intent we give to the watcher has the extra data
1263 // stripped off, since it can contain private information.
1264 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001265 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001266 aInfo.applicationInfo.packageName);
1267 } catch (RemoteException e) {
1268 mService.mController = null;
1269 }
Ben Gruver5e207332013-04-03 17:41:37 -07001270 }
Craig Mautner6170f732013-04-02 13:05:23 -07001271
Ben Gruver5e207332013-04-03 17:41:37 -07001272 if (abort) {
1273 if (resultRecord != null) {
1274 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001275 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001276 }
Ben Gruver5e207332013-04-03 17:41:37 -07001277 // We pretend to the caller that it was really started, but
1278 // they will just get a cancel result.
1279 setDismissKeyguard(false);
1280 ActivityOptions.abort(options);
1281 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001282 }
1283
1284 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001285 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1286 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001287 if (outActivity != null) {
1288 outActivity[0] = r;
1289 }
1290
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001291 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001292 if (stack.mResumedActivity == null
1293 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001294 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1295 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001296 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001297 mService.mPendingActivityLaunches.add(pal);
1298 setDismissKeyguard(false);
1299 ActivityOptions.abort(options);
1300 return ActivityManager.START_SWITCHES_CANCELED;
1301 }
1302 }
1303
1304 if (mService.mDidAppSwitch) {
1305 // This is the second allowed switch since we stopped switches,
1306 // so now just generally allow switches. Use case: user presses
1307 // home (switches disabled, switch to home, mDidAppSwitch now true);
1308 // user taps a home icon (coming from home so allowed, we hit here
1309 // and now allow anyone to switch again).
1310 mService.mAppSwitchesAllowedTime = 0;
1311 } else {
1312 mService.mDidAppSwitch = true;
1313 }
1314
1315 mService.doPendingActivityLaunchesLocked(false);
1316
Craig Mautner8849a5e2013-04-02 16:41:03 -07001317 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001318
1319 if (allPausedActivitiesComplete()) {
1320 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001321 // activity start, but we are not actually doing an activity
1322 // switch... just dismiss the keyguard now, because we
1323 // probably want to see whatever is behind it.
1324 dismissKeyguard();
1325 }
1326 return err;
1327 }
1328
Craig Mautnerac6f8432013-07-17 13:24:59 -07001329 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001330 final TaskRecord task = r.task;
1331 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001332 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001333 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001334 if (taskStack.isOnHomeDisplay()) {
1335 if (mFocusedStack != taskStack) {
1336 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1337 "focused stack to r=" + r + " task=" + task);
1338 mFocusedStack = taskStack;
1339 } else {
1340 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1341 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1342 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001343 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001344 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001345 }
1346
Craig Mautnere0a38842013-12-16 16:14:02 -08001347 final ActivityContainer container = r.mInitialActivityContainer;
1348 if (container != null) {
1349 // The first time put it on the desired stack, after this put on task stack.
1350 r.mInitialActivityContainer = null;
1351 return container.mStack;
1352 }
1353
Craig Mautner4a1cb222013-12-04 16:14:06 -08001354 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001355 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1356 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1357 return mFocusedStack;
1358 }
1359
Craig Mautnere0a38842013-12-16 16:14:02 -08001360 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1361 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1362 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1363 if (!stack.isHomeStack()) {
1364 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1365 "adjustStackFocus: Setting focused stack=" + stack);
1366 mFocusedStack = stack;
1367 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001368 }
1369 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001370
Craig Mautner4a1cb222013-12-04 16:14:06 -08001371 // Need to create an app stack for this user.
1372 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001373 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1374 " stackId=" + stackId);
1375 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001376 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001377 }
1378 return mHomeStack;
1379 }
1380
Craig Mautner29219d92013-04-16 20:19:12 -07001381 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001382 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001383 final TaskRecord task = r.task;
1384 boolean isHomeActivity = !r.isApplicationActivity();
1385 if (!isHomeActivity && task != null) {
1386 isHomeActivity = !task.isApplicationTask();
1387 }
1388 if (!isHomeActivity && task != null) {
1389 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1390 isHomeActivity = parent != null && parent.isHomeActivity();
1391 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001392 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001393 }
1394 }
1395
Craig Mautner8849a5e2013-04-02 16:41:03 -07001396 final int startActivityUncheckedLocked(ActivityRecord r,
1397 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1398 Bundle options) {
1399 final Intent intent = r.intent;
1400 final int callingUid = r.launchedFromUid;
1401
1402 int launchFlags = intent.getFlags();
1403
Craig Mautner8849a5e2013-04-02 16:41:03 -07001404 // We'll invoke onUserLeaving before onPause only if the launching
1405 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001406 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1407 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001408
1409 // If the caller has asked not to resume at this point, we make note
1410 // of this in the record so that we can skip it when trying to find
1411 // the top running activity.
1412 if (!doResume) {
1413 r.delayedResume = true;
1414 }
1415
1416 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1417
1418 // If the onlyIfNeeded flag is set, then we can do this if the activity
1419 // being launched is the same as the one making the call... or, as
1420 // a special case, if we do not know the caller then we count the
1421 // current top activity as the caller.
1422 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1423 ActivityRecord checkedCaller = sourceRecord;
1424 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001425 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001426 }
1427 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1428 // Caller is not the same as launcher, so always needed.
1429 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1430 }
1431 }
1432
1433 if (sourceRecord == null) {
1434 // This activity is not being started from another... in this
1435 // case we -always- start a new task.
1436 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001437 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1438 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001439 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1440 }
1441 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1442 // The original activity who is starting us is running as a single
1443 // instance... this new activity it is starting must go on its
1444 // own task.
1445 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1446 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1447 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1448 // The activity being started is a single instance... it always
1449 // gets launched into its own task.
1450 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1451 }
1452
Craig Mautner88629292013-11-10 20:39:05 -08001453 ActivityInfo newTaskInfo = null;
1454 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001455 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001456 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001457 if (sourceRecord.finishing) {
1458 // If the source is finishing, we can't further count it as our source. This
1459 // is because the task it is associated with may now be empty and on its way out,
1460 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001461 // the NEW_TASK flow and try to find a task for it. But save the task information
1462 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001463 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1464 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1465 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1466 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001467 newTaskInfo = sourceRecord.info;
1468 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001469 }
1470 sourceRecord = null;
1471 sourceStack = null;
1472 } else {
1473 sourceStack = sourceRecord.task.stack;
1474 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001475 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001476 sourceStack = null;
1477 }
1478
Craig Mautner8849a5e2013-04-02 16:41:03 -07001479 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1480 // For whatever reason this activity is being launched into a new
1481 // task... yet the caller has requested a result back. Well, that
1482 // is pretty messed up, so instead immediately send back a cancel
1483 // and let the new task continue launched as normal without a
1484 // dependency on its originator.
1485 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1486 r.resultTo.task.stack.sendActivityResultLocked(-1,
1487 r.resultTo, r.resultWho, r.requestCode,
1488 Activity.RESULT_CANCELED, null);
1489 r.resultTo = null;
1490 }
1491
1492 boolean addingToTask = false;
1493 boolean movedHome = false;
1494 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001495 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001496 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1497 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1498 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1499 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1500 // If bring to front is requested, and no result is requested, and
1501 // we can find a task that was started with this same
1502 // component, then instead of launching bring that one to the front.
1503 if (r.resultTo == null) {
1504 // See if there is a task to bring to the front. If this is
1505 // a SINGLE_INSTANCE activity, there can be one and only one
1506 // instance of it in the history, and it is always in its own
1507 // unique task, so we do a special search.
1508 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001509 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001510 : findActivityLocked(intent, r.info);
1511 if (intentActivity != null) {
Craig Mautneraea74a52014-03-08 14:23:10 -08001512 if (isLockTaskModeViolation(intentActivity.task)) {
1513 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1514 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1515 }
Craig Mautner29219d92013-04-16 20:19:12 -07001516 if (r.task == null) {
1517 r.task = intentActivity.task;
1518 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001519 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001520 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001521 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1522 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001523 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001524 if (intentActivity.task.intent == null) {
1525 // This task was started because of movement of
1526 // the activity based on affinity... now that we
1527 // are actually launching it, we can assign the
1528 // base intent.
1529 intentActivity.task.setIntent(intent, r.info);
1530 }
1531 // If the target task is not in the front, then we need
1532 // to bring it to the front... except... well, with
1533 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1534 // to have the same behavior as if a new instance was
1535 // being started, which means not bringing it to the front
1536 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001537 final ActivityStack lastStack = getLastStack();
1538 ActivityRecord curTop = lastStack == null?
1539 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001540 if (curTop != null && (curTop.task != intentActivity.task ||
1541 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001542 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001543 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1544 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001545 // We really do want to push this one into the
1546 // user's face, right now.
1547 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001548 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001549 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001550 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1551 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001552 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001553 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001554 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001555 options = null;
1556 }
1557 }
1558 // If the caller has requested that the target task be
1559 // reset, then do so.
1560 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1561 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1562 }
1563 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1564 // We don't need to start a new activity, and
1565 // the client said not to do anything if that
1566 // is the case, so this is it! And for paranoia, make
1567 // sure we have correctly resumed the top activity.
1568 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001569 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001570 } else {
1571 ActivityOptions.abort(options);
1572 }
1573 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1574 }
1575 if ((launchFlags &
1576 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1577 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1578 // The caller has requested to completely replace any
1579 // existing task with its new activity. Well that should
1580 // not be too hard...
1581 reuseTask = intentActivity.task;
1582 reuseTask.performClearTaskLocked();
1583 reuseTask.setIntent(r.intent, r.info);
1584 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1585 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1586 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1587 // In this situation we want to remove all activities
1588 // from the task up to the one being started. In most
1589 // cases this means we are resetting the task to its
1590 // initial state.
1591 ActivityRecord top =
1592 intentActivity.task.performClearTaskLocked(r, launchFlags);
1593 if (top != null) {
1594 if (top.frontOfTask) {
1595 // Activity aliases may mean we use different
1596 // intents for the top activity, so make sure
1597 // the task now has the identity of the new
1598 // intent.
1599 top.task.setIntent(r.intent, r.info);
1600 }
1601 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1602 r, top.task);
1603 top.deliverNewIntentLocked(callingUid, r.intent);
1604 } else {
1605 // A special case: we need to
1606 // start the activity because it is not currently
1607 // running, and the caller has asked to clear the
1608 // current task to have this activity at the top.
1609 addingToTask = true;
1610 // Now pretend like this activity is being started
1611 // by the top of its task, so it is put in the
1612 // right place.
1613 sourceRecord = intentActivity;
1614 }
1615 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1616 // In this case the top activity on the task is the
1617 // same as the one being launched, so we take that
1618 // as a request to bring the task to the foreground.
1619 // If the top activity in the task is the root
1620 // activity, deliver this new intent to it if it
1621 // desires.
1622 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1623 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1624 && intentActivity.realActivity.equals(r.realActivity)) {
1625 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1626 intentActivity.task);
1627 if (intentActivity.frontOfTask) {
1628 intentActivity.task.setIntent(r.intent, r.info);
1629 }
1630 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1631 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1632 // In this case we are launching the root activity
1633 // of the task, but with a different intent. We
1634 // should start a new instance on top.
1635 addingToTask = true;
1636 sourceRecord = intentActivity;
1637 }
1638 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1639 // In this case an activity is being launched in to an
1640 // existing task, without resetting that task. This
1641 // is typically the situation of launching an activity
1642 // from a notification or shortcut. We want to place
1643 // the new activity on top of the current task.
1644 addingToTask = true;
1645 sourceRecord = intentActivity;
1646 } else if (!intentActivity.task.rootWasReset) {
1647 // In this case we are launching in to an existing task
1648 // that has not yet been started from its front door.
1649 // The current task has been brought to the front.
1650 // Ideally, we'd probably like to place this new task
1651 // at the bottom of its stack, but that's a little hard
1652 // to do with the current organization of the code so
1653 // for now we'll just drop it.
1654 intentActivity.task.setIntent(r.intent, r.info);
1655 }
1656 if (!addingToTask && reuseTask == null) {
1657 // We didn't do anything... but it was needed (a.k.a., client
1658 // don't use that intent!) And for paranoia, make
1659 // sure we have correctly resumed the top activity.
1660 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001661 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001662 } else {
1663 ActivityOptions.abort(options);
1664 }
1665 return ActivityManager.START_TASK_TO_FRONT;
1666 }
1667 }
1668 }
1669 }
1670
1671 //String uri = r.intent.toURI();
1672 //Intent intent2 = new Intent(uri);
1673 //Slog.i(TAG, "Given intent: " + r.intent);
1674 //Slog.i(TAG, "URI is: " + uri);
1675 //Slog.i(TAG, "To intent: " + intent2);
1676
1677 if (r.packageName != null) {
1678 // If the activity being launched is the same as the one currently
1679 // at the top, then we need to check if it should only be launched
1680 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001681 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001682 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001683 if (top != null && r.resultTo == null) {
1684 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1685 if (top.app != null && top.app.thread != null) {
1686 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1687 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1688 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1689 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1690 top.task);
1691 // For paranoia, make sure we have correctly
1692 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001693 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001694 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001695 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001696 }
1697 ActivityOptions.abort(options);
1698 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1699 // We don't need to start a new activity, and
1700 // the client said not to do anything if that
1701 // is the case, so this is it!
1702 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1703 }
1704 top.deliverNewIntentLocked(callingUid, r.intent);
1705 return ActivityManager.START_DELIVERED_TO_TOP;
1706 }
1707 }
1708 }
1709 }
1710
1711 } else {
1712 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001713 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1714 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001715 }
1716 ActivityOptions.abort(options);
1717 return ActivityManager.START_CLASS_NOT_FOUND;
1718 }
1719
1720 boolean newTask = false;
1721 boolean keepCurTransition = false;
1722
1723 // Should this be considered a new task?
1724 if (r.resultTo == null && !addingToTask
1725 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautneraea74a52014-03-08 14:23:10 -08001726 if (isLockTaskModeViolation(reuseTask)) {
1727 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1728 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1729 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001730 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001731 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001732 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001733 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1734 newTaskInfo != null ? newTaskInfo : r.info,
1735 newTaskIntent != null ? newTaskIntent : intent,
1736 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001737 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1738 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001739 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001740 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001741 }
1742 newTask = true;
1743 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001744 if ((launchFlags &
1745 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1746 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1747 // Caller wants to appear on home activity, so before starting
1748 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001749 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001750 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001751 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001752 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001753 TaskRecord sourceTask = sourceRecord.task;
Craig Mautneraea74a52014-03-08 14:23:10 -08001754 if (isLockTaskModeViolation(sourceTask)) {
1755 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1756 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1757 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001758 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001759 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001760 if (!addingToTask &&
1761 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1762 // In this case, we are adding the activity to an existing
1763 // task, but the caller has asked to clear that task if the
1764 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001765 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001766 keepCurTransition = true;
1767 if (top != null) {
1768 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1769 top.deliverNewIntentLocked(callingUid, r.intent);
1770 // For paranoia, make sure we have correctly
1771 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001772 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001773 if (doResume) {
1774 targetStack.resumeTopActivityLocked(null);
1775 }
1776 ActivityOptions.abort(options);
1777 return ActivityManager.START_DELIVERED_TO_TOP;
1778 }
1779 } else if (!addingToTask &&
1780 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1781 // In this case, we are launching an activity in our own task
1782 // that may already be running somewhere in the history, and
1783 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001784 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001785 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001786 final TaskRecord task = top.task;
1787 task.moveActivityToFrontLocked(top);
1788 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001789 top.updateOptionsLocked(options);
1790 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001791 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001792 if (doResume) {
1793 targetStack.resumeTopActivityLocked(null);
1794 }
1795 return ActivityManager.START_DELIVERED_TO_TOP;
1796 }
1797 }
1798 // An existing activity is starting this new activity, so we want
1799 // to keep the new one in the same task as the one that is starting
1800 // it.
Craig Mautneraea74a52014-03-08 14:23:10 -08001801 if (isLockTaskModeViolation(sourceTask)) {
1802 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1803 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1804 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001805 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001806 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001807 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001808
1809 } else {
1810 // This not being started from an existing activity, and not part
1811 // of a new task... just put it in the top task, though these days
1812 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001813 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001814 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001815 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001816 r.setTask(prev != null ? prev.task
1817 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1818 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001819 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1820 + " in new guessed " + r.task);
1821 }
1822
1823 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1824 intent, r.getUriPermissionsLocked());
1825
1826 if (newTask) {
1827 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1828 }
1829 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001830 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001831 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001832 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001833 return ActivityManager.START_SUCCESS;
1834 }
1835
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001836 void acquireLaunchWakelock() {
1837 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1838 throw new IllegalStateException("Calling must be system uid");
1839 }
1840 mLaunchingActivity.acquire();
1841 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1842 // To be safe, don't allow the wake lock to be held for too long.
1843 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1844 }
1845 }
1846
Craig Mautnerf3333272013-04-22 10:55:53 -07001847 // Checked.
1848 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1849 Configuration config) {
1850 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1851
Craig Mautnerf3333272013-04-22 10:55:53 -07001852 ArrayList<ActivityRecord> stops = null;
1853 ArrayList<ActivityRecord> finishes = null;
1854 ArrayList<UserStartedState> startingUsers = null;
1855 int NS = 0;
1856 int NF = 0;
1857 IApplicationThread sendThumbnail = null;
1858 boolean booting = false;
1859 boolean enableScreen = false;
1860 boolean activityRemoved = false;
1861
1862 ActivityRecord r = ActivityRecord.forToken(token);
1863 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001864 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1865 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001866 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1867 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001868 if (fromTimeout) {
1869 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001870 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001871
1872 // This is a hack to semi-deal with a race condition
1873 // in the client where it can be constructed with a
1874 // newer configuration from when we asked it to launch.
1875 // We'll update with whatever configuration it now says
1876 // it used to launch.
1877 if (config != null) {
1878 r.configuration = config;
1879 }
1880
1881 // We are now idle. If someone is waiting for a thumbnail from
1882 // us, we can now deliver.
1883 r.idle = true;
1884
1885 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1886 sendThumbnail = r.app.thread;
1887 r.thumbnailNeeded = false;
1888 }
1889
1890 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1891 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1892 mService.mBooted = true;
1893 enableScreen = true;
1894 }
1895 }
1896
1897 if (allResumedActivitiesIdle()) {
1898 if (r != null) {
1899 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001900 }
1901
1902 if (mLaunchingActivity.isHeld()) {
1903 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1904 if (VALIDATE_WAKE_LOCK_CALLER &&
1905 Binder.getCallingUid() != Process.myUid()) {
1906 throw new IllegalStateException("Calling must be system uid");
1907 }
1908 mLaunchingActivity.release();
1909 }
1910 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001911 }
1912
1913 // Atomically retrieve all of the other things to do.
1914 stops = processStoppingActivitiesLocked(true);
1915 NS = stops != null ? stops.size() : 0;
1916 if ((NF=mFinishingActivities.size()) > 0) {
1917 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1918 mFinishingActivities.clear();
1919 }
1920
1921 final ArrayList<ActivityRecord> thumbnails;
1922 final int NT = mCancelledThumbnails.size();
1923 if (NT > 0) {
1924 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1925 mCancelledThumbnails.clear();
1926 } else {
1927 thumbnails = null;
1928 }
1929
1930 if (isFrontStack(mHomeStack)) {
1931 booting = mService.mBooting;
1932 mService.mBooting = false;
1933 }
1934
1935 if (mStartingUsers.size() > 0) {
1936 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1937 mStartingUsers.clear();
1938 }
1939
1940 // Perform the following actions from unsynchronized state.
1941 final IApplicationThread thumbnailThread = sendThumbnail;
1942 mHandler.post(new Runnable() {
1943 @Override
1944 public void run() {
1945 if (thumbnailThread != null) {
1946 try {
1947 thumbnailThread.requestThumbnail(token);
1948 } catch (Exception e) {
1949 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1950 mService.sendPendingThumbnail(null, token, null, null, true);
1951 }
1952 }
1953
1954 // Report back to any thumbnail receivers.
1955 for (int i = 0; i < NT; i++) {
1956 ActivityRecord r = thumbnails.get(i);
1957 mService.sendPendingThumbnail(r, null, null, null, true);
1958 }
1959 }
1960 });
1961
1962 // Stop any activities that are scheduled to do so but have been
1963 // waiting for the next one to start.
1964 for (int i = 0; i < NS; i++) {
1965 r = stops.get(i);
1966 final ActivityStack stack = r.task.stack;
1967 if (r.finishing) {
1968 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1969 } else {
1970 stack.stopActivityLocked(r);
1971 }
1972 }
1973
1974 // Finish any activities that are scheduled to do so but have been
1975 // waiting for the next one to start.
1976 for (int i = 0; i < NF; i++) {
1977 r = finishes.get(i);
1978 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1979 }
1980
1981 if (booting) {
1982 mService.finishBooting();
1983 } else if (startingUsers != null) {
1984 for (int i = 0; i < startingUsers.size(); i++) {
1985 mService.finishUserSwitch(startingUsers.get(i));
1986 }
1987 }
1988
1989 mService.trimApplications();
1990 //dump();
1991 //mWindowManager.dump();
1992
1993 if (enableScreen) {
1994 mService.enableScreenAfterBoot();
1995 }
1996
1997 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001998 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001999 }
2000
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002001 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07002002 }
2003
Craig Mautner8e569572013-10-11 17:36:59 -07002004 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07002005 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002006 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2007 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002008 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2009 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2010 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002011 }
Craig Mautner19091252013-10-05 00:03:53 -07002012 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002013 }
2014
2015 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002016 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2017 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002018 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2019 stacks.get(stackNdx).closeSystemDialogsLocked();
2020 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002021 }
2022 }
2023
Craig Mautner93529a42013-10-04 15:03:13 -07002024 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002025 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002026 }
2027
Craig Mautner8d341ef2013-03-26 09:03:27 -07002028 /**
2029 * @return true if some activity was finished (or would have finished if doit were true).
2030 */
2031 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2032 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002033 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2034 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002035 final int numStacks = stacks.size();
2036 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2037 final ActivityStack stack = stacks.get(stackNdx);
2038 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2039 didSomething = true;
2040 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002041 }
2042 }
2043 return didSomething;
2044 }
2045
Dianne Hackborna413dc02013-07-12 12:02:55 -07002046 void updatePreviousProcessLocked(ActivityRecord r) {
2047 // Now that this process has stopped, we may want to consider
2048 // it to be the previous app to try to keep around in case
2049 // the user wants to return to it.
2050
2051 // First, found out what is currently the foreground app, so that
2052 // we don't blow away the previous app if this activity is being
2053 // hosted by the process that is actually still the foreground.
2054 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002055 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2056 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002057 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2058 final ActivityStack stack = stacks.get(stackNdx);
2059 if (isFrontStack(stack)) {
2060 if (stack.mResumedActivity != null) {
2061 fgApp = stack.mResumedActivity.app;
2062 } else if (stack.mPausingActivity != null) {
2063 fgApp = stack.mPausingActivity.app;
2064 }
2065 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002066 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002067 }
2068 }
2069
2070 // Now set this one as the previous process, only if that really
2071 // makes sense to.
2072 if (r.app != null && fgApp != null && r.app != fgApp
2073 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002074 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002075 mService.mPreviousProcess = r.app;
2076 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2077 }
2078 }
2079
Craig Mautner05d29032013-05-03 13:40:13 -07002080 boolean resumeTopActivitiesLocked() {
2081 return resumeTopActivitiesLocked(null, null, null);
2082 }
2083
2084 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2085 Bundle targetOptions) {
2086 if (targetStack == null) {
2087 targetStack = getFocusedStack();
2088 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002089 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002090 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002091 if (isFrontStack(targetStack)) {
2092 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2093 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002094 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2095 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002096 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2097 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002098 if (stack == targetStack) {
2099 // Already started above.
2100 continue;
2101 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002102 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002103 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002104 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002105 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002106 }
Craig Mautner05d29032013-05-03 13:40:13 -07002107 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002108 }
2109
2110 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002111 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2112 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002113 final int numStacks = stacks.size();
2114 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2115 final ActivityStack stack = stacks.get(stackNdx);
2116 stack.finishTopRunningActivityLocked(app);
2117 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002118 }
2119 }
2120
Craig Mautneraea74a52014-03-08 14:23:10 -08002121 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2122 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2123 mUserLeaving = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002124 }
Craig Mautneraea74a52014-03-08 14:23:10 -08002125 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2126 // Caller wants the home activity moved with it. To accomplish this,
2127 // we'll just indicate that this task returns to the home task.
2128 task.mOnTopOfHome = true;
2129 }
2130 task.stack.moveTaskToFrontLocked(task, null, options);
2131 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2132 + task.stack);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002133 }
2134
Craig Mautner967212c2013-04-13 21:10:58 -07002135 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002136 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2137 if (weakReference != null) {
2138 ActivityContainer activityContainer = weakReference.get();
2139 if (activityContainer != null) {
2140 return activityContainer.mStack;
2141 } else {
2142 mActivityContainers.remove(stackId);
2143 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002144 }
2145 return null;
2146 }
2147
Craig Mautner967212c2013-04-13 21:10:58 -07002148 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002149 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002150 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2151 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002152 }
2153 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002154 }
2155
Craig Mautner4a1cb222013-12-04 16:14:06 -08002156 IBinder getHomeActivityToken() {
2157 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2158 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2159 final TaskRecord task = tasks.get(taskNdx);
2160 if (task.isHomeTask()) {
2161 final ArrayList<ActivityRecord> activities = task.mActivities;
2162 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2163 final ActivityRecord r = activities.get(activityNdx);
2164 if (r.isHomeActivity()) {
2165 return r.appToken;
2166 }
2167 }
2168 }
2169 }
2170 return null;
2171 }
2172
2173 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2174 IActivityContainerCallback callback) {
2175 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2176 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002177 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002178 if (parentActivity != null) {
2179 parentActivity.mChildContainers.add(activityContainer.mStack);
2180 }
2181 return activityContainer;
2182 }
2183
2184 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2185 IActivityContainerCallback callback) {
2186 return createActivityContainer(parentActivity, getNextStackId(), callback);
2187 }
2188
Craig Mautner34b73df2014-01-12 21:11:08 -08002189 void removeChildActivityContainers(ActivityRecord parentActivity) {
2190 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2191 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2192 if (container == null) {
2193 mActivityContainers.removeAt(ndx);
2194 continue;
2195 }
2196 if (container.mParentActivity != parentActivity) {
2197 continue;
2198 }
2199
2200 ActivityStack stack = container.mStack;
2201 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2202 if (top != null) {
2203 // TODO: Make sure the next activity doesn't start up when top is destroyed.
Craig Mautner95da1082014-02-24 17:54:35 -08002204 stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
Craig Mautner34b73df2014-01-12 21:11:08 -08002205 }
2206 mActivityContainers.removeAt(ndx);
2207 container.detachLocked();
2208 }
2209 }
2210
Craig Mautner95da1082014-02-24 17:54:35 -08002211 void deleteActivityContainer(IActivityContainer container) {
2212 ActivityContainer activityContainer = (ActivityContainer)container;
2213 if (activityContainer != null) {
2214 activityContainer.mStack.destroyActivitiesLocked(null, true,
2215 "deleteActivityContainer");
2216 final ActivityRecord parent = activityContainer.mParentActivity;
2217 if (parent != null) {
2218 parent.mChildContainers.remove(activityContainer);
2219 }
2220 final int stackId = activityContainer.mStackId;
2221 mActivityContainers.remove(stackId);
2222 mWindowManager.removeStack(stackId);
2223 }
2224 }
2225
Craig Mautner4a1cb222013-12-04 16:14:06 -08002226 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002227 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2228 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002229 return -1;
2230 }
2231
2232 ActivityContainer activityContainer =
2233 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002234 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002235 return stackId;
2236 }
2237
2238 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002239 while (true) {
2240 if (++mLastStackId <= HOME_STACK_ID) {
2241 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002242 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002243 if (getStack(mLastStackId) == null) {
2244 break;
2245 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002246 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002247 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002248 }
2249
2250 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002251 final TaskRecord task = anyTaskForIdLocked(taskId);
2252 if (task == null) {
2253 return;
2254 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002255 final ActivityStack stack = getStack(stackId);
2256 if (stack == null) {
2257 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2258 return;
2259 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002260 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002261 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002262 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002263 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002264 }
2265
Craig Mautnerac6f8432013-07-17 13:24:59 -07002266 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002267 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002268 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2269 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002270 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2271 final ActivityStack stack = stacks.get(stackNdx);
2272 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2273 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2274 continue;
2275 }
2276 final ActivityRecord ar = stack.findTaskLocked(r);
2277 if (ar != null) {
2278 return ar;
2279 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002280 }
2281 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002282 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002283 return null;
2284 }
2285
2286 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002287 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2288 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002289 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2290 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2291 if (ar != null) {
2292 return ar;
2293 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002294 }
2295 }
2296 return null;
2297 }
2298
Craig Mautner8d341ef2013-03-26 09:03:27 -07002299 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002300 scheduleSleepTimeout();
2301 if (!mGoingToSleep.isHeld()) {
2302 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002303 if (mLaunchingActivity.isHeld()) {
2304 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2305 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002306 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002307 mLaunchingActivity.release();
2308 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002309 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002310 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002311 checkReadyForSleepLocked();
Craig Mautneraea74a52014-03-08 14:23:10 -08002312 setLockTaskModeLocked(null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002313 }
2314
2315 boolean shutdownLocked(int timeout) {
2316 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002317 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002318
2319 final long endTime = System.currentTimeMillis() + timeout;
2320 while (true) {
2321 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002322 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2323 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002324 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2325 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2326 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002327 }
2328 if (cantShutdown) {
2329 long timeRemaining = endTime - System.currentTimeMillis();
2330 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002331 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002332 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002333 } catch (InterruptedException e) {
2334 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002335 } else {
2336 Slog.w(TAG, "Activity manager shutdown timed out");
2337 timedout = true;
2338 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002339 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002340 } else {
2341 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002342 }
2343 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002344
2345 // Force checkReadyForSleep to complete.
2346 mSleepTimeout = true;
2347 checkReadyForSleepLocked();
2348
Craig Mautner8d341ef2013-03-26 09:03:27 -07002349 return timedout;
2350 }
2351
2352 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002353 removeSleepTimeouts();
2354 if (mGoingToSleep.isHeld()) {
2355 mGoingToSleep.release();
2356 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002357 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2358 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002359 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2360 final ActivityStack stack = stacks.get(stackNdx);
2361 stack.awakeFromSleepingLocked();
2362 if (isFrontStack(stack)) {
2363 resumeTopActivitiesLocked();
2364 }
Craig Mautner5314a402013-09-26 12:40:16 -07002365 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002366 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002367 mGoingToSleepActivities.clear();
2368 }
2369
2370 void activitySleptLocked(ActivityRecord r) {
2371 mGoingToSleepActivities.remove(r);
2372 checkReadyForSleepLocked();
2373 }
2374
2375 void checkReadyForSleepLocked() {
2376 if (!mService.isSleepingOrShuttingDown()) {
2377 // Do not care.
2378 return;
2379 }
2380
2381 if (!mSleepTimeout) {
2382 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002383 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2384 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002385 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2386 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2387 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002388 }
2389
2390 if (mStoppingActivities.size() > 0) {
2391 // Still need to tell some activities to stop; can't sleep yet.
2392 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2393 + mStoppingActivities.size() + " activities");
2394 scheduleIdleLocked();
2395 dontSleep = true;
2396 }
2397
2398 if (mGoingToSleepActivities.size() > 0) {
2399 // Still need to tell some activities to sleep; can't sleep yet.
2400 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2401 + mGoingToSleepActivities.size() + " activities");
2402 dontSleep = true;
2403 }
2404
2405 if (dontSleep) {
2406 return;
2407 }
2408 }
2409
Craig Mautnere0a38842013-12-16 16:14:02 -08002410 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2411 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002412 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2413 stacks.get(stackNdx).goToSleep();
2414 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002415 }
2416
2417 removeSleepTimeouts();
2418
2419 if (mGoingToSleep.isHeld()) {
2420 mGoingToSleep.release();
2421 }
2422 if (mService.mShuttingDown) {
2423 mService.notifyAll();
2424 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002425 }
2426
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002427 boolean reportResumedActivityLocked(ActivityRecord r) {
2428 final ActivityStack stack = r.task.stack;
2429 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002430 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002431 }
2432 if (allResumedActivitiesComplete()) {
2433 ensureActivitiesVisibleLocked(null, 0);
2434 mWindowManager.executeAppTransition();
2435 return true;
2436 }
2437 return false;
2438 }
2439
Craig Mautner8d341ef2013-03-26 09:03:27 -07002440 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002441 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2442 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002443 final int numStacks = stacks.size();
2444 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2445 final ActivityStack stack = stacks.get(stackNdx);
2446 stack.handleAppCrashLocked(app);
2447 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002448 }
2449 }
2450
Craig Mautnerde4ef022013-04-07 19:01:33 -07002451 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002452 // First the front stacks. In case any are not fullscreen and are in front of home.
2453 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002454 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2455 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002456 final int topStackNdx = stacks.size() - 1;
2457 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2458 final ActivityStack stack = stacks.get(stackNdx);
2459 if (stackNdx == topStackNdx) {
2460 // Top stack.
2461 showHomeBehindStack =
2462 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2463 } else {
2464 // Back stack.
2465 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2466 showHomeBehindStack);
2467 }
Craig Mautner580ea812013-04-25 12:58:38 -07002468 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002469 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002470 }
2471
2472 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002473 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2474 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002475 final int numStacks = stacks.size();
2476 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2477 final ActivityStack stack = stacks.get(stackNdx);
2478 stack.scheduleDestroyActivities(app, false, reason);
2479 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002480 }
2481 }
2482
2483 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002484 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2485 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002486 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002487
Craig Mautner858d8a62013-04-23 17:08:34 -07002488 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002489 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2490 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002491 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002492 final ActivityStack stack = stacks.get(stackNdx);
2493 stack.switchUserLocked(userId);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002494 TaskRecord task = stack.topTask();
2495 if (task != null) {
2496 mWindowManager.moveTaskToTop(task.taskId);
2497 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002498 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002499 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002500
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002501 ActivityStack stack = getStack(restoreStackId);
2502 if (stack == null) {
2503 stack = mHomeStack;
2504 }
2505 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002506 if (stack.isOnHomeDisplay()) {
2507 moveHomeStack(homeInFront);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002508 TaskRecord task = stack.topTask();
2509 if (task != null) {
2510 mWindowManager.moveTaskToTop(task.taskId);
2511 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002512 } else {
2513 // Stack was moved to another display while user was swapped out.
2514 resumeHomeActivity(null);
2515 }
Craig Mautner93529a42013-10-04 15:03:13 -07002516 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002517 }
2518
Craig Mautnerde4ef022013-04-07 19:01:33 -07002519 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2520 int N = mStoppingActivities.size();
2521 if (N <= 0) return null;
2522
2523 ArrayList<ActivityRecord> stops = null;
2524
2525 final boolean nowVisible = allResumedActivitiesVisible();
2526 for (int i=0; i<N; i++) {
2527 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002528 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002529 + nowVisible + " waitingVisible=" + s.waitingVisible
2530 + " finishing=" + s.finishing);
2531 if (s.waitingVisible && nowVisible) {
2532 mWaitingVisibleActivities.remove(s);
2533 s.waitingVisible = false;
2534 if (s.finishing) {
2535 // If this activity is finishing, it is sitting on top of
2536 // everyone else but we now know it is no longer needed...
2537 // so get rid of it. Otherwise, we need to go through the
2538 // normal flow and hide it once we determine that it is
2539 // hidden by the activities in front of it.
2540 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002541 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002542 }
2543 }
2544 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2545 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2546 if (stops == null) {
2547 stops = new ArrayList<ActivityRecord>();
2548 }
2549 stops.add(s);
2550 mStoppingActivities.remove(i);
2551 N--;
2552 i--;
2553 }
2554 }
2555
2556 return stops;
2557 }
2558
Craig Mautnercf910b02013-04-23 11:23:27 -07002559 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002560 // FIXME
2561/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2562 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002563 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002564 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002565 if (isFrontStack(stack)) {
2566 if (r == null) {
2567 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2568 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002569 final ActivityRecord pausing = stack.mPausingActivity;
2570 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002571 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002572 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002573 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002574 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002575 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002576 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002577 }
2578 }
2579 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002580 final ActivityRecord resumed = stack.mResumedActivity;
2581 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002582 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002583 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002584 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002585 if (r != null && (state == ActivityState.INITIALIZING
2586 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002587 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002588 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002589 }
2590 }
2591 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002592*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002593 }
2594
Craig Mautner27084302013-03-25 08:05:25 -07002595 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002596 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002597 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002598 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002599 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002600 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2601 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2602 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002603 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002604 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002605
Craig Mautner20e72272013-04-01 13:45:53 -07002606 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002607 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002608 }
2609
Dianne Hackborn390517b2013-05-30 15:03:32 -07002610 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2611 boolean needSep, String prefix) {
2612 if (activity != null) {
2613 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2614 if (needSep) {
2615 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002616 }
2617 pw.print(prefix);
2618 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002619 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002620 }
2621 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002622 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002623 }
2624
Craig Mautner8d341ef2013-03-26 09:03:27 -07002625 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2626 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002627 boolean printed = false;
2628 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002629 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2630 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2631 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2632 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002633 final int numStacks = stacks.size();
2634 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2635 final ActivityStack stack = stacks.get(stackNdx);
2636 StringBuilder stackHeader = new StringBuilder(128);
2637 stackHeader.append(" Stack #");
2638 stackHeader.append(stack.mStackId);
2639 stackHeader.append(":");
2640 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2641 needSep, stackHeader.toString());
2642 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2643 !dumpAll, false, dumpPackage, true,
2644 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002645
Craig Mautner4a1cb222013-12-04 16:14:06 -08002646 needSep = printed;
2647 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2648 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002649 if (pr) {
2650 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002651 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002652 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002653 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2654 " mResumedActivity: ");
2655 if (pr) {
2656 printed = true;
2657 needSep = false;
2658 }
2659 if (dumpAll) {
2660 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2661 " mLastPausedActivity: ");
2662 if (pr) {
2663 printed = true;
2664 needSep = true;
2665 }
2666 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2667 needSep, " mLastNoHistoryActivity: ");
2668 }
2669 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002670 }
2671 }
2672
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002673 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2674 false, dumpPackage, true, " Activities waiting to finish:", null);
2675 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2676 false, dumpPackage, true, " Activities waiting to stop:", null);
2677 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2678 false, dumpPackage, true, " Activities waiting for another to become visible:",
2679 null);
2680 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2681 false, dumpPackage, true, " Activities waiting to sleep:", null);
2682 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2683 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002684
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002685 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002686 }
2687
Dianne Hackborn390517b2013-05-30 15:03:32 -07002688 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002689 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002690 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002691 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002692 String innerPrefix = null;
2693 String[] args = null;
2694 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002695 for (int i=list.size()-1; i>=0; i--) {
2696 final ActivityRecord r = list.get(i);
2697 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2698 continue;
2699 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002700 if (innerPrefix == null) {
2701 innerPrefix = prefix + " ";
2702 args = new String[0];
2703 }
2704 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002705 final boolean full = !brief && (complete || !r.isInHistory());
2706 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002707 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002708 needNL = false;
2709 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002710 if (header1 != null) {
2711 pw.println(header1);
2712 header1 = null;
2713 }
2714 if (header2 != null) {
2715 pw.println(header2);
2716 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002717 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002718 if (lastTask != r.task) {
2719 lastTask = r.task;
2720 pw.print(prefix);
2721 pw.print(full ? "* " : " ");
2722 pw.println(lastTask);
2723 if (full) {
2724 lastTask.dump(pw, prefix + " ");
2725 } else if (complete) {
2726 // Complete + brief == give a summary. Isn't that obvious?!?
2727 if (lastTask.intent != null) {
2728 pw.print(prefix); pw.print(" ");
2729 pw.println(lastTask.intent.toInsecureStringWithClip());
2730 }
2731 }
2732 }
2733 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2734 pw.print(" #"); pw.print(i); pw.print(": ");
2735 pw.println(r);
2736 if (full) {
2737 r.dump(pw, innerPrefix);
2738 } else if (complete) {
2739 // Complete + brief == give a summary. Isn't that obvious?!?
2740 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2741 if (r.app != null) {
2742 pw.print(innerPrefix); pw.println(r.app);
2743 }
2744 }
2745 if (client && r.app != null && r.app.thread != null) {
2746 // flush anything that is already in the PrintWriter since the thread is going
2747 // to write to the file descriptor directly
2748 pw.flush();
2749 try {
2750 TransferPipe tp = new TransferPipe();
2751 try {
2752 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2753 r.appToken, innerPrefix, args);
2754 // Short timeout, since blocking here can
2755 // deadlock with the application.
2756 tp.go(fd, 2000);
2757 } finally {
2758 tp.kill();
2759 }
2760 } catch (IOException e) {
2761 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2762 } catch (RemoteException e) {
2763 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2764 }
2765 needNL = true;
2766 }
2767 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002768 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002769 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002770
Craig Mautnerf3333272013-04-22 10:55:53 -07002771 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002772 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002773 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2774 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002775 }
2776
2777 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002778 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002779 }
2780
2781 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002782 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002783 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2784 }
2785
Craig Mautner05d29032013-05-03 13:40:13 -07002786 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002787 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2788 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2789 }
Craig Mautner05d29032013-05-03 13:40:13 -07002790 }
2791
Craig Mautner0eea92c2013-05-16 13:35:39 -07002792 void removeSleepTimeouts() {
2793 mSleepTimeout = false;
2794 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2795 }
2796
2797 final void scheduleSleepTimeout() {
2798 removeSleepTimeouts();
2799 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2800 }
2801
Craig Mautner4a1cb222013-12-04 16:14:06 -08002802 @Override
2803 public void onDisplayAdded(int displayId) {
2804 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2805 }
2806
2807 @Override
2808 public void onDisplayRemoved(int displayId) {
2809 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2810 }
2811
2812 @Override
2813 public void onDisplayChanged(int displayId) {
2814 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2815 }
2816
2817 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002818 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002819 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002820 newDisplay = mActivityDisplays.get(displayId) == null;
2821 if (newDisplay) {
2822 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2823 mActivityDisplays.put(displayId, activityDisplay);
2824 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002825 }
Craig Mautner4504de52013-12-20 09:06:56 -08002826 if (newDisplay) {
2827 mWindowManager.onDisplayAdded(displayId);
2828 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002829 }
2830
2831 public void handleDisplayRemovedLocked(int displayId) {
2832 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002833 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2834 if (activityDisplay != null) {
2835 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002836 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002837 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002838 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002839 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002840 }
2841 }
2842 mWindowManager.onDisplayRemoved(displayId);
2843 }
2844
2845 public void handleDisplayChangedLocked(int displayId) {
2846 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002847 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2848 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002849 // TODO: Update the bounds.
2850 }
2851 }
2852 mWindowManager.onDisplayChanged(displayId);
2853 }
2854
2855 StackInfo getStackInfo(ActivityStack stack) {
2856 StackInfo info = new StackInfo();
2857 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2858 info.displayId = Display.DEFAULT_DISPLAY;
2859 info.stackId = stack.mStackId;
2860
2861 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2862 final int numTasks = tasks.size();
2863 int[] taskIds = new int[numTasks];
2864 String[] taskNames = new String[numTasks];
2865 for (int i = 0; i < numTasks; ++i) {
2866 final TaskRecord task = tasks.get(i);
2867 taskIds[i] = task.taskId;
2868 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2869 : task.realActivity != null ? task.realActivity.flattenToString()
2870 : task.getTopActivity() != null ? task.getTopActivity().packageName
2871 : "unknown";
2872 }
2873 info.taskIds = taskIds;
2874 info.taskNames = taskNames;
2875 return info;
2876 }
2877
2878 StackInfo getStackInfoLocked(int stackId) {
2879 ActivityStack stack = getStack(stackId);
2880 if (stack != null) {
2881 return getStackInfo(stack);
2882 }
2883 return null;
2884 }
2885
2886 ArrayList<StackInfo> getAllStackInfosLocked() {
2887 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002888 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2889 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002890 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2891 list.add(getStackInfo(stacks.get(ndx)));
2892 }
2893 }
2894 return list;
2895 }
2896
Craig Mautneraea74a52014-03-08 14:23:10 -08002897 void setLockTaskModeLocked(TaskRecord task) {
2898 if (task == null) {
2899 // Take out of lock task mode.
2900 mLockTaskModeTask = null;
2901 return;
2902 }
2903 if (isLockTaskModeViolation(task)) {
2904 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2905 return;
2906 }
2907 mLockTaskModeTask = task;
2908 findTaskToMoveToFrontLocked(task, 0, null);
2909 resumeTopActivitiesLocked();
2910 }
2911
2912 boolean isLockTaskModeViolation(TaskRecord task) {
2913 return mLockTaskModeTask != null && mLockTaskModeTask != task;
2914 }
2915
2916 void endLockTaskModeIfTaskEnding(TaskRecord task) {
2917 if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
2918 mLockTaskModeTask = null;
2919 }
2920 }
2921
2922 boolean isInLockTaskMode() {
2923 return mLockTaskModeTask != null;
2924 }
2925
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002926 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002927
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002928 public ActivityStackSupervisorHandler(Looper looper) {
2929 super(looper);
2930 }
2931
Craig Mautnerf3333272013-04-22 10:55:53 -07002932 void activityIdleInternal(ActivityRecord r) {
2933 synchronized (mService) {
2934 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2935 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002936 }
2937
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002938 @Override
2939 public void handleMessage(Message msg) {
2940 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002941 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002942 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002943 if (mService.mDidDexOpt) {
2944 mService.mDidDexOpt = false;
2945 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2946 nmsg.obj = msg.obj;
2947 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2948 return;
2949 }
2950 // We don't at this point know if the activity is fullscreen,
2951 // so we need to be conservative and assume it isn't.
2952 activityIdleInternal((ActivityRecord)msg.obj);
2953 } break;
2954 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002955 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002956 activityIdleInternal((ActivityRecord)msg.obj);
2957 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002958 case RESUME_TOP_ACTIVITY_MSG: {
2959 synchronized (mService) {
2960 resumeTopActivitiesLocked();
2961 }
2962 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002963 case SLEEP_TIMEOUT_MSG: {
2964 synchronized (mService) {
2965 if (mService.isSleepingOrShuttingDown()) {
2966 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2967 mSleepTimeout = true;
2968 checkReadyForSleepLocked();
2969 }
2970 }
2971 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002972 case LAUNCH_TIMEOUT_MSG: {
2973 if (mService.mDidDexOpt) {
2974 mService.mDidDexOpt = false;
2975 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2976 return;
2977 }
2978 synchronized (mService) {
2979 if (mLaunchingActivity.isHeld()) {
2980 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2981 if (VALIDATE_WAKE_LOCK_CALLER
2982 && Binder.getCallingUid() != Process.myUid()) {
2983 throw new IllegalStateException("Calling must be system uid");
2984 }
2985 mLaunchingActivity.release();
2986 }
2987 }
2988 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002989 case HANDLE_DISPLAY_ADDED: {
2990 handleDisplayAddedLocked(msg.arg1);
2991 } break;
2992 case HANDLE_DISPLAY_CHANGED: {
2993 handleDisplayChangedLocked(msg.arg1);
2994 } break;
2995 case HANDLE_DISPLAY_REMOVED: {
2996 handleDisplayRemovedLocked(msg.arg1);
2997 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002998 }
2999 }
3000 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003001
Craig Mautner4a1cb222013-12-04 16:14:06 -08003002 class ActivityContainer extends IActivityContainer.Stub {
3003 final int mStackId;
3004 final IActivityContainerCallback mCallback;
3005 final ActivityStack mStack;
3006 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08003007 final String mIdString;
Craig Mautnered6649f2013-12-02 14:08:25 -08003008
Craig Mautner4a1cb222013-12-04 16:14:06 -08003009 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08003010 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003011
3012 ActivityContainer(ActivityRecord parentActivity, int stackId,
3013 IActivityContainerCallback callback) {
3014 synchronized (mService) {
3015 mStackId = stackId;
3016 mStack = new ActivityStack(this);
3017 mParentActivity = parentActivity;
3018 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08003019 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3020 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003021 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003022 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003023
Craig Mautnere0a38842013-12-16 16:14:02 -08003024 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003025 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3026 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08003027 mActivityDisplay = activityDisplay;
3028 mStack.mDisplayId = activityDisplay.mDisplayId;
3029 mStack.mStacks = activityDisplay.mStacks;
3030
3031 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003032 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003033 }
3034
3035 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003036 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003037 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003038 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3039 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003040 return;
3041 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003042 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003043 }
3044 }
3045
3046 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003047 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003048 if (mActivityDisplay != null) {
3049 return mActivityDisplay.mDisplayId;
3050 }
3051 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003052 }
3053
Jeff Brownca9bc702014-02-11 14:32:56 -08003054 @Override
3055 public boolean injectEvent(InputEvent event) {
3056 final long origId = Binder.clearCallingIdentity();
3057 try {
3058 if (mActivityDisplay != null) {
3059 return mInputManagerInternal.injectInputEvent(event,
3060 mActivityDisplay.mDisplayId,
3061 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3062 }
3063 return false;
3064 } finally {
3065 Binder.restoreCallingIdentity(origId);
3066 }
3067 }
3068
Craig Mautner34b73df2014-01-12 21:11:08 -08003069 private void detachLocked() {
3070 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3071 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003072 if (mActivityDisplay != null) {
3073 mActivityDisplay.detachActivitiesLocked(mStack);
3074 mActivityDisplay = null;
3075 mStack.mDisplayId = -1;
3076 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003077 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003078 }
3079 }
3080
3081 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003082 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003083 synchronized (mService) {
3084 detachLocked();
3085 }
3086 }
3087
3088 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003089 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003090 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003091 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3092 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3093 // TODO: Switch to user app stacks here.
3094 String mimeType = intent.getType();
3095 if (mimeType == null && intent.getData() != null
3096 && "content".equals(intent.getData().getScheme())) {
3097 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3098 }
3099 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3100 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003101 }
3102
3103 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003104 public final int startActivityIntentSender(IIntentSender intentSender) {
3105 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3106
3107 if (!(intentSender instanceof PendingIntentRecord)) {
3108 throw new IllegalArgumentException("Bad PendingIntent object");
3109 }
3110
3111 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3112 null, 0, 0, 0, null, this);
3113 }
3114
3115 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003116 public IBinder asBinder() {
3117 return this;
3118 }
3119
Craig Mautner4504de52013-12-20 09:06:56 -08003120 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003121 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003122 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3123
3124 final long origId = Binder.clearCallingIdentity();
3125 try {
3126 synchronized (mService) {
3127 ActivityDisplay activityDisplay =
3128 new ActivityDisplay(surface, width, height, density);
3129 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3130 attachToDisplayLocked(activityDisplay);
3131 mStack.resumeTopActivityLocked(null);
3132 }
3133 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3134 + mActivityDisplay);
3135 } finally {
3136 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003137 }
Craig Mautner4504de52013-12-20 09:06:56 -08003138 }
3139
Craig Mautner4a1cb222013-12-04 16:14:06 -08003140 ActivityStackSupervisor getOuter() {
3141 return ActivityStackSupervisor.this;
3142 }
3143
3144 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003145 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003146 }
3147
3148 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003149 if (mActivityDisplay != null) {
3150 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003151 } else {
3152 outBounds.set(0, 0);
3153 }
3154 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003155
3156 @Override
3157 public String toString() {
3158 return mIdString + (mActivityDisplay == null ? "N" : "A");
3159 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003160 }
3161
Craig Mautner4a1cb222013-12-04 16:14:06 -08003162 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3163 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003164 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003165 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003166 int mDisplayId;
3167 Display mDisplay;
3168 DisplayInfo mDisplayInfo = new DisplayInfo();
3169 Surface mSurface;
Craig Mautnered6649f2013-12-02 14:08:25 -08003170
Craig Mautner4a1cb222013-12-04 16:14:06 -08003171 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3172 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003173 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003174
Craig Mautner4504de52013-12-20 09:06:56 -08003175 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3176 * here. */
3177 VirtualDisplay mVirtualDisplay;
3178
Craig Mautnere0a38842013-12-16 16:14:02 -08003179 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003180 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003181 }
3182
Craig Mautner34b73df2014-01-12 21:11:08 -08003183 ActivityDisplay(Surface surface, int width, int height, int density) {
3184 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3185 long ident = Binder.clearCallingIdentity();
3186 try {
3187 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3188 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3189 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3190 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3191 } finally {
3192 Binder.restoreCallingIdentity(ident);
3193 }
3194
3195 init(mVirtualDisplay.getDisplay());
3196 mSurface = surface;
3197
3198 mWindowManager.handleDisplayAdded(mDisplayId);
3199 }
3200
3201 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003202 mDisplay = display;
3203 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003204 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnered6649f2013-12-02 14:08:25 -08003205 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003206
3207 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003208 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3209 + mDisplayId);
3210 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003211 }
3212
Craig Mautnere0a38842013-12-16 16:14:02 -08003213 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003214 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003215 + " from displayId=" + mDisplayId);
3216 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003217 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3218 mVirtualDisplay.release();
3219 mVirtualDisplay = null;
3220 }
3221 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003222 }
3223
3224 void getBounds(Point bounds) {
3225 mDisplay.getDisplayInfo(mDisplayInfo);
3226 bounds.x = mDisplayInfo.appWidth;
3227 bounds.y = mDisplayInfo.appHeight;
3228 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003229
3230 @Override
3231 public String toString() {
3232 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3233 + " numStacks=" + mStacks.size() + "}";
3234 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003235 }
Craig Mautner27084302013-03-25 08:05:25 -07003236}